@ -535,6 +535,103 @@ static int rm_assemble_video_frame(AVFormatContext *s, RMContext *rm, AVPacket *
return 1 ;
}
static int
ff_rm_parse_packet ( AVFormatContext * s , AVStream * st , int len , AVPacket * pkt ,
int * seq , int * flags , int64_t * timestamp )
{
ByteIOContext * pb = & s - > pb ;
RMContext * rm = s - > priv_data ;
if ( st - > codec - > codec_type = = CODEC_TYPE_VIDEO ) {
rm - > current_stream = st - > id ;
if ( rm_assemble_video_frame ( s , rm , pkt , len ) = = 1 )
return - 1 ; //got partial frame
} else if ( st - > codec - > codec_type = = CODEC_TYPE_AUDIO ) {
if ( ( st - > codec - > codec_id = = CODEC_ID_RA_288 ) | |
( st - > codec - > codec_id = = CODEC_ID_COOK ) | |
( st - > codec - > codec_id = = CODEC_ID_ATRAC3 ) ) {
int x ;
int sps = rm - > sub_packet_size ;
int cfs = rm - > coded_framesize ;
int h = rm - > sub_packet_h ;
int y = rm - > sub_packet_cnt ;
int w = rm - > audio_framesize ;
if ( * flags & 2 )
y = rm - > sub_packet_cnt = 0 ;
if ( ! y )
rm - > audiotimestamp = * timestamp ;
switch ( st - > codec - > codec_id ) {
case CODEC_ID_RA_288 :
for ( x = 0 ; x < h / 2 ; x + + )
get_buffer ( pb , rm - > audiobuf + x * 2 * w + y * cfs , cfs ) ;
break ;
case CODEC_ID_ATRAC3 :
case CODEC_ID_COOK :
for ( x = 0 ; x < w / sps ; x + + )
get_buffer ( pb , rm - > audiobuf + sps * ( h * x + ( ( h + 1 ) / 2 ) * ( y & 1 ) + ( y > > 1 ) ) , sps ) ;
break ;
}
if ( + + ( rm - > sub_packet_cnt ) < h )
return - 1 ;
else {
rm - > sub_packet_cnt = 0 ;
rm - > audio_stream_num = st - > index ;
rm - > audio_pkt_cnt = h * w / st - > codec - > block_align - 1 ;
// Release first audio packet
av_new_packet ( pkt , st - > codec - > block_align ) ;
memcpy ( pkt - > data , rm - > audiobuf , st - > codec - > block_align ) ;
* timestamp = rm - > audiotimestamp ;
* flags = 2 ; // Mark first packet as keyframe
}
} else if ( st - > codec - > codec_id = = CODEC_ID_AAC ) {
int x ;
rm - > audio_stream_num = st - > index ;
rm - > sub_packet_cnt = ( get_be16 ( pb ) & 0xf0 ) > > 4 ;
if ( rm - > sub_packet_cnt ) {
for ( x = 0 ; x < rm - > sub_packet_cnt ; x + + )
rm - > sub_packet_lengths [ x ] = get_be16 ( pb ) ;
// Release first audio packet
rm - > audio_pkt_cnt = rm - > sub_packet_cnt - 1 ;
av_get_packet ( pb , pkt , rm - > sub_packet_lengths [ 0 ] ) ;
* flags = 2 ; // Mark first packet as keyframe
}
} else
av_get_packet ( pb , pkt , len ) ;
} else
av_get_packet ( pb , pkt , len ) ;
if ( ( st - > discard > = AVDISCARD_NONKEY & & ! ( * flags & 2 ) )
| | st - > discard > = AVDISCARD_ALL ) {
av_free_packet ( pkt ) ;
return - 1 ;
}
pkt - > stream_index = st - > index ;
#if 0
if ( st - > codec - > codec_type = = CODEC_TYPE_VIDEO ) {
if ( st - > codec - > codec_id = = CODEC_ID_RV20 ) {
int seq = 128 * ( pkt - > data [ 2 ] & 0x7F ) + ( pkt - > data [ 3 ] > > 1 ) ;
av_log ( NULL , AV_LOG_DEBUG , " %d % " PRId64 " %d \n " , * timestamp , * timestamp * 512LL / 25 , seq ) ;
seq | = ( * timestamp & ~ 0x3FFF ) ;
if ( seq - * timestamp > 0x2000 ) seq - = 0x4000 ;
if ( seq - * timestamp < - 0x2000 ) seq + = 0x4000 ;
}
}
# endif
pkt - > pts = * timestamp ;
if ( * flags & 2 )
pkt - > flags | = PKT_FLAG_KEY ;
return 0 ;
}
static int rm_read_packet ( AVFormatContext * s , AVPacket * pkt )
{
RMContext * rm = s - > priv_data ;
@ -593,91 +690,10 @@ resync:
return AVERROR ( EIO ) ;
st = s - > streams [ i ] ;
if ( st - > codec - > codec_type = = CODEC_TYPE_VIDEO ) {
rm - > current_stream = st - > id ;
if ( rm_assemble_video_frame ( s , rm , pkt , len ) = = 1 )
goto resync ; //got partial frame
} else if ( st - > codec - > codec_type = = CODEC_TYPE_AUDIO ) {
if ( ( st - > codec - > codec_id = = CODEC_ID_RA_288 ) | |
( st - > codec - > codec_id = = CODEC_ID_COOK ) | |
( st - > codec - > codec_id = = CODEC_ID_ATRAC3 ) ) {
int x ;
int sps = rm - > sub_packet_size ;
int cfs = rm - > coded_framesize ;
int h = rm - > sub_packet_h ;
int y = rm - > sub_packet_cnt ;
int w = rm - > audio_framesize ;
if ( flags & 2 )
y = rm - > sub_packet_cnt = 0 ;
if ( ! y )
rm - > audiotimestamp = timestamp ;
switch ( st - > codec - > codec_id ) {
case CODEC_ID_RA_288 :
for ( x = 0 ; x < h / 2 ; x + + )
get_buffer ( pb , rm - > audiobuf + x * 2 * w + y * cfs , cfs ) ;
break ;
case CODEC_ID_ATRAC3 :
case CODEC_ID_COOK :
for ( x = 0 ; x < w / sps ; x + + )
get_buffer ( pb , rm - > audiobuf + sps * ( h * x + ( ( h + 1 ) / 2 ) * ( y & 1 ) + ( y > > 1 ) ) , sps ) ;
break ;
}
if ( + + ( rm - > sub_packet_cnt ) < h )
goto resync ;
else {
rm - > sub_packet_cnt = 0 ;
rm - > audio_stream_num = st - > index ;
rm - > audio_pkt_cnt = h * w / st - > codec - > block_align - 1 ;
// Release first audio packet
av_new_packet ( pkt , st - > codec - > block_align ) ;
memcpy ( pkt - > data , rm - > audiobuf , st - > codec - > block_align ) ;
timestamp = rm - > audiotimestamp ;
flags = 2 ; // Mark first packet as keyframe
}
} else if ( st - > codec - > codec_id = = CODEC_ID_AAC ) {
int x ;
rm - > audio_stream_num = st - > index ;
rm - > sub_packet_cnt = ( get_be16 ( pb ) & 0xf0 ) > > 4 ;
if ( rm - > sub_packet_cnt ) {
for ( x = 0 ; x < rm - > sub_packet_cnt ; x + + )
rm - > sub_packet_lengths [ x ] = get_be16 ( pb ) ;
// Release first audio packet
rm - > audio_pkt_cnt = rm - > sub_packet_cnt - 1 ;
av_get_packet ( pb , pkt , rm - > sub_packet_lengths [ 0 ] ) ;
flags = 2 ; // Mark first packet as keyframe
}
} else
av_get_packet ( pb , pkt , len ) ;
} else
av_get_packet ( pb , pkt , len ) ;
if ( ( st - > discard > = AVDISCARD_NONKEY & & ! ( flags & 2 ) )
| | st - > discard > = AVDISCARD_ALL ) {
av_free_packet ( pkt ) ;
if ( ff_rm_parse_packet ( s , st , len , pkt , & seq , & flags , & timestamp ) < 0 )
goto resync ;
}
pkt - > stream_index = st - > index ;
#if 0
if ( st - > codec - > codec_type = = CODEC_TYPE_VIDEO ) {
if ( st - > codec - > codec_id = = CODEC_ID_RV20 ) {
int seq = 128 * ( pkt - > data [ 2 ] & 0x7F ) + ( pkt - > data [ 3 ] > > 1 ) ;
av_log ( NULL , AV_LOG_DEBUG , " %d % " PRId64 " %d \n " , timestamp , timestamp * 512LL / 25 , seq ) ;
seq | = ( timestamp & ~ 0x3FFF ) ;
if ( seq - timestamp > 0x2000 ) seq - = 0x4000 ;
if ( seq - timestamp < - 0x2000 ) seq + = 0x4000 ;
}
}
# endif
pkt - > pts = timestamp ;
if ( flags & 2 ) {
pkt - > flags | = PKT_FLAG_KEY ;
if ( ( seq & 0x7F ) = = 1 )
av_add_index_entry ( st , pos , timestamp , 0 , 0 , AVINDEX_KEYFRAME ) ;
}