summaryrefslogtreecommitdiff
path: root/libavformat
diff options
context:
space:
mode:
authorAnton Khirnov <anton@khirnov.net>2015-10-21 11:22:13 +0200
committerAnton Khirnov <anton@khirnov.net>2015-12-12 21:20:33 +0100
commit6bf4c1d71199b92894f24db6386ed5070e590a16 (patch)
tree45867569e8042e9ee5a788d3688cd00765d55ce9 /libavformat
parent9f1eccb97bf8894cb18b14f642500686505ef186 (diff)
downloadffmpeg-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.c37
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;