Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/FFmpeg/FFmpeg.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAman Gupta <aman@tmm1.net>2017-12-29 04:33:14 +0300
committerMatthieu Bouron <matthieu.bouron@gmail.com>2018-01-07 00:12:31 +0300
commit9d9835017f67db7e37b6b5a42a247e17b05bf8fc (patch)
treed461a364bde88596d6c33eb4817eb9693b8e8e90 /libavcodec/mediacodecdec.c
parent8bbd8c8d52dbcb15773717d3512f8fb68e860bf2 (diff)
lavc/mediacodecdec: switch to new decoding API
Using the new API gives the decoder the ability to produce N frames per input packet. This is particularly useful with mpeg2 decoders on some android devices, which automatically deinterlace video and produce one frame per field. Signed-off-by: Aman Gupta <aman@tmm1.net> Signed-off-by: Matthieu Bouron <matthieu.bouron@gmail.com>
Diffstat (limited to 'libavcodec/mediacodecdec.c')
-rw-r--r--libavcodec/mediacodecdec.c80
1 files changed, 48 insertions, 32 deletions
diff --git a/libavcodec/mediacodecdec.c b/libavcodec/mediacodecdec.c
index b698ceaef9..35a9e34861 100644
--- a/libavcodec/mediacodecdec.c
+++ b/libavcodec/mediacodecdec.c
@@ -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,