@ -391,33 +391,11 @@ done:
return ret ;
}
static int mediacodec_send_receive ( AVCodecContext * avctx ,
MediaCodecH264DecContext * s ,
AVFrame * frame , bool wait )
{
int ret ;
/* send any pending data from buffered packet */
while ( s - > buffered_pkt . size ) {
ret = ff_mediacodec_dec_send ( avctx , s - > ctx , & s - > buffered_pkt ) ;
if ( ret = = AVERROR ( EAGAIN ) )
break ;
else if ( ret < 0 )
return ret ;
s - > buffered_pkt . size - = ret ;
s - > buffered_pkt . data + = ret ;
if ( s - > buffered_pkt . size < = 0 )
av_packet_unref ( & s - > buffered_pkt ) ;
}
/* check for new frame */
return ff_mediacodec_dec_receive ( avctx , s - > ctx , frame , wait ) ;
}
static int mediacodec_receive_frame ( AVCodecContext * avctx , AVFrame * frame )
{
MediaCodecH264DecContext * s = avctx - > priv_data ;
int ret ;
ssize_t index ;
/* In delay_flush mode, wait until the user has released or rendered
all retained frames . */
@ -427,28 +405,54 @@ static int mediacodec_receive_frame(AVCodecContext *avctx, AVFrame *frame)
}
}
/* flush buffered packet and check for new frame */
ret = mediacodec_send _receive( avctx , s , frame , false ) ;
/* poll for new frame */
ret = ff_mediacodec_dec _receive( avctx , s - > ctx , frame , false ) ;
if ( ret ! = AVERROR ( EAGAIN ) )
return ret ;
/* skip fetching new packet if we still have one buffered */
if ( s - > buffered_pkt . size > 0 )
return mediacodec_send_receive ( avctx , s , frame , true ) ;
/* feed decoder */
while ( 1 ) {
if ( s - > ctx - > current_input_buffer < 0 ) {
/* poll for input space */
index = ff_AMediaCodec_dequeueInputBuffer ( s - > ctx - > codec , 0 ) ;
if ( index < 0 ) {
/* no space, block for an output frame to appear */
return ff_mediacodec_dec_receive ( avctx , s - > ctx , frame , true ) ;
}
s - > ctx - > current_input_buffer = index ;
}
/* try to flush any buffered packet data */
if ( s - > buffered_pkt . size > 0 ) {
ret = ff_mediacodec_dec_send ( avctx , s - > ctx , & s - > buffered_pkt , false ) ;
if ( ret > = 0 ) {
s - > buffered_pkt . size - = ret ;
s - > buffered_pkt . data + = ret ;
if ( s - > buffered_pkt . size < = 0 )
av_packet_unref ( & s - > buffered_pkt ) ;
} else if ( ret < 0 & & ret ! = AVERROR ( EAGAIN ) ) {
return ret ;
}
/* poll for space again */
continue ;
}
/* fetch new packet or eof */
ret = ff_decode_get_packet ( avctx , & s - > buffered_pkt ) ;
if ( ret = = AVERROR_EOF ) {
AVPacket null_pkt = { 0 } ;
ret = ff_mediacodec_dec_send ( avctx , s - > ctx , & null_pkt ) ;
ret = ff_mediacodec_dec_send ( avctx , s - > ctx , & null_pkt , true ) ;
if ( ret < 0 )
return ret ;
}
else if ( ret < 0 )
} else if ( ret = = AVERROR ( EAGAIN ) & & s - > ctx - > current_input_buffer < 0 ) {
return ff_mediacodec_dec_receive ( avctx , s - > ctx , frame , true ) ;
} else if ( ret < 0 ) {
return ret ;
}
}
/* crank decoder with new packet */
return mediacodec_send_receive ( avctx , s , frame , true ) ;
return AVERROR ( EAGAIN ) ;
}
static void mediacodec_decode_flush ( AVCodecContext * avctx )