|
|
@@ -31,6 +31,7 @@ |
|
|
|
#include "libavutil/pixfmt.h" |
|
|
|
|
|
|
|
#include "avcodec.h" |
|
|
|
#include "decode.h" |
|
|
|
#include "h264_parse.h" |
|
|
|
#include "hevc_parse.h" |
|
|
|
#include "hwaccel.h" |
|
|
@@ -424,29 +425,13 @@ static int mediacodec_process_data(AVCodecContext *avctx, AVFrame *frame, |
|
|
|
return ff_mediacodec_dec_decode(avctx, s->ctx, frame, got_frame, pkt); |
|
|
|
} |
|
|
|
|
|
|
|
static int mediacodec_decode_frame(AVCodecContext *avctx, void *data, |
|
|
|
int *got_frame, AVPacket *avpkt) |
|
|
|
static int mediacodec_receive_frame(AVCodecContext *avctx, AVFrame *frame) |
|
|
|
{ |
|
|
|
MediaCodecH264DecContext *s = avctx->priv_data; |
|
|
|
AVFrame *frame = data; |
|
|
|
int ret; |
|
|
|
|
|
|
|
/* buffer the input packet */ |
|
|
|
if (avpkt->size) { |
|
|
|
AVPacket input_pkt = { 0 }; |
|
|
|
|
|
|
|
if (av_fifo_space(s->fifo) < sizeof(input_pkt)) { |
|
|
|
ret = av_fifo_realloc2(s->fifo, |
|
|
|
av_fifo_size(s->fifo) + sizeof(input_pkt)); |
|
|
|
if (ret < 0) |
|
|
|
return ret; |
|
|
|
} |
|
|
|
|
|
|
|
ret = av_packet_ref(&input_pkt, avpkt); |
|
|
|
if (ret < 0) |
|
|
|
return ret; |
|
|
|
av_fifo_generic_write(s->fifo, &input_pkt, sizeof(input_pkt), NULL); |
|
|
|
} |
|
|
|
int got_frame = 0; |
|
|
|
int is_eof = 0; |
|
|
|
AVPacket pkt = { 0 }; |
|
|
|
|
|
|
|
/* |
|
|
|
* MediaCodec.flush() discards both input and output buffers, thus we |
|
|
@@ -470,26 +455,57 @@ static int mediacodec_decode_frame(AVCodecContext *avctx, void *data, |
|
|
|
*/ |
|
|
|
if (ff_mediacodec_dec_is_flushing(avctx, s->ctx)) { |
|
|
|
if (!ff_mediacodec_dec_flush(avctx, s->ctx)) { |
|
|
|
return avpkt->size; |
|
|
|
return AVERROR(EAGAIN); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
ret = ff_decode_get_packet(avctx, &pkt); |
|
|
|
if (ret == AVERROR_EOF) |
|
|
|
is_eof = 1; |
|
|
|
else if (ret == AVERROR(EAGAIN)) |
|
|
|
; /* no input packet, but fallthrough to check for pending frames */ |
|
|
|
else if (ret < 0) |
|
|
|
return ret; |
|
|
|
|
|
|
|
/* buffer the input packet */ |
|
|
|
if (pkt.size) { |
|
|
|
if (av_fifo_space(s->fifo) < sizeof(pkt)) { |
|
|
|
ret = av_fifo_realloc2(s->fifo, |
|
|
|
av_fifo_size(s->fifo) + sizeof(pkt)); |
|
|
|
if (ret < 0) { |
|
|
|
av_packet_unref(&pkt); |
|
|
|
return ret; |
|
|
|
} |
|
|
|
} |
|
|
|
av_fifo_generic_write(s->fifo, &pkt, sizeof(pkt), NULL); |
|
|
|
} |
|
|
|
|
|
|
|
/* process buffered data */ |
|
|
|
while (!*got_frame) { |
|
|
|
while (!got_frame) { |
|
|
|
/* prepare the input data */ |
|
|
|
if (s->buffered_pkt.size <= 0) { |
|
|
|
av_packet_unref(&s->buffered_pkt); |
|
|
|
|
|
|
|
/* no more data */ |
|
|
|
if (av_fifo_size(s->fifo) < sizeof(AVPacket)) { |
|
|
|
return avpkt->size ? avpkt->size : |
|
|
|
ff_mediacodec_dec_decode(avctx, s->ctx, frame, got_frame, avpkt); |
|
|
|
AVPacket null_pkt = { 0 }; |
|
|
|
if (is_eof) { |
|
|
|
ret = ff_mediacodec_dec_decode(avctx, s->ctx, frame, |
|
|
|
&got_frame, &null_pkt); |
|
|
|
if (ret < 0) |
|
|
|
return ret; |
|
|
|
else if (got_frame) |
|
|
|
return 0; |
|
|
|
else |
|
|
|
return AVERROR_EOF; |
|
|
|
} |
|
|
|
return AVERROR(EAGAIN); |
|
|
|
} |
|
|
|
|
|
|
|
av_fifo_generic_read(s->fifo, &s->buffered_pkt, sizeof(s->buffered_pkt), NULL); |
|
|
|
} |
|
|
|
|
|
|
|
ret = mediacodec_process_data(avctx, frame, got_frame, &s->buffered_pkt); |
|
|
|
ret = mediacodec_process_data(avctx, frame, &got_frame, &s->buffered_pkt); |
|
|
|
if (ret < 0) |
|
|
|
return ret; |
|
|
|
|
|
|
@@ -497,7 +513,7 @@ static int mediacodec_decode_frame(AVCodecContext *avctx, void *data, |
|
|
|
s->buffered_pkt.data += ret; |
|
|
|
} |
|
|
|
|
|
|
|
return avpkt->size; |
|
|
|
return 0; |
|
|
|
} |
|
|
|
|
|
|
|
static void mediacodec_decode_flush(AVCodecContext *avctx) |
|
|
@@ -537,7 +553,7 @@ AVCodec ff_h264_mediacodec_decoder = { |
|
|
|
.id = AV_CODEC_ID_H264, |
|
|
|
.priv_data_size = sizeof(MediaCodecH264DecContext), |
|
|
|
.init = mediacodec_decode_init, |
|
|
|
.decode = mediacodec_decode_frame, |
|
|
|
.receive_frame = mediacodec_receive_frame, |
|
|
|
.flush = mediacodec_decode_flush, |
|
|
|
.close = mediacodec_decode_close, |
|
|
|
.capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_AVOID_PROBING | AV_CODEC_CAP_HARDWARE, |
|
|
@@ -556,7 +572,7 @@ AVCodec ff_hevc_mediacodec_decoder = { |
|
|
|
.id = AV_CODEC_ID_HEVC, |
|
|
|
.priv_data_size = sizeof(MediaCodecH264DecContext), |
|
|
|
.init = mediacodec_decode_init, |
|
|
|
.decode = mediacodec_decode_frame, |
|
|
|
.receive_frame = mediacodec_receive_frame, |
|
|
|
.flush = mediacodec_decode_flush, |
|
|
|
.close = mediacodec_decode_close, |
|
|
|
.capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_AVOID_PROBING | AV_CODEC_CAP_HARDWARE, |
|
|
@@ -575,7 +591,7 @@ AVCodec ff_mpeg2_mediacodec_decoder = { |
|
|
|
.id = AV_CODEC_ID_MPEG2VIDEO, |
|
|
|
.priv_data_size = sizeof(MediaCodecH264DecContext), |
|
|
|
.init = mediacodec_decode_init, |
|
|
|
.decode = mediacodec_decode_frame, |
|
|
|
.receive_frame = mediacodec_receive_frame, |
|
|
|
.flush = mediacodec_decode_flush, |
|
|
|
.close = mediacodec_decode_close, |
|
|
|
.capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_AVOID_PROBING | AV_CODEC_CAP_HARDWARE, |
|
|
@@ -593,7 +609,7 @@ AVCodec ff_mpeg4_mediacodec_decoder = { |
|
|
|
.id = AV_CODEC_ID_MPEG4, |
|
|
|
.priv_data_size = sizeof(MediaCodecH264DecContext), |
|
|
|
.init = mediacodec_decode_init, |
|
|
|
.decode = mediacodec_decode_frame, |
|
|
|
.receive_frame = mediacodec_receive_frame, |
|
|
|
.flush = mediacodec_decode_flush, |
|
|
|
.close = mediacodec_decode_close, |
|
|
|
.capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_AVOID_PROBING | AV_CODEC_CAP_HARDWARE, |
|
|
@@ -611,7 +627,7 @@ AVCodec ff_vp8_mediacodec_decoder = { |
|
|
|
.id = AV_CODEC_ID_VP8, |
|
|
|
.priv_data_size = sizeof(MediaCodecH264DecContext), |
|
|
|
.init = mediacodec_decode_init, |
|
|
|
.decode = mediacodec_decode_frame, |
|
|
|
.receive_frame = mediacodec_receive_frame, |
|
|
|
.flush = mediacodec_decode_flush, |
|
|
|
.close = mediacodec_decode_close, |
|
|
|
.capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_AVOID_PROBING | AV_CODEC_CAP_HARDWARE, |
|
|
@@ -629,7 +645,7 @@ AVCodec ff_vp9_mediacodec_decoder = { |
|
|
|
.id = AV_CODEC_ID_VP9, |
|
|
|
.priv_data_size = sizeof(MediaCodecH264DecContext), |
|
|
|
.init = mediacodec_decode_init, |
|
|
|
.decode = mediacodec_decode_frame, |
|
|
|
.receive_frame = mediacodec_receive_frame, |
|
|
|
.flush = mediacodec_decode_flush, |
|
|
|
.close = mediacodec_decode_close, |
|
|
|
.capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_AVOID_PROBING | AV_CODEC_CAP_HARDWARE, |
|
|
|