Mercurial > libavformat.hg
comparison asfdec.c @ 4924:c090f960fc8a libavformat
Per-stream language-tags extraction in asfdec.
Patch by Cyril Comparon: gmail(name, surname);
Original thread: Suggestion for a centralized language-tag facility in libavformat
Date: 04/10/2009 07:33 PM
author | benoit |
---|---|
date | Tue, 12 May 2009 12:35:46 +0000 |
parents | 7c3c541b421e |
children | 2a4f618b2da3 |
comparison
equal
deleted
inserted
replaced
4923:a88b31642727 | 4924:c090f960fc8a |
---|---|
18 * License along with FFmpeg; if not, write to the Free Software | 18 * License along with FFmpeg; if not, write to the Free Software |
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
20 */ | 20 */ |
21 | 21 |
22 #include "libavutil/common.h" | 22 #include "libavutil/common.h" |
23 #include "libavutil/avstring.h" | |
23 #include "libavcodec/mpegaudio.h" | 24 #include "libavcodec/mpegaudio.h" |
24 #include "avformat.h" | 25 #include "avformat.h" |
25 #include "riff.h" | 26 #include "riff.h" |
26 #include "asf.h" | 27 #include "asf.h" |
27 #include "asfcrypt.h" | 28 #include "asfcrypt.h" |
29 #include "avlanguage.h" | |
28 | 30 |
29 void ff_mms_set_stream_selection(URLContext *h, AVFormatContext *format); | 31 void ff_mms_set_stream_selection(URLContext *h, AVFormatContext *format); |
30 | 32 |
31 #undef NDEBUG | 33 #undef NDEBUG |
32 #include <assert.h> | 34 #include <assert.h> |
74 else PRINT_IF_GUID(g, ff_asf_extended_content_header); | 76 else PRINT_IF_GUID(g, ff_asf_extended_content_header); |
75 else PRINT_IF_GUID(g, ff_asf_ext_stream_embed_stream_header); | 77 else PRINT_IF_GUID(g, ff_asf_ext_stream_embed_stream_header); |
76 else PRINT_IF_GUID(g, ff_asf_ext_stream_audio_stream); | 78 else PRINT_IF_GUID(g, ff_asf_ext_stream_audio_stream); |
77 else PRINT_IF_GUID(g, ff_asf_metadata_header); | 79 else PRINT_IF_GUID(g, ff_asf_metadata_header); |
78 else PRINT_IF_GUID(g, stream_bitrate_guid); | 80 else PRINT_IF_GUID(g, stream_bitrate_guid); |
81 else PRINT_IF_GUID(g, ff_asf_language_guid); | |
79 else | 82 else |
80 dprintf(NULL, "(GUID: unknown) "); | 83 dprintf(NULL, "(GUID: unknown) "); |
81 for(i=0;i<16;i++) | 84 for(i=0;i<16;i++) |
82 dprintf(NULL, " 0x%02x,", (*g)[i]); | 85 dprintf(NULL, " 0x%02x,", (*g)[i]); |
83 dprintf(NULL, "}\n"); | 86 dprintf(NULL, "}\n"); |
236 if (!asf_st) | 239 if (!asf_st) |
237 return AVERROR(ENOMEM); | 240 return AVERROR(ENOMEM); |
238 st->priv_data = asf_st; | 241 st->priv_data = asf_st; |
239 start_time = asf->hdr.preroll; | 242 start_time = asf->hdr.preroll; |
240 | 243 |
244 asf_st->stream_language_index = 128; // invalid stream index means no language info | |
245 | |
241 if(!(asf->hdr.flags & 0x01)) { // if we aren't streaming... | 246 if(!(asf->hdr.flags & 0x01)) { // if we aren't streaming... |
242 st->duration = asf->hdr.send_time / | 247 st->duration = asf->hdr.send_time / |
243 (10000000 / 1000) - start_time; | 248 (10000000 / 1000) - start_time; |
244 } | 249 } |
245 get_guid(pb, &g); | 250 get_guid(pb, &g); |
401 bitrate= get_le32(pb); | 406 bitrate= get_le32(pb); |
402 stream_id= (flags & 0x7f); | 407 stream_id= (flags & 0x7f); |
403 // av_log(s, AV_LOG_ERROR, "flags: 0x%x stream id %d, bitrate %d\n", flags, stream_id, bitrate); | 408 // av_log(s, AV_LOG_ERROR, "flags: 0x%x stream id %d, bitrate %d\n", flags, stream_id, bitrate); |
404 asf->stream_bitrates[stream_id]= bitrate; | 409 asf->stream_bitrates[stream_id]= bitrate; |
405 } | 410 } |
411 } else if (!guidcmp(&g, &ff_asf_language_guid)) { | |
412 int j; | |
413 int stream_count = get_le16(pb); | |
414 for(j = 0; j < stream_count; j++) { | |
415 char lang[6]; | |
416 unsigned int lang_len = get_byte(pb); | |
417 get_str16_nolen(pb, lang_len, lang, sizeof(lang)); | |
418 if (j < 128) | |
419 av_strlcpy(asf->stream_languages[j], lang, sizeof(*asf->stream_languages)); | |
420 } | |
406 } else if (!guidcmp(&g, &ff_asf_extended_content_header)) { | 421 } else if (!guidcmp(&g, &ff_asf_extended_content_header)) { |
407 int desc_count, i; | 422 int desc_count, i; |
408 | 423 |
409 desc_count = get_le16(pb); | 424 desc_count = get_le16(pb); |
410 for(i=0;i<desc_count;i++) { | 425 for(i=0;i<desc_count;i++) { |
441 } | 456 } |
442 } | 457 } |
443 } else if (!guidcmp(&g, &ff_asf_ext_stream_header)) { | 458 } else if (!guidcmp(&g, &ff_asf_ext_stream_header)) { |
444 int ext_len, payload_ext_ct, stream_ct; | 459 int ext_len, payload_ext_ct, stream_ct; |
445 uint32_t ext_d, leak_rate, stream_num; | 460 uint32_t ext_d, leak_rate, stream_num; |
461 unsigned int stream_languageid_index; | |
446 | 462 |
447 get_le64(pb); // starttime | 463 get_le64(pb); // starttime |
448 get_le64(pb); // endtime | 464 get_le64(pb); // endtime |
449 leak_rate = get_le32(pb); // leak-datarate | 465 leak_rate = get_le32(pb); // leak-datarate |
450 get_le32(pb); // bucket-datasize | 466 get_le32(pb); // bucket-datasize |
453 get_le32(pb); // alt-bucket-datasize | 469 get_le32(pb); // alt-bucket-datasize |
454 get_le32(pb); // alt-init-bucket-fullness | 470 get_le32(pb); // alt-init-bucket-fullness |
455 get_le32(pb); // max-object-size | 471 get_le32(pb); // max-object-size |
456 get_le32(pb); // flags (reliable,seekable,no_cleanpoints?,resend-live-cleanpoints, rest of bits reserved) | 472 get_le32(pb); // flags (reliable,seekable,no_cleanpoints?,resend-live-cleanpoints, rest of bits reserved) |
457 stream_num = get_le16(pb); // stream-num | 473 stream_num = get_le16(pb); // stream-num |
458 get_le16(pb); // stream-language-id-index | 474 |
475 stream_languageid_index = get_le16(pb); // stream-language-id-index | |
476 if (stream_num < 128) | |
477 asf->streams[stream_num].stream_language_index = stream_languageid_index; | |
478 | |
459 get_le64(pb); // avg frametime in 100ns units | 479 get_le64(pb); // avg frametime in 100ns units |
460 stream_ct = get_le16(pb); //stream-name-count | 480 stream_ct = get_le16(pb); //stream-name-count |
461 payload_ext_ct = get_le16(pb); //payload-extension-system-count | 481 payload_ext_ct = get_le16(pb); //payload-extension-system-count |
462 | 482 |
463 if (stream_num < 128) | 483 if (stream_num < 128) |
533 if (dar[i].num > 0 && dar[i].den > 0) | 553 if (dar[i].num > 0 && dar[i].den > 0) |
534 av_reduce(&st->sample_aspect_ratio.num, | 554 av_reduce(&st->sample_aspect_ratio.num, |
535 &st->sample_aspect_ratio.den, | 555 &st->sample_aspect_ratio.den, |
536 dar[i].num, dar[i].den, INT_MAX); | 556 dar[i].num, dar[i].den, INT_MAX); |
537 //av_log(s, AV_LOG_ERROR, "dar %d:%d sar=%d:%d\n", dar[i].num, dar[i].den, st->sample_aspect_ratio.num, st->sample_aspect_ratio.den); | 557 //av_log(s, AV_LOG_ERROR, "dar %d:%d sar=%d:%d\n", dar[i].num, dar[i].den, st->sample_aspect_ratio.num, st->sample_aspect_ratio.den); |
558 | |
559 // copy and convert language codes to the frontend | |
560 if (asf->streams[i].stream_language_index < 128) { | |
561 const char *rfc1766 = asf->stream_languages[asf->streams[i].stream_language_index]; | |
562 if (rfc1766 && strlen(rfc1766) > 1) { | |
563 const char primary_tag[3] = { rfc1766[0], rfc1766[1], '\0' }; // ignore country code if any | |
564 const char *iso6392 = av_convert_lang_to(primary_tag, AV_LANG_ISO639_2_BIBL); | |
565 if (iso6392) | |
566 av_metadata_set(&st->metadata, "language", iso6392); | |
567 } | |
568 } | |
538 } | 569 } |
539 } | 570 } |
540 | 571 |
541 return 0; | 572 return 0; |
542 } | 573 } |