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 }