PageRenderTime 48ms CodeModel.GetById 14ms app.highlight 29ms RepoModel.GetById 1ms app.codeStats 0ms

/src/dump_yaml.c

https://code.google.com/
C | 429 lines | 296 code | 94 blank | 39 comment | 18 complexity | 8f79d36164538a9f2f7f63fd574133db MD5 | raw file
  1/*
  2    $Id: dump_yaml.c 231 2011-06-27 13:46:19Z marc.noirot $
  3
  4    FLV Metadata updater
  5
  6    Copyright (C) 2007-2012 Marc Noirot <marc.noirot AT gmail.com>
  7
  8    This file is part of FLVMeta.
  9
 10    FLVMeta is free software; you can redistribute it and/or modify
 11    it under the terms of the GNU General Public License as published by
 12    the Free Software Foundation; either version 2 of the License, or
 13    (at your option) any later version.
 14
 15    FLVMeta is distributed in the hope that it will be useful,
 16    but WITHOUT ANY WARRANTY; without even the implied warranty of
 17    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 18    GNU General Public License for more details.
 19
 20    You should have received a copy of the GNU General Public License
 21    along with FLVMeta; if not, write to the Free Software
 22    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 23*/
 24#include "dump.h"
 25#include "dump_yaml.h"
 26#include "yaml.h"
 27
 28#include <stdio.h>
 29#include <string.h>
 30
 31/* YAML metadata dumping */
 32static void amf_data_yaml_dump(const amf_data * data, yaml_emitter_t * emitter) {
 33    if (data != NULL) {
 34        amf_node * node;
 35        yaml_event_t event;
 36        time_t time;
 37        struct tm * t;
 38        char str[128];
 39
 40        switch (data->type) {
 41            case AMF_TYPE_NUMBER:
 42                sprintf(str, "%.12g", data->number_data);
 43                yaml_scalar_event_initialize(&event, NULL, NULL, (yaml_char_t*)str, (int)strlen(str), 1, 1, YAML_ANY_SCALAR_STYLE);
 44                yaml_emitter_emit(emitter, &event);
 45                break;
 46            case AMF_TYPE_BOOLEAN:
 47                sprintf(str, (data->boolean_data) ? "true" : "false");
 48                yaml_scalar_event_initialize(&event, NULL, NULL, (yaml_char_t*)str, (int)strlen(str), 1, 1, YAML_ANY_SCALAR_STYLE);
 49                yaml_emitter_emit(emitter, &event);
 50                break;
 51            case AMF_TYPE_STRING:
 52                yaml_scalar_event_initialize(&event, NULL, NULL, amf_string_get_bytes(data), (int)amf_string_get_size(data), 1, 1, YAML_ANY_SCALAR_STYLE);
 53                yaml_emitter_emit(emitter, &event);
 54                break;
 55            case AMF_TYPE_OBJECT:
 56                yaml_mapping_start_event_initialize(&event, NULL, NULL, 1, YAML_ANY_MAPPING_STYLE);
 57                yaml_emitter_emit(emitter, &event);
 58                node = amf_object_first(data);
 59                while (node != NULL) {
 60                    amf_data * name;
 61                    name = amf_object_get_name(node);
 62                    /* if this fails, we skip the current entry */
 63                    if (yaml_scalar_event_initialize(&event, NULL, NULL, amf_string_get_bytes(name), amf_string_get_size(name), 1, 1, YAML_ANY_SCALAR_STYLE)) {
 64                        yaml_emitter_emit(emitter, &event);
 65                        amf_data_yaml_dump(amf_object_get_data(node), emitter);
 66                    }
 67                    node = amf_object_next(node);
 68                }
 69                yaml_mapping_end_event_initialize(&event);
 70                yaml_emitter_emit(emitter, &event);
 71                break;
 72            case AMF_TYPE_NULL:
 73            case AMF_TYPE_UNDEFINED:
 74                yaml_scalar_event_initialize(&event, NULL, NULL, (yaml_char_t*)"null", 4, 1, 1, YAML_ANY_SCALAR_STYLE);
 75                yaml_emitter_emit(emitter, &event);
 76                break;
 77            case AMF_TYPE_ASSOCIATIVE_ARRAY:
 78                yaml_mapping_start_event_initialize(&event, NULL, NULL, 1, YAML_ANY_MAPPING_STYLE);
 79                yaml_emitter_emit(emitter, &event);
 80                node = amf_associative_array_first(data);
 81                while (node != NULL) {
 82                    amf_data * name;
 83                    name = amf_associative_array_get_name(node);
 84                    /* if this fails, we skip the current entry */
 85                    if (yaml_scalar_event_initialize(&event, NULL, NULL, amf_string_get_bytes(name), amf_string_get_size(name), 1, 1, YAML_ANY_SCALAR_STYLE)) {
 86                        yaml_emitter_emit(emitter, &event);
 87                        amf_data_yaml_dump(amf_associative_array_get_data(node), emitter);
 88                    }
 89                    node = amf_associative_array_next(node);
 90                }
 91                yaml_mapping_end_event_initialize(&event);
 92                yaml_emitter_emit(emitter, &event);
 93                break;
 94            case AMF_TYPE_ARRAY:
 95                yaml_sequence_start_event_initialize(&event, NULL, NULL, 1, YAML_ANY_SEQUENCE_STYLE);
 96                yaml_emitter_emit(emitter, &event);
 97                node = amf_array_first(data);
 98                while (node != NULL) {
 99                    amf_data_yaml_dump(amf_array_get(node), emitter);
100                    node = amf_array_next(node);
101                }
102                yaml_sequence_end_event_initialize(&event);
103                yaml_emitter_emit(emitter, &event);
104                break;
105            case AMF_TYPE_DATE:
106                time = amf_date_to_time_t(data);
107                tzset();
108                t = localtime(&time);
109                strftime(str, sizeof(str), "%Y-%m-%dT%H:%M:%S", t);
110                yaml_scalar_event_initialize(&event, NULL, NULL, (yaml_char_t*)str, (int)strlen(str), 1, 1, YAML_ANY_SCALAR_STYLE);
111                yaml_emitter_emit(emitter, &event);
112                break;
113            case AMF_TYPE_XML: break;
114            case AMF_TYPE_CLASS: break;
115            default: break;
116        }
117    }
118}
119
120/* YAML FLV file full dump callbacks */
121
122static int yaml_on_header(flv_header * header, flv_parser * parser) {
123    yaml_emitter_t * emitter;
124    yaml_event_t event;
125    char buffer[20];
126
127    emitter = (yaml_emitter_t *)parser->user_data;
128
129    yaml_mapping_start_event_initialize(&event, NULL, NULL, 1, YAML_ANY_MAPPING_STYLE);
130    yaml_emitter_emit(emitter, &event);
131
132    /* magic */
133    yaml_scalar_event_initialize(&event, NULL, NULL, (yaml_char_t*)"magic", 5, 1, 1, YAML_ANY_SCALAR_STYLE);
134    yaml_emitter_emit(emitter, &event);
135
136    sprintf(buffer, "%.3s", header->signature);
137    yaml_scalar_event_initialize(&event, NULL, NULL, (yaml_char_t*)buffer, (int)strlen(buffer), 1, 1, YAML_ANY_SCALAR_STYLE);
138    yaml_emitter_emit(emitter, &event);
139
140    /* hasVideo */
141    yaml_scalar_event_initialize(&event, NULL, NULL, (yaml_char_t*)"hasVideo", 8, 1, 1, YAML_ANY_SCALAR_STYLE);
142    yaml_emitter_emit(emitter, &event);
143
144    sprintf(buffer, "%s", flv_header_has_video(*header) ? "true" : "false");
145    yaml_scalar_event_initialize(&event, NULL, NULL, (yaml_char_t*)buffer, (int)strlen(buffer), 1, 1, YAML_ANY_SCALAR_STYLE);
146    yaml_emitter_emit(emitter, &event);
147
148    /* hasAudio */
149    yaml_scalar_event_initialize(&event, NULL, NULL, (yaml_char_t*)"hasAudio", 8, 1, 1, YAML_ANY_SCALAR_STYLE);
150    yaml_emitter_emit(emitter, &event);
151
152    sprintf(buffer, "%s", flv_header_has_audio(*header) ? "true" : "false");
153    yaml_scalar_event_initialize(&event, NULL, NULL, (yaml_char_t*)buffer, (int)strlen(buffer), 1, 1, YAML_ANY_SCALAR_STYLE);
154    yaml_emitter_emit(emitter, &event);
155
156    /* version */
157    yaml_scalar_event_initialize(&event, NULL, NULL, (yaml_char_t*)"version", 7, 1, 1, YAML_ANY_SCALAR_STYLE);
158    yaml_emitter_emit(emitter, &event);
159
160    sprintf(buffer, "%i", header->version);
161    yaml_scalar_event_initialize(&event, NULL, NULL, (yaml_char_t*)buffer, (int)strlen(buffer), 1, 1, YAML_ANY_SCALAR_STYLE);
162    yaml_emitter_emit(emitter, &event);
163
164    /* start of tags array */
165    yaml_scalar_event_initialize(&event, NULL, NULL, (yaml_char_t*)"tags", 4, 1, 1, YAML_ANY_SCALAR_STYLE);
166    yaml_emitter_emit(emitter, &event);
167
168    yaml_sequence_start_event_initialize(&event, NULL, NULL, 1, YAML_ANY_SEQUENCE_STYLE);
169    yaml_emitter_emit(emitter, &event);
170
171    return OK;
172}
173
174static int yaml_on_tag(flv_tag * tag, flv_parser * parser) {
175    const char * str;
176    yaml_emitter_t * emitter;
177    yaml_event_t event;
178    char buffer[20];
179
180    emitter = (yaml_emitter_t *)parser->user_data;
181
182    str = dump_string_get_tag_type(tag);
183
184    yaml_mapping_start_event_initialize(&event, NULL, NULL, 1, YAML_ANY_MAPPING_STYLE);
185    yaml_emitter_emit(emitter, &event);
186
187    /* type */
188    yaml_scalar_event_initialize(&event, NULL, NULL, (yaml_char_t*)"type", 4, 1, 1, YAML_ANY_SCALAR_STYLE);
189    yaml_emitter_emit(emitter, &event);
190
191    yaml_scalar_event_initialize(&event, NULL, NULL, (yaml_char_t*)str, (int)strlen(str), 1, 1, YAML_ANY_SCALAR_STYLE);
192    yaml_emitter_emit(emitter, &event);
193
194    /* timestamp */
195    yaml_scalar_event_initialize(&event, NULL, NULL, (yaml_char_t*)"timestamp", 9, 1, 1, YAML_ANY_SCALAR_STYLE);
196    yaml_emitter_emit(emitter, &event);
197
198    sprintf(buffer, "%i", flv_tag_get_timestamp(*tag));
199    yaml_scalar_event_initialize(&event, NULL, NULL, (yaml_char_t*)buffer, (int)strlen(buffer), 1, 1, YAML_ANY_SCALAR_STYLE);
200    yaml_emitter_emit(emitter, &event);
201
202    /* data size */
203    yaml_scalar_event_initialize(&event, NULL, NULL, (yaml_char_t*)"dataSize", 8, 1, 1, YAML_ANY_SCALAR_STYLE);
204    yaml_emitter_emit(emitter, &event);
205
206    sprintf(buffer, "%i", flv_tag_get_body_length(*tag));
207    yaml_scalar_event_initialize(&event, NULL, NULL, (yaml_char_t*)buffer, (int)strlen(buffer), 1, 1, YAML_ANY_SCALAR_STYLE);
208    yaml_emitter_emit(emitter, &event);
209
210    /* offset */
211    yaml_scalar_event_initialize(&event, NULL, NULL, (yaml_char_t*)"offset", 6, 1, 1, YAML_ANY_SCALAR_STYLE);
212    yaml_emitter_emit(emitter, &event);
213
214    sprintf(buffer, "%" FILE_OFFSET_PRINTF_FORMAT "i", parser->stream->current_tag_offset);
215    yaml_scalar_event_initialize(&event, NULL, NULL, (yaml_char_t*)buffer, (int)strlen(buffer), 1, 1, YAML_ANY_SCALAR_STYLE);
216    yaml_emitter_emit(emitter, &event);
217
218    return OK;
219}
220
221static int yaml_on_video_tag(flv_tag * tag, flv_video_tag vt, flv_parser * parser) {
222    const char * str;
223    yaml_emitter_t * emitter;
224    yaml_event_t event;
225
226    emitter = (yaml_emitter_t *)parser->user_data;
227
228    yaml_scalar_event_initialize(&event, NULL, NULL, (yaml_char_t*)"videoData", 9, 1, 1, YAML_ANY_SCALAR_STYLE);
229    yaml_emitter_emit(emitter, &event);
230
231    yaml_mapping_start_event_initialize(&event, NULL, NULL, 1, YAML_ANY_MAPPING_STYLE);
232    yaml_emitter_emit(emitter, &event);
233
234    str = dump_string_get_video_codec(vt);
235
236    yaml_scalar_event_initialize(&event, NULL, NULL, (yaml_char_t*)"codecID", 7, 1, 1, YAML_ANY_SCALAR_STYLE);
237    yaml_emitter_emit(emitter, &event);
238
239    yaml_scalar_event_initialize(&event, NULL, NULL, (yaml_char_t*)str, (int)strlen(str), 1, 1, YAML_ANY_SCALAR_STYLE);
240    yaml_emitter_emit(emitter, &event);
241
242    str = dump_string_get_video_frame_type(vt);
243
244    yaml_scalar_event_initialize(&event, NULL, NULL, (yaml_char_t*)"frameType", 9, 1, 1, YAML_ANY_SCALAR_STYLE);
245    yaml_emitter_emit(emitter, &event);
246
247    yaml_scalar_event_initialize(&event, NULL, NULL, (yaml_char_t*)str, (int)strlen(str), 1, 1, YAML_ANY_SCALAR_STYLE);
248    yaml_emitter_emit(emitter, &event);
249
250    yaml_mapping_end_event_initialize(&event);
251    yaml_emitter_emit(emitter, &event);
252
253    return OK;
254}
255
256static int yaml_on_audio_tag(flv_tag * tag, flv_audio_tag at, flv_parser * parser) {
257    const char * str;
258    yaml_emitter_t * emitter;
259    yaml_event_t event;
260
261    emitter = (yaml_emitter_t *)parser->user_data;
262
263    yaml_scalar_event_initialize(&event, NULL, NULL, (yaml_char_t*)"audioData", 9, 1, 1, YAML_ANY_SCALAR_STYLE);
264    yaml_emitter_emit(emitter, &event);
265
266    yaml_mapping_start_event_initialize(&event, NULL, NULL, 1, YAML_ANY_MAPPING_STYLE);
267    yaml_emitter_emit(emitter, &event);
268
269    str = dump_string_get_sound_type(at);
270
271    yaml_scalar_event_initialize(&event, NULL, NULL, (yaml_char_t*)"type", 4, 1, 1, YAML_ANY_SCALAR_STYLE);
272    yaml_emitter_emit(emitter, &event);
273
274    yaml_scalar_event_initialize(&event, NULL, NULL, (yaml_char_t*)str, (int)strlen(str), 1, 1, YAML_ANY_SCALAR_STYLE);
275    yaml_emitter_emit(emitter, &event);
276
277    str = dump_string_get_sound_size(at);
278
279    yaml_scalar_event_initialize(&event, NULL, NULL, (yaml_char_t*)"size", 4, 1, 1, YAML_ANY_SCALAR_STYLE);
280    yaml_emitter_emit(emitter, &event);
281
282    yaml_scalar_event_initialize(&event, NULL, NULL, (yaml_char_t*)str, (int)strlen(str), 1, 1, YAML_ANY_SCALAR_STYLE);
283    yaml_emitter_emit(emitter, &event);
284
285    str = dump_string_get_sound_rate(at);
286
287    yaml_scalar_event_initialize(&event, NULL, NULL, (yaml_char_t*)"rate", 4, 1, 1, YAML_ANY_SCALAR_STYLE);
288    yaml_emitter_emit(emitter, &event);
289
290    yaml_scalar_event_initialize(&event, NULL, NULL, (yaml_char_t*)str, (int)strlen(str), 1, 1, YAML_ANY_SCALAR_STYLE);
291    yaml_emitter_emit(emitter, &event);
292
293    str = dump_string_get_sound_format(at);
294
295    yaml_scalar_event_initialize(&event, NULL, NULL, (yaml_char_t*)"format", 6, 1, 1, YAML_ANY_SCALAR_STYLE);
296    yaml_emitter_emit(emitter, &event);
297
298    yaml_scalar_event_initialize(&event, NULL, NULL, (yaml_char_t*)str, (int)strlen(str), 1, 1, YAML_ANY_SCALAR_STYLE);
299    yaml_emitter_emit(emitter, &event);
300
301    yaml_mapping_end_event_initialize(&event);
302    yaml_emitter_emit(emitter, &event);
303
304    return OK;
305}
306
307static int yaml_on_metadata_tag(flv_tag * tag, amf_data * name, amf_data * data, flv_parser * parser) {
308    yaml_emitter_t * emitter;
309    yaml_event_t event;
310
311    emitter = (yaml_emitter_t *)parser->user_data;
312
313    yaml_scalar_event_initialize(&event, NULL, NULL, (yaml_char_t*)"scriptDataObject", 16, 1, 1, YAML_ANY_SCALAR_STYLE);
314    yaml_emitter_emit(emitter, &event);
315
316    amf_data_yaml_dump(data, emitter);
317
318    return OK;
319}
320
321static int yaml_on_prev_tag_size(uint32 size, flv_parser * parser) {
322    yaml_emitter_t * emitter;
323    yaml_event_t event;
324
325    emitter = (yaml_emitter_t *)parser->user_data;
326
327    yaml_mapping_end_event_initialize(&event);
328    yaml_emitter_emit(emitter, &event);
329
330    return OK;
331}
332
333static int yaml_on_stream_end(flv_parser * parser) {
334    yaml_emitter_t * emitter;
335    yaml_event_t event;
336
337    emitter = (yaml_emitter_t *)parser->user_data;
338
339    yaml_sequence_end_event_initialize(&event);
340    yaml_emitter_emit(emitter, &event);
341
342    yaml_mapping_end_event_initialize(&event);
343    yaml_emitter_emit(emitter, &event);
344
345    return OK;
346}
347
348/* YAML FLV file metadata dump callbacks */
349static int yaml_on_metadata_tag_only(flv_tag * tag, amf_data * name, amf_data * data, flv_parser * parser) {
350    flvmeta_opts * options = (flvmeta_opts*) parser->user_data;
351
352    if (options->metadata_event == NULL) {
353        if (!strcmp((char*)amf_string_get_bytes(name), "onMetaData")) {
354            dump_yaml_amf_data(data);
355            return FLVMETA_DUMP_STOP_OK;
356        }
357    }
358    else {
359        if (!strcmp((char*)amf_string_get_bytes(name), options->metadata_event)) {
360            dump_yaml_amf_data(data);
361        }
362    }
363    return OK;
364}
365
366/* dumping functions */
367void dump_yaml_setup_metadata_dump(flv_parser * parser) {
368    if (parser != NULL) {
369        parser->on_metadata_tag = yaml_on_metadata_tag_only;
370    }
371}
372
373int dump_yaml_file(flv_parser * parser, const flvmeta_opts * options) {
374    yaml_emitter_t emitter;
375    yaml_event_t event;
376    int ret;
377    
378    parser->on_header = yaml_on_header;
379    parser->on_tag = yaml_on_tag;
380    parser->on_audio_tag = yaml_on_audio_tag;
381    parser->on_video_tag = yaml_on_video_tag;
382    parser->on_metadata_tag = yaml_on_metadata_tag;
383    parser->on_prev_tag_size = yaml_on_prev_tag_size;
384    parser->on_stream_end = yaml_on_stream_end;
385
386    yaml_emitter_initialize(&emitter);
387    yaml_emitter_set_output_file(&emitter, stdout);
388    yaml_emitter_open(&emitter);
389
390    yaml_document_start_event_initialize(&event, NULL, NULL, NULL, 0);
391    yaml_emitter_emit(&emitter, &event);
392    
393    parser->user_data = &emitter;
394
395    ret = flv_parse(options->input_file, parser);
396
397    yaml_document_end_event_initialize(&event, 1);
398    yaml_emitter_emit(&emitter, &event);
399
400    yaml_emitter_flush(&emitter);
401    yaml_emitter_close(&emitter);
402    yaml_emitter_delete(&emitter);
403
404    return ret;
405}
406
407int dump_yaml_amf_data(const amf_data * data) {
408    yaml_emitter_t emitter;
409    yaml_event_t event;
410
411    yaml_emitter_initialize(&emitter);
412    yaml_emitter_set_output_file(&emitter, stdout);
413    yaml_emitter_open(&emitter);
414
415    yaml_document_start_event_initialize(&event, NULL, NULL, NULL, 0);
416    yaml_emitter_emit(&emitter, &event);
417
418    /* dump AMF into YAML */
419    amf_data_yaml_dump(data, &emitter);
420
421    yaml_document_end_event_initialize(&event, 1);
422    yaml_emitter_emit(&emitter, &event);
423
424    yaml_emitter_flush(&emitter);
425    yaml_emitter_close(&emitter);
426    yaml_emitter_delete(&emitter);
427
428    return OK;
429}