|
|
|
@@ -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); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|