diff options
Diffstat (limited to 'src/plugins/asf_extractor.c')
-rw-r--r-- | src/plugins/asf_extractor.c | 491 |
1 files changed, 144 insertions, 347 deletions
diff --git a/src/plugins/asf_extractor.c b/src/plugins/asf_extractor.c index ea8b803..459af86 100644 --- a/src/plugins/asf_extractor.c +++ b/src/plugins/asf_extractor.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | This file is part of libextractor. | 2 | This file is part of libextractor. |
3 | (C) 2002, 2003 Vidyut Samanta and Christian Grothoff | 3 | (C) 2002, 2003, 2011 Vidyut Samanta and Christian Grothoff |
4 | 4 | ||
5 | libextractor is free software; you can redistribute it and/or modify | 5 | libextractor is free software; you can redistribute it and/or modify |
6 | it under the terms of the GNU General Public License as published | 6 | it under the terms of the GNU General Public License as published |
@@ -53,28 +53,20 @@ | |||
53 | 53 | ||
54 | #include "platform.h" | 54 | #include "platform.h" |
55 | #include "extractor.h" | 55 | #include "extractor.h" |
56 | #include "convert.h" | ||
57 | #include <stdint.h> | ||
56 | 58 | ||
57 | #define CODEC_TYPE_AUDIO 0 | ||
58 | #define CODEC_TYPE_VIDEO 1 | ||
59 | #define CODEC_TYPE_CONTROL 2 | ||
60 | #define MAX_NUM_STREAMS 23 | ||
61 | |||
62 | #define DEFRAG_BUFSIZE 65536 | ||
63 | #define DEMUX_START 1 | ||
64 | #define DEMUX_FINISHED 0 | 59 | #define DEMUX_FINISHED 0 |
60 | #define DEMUX_START 1 | ||
65 | 61 | ||
66 | 62 | ||
67 | /* | 63 | /* |
68 | * define asf GUIDs (list from avifile) | 64 | * define asf GUIDs (list from avifile) |
69 | */ | 65 | */ |
70 | #define GUID_ERROR 0 | 66 | #define GUID_ERROR 0 |
71 | |||
72 | /* base ASF objects */ | ||
73 | #define GUID_ASF_HEADER 1 | 67 | #define GUID_ASF_HEADER 1 |
74 | #define GUID_ASF_DATA 2 | 68 | #define GUID_ASF_DATA 2 |
75 | #define GUID_ASF_SIMPLE_INDEX 3 | 69 | #define GUID_ASF_SIMPLE_INDEX 3 |
76 | |||
77 | /* header ASF objects */ | ||
78 | #define GUID_ASF_FILE_PROPERTIES 4 | 70 | #define GUID_ASF_FILE_PROPERTIES 4 |
79 | #define GUID_ASF_STREAM_PROPERTIES 5 | 71 | #define GUID_ASF_STREAM_PROPERTIES 5 |
80 | #define GUID_ASF_STREAM_BITRATE_PROPERTIES 6 | 72 | #define GUID_ASF_STREAM_BITRATE_PROPERTIES 6 |
@@ -88,33 +80,16 @@ | |||
88 | #define GUID_ASF_EXTENDED_CONTENT_DESCRIPTION 14 | 80 | #define GUID_ASF_EXTENDED_CONTENT_DESCRIPTION 14 |
89 | #define GUID_ASF_ERROR_CORRECTION 15 | 81 | #define GUID_ASF_ERROR_CORRECTION 15 |
90 | #define GUID_ASF_PADDING 16 | 82 | #define GUID_ASF_PADDING 16 |
91 | |||
92 | /* stream properties object stream type */ | ||
93 | #define GUID_ASF_AUDIO_MEDIA 17 | 83 | #define GUID_ASF_AUDIO_MEDIA 17 |
94 | #define GUID_ASF_VIDEO_MEDIA 18 | 84 | #define GUID_ASF_VIDEO_MEDIA 18 |
95 | #define GUID_ASF_COMMAND_MEDIA 19 | 85 | #define GUID_ASF_COMMAND_MEDIA 19 |
96 | |||
97 | /* stream properties object error correction type */ | ||
98 | #define GUID_ASF_NO_ERROR_CORRECTION 20 | 86 | #define GUID_ASF_NO_ERROR_CORRECTION 20 |
99 | #define GUID_ASF_AUDIO_SPREAD 21 | 87 | #define GUID_ASF_AUDIO_SPREAD 21 |
100 | |||
101 | /* mutual exclusion object exlusion type */ | ||
102 | #define GUID_ASF_MUTEX_BITRATE 22 | 88 | #define GUID_ASF_MUTEX_BITRATE 22 |
103 | #define GUID_ASF_MUTEX_UKNOWN 23 | 89 | #define GUID_ASF_MUTEX_UKNOWN 23 |
104 | |||
105 | /* header extension */ | ||
106 | #define GUID_ASF_RESERVED_1 24 | 90 | #define GUID_ASF_RESERVED_1 24 |
107 | |||
108 | /* script command */ | ||
109 | #define GUID_ASF_RESERVED_SCRIPT_COMMNAND 25 | 91 | #define GUID_ASF_RESERVED_SCRIPT_COMMNAND 25 |
110 | |||
111 | /* marker object */ | ||
112 | #define GUID_ASF_RESERVED_MARKER 26 | 92 | #define GUID_ASF_RESERVED_MARKER 26 |
113 | |||
114 | /* various */ | ||
115 | /* | ||
116 | #define GUID_ASF_HEAD2 27 | ||
117 | */ | ||
118 | #define GUID_ASF_AUDIO_CONCEAL_NONE 27 | 93 | #define GUID_ASF_AUDIO_CONCEAL_NONE 27 |
119 | #define GUID_ASF_CODEC_COMMENT1_HEADER 28 | 94 | #define GUID_ASF_CODEC_COMMENT1_HEADER 28 |
120 | #define GUID_ASF_2_0_HEADER 29 | 95 | #define GUID_ASF_2_0_HEADER 29 |
@@ -122,28 +97,15 @@ | |||
122 | #define GUID_END 30 | 97 | #define GUID_END 30 |
123 | 98 | ||
124 | 99 | ||
125 | /* asf stream types */ | ||
126 | #define ASF_STREAM_TYPE_UNKNOWN 0 | ||
127 | #define ASF_STREAM_TYPE_AUDIO 1 | ||
128 | #define ASF_STREAM_TYPE_VIDEO 2 | ||
129 | #define ASF_STREAM_TYPE_CONTROL 3 | ||
130 | |||
131 | #define ASF_MAX_NUM_STREAMS 23 | ||
132 | |||
133 | |||
134 | typedef unsigned long long ext_uint64_t; | ||
135 | typedef unsigned int ext_uint32_t; | ||
136 | typedef unsigned short ext_uint16_t; | ||
137 | typedef unsigned char ext_uint8_t; | ||
138 | |||
139 | typedef struct | 100 | typedef struct |
140 | { | 101 | { |
141 | ext_uint32_t v1; | 102 | uint32_t v1; |
142 | ext_uint16_t v2; | 103 | uint16_t v2; |
143 | ext_uint16_t v3; | 104 | uint16_t v3; |
144 | ext_uint8_t v4[8]; | 105 | uint8_t v4[8]; |
145 | } LE_GUID; | 106 | } LE_GUID; |
146 | 107 | ||
108 | |||
147 | static const struct | 109 | static const struct |
148 | { | 110 | { |
149 | const char *name; | 111 | const char *name; |
@@ -342,92 +304,29 @@ static const struct | |||
342 | { | 304 | { |
343 | 0x90, 0x34, 0x00, 0xa0, 0xc9, 0x03, 0x49, 0xbe}}},}; | 305 | 0x90, 0x34, 0x00, 0xa0, 0xc9, 0x03, 0x49, 0xbe}}},}; |
344 | 306 | ||
345 | typedef struct | ||
346 | { | ||
347 | int num; | ||
348 | int seq; | ||
349 | |||
350 | int frag_offset; | ||
351 | int64_t timestamp; | ||
352 | int ts_per_kbyte; | ||
353 | int defrag; | ||
354 | 307 | ||
355 | ext_uint32_t buf_type; | 308 | struct demux_asf_s |
356 | int stream_id; | ||
357 | |||
358 | ext_uint8_t *buffer; | ||
359 | } asf_stream_t; | ||
360 | |||
361 | typedef struct demux_asf_s | ||
362 | { | 309 | { |
363 | /* pointer to the stream data */ | 310 | /* pointer to the stream data */ |
364 | const char *input; | 311 | const char *input; |
365 | /* current position in stream */ | 312 | /* current position in stream */ |
366 | size_t inputPos; | 313 | size_t inputPos; |
367 | size_t inputLen; | ||
368 | |||
369 | int keyframe_found; | ||
370 | |||
371 | int seqno; | ||
372 | ext_uint32_t packet_size; | ||
373 | ext_uint8_t packet_flags; | ||
374 | ext_uint32_t data_size; | ||
375 | |||
376 | ext_uint32_t bitrates[MAX_NUM_STREAMS]; | ||
377 | int num_streams; | ||
378 | int num_audio_streams; | ||
379 | int num_video_streams; | ||
380 | int audio_stream; | ||
381 | int video_stream; | ||
382 | int audio_stream_id; | ||
383 | int video_stream_id; | ||
384 | int control_stream_id; | ||
385 | |||
386 | ext_uint16_t wavex[1024]; | ||
387 | int wavex_size; | ||
388 | |||
389 | char title[512]; | ||
390 | char author[512]; | ||
391 | char copyright[512]; | ||
392 | char comment[512]; | ||
393 | |||
394 | ext_uint32_t length, rate; | ||
395 | 314 | ||
396 | /* packet filling */ | 315 | size_t inputLen; |
397 | int packet_size_left; | ||
398 | |||
399 | /* frame rate calculations, discontinuity detection */ | ||
400 | |||
401 | int64_t last_pts[2]; | ||
402 | int32_t frame_duration; | ||
403 | int send_newpts; | ||
404 | int64_t last_frame_pts; | ||
405 | 316 | ||
406 | /* only for reading */ | 317 | uint32_t length; |
407 | ext_uint32_t packet_padsize; | ||
408 | int nb_frames; | ||
409 | ext_uint8_t frame_flag; | ||
410 | ext_uint8_t segtype; | ||
411 | int frame; | ||
412 | 318 | ||
413 | int status; | 319 | int status; |
414 | 320 | ||
415 | /* byte reordering from audio streams */ | 321 | char *title; |
416 | int reorder_h; | 322 | char *author; |
417 | int reorder_w; | 323 | char *copyright; |
418 | int reorder_b; | 324 | char *comment; |
419 | 325 | char *rating; | |
420 | off_t header_size; | 326 | }; |
421 | int buf_flag_seek; | ||
422 | |||
423 | /* first packet position */ | ||
424 | int64_t first_packet_pos; | ||
425 | |||
426 | int reference_mode; | ||
427 | } demux_asf_t; | ||
428 | 327 | ||
429 | static int | 328 | static int |
430 | readBuf (demux_asf_t * this, void *buf, int len) | 329 | readBuf (struct demux_asf_s * this, void *buf, int len) |
431 | { | 330 | { |
432 | int min; | 331 | int min; |
433 | 332 | ||
@@ -439,10 +338,10 @@ readBuf (demux_asf_t * this, void *buf, int len) | |||
439 | return min; | 338 | return min; |
440 | } | 339 | } |
441 | 340 | ||
442 | static ext_uint8_t | 341 | static uint8_t |
443 | get_byte (demux_asf_t * this) | 342 | get_byte (struct demux_asf_s * this) |
444 | { | 343 | { |
445 | ext_uint8_t buf; | 344 | uint8_t buf; |
446 | int i; | 345 | int i; |
447 | 346 | ||
448 | i = readBuf (this, &buf, 1); | 347 | i = readBuf (this, &buf, 1); |
@@ -451,10 +350,10 @@ get_byte (demux_asf_t * this) | |||
451 | return buf; | 350 | return buf; |
452 | } | 351 | } |
453 | 352 | ||
454 | static ext_uint16_t | 353 | static uint16_t |
455 | get_le16 (demux_asf_t * this) | 354 | get_le16 (struct demux_asf_s * this) |
456 | { | 355 | { |
457 | ext_uint8_t buf[2]; | 356 | uint8_t buf[2]; |
458 | int i; | 357 | int i; |
459 | 358 | ||
460 | i = readBuf (this, buf, 2); | 359 | i = readBuf (this, buf, 2); |
@@ -463,10 +362,10 @@ get_le16 (demux_asf_t * this) | |||
463 | return buf[0] | (buf[1] << 8); | 362 | return buf[0] | (buf[1] << 8); |
464 | } | 363 | } |
465 | 364 | ||
466 | static ext_uint32_t | 365 | static uint32_t |
467 | get_le32 (demux_asf_t * this) | 366 | get_le32 (struct demux_asf_s * this) |
468 | { | 367 | { |
469 | ext_uint8_t buf[4]; | 368 | uint8_t buf[4]; |
470 | int i; | 369 | int i; |
471 | 370 | ||
472 | i = readBuf (this, buf, 4); | 371 | i = readBuf (this, buf, 4); |
@@ -475,26 +374,26 @@ get_le32 (demux_asf_t * this) | |||
475 | return buf[0] | (buf[1] << 8) | (buf[2] << 16) | (buf[3] << 24); | 374 | return buf[0] | (buf[1] << 8) | (buf[2] << 16) | (buf[3] << 24); |
476 | } | 375 | } |
477 | 376 | ||
478 | static ext_uint64_t | 377 | static uint64_t |
479 | get_le64 (demux_asf_t * this) | 378 | get_le64 (struct demux_asf_s * this) |
480 | { | 379 | { |
481 | ext_uint8_t buf[8]; | 380 | uint8_t buf[8]; |
482 | int i; | 381 | int i; |
483 | 382 | ||
484 | i = readBuf (this, buf, 8); | 383 | i = readBuf (this, buf, 8); |
485 | if (i != 8) | 384 | if (i != 8) |
486 | this->status = DEMUX_FINISHED; | 385 | this->status = DEMUX_FINISHED; |
487 | return (ext_uint64_t) buf[0] | 386 | return (uint64_t) buf[0] |
488 | | ((ext_uint64_t) buf[1] << 8) | 387 | | ((uint64_t) buf[1] << 8) |
489 | | ((ext_uint64_t) buf[2] << 16) | 388 | | ((uint64_t) buf[2] << 16) |
490 | | ((ext_uint64_t) buf[3] << 24) | 389 | | ((uint64_t) buf[3] << 24) |
491 | | ((ext_uint64_t) buf[4] << 32) | 390 | | ((uint64_t) buf[4] << 32) |
492 | | ((ext_uint64_t) buf[5] << 40) | 391 | | ((uint64_t) buf[5] << 40) |
493 | | ((ext_uint64_t) buf[6] << 48) | ((ext_uint64_t) buf[7] << 54); | 392 | | ((uint64_t) buf[6] << 48) | ((uint64_t) buf[7] << 54); |
494 | } | 393 | } |
495 | 394 | ||
496 | static int | 395 | static int |
497 | get_guid (demux_asf_t * this) | 396 | get_guid (struct demux_asf_s * this) |
498 | { | 397 | { |
499 | int i; | 398 | int i; |
500 | LE_GUID g; | 399 | LE_GUID g; |
@@ -513,193 +412,72 @@ get_guid (demux_asf_t * this) | |||
513 | return GUID_ERROR; | 412 | return GUID_ERROR; |
514 | } | 413 | } |
515 | 414 | ||
516 | static void | ||
517 | get_str16_nolen (demux_asf_t * this, int len, char *buf, int buf_size) | ||
518 | { | ||
519 | |||
520 | int c; | ||
521 | char *q; | ||
522 | |||
523 | q = buf; | ||
524 | while (len > 0) | ||
525 | { | ||
526 | c = get_le16 (this); | ||
527 | if ((q - buf) < buf_size - 1) | ||
528 | *q++ = c; | ||
529 | len -= 2; | ||
530 | } | ||
531 | *q = '\0'; | ||
532 | } | ||
533 | 415 | ||
534 | static int | 416 | static int |
535 | asf_read_header (demux_asf_t * this) | 417 | asf_read_header (struct demux_asf_s * this) |
536 | { | 418 | { |
537 | int guid; | 419 | int guid; |
538 | ext_uint64_t gsize; | 420 | uint64_t gsize; |
421 | uint16_t len1, len2, len3, len4, len5; | ||
539 | 422 | ||
540 | guid = get_guid (this); | 423 | guid = get_guid (this); |
541 | if (guid != GUID_ASF_HEADER) | 424 | if (guid != GUID_ASF_HEADER) |
542 | return 0; | 425 | return 0; |
543 | get_le64 (this); | 426 | get_le64 (this); /* object size */ |
544 | get_le32 (this); | 427 | get_le32 (this); /* number of header objects */ |
545 | get_byte (this); | 428 | get_byte (this); /* reserved 1 */ |
546 | get_byte (this); | 429 | get_byte (this); /* reserved 2 */ |
547 | |||
548 | while (this->status != DEMUX_FINISHED) | 430 | while (this->status != DEMUX_FINISHED) |
549 | { | 431 | { |
550 | guid = get_guid (this); | 432 | guid = get_guid (this); /* object ID */ |
551 | gsize = get_le64 (this); | 433 | gsize = get_le64 (this); /* object size */ |
552 | |||
553 | if (gsize < 24) | 434 | if (gsize < 24) |
554 | goto fail; | 435 | goto fail; |
555 | |||
556 | switch (guid) | 436 | switch (guid) |
557 | { | 437 | { |
558 | case GUID_ASF_FILE_PROPERTIES: | 438 | case GUID_ASF_FILE_PROPERTIES: |
559 | { | 439 | guid = get_guid (this); /* file ID */ |
560 | ext_uint64_t start_time, end_time; | 440 | get_le64 (this); /* file size */ |
561 | 441 | get_le64 (this); /* creation date */ | |
562 | guid = get_guid (this); | 442 | get_le64 (this); /* nb_packets */ |
563 | get_le64 (this); /* file size */ | 443 | this->length = get_le64 (this); /* play duration in 100 ns units */ |
564 | get_le64 (this); /* file time */ | 444 | get_le64 (this); /* send duration */ |
565 | get_le64 (this); /* nb_packets */ | 445 | get_le64 (this); /* preroll */ |
566 | 446 | get_le32 (this); /* flags */ | |
567 | end_time = get_le64 (this); | 447 | get_le32 (this); /* min size */ |
568 | 448 | get_le32 (this); /* max size */ | |
569 | this->length = get_le64 (this) / 10000; | 449 | get_le32 (this); /* max bitrate */ |
570 | if (this->length) | ||
571 | this->rate = this->inputLen / (this->length / 1000); | ||
572 | else | ||
573 | this->rate = 0; | ||
574 | |||
575 | |||
576 | start_time = get_le32 (this); /* start timestamp in 1/1000 s */ | ||
577 | |||
578 | get_le32 (this); /* unknown */ | ||
579 | get_le32 (this); /* min size */ | ||
580 | this->packet_size = get_le32 (this); /* max size */ | ||
581 | get_le32 (this); /* max bitrate */ | ||
582 | get_le32 (this); | ||
583 | } | ||
584 | break; | 450 | break; |
585 | |||
586 | case (GUID_ASF_STREAM_PROPERTIES): | ||
587 | { | ||
588 | int type; | ||
589 | ext_uint32_t total_size, stream_data_size; | ||
590 | ext_uint16_t stream_id; | ||
591 | ext_uint64_t pos1, pos2; | ||
592 | pos1 = this->inputPos; | ||
593 | |||
594 | guid = get_guid (this); | ||
595 | switch (guid) | ||
596 | { | ||
597 | case GUID_ASF_AUDIO_MEDIA: | ||
598 | type = CODEC_TYPE_AUDIO; | ||
599 | break; | ||
600 | |||
601 | case GUID_ASF_VIDEO_MEDIA: | ||
602 | type = CODEC_TYPE_VIDEO; | ||
603 | break; | ||
604 | |||
605 | case GUID_ASF_COMMAND_MEDIA: | ||
606 | type = CODEC_TYPE_CONTROL; | ||
607 | break; | ||
608 | |||
609 | default: | ||
610 | goto fail; | ||
611 | } | ||
612 | |||
613 | guid = get_guid (this); | ||
614 | get_le64 (this); | ||
615 | total_size = get_le32 (this); | ||
616 | if (total_size > sizeof (this->wavex)) | ||
617 | goto fail; | ||
618 | stream_data_size = get_le32 (this); | ||
619 | stream_id = get_le16 (this); /* stream id */ | ||
620 | get_le32 (this); | ||
621 | |||
622 | if (type == CODEC_TYPE_AUDIO) | ||
623 | { | ||
624 | ext_uint8_t buffer[6]; | ||
625 | |||
626 | readBuf (this, (ext_uint8_t *) this->wavex, total_size); | ||
627 | if (guid == GUID_ASF_AUDIO_SPREAD) | ||
628 | { | ||
629 | readBuf (this, buffer, 6); | ||
630 | this->reorder_h = buffer[0]; | ||
631 | this->reorder_w = (buffer[2] << 8) | buffer[1]; | ||
632 | this->reorder_b = (buffer[4] << 8) | buffer[3]; | ||
633 | this->reorder_w /= this->reorder_b; | ||
634 | } | ||
635 | else | ||
636 | { | ||
637 | this->reorder_b = this->reorder_h = this->reorder_w = 1; | ||
638 | } | ||
639 | |||
640 | this->wavex_size = total_size; /* 18 + this->wavex[8]; */ | ||
641 | this->num_audio_streams++; | ||
642 | } | ||
643 | else if (type == CODEC_TYPE_VIDEO) | ||
644 | { | ||
645 | |||
646 | ext_uint16_t i; | ||
647 | |||
648 | get_le32 (this); /* width */ | ||
649 | get_le32 (this); /* height */ | ||
650 | get_byte (this); | ||
651 | |||
652 | i = get_le16 (this); /* size */ | ||
653 | this->inputPos += i; | ||
654 | this->num_video_streams++; | ||
655 | } | ||
656 | else if (type == CODEC_TYPE_CONTROL) | ||
657 | { | ||
658 | this->control_stream_id = stream_id; | ||
659 | } | ||
660 | |||
661 | this->num_streams++; | ||
662 | pos2 = this->inputPos; | ||
663 | this->inputPos += gsize - (pos2 - pos1 + 24); | ||
664 | } | ||
665 | break; | ||
666 | |||
667 | case GUID_ASF_DATA: | 451 | case GUID_ASF_DATA: |
668 | goto headers_ok; | 452 | goto headers_ok; |
669 | break; | 453 | break; |
670 | case GUID_ASF_CONTENT_DESCRIPTION: | 454 | case GUID_ASF_CONTENT_DESCRIPTION: |
671 | { | 455 | len1 = get_le16 (this); |
672 | ext_uint16_t len1, len2, len3, len4, len5; | 456 | len2 = get_le16 (this); |
673 | 457 | len3 = get_le16 (this); | |
674 | len1 = get_le16 (this); | 458 | len4 = get_le16 (this); |
675 | len2 = get_le16 (this); | 459 | len5 = get_le16 (this); |
676 | len3 = get_le16 (this); | 460 | this->title = EXTRACTOR_common_convert_to_utf8 (&this->input[this->inputPos], |
677 | len4 = get_le16 (this); | 461 | len1, |
678 | len5 = get_le16 (this); | 462 | "UTF-16"); |
679 | get_str16_nolen (this, len1, this->title, sizeof (this->title)); | 463 | this->inputPos += len1; |
680 | get_str16_nolen (this, len2, this->author, sizeof (this->author)); | 464 | this->author = EXTRACTOR_common_convert_to_utf8 (&this->input[this->inputPos], |
681 | get_str16_nolen (this, len3, this->copyright, | 465 | len2, |
682 | sizeof (this->copyright)); | 466 | "UTF-16"); |
683 | get_str16_nolen (this, len4, this->comment, | 467 | this->inputPos += len2; |
684 | sizeof (this->comment)); | 468 | this->copyright = EXTRACTOR_common_convert_to_utf8 (&this->input[this->inputPos], |
685 | this->inputPos += len5; | 469 | len3, |
686 | } | 470 | "UTF-16"); |
471 | this->inputPos += len3; | ||
472 | this->comment = EXTRACTOR_common_convert_to_utf8 (&this->input[this->inputPos], | ||
473 | len4, | ||
474 | "UTF-16"); | ||
475 | this->inputPos += len4; | ||
476 | this->rating = EXTRACTOR_common_convert_to_utf8 (&this->input[this->inputPos], | ||
477 | len5, | ||
478 | "UTF-16"); | ||
479 | this->inputPos += len5; | ||
687 | break; | 480 | break; |
688 | |||
689 | case GUID_ASF_STREAM_BITRATE_PROPERTIES: | ||
690 | { | ||
691 | ext_uint16_t streams, stream_id; | ||
692 | ext_uint16_t i; | ||
693 | |||
694 | streams = get_le16 (this); | ||
695 | for (i = 0; i < streams; i++) | ||
696 | { | ||
697 | stream_id = get_le16 (this); | ||
698 | this->bitrates[stream_id] = get_le32 (this); | ||
699 | } | ||
700 | } | ||
701 | break; | ||
702 | |||
703 | default: | 481 | default: |
704 | this->inputPos += gsize - 24; | 482 | this->inputPos += gsize - 24; |
705 | } | 483 | } |
@@ -707,10 +485,7 @@ asf_read_header (demux_asf_t * this) | |||
707 | 485 | ||
708 | headers_ok: | 486 | headers_ok: |
709 | this->inputPos += sizeof (LE_GUID) + 10; | 487 | this->inputPos += sizeof (LE_GUID) + 10; |
710 | this->packet_size_left = 0; | ||
711 | this->first_packet_pos = this->inputPos; | ||
712 | return 1; | 488 | return 1; |
713 | |||
714 | fail: | 489 | fail: |
715 | return 0; | 490 | return 0; |
716 | } | 491 | } |
@@ -734,57 +509,79 @@ EXTRACTOR_asf_extract (const char *data, | |||
734 | void *proc_cls, | 509 | void *proc_cls, |
735 | const char *options) | 510 | const char *options) |
736 | { | 511 | { |
737 | demux_asf_t this; | 512 | struct demux_asf_s this; |
738 | size_t slen; | 513 | size_t slen; |
514 | char duration_str[30]; | ||
515 | int ret; | ||
739 | 516 | ||
740 | memset (&this, 0, sizeof (demux_asf_t)); | 517 | memset (&this, 0, sizeof (struct demux_asf_s)); |
741 | this.input = data; | 518 | this.input = data; |
742 | this.inputLen = size; | 519 | this.inputLen = size; |
743 | this.status = DEMUX_START; | 520 | this.status = DEMUX_START; |
744 | if (0 == asf_read_header (&this)) | 521 | ret = 0; |
745 | return 0; | 522 | if (1 == asf_read_header (&this)) |
746 | 523 | { | |
747 | if ( ( (0 < (slen = strlen(this.title))) && | 524 | snprintf (duration_str, |
748 | (0 != proc (proc_cls, | 525 | sizeof (duration_str), |
749 | "asf", | 526 | "%llu ms", (unsigned long long) (this.length / 10000LL)); |
750 | EXTRACTOR_METATYPE_TITLE, | 527 | if ( ( (this.title != NULL) && |
751 | EXTRACTOR_METAFORMAT_C_STRING, | 528 | (0 < (slen = strlen(this.title))) && |
752 | "text/plain", | 529 | (0 != proc (proc_cls, |
753 | this.title, | 530 | "asf", |
754 | slen + 1)) ) || | 531 | EXTRACTOR_METATYPE_TITLE, |
755 | ( (0 < (slen = strlen(this.author))) && | 532 | EXTRACTOR_METAFORMAT_C_STRING, |
756 | (0 != proc (proc_cls, | 533 | "text/plain", |
757 | "asf", | 534 | this.title, |
758 | EXTRACTOR_METATYPE_AUTHOR_NAME, | 535 | slen + 1)) ) || |
759 | EXTRACTOR_METAFORMAT_C_STRING, | 536 | ( (this.author != NULL) && |
760 | "text/plain", | 537 | (0 < (slen = strlen(this.author))) && |
761 | this.author, | 538 | (0 != proc (proc_cls, |
762 | slen + 1)) ) || | 539 | "asf", |
763 | ( (0 < (slen = strlen(this.comment))) && | 540 | EXTRACTOR_METATYPE_AUTHOR_NAME, |
541 | EXTRACTOR_METAFORMAT_C_STRING, | ||
542 | "text/plain", | ||
543 | this.author, | ||
544 | slen + 1)) ) || | ||
545 | ( (this.comment != NULL) && | ||
546 | (0 < (slen = strlen(this.comment))) && | ||
547 | (0 != proc (proc_cls, | ||
548 | "asf", | ||
549 | EXTRACTOR_METATYPE_COMMENT, | ||
550 | EXTRACTOR_METAFORMAT_C_STRING, | ||
551 | "text/plain", | ||
552 | this.comment, | ||
553 | slen + 1)) ) || | ||
554 | ( (this.copyright != NULL) && | ||
555 | (0 < (slen = strlen(this.copyright))) && | ||
556 | (0 != proc (proc_cls, | ||
557 | "asf", | ||
558 | EXTRACTOR_METATYPE_COPYRIGHT, | ||
559 | EXTRACTOR_METAFORMAT_C_STRING, | ||
560 | "text/plain", | ||
561 | this.copyright, | ||
562 | slen + 1)) ) || | ||
764 | (0 != proc (proc_cls, | 563 | (0 != proc (proc_cls, |
765 | "asf", | 564 | "asf", |
766 | EXTRACTOR_METATYPE_COMMENT, | 565 | EXTRACTOR_METATYPE_MIMETYPE, |
767 | EXTRACTOR_METAFORMAT_C_STRING, | 566 | EXTRACTOR_METAFORMAT_C_STRING, |
768 | "text/plain", | 567 | "text/plain", |
769 | this.comment, | 568 | "video/x-ms-asf", |
770 | slen + 1)) ) || | 569 | strlen("video/x-ms-asf") + 1)) || |
771 | ( (0 < (slen = strlen(this.copyright))) && | ||
772 | (0 != proc (proc_cls, | 570 | (0 != proc (proc_cls, |
773 | "asf", | 571 | "asf", |
774 | EXTRACTOR_METATYPE_COPYRIGHT, | 572 | EXTRACTOR_METATYPE_DURATION, |
775 | EXTRACTOR_METAFORMAT_C_STRING, | 573 | EXTRACTOR_METAFORMAT_C_STRING, |
776 | "text/plain", | 574 | "text/plain", |
777 | this.copyright, | 575 | duration_str, |
778 | slen + 1)) ) || | 576 | strlen(duration_str) + 1)) ) |
779 | (0 != proc (proc_cls, | 577 | ret = 1; |
780 | "asf", | 578 | } |
781 | EXTRACTOR_METATYPE_MIMETYPE, | 579 | free (this.title); |
782 | EXTRACTOR_METAFORMAT_C_STRING, | 580 | free (this.author); |
783 | "text/plain", | 581 | free (this.copyright); |
784 | "video/x-ms-asf", | 582 | free (this.comment); |
785 | strlen("video/x-ms-asf") + 1)) ) | 583 | free (this.rating); |
786 | return 1; | 584 | return ret; |
787 | return 0; | ||
788 | } | 585 | } |
789 | 586 | ||
790 | /* end of asf_extractor.c */ | 587 | /* end of asf_extractor.c */ |