|
|
@@ -138,6 +138,29 @@ static int swf_read_header(AVFormatContext *s) |
|
|
|
return 0; |
|
|
|
} |
|
|
|
|
|
|
|
static AVStream *create_new_audio_stream(AVFormatContext *s, int id, int info) |
|
|
|
{ |
|
|
|
int sample_rate_code; |
|
|
|
AVStream *ast = avformat_new_stream(s, NULL); |
|
|
|
if (!ast) |
|
|
|
return NULL; |
|
|
|
ast->id = id; |
|
|
|
if (info & 1) { |
|
|
|
ast->codec->channels = 2; |
|
|
|
ast->codec->channel_layout = AV_CH_LAYOUT_STEREO; |
|
|
|
} else { |
|
|
|
ast->codec->channels = 1; |
|
|
|
ast->codec->channel_layout = AV_CH_LAYOUT_MONO; |
|
|
|
} |
|
|
|
ast->codec->codec_type = AVMEDIA_TYPE_AUDIO; |
|
|
|
ast->codec->codec_id = ff_codec_get_id(swf_audio_codec_tags, info>>4 & 15); |
|
|
|
ast->need_parsing = AVSTREAM_PARSE_FULL; |
|
|
|
sample_rate_code = info>>2 & 3; |
|
|
|
ast->codec->sample_rate = 44100 >> (3 - sample_rate_code); |
|
|
|
avpriv_set_pts_info(ast, 64, 1, ast->codec->sample_rate); |
|
|
|
return ast; |
|
|
|
} |
|
|
|
|
|
|
|
static int swf_read_packet(AVFormatContext *s, AVPacket *pkt) |
|
|
|
{ |
|
|
|
SWFContext *swf = s->priv_data; |
|
|
@@ -184,7 +207,6 @@ static int swf_read_packet(AVFormatContext *s, AVPacket *pkt) |
|
|
|
len -= 8; |
|
|
|
} else if (tag == TAG_STREAMHEAD || tag == TAG_STREAMHEAD2) { |
|
|
|
/* streaming found */ |
|
|
|
int sample_rate_code; |
|
|
|
|
|
|
|
for (i=0; i<s->nb_streams; i++) { |
|
|
|
st = s->streams[i]; |
|
|
@@ -195,27 +217,12 @@ static int swf_read_packet(AVFormatContext *s, AVPacket *pkt) |
|
|
|
avio_r8(pb); |
|
|
|
v = avio_r8(pb); |
|
|
|
swf->samples_per_frame = avio_rl16(pb); |
|
|
|
ast = avformat_new_stream(s, NULL); |
|
|
|
ast = create_new_audio_stream(s, -1, v); /* -1 to avoid clash with video stream ch_id */ |
|
|
|
if (!ast) |
|
|
|
return AVERROR(ENOMEM); |
|
|
|
ast->id = -1; /* -1 to avoid clash with video stream ch_id */ |
|
|
|
if (v & 1) { |
|
|
|
ast->codec->channels = 2; |
|
|
|
ast->codec->channel_layout = AV_CH_LAYOUT_STEREO; |
|
|
|
} else { |
|
|
|
ast->codec->channels = 1; |
|
|
|
ast->codec->channel_layout = AV_CH_LAYOUT_MONO; |
|
|
|
} |
|
|
|
ast->codec->codec_type = AVMEDIA_TYPE_AUDIO; |
|
|
|
ast->codec->codec_id = ff_codec_get_id(swf_audio_codec_tags, (v>>4) & 15); |
|
|
|
ast->need_parsing = AVSTREAM_PARSE_FULL; |
|
|
|
sample_rate_code= (v>>2) & 3; |
|
|
|
ast->codec->sample_rate = 44100 >> (3 - sample_rate_code); |
|
|
|
avpriv_set_pts_info(ast, 64, 1, ast->codec->sample_rate); |
|
|
|
len -= 4; |
|
|
|
} else if (tag == TAG_DEFINESOUND) { |
|
|
|
/* audio stream */ |
|
|
|
int sample_rate_code; |
|
|
|
int ch_id = avio_rl16(pb); |
|
|
|
|
|
|
|
for (i=0; i<s->nb_streams; i++) { |
|
|
@@ -229,17 +236,9 @@ static int swf_read_packet(AVFormatContext *s, AVPacket *pkt) |
|
|
|
// these are smaller audio streams in DEFINESOUND tags, but it's technically |
|
|
|
// possible they could be huge. Break it up into multiple packets if it's big. |
|
|
|
v = avio_r8(pb); |
|
|
|
ast = avformat_new_stream(s, NULL); |
|
|
|
ast = create_new_audio_stream(s, ch_id, v); |
|
|
|
if (!ast) |
|
|
|
return AVERROR(ENOMEM); |
|
|
|
ast->id = ch_id; |
|
|
|
ast->codec->channels = 1 + (v&1); |
|
|
|
ast->codec->codec_type = AVMEDIA_TYPE_AUDIO; |
|
|
|
ast->codec->codec_id = ff_codec_get_id(swf_audio_codec_tags, (v>>4) & 15); |
|
|
|
ast->need_parsing = AVSTREAM_PARSE_FULL; |
|
|
|
sample_rate_code= (v>>2) & 3; |
|
|
|
ast->codec->sample_rate = 44100 >> (3 - sample_rate_code); |
|
|
|
avpriv_set_pts_info(ast, 64, 1, ast->codec->sample_rate); |
|
|
|
ast->duration = avio_rl32(pb); // number of samples |
|
|
|
if (((v>>4) & 15) == 2) { // MP3 sound data record |
|
|
|
ast->skip_samples = avio_rl16(pb); |
|
|
|