Mercurial > libavformat.hg
diff 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 |
line wrap: on
line diff
--- a/asfdec.c Mon May 11 04:35:15 2009 +0000 +++ b/asfdec.c Tue May 12 12:35:46 2009 +0000 @@ -20,11 +20,13 @@ */ #include "libavutil/common.h" +#include "libavutil/avstring.h" #include "libavcodec/mpegaudio.h" #include "avformat.h" #include "riff.h" #include "asf.h" #include "asfcrypt.h" +#include "avlanguage.h" void ff_mms_set_stream_selection(URLContext *h, AVFormatContext *format); @@ -76,6 +78,7 @@ else PRINT_IF_GUID(g, ff_asf_ext_stream_audio_stream); else PRINT_IF_GUID(g, ff_asf_metadata_header); else PRINT_IF_GUID(g, stream_bitrate_guid); + else PRINT_IF_GUID(g, ff_asf_language_guid); else dprintf(NULL, "(GUID: unknown) "); for(i=0;i<16;i++) @@ -238,6 +241,8 @@ st->priv_data = asf_st; start_time = asf->hdr.preroll; + asf_st->stream_language_index = 128; // invalid stream index means no language info + if(!(asf->hdr.flags & 0x01)) { // if we aren't streaming... st->duration = asf->hdr.send_time / (10000000 / 1000) - start_time; @@ -403,6 +408,16 @@ // av_log(s, AV_LOG_ERROR, "flags: 0x%x stream id %d, bitrate %d\n", flags, stream_id, bitrate); asf->stream_bitrates[stream_id]= bitrate; } + } else if (!guidcmp(&g, &ff_asf_language_guid)) { + int j; + int stream_count = get_le16(pb); + for(j = 0; j < stream_count; j++) { + char lang[6]; + unsigned int lang_len = get_byte(pb); + get_str16_nolen(pb, lang_len, lang, sizeof(lang)); + if (j < 128) + av_strlcpy(asf->stream_languages[j], lang, sizeof(*asf->stream_languages)); + } } else if (!guidcmp(&g, &ff_asf_extended_content_header)) { int desc_count, i; @@ -443,6 +458,7 @@ } else if (!guidcmp(&g, &ff_asf_ext_stream_header)) { int ext_len, payload_ext_ct, stream_ct; uint32_t ext_d, leak_rate, stream_num; + unsigned int stream_languageid_index; get_le64(pb); // starttime get_le64(pb); // endtime @@ -455,7 +471,11 @@ get_le32(pb); // max-object-size get_le32(pb); // flags (reliable,seekable,no_cleanpoints?,resend-live-cleanpoints, rest of bits reserved) stream_num = get_le16(pb); // stream-num - get_le16(pb); // stream-language-id-index + + stream_languageid_index = get_le16(pb); // stream-language-id-index + if (stream_num < 128) + asf->streams[stream_num].stream_language_index = stream_languageid_index; + get_le64(pb); // avg frametime in 100ns units stream_ct = get_le16(pb); //stream-name-count payload_ext_ct = get_le16(pb); //payload-extension-system-count @@ -535,6 +555,17 @@ &st->sample_aspect_ratio.den, dar[i].num, dar[i].den, INT_MAX); //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); + + // copy and convert language codes to the frontend + if (asf->streams[i].stream_language_index < 128) { + const char *rfc1766 = asf->stream_languages[asf->streams[i].stream_language_index]; + if (rfc1766 && strlen(rfc1766) > 1) { + const char primary_tag[3] = { rfc1766[0], rfc1766[1], '\0' }; // ignore country code if any + const char *iso6392 = av_convert_lang_to(primary_tag, AV_LANG_ISO639_2_BIBL); + if (iso6392) + av_metadata_set(&st->metadata, "language", iso6392); + } + } } }
