diff options
author | Anton Khirnov <anton@khirnov.net> | 2015-10-21 11:22:13 +0200 |
---|---|---|
committer | Anton Khirnov <anton@khirnov.net> | 2015-12-12 21:20:33 +0100 |
commit | 6bf4c1d71199b92894f24db6386ed5070e590a16 (patch) | |
tree | 45867569e8042e9ee5a788d3688cd00765d55ce9 /libavformat | |
parent | 9f1eccb97bf8894cb18b14f642500686505ef186 (diff) | |
download | ffmpeg-6bf4c1d71199b92894f24db6386ed5070e590a16.tar.gz |
r3d: do not create the audio stream until we know the sample rate
Diffstat (limited to 'libavformat')
-rw-r--r-- | libavformat/r3d.c | 37 |
1 files changed, 25 insertions, 12 deletions
diff --git a/libavformat/r3d.c b/libavformat/r3d.c index c56bdc63be..fb066a65be 100644 --- a/libavformat/r3d.c +++ b/libavformat/r3d.c @@ -29,6 +29,8 @@ typedef struct R3DContext { unsigned video_offsets_count; unsigned *video_offsets; unsigned rdvo_offset; + + int audio_channels; } R3DContext; typedef struct Atom { @@ -52,6 +54,7 @@ static int read_atom(AVFormatContext *s, Atom *atom) static int r3d_read_red1(AVFormatContext *s) { AVStream *st = avformat_new_stream(s, NULL); + R3DContext *r3d = s->priv_data; char filename[258]; int tmp; int av_unused tmp2; @@ -89,17 +92,8 @@ static int r3d_read_red1(AVFormatContext *s) st->avg_frame_rate = framerate; } - tmp = avio_r8(s->pb); // audio channels + r3d->audio_channels = avio_r8(s->pb); // audio channels av_log(s, AV_LOG_TRACE, "audio channels %d\n", tmp); - if (tmp > 0) { - AVStream *ast = avformat_new_stream(s, NULL); - if (!ast) - return AVERROR(ENOMEM); - ast->codec->codec_type = AVMEDIA_TYPE_AUDIO; - ast->codec->codec_id = AV_CODEC_ID_PCM_S32BE; - ast->codec->channels = tmp; - avpriv_set_pts_info(ast, 32, 1, st->time_base.den); - } avio_read(s->pb, filename, 257); filename[sizeof(filename)-1] = 0; @@ -183,6 +177,11 @@ static int r3d_read_header(AVFormatContext *s) return -1; } + /* we cannot create the audio stream now because we do not know the + * sample rate */ + if (r3d->audio_channels) + s->ctx_flags |= AVFMTCTX_NOHEADER; + s->internal->data_offset = avio_tell(s->pb); av_log(s, AV_LOG_TRACE, "data offset %#"PRIx64"\n", s->internal->data_offset); if (!s->pb->seekable) @@ -271,13 +270,26 @@ static int r3d_read_redv(AVFormatContext *s, AVPacket *pkt, Atom *atom) static int r3d_read_reda(AVFormatContext *s, AVPacket *pkt, Atom *atom) { - AVStream *st = s->streams[1]; + R3DContext *r3d = s->priv_data; + AVStream *st; int av_unused tmp, tmp2; int samples, size; int64_t pos = avio_tell(s->pb); unsigned dts; int ret; + if (s->nb_streams < 2) { + st = avformat_new_stream(s, NULL); + if (!st) + return AVERROR(ENOMEM); + st->codec->codec_type = AVMEDIA_TYPE_AUDIO; + st->codec->codec_id = AV_CODEC_ID_PCM_S32BE; + st->codec->channels = r3d->audio_channels; + avpriv_set_pts_info(st, 32, 1, s->streams[0]->time_base.den); + } else { + st = s->streams[1]; + } + dts = avio_rb32(s->pb); st->codec->sample_rate = avio_rb32(s->pb); @@ -321,6 +333,7 @@ static int r3d_read_reda(AVFormatContext *s, AVPacket *pkt, Atom *atom) static int r3d_read_packet(AVFormatContext *s, AVPacket *pkt) { + R3DContext *r3d = s->priv_data; Atom atom; int err = 0; @@ -337,7 +350,7 @@ static int r3d_read_packet(AVFormatContext *s, AVPacket *pkt) return 0; break; case MKTAG('R','E','D','A'): - if (s->nb_streams < 2) + if (!r3d->audio_channels) return -1; if (s->streams[1]->discard == AVDISCARD_ALL) goto skip; |