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