diff options
author | Cyril Comparon <cyril.comparon@gmail.com> | 2009-05-12 12:35:46 +0000 |
---|---|---|
committer | Benoit Fouet <benoit.fouet@free.fr> | 2009-05-12 12:35:46 +0000 |
commit | 5f1ac36dd2f7f04a3a213f717757c16a1287bda6 (patch) | |
tree | 894cabb076870b6a30399e7b3ab37a9ab11bd6a4 /libavformat/asfdec.c | |
parent | de9618013711ebc4d562c8fe4c53f51a90b2afe0 (diff) | |
download | ffmpeg-5f1ac36dd2f7f04a3a213f717757c16a1287bda6.tar.gz |
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
Originally committed as revision 18800 to svn://svn.ffmpeg.org/ffmpeg/trunk
Diffstat (limited to 'libavformat/asfdec.c')
-rw-r--r-- | libavformat/asfdec.c | 33 |
1 files changed, 32 insertions, 1 deletions
diff --git a/libavformat/asfdec.c b/libavformat/asfdec.c index e76f98beb2..3810663c2f 100644 --- a/libavformat/asfdec.c +++ b/libavformat/asfdec.c @@ -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 @@ static void print_guid(const ff_asf_guid *g) 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 @@ static int asf_read_header(AVFormatContext *s, AVFormatParameters *ap) 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 @@ static int asf_read_header(AVFormatContext *s, AVFormatParameters *ap) // 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 @@ static int asf_read_header(AVFormatContext *s, AVFormatParameters *ap) } 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 @@ static int asf_read_header(AVFormatContext *s, AVFormatParameters *ap) 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 @@ static int asf_read_header(AVFormatContext *s, AVFormatParameters *ap) &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); + } + } } } |