@ -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 ;
@ -92,17 +95,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 ;
@ -185,6 +179,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 )
@ -273,13 +272,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 ) ;
@ -324,6 +336,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 ;
@ -340,9 +353,9 @@ 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 )
if ( s - > nb_streams > = 2 & & s - > streams [ 1 ] - > discard = = AVDISCARD_ALL )
goto skip ;
if ( ! ( err = r3d_read_reda ( s , pkt , & atom ) ) )
return 0 ;