summaryrefslogtreecommitdiffstats
path: root/video/decode/vd_lavc.c
diff options
context:
space:
mode:
Diffstat (limited to 'video/decode/vd_lavc.c')
-rw-r--r--video/decode/vd_lavc.c53
1 files changed, 19 insertions, 34 deletions
diff --git a/video/decode/vd_lavc.c b/video/decode/vd_lavc.c
index 9b65912fe4..a8c0c41f0c 100644
--- a/video/decode/vd_lavc.c
+++ b/video/decode/vd_lavc.c
@@ -755,15 +755,18 @@ static int get_buffer2_hwdec(AVCodecContext *avctx, AVFrame *pic, int flags)
return 0;
}
-static struct mp_image *read_output(struct dec_video *vd, bool eof)
+static bool read_output(struct dec_video *vd, bool progress,
+ struct mp_image **out_image)
{
vd_ffmpeg_ctx *ctx = vd->priv;
+ assert(!*out_image);
+
if (!ctx->num_delay_queue)
- return NULL;
+ return progress;
- if (ctx->num_delay_queue <= ctx->max_delay_queue && !eof)
- return NULL;
+ if (ctx->num_delay_queue <= ctx->max_delay_queue && progress)
+ return true;
struct mp_image *res = ctx->delay_queue[0];
MP_TARRAY_REMOVE_AT(ctx->delay_queue, ctx->num_delay_queue, 0);
@@ -773,7 +776,7 @@ static struct mp_image *read_output(struct dec_video *vd, bool eof)
res = res ? mp_img_swap_to_native(res) : NULL;
if (!res)
- return NULL;
+ return progress;
if (!ctx->hwdec_notified && vd->opts->hwdec_api != HWDEC_NONE) {
if (ctx->hwdec) {
@@ -792,7 +795,8 @@ static struct mp_image *read_output(struct dec_video *vd, bool eof)
ctx->hw_probing = false;
}
- return res;
+ *out_image = res;
+ return true;
}
static bool prepare_decoding(struct dec_video *vd)
@@ -878,14 +882,14 @@ static bool send_packet(struct dec_video *vd, struct demux_packet *pkt)
return do_send_packet(vd, pkt);
}
-// Returns EOF state.
+// Returns whether decoder is still active (!EOF state).
static bool decode_frame(struct dec_video *vd)
{
vd_ffmpeg_ctx *ctx = vd->priv;
AVCodecContext *avctx = ctx->avctx;
if (!prepare_decoding(vd))
- return false;
+ return true;
hwdec_lock(ctx);
int ret = avcodec_receive_frame(avctx, ctx->pic);
@@ -895,13 +899,13 @@ static bool decode_frame(struct dec_video *vd)
// If flushing was initialized earlier and has ended now, make it start
// over in case we get new packets at some point in the future.
reset_avctx(vd);
- return true;
+ return false;
} else if (ret < 0 && ret != AVERROR(EAGAIN)) {
handle_err(vd);
}
if (!ctx->pic->buf[0])
- return false;
+ return true;
ctx->hwdec_fail_count = 0;
@@ -917,7 +921,7 @@ static bool decode_frame(struct dec_video *vd)
struct mp_image *mpi = mp_image_from_av_frame(ctx->pic);
if (!mpi) {
av_frame_unref(ctx->pic);
- return false;
+ return true;
}
assert(mpi->planes[0] || mpi->planes[3]);
mpi->pts = mp_pts_from_av(ctx->pic->pts, &ctx->codec_timebase);
@@ -935,14 +939,14 @@ static bool decode_frame(struct dec_video *vd)
av_frame_unref(ctx->pic);
MP_TARRAY_APPEND(ctx, ctx->delay_queue, ctx->num_delay_queue, mpi);
- return false;
+ return true;
}
-static struct mp_image *receive_frame(struct dec_video *vd)
+static bool receive_frame(struct dec_video *vd, struct mp_image **out_image)
{
vd_ffmpeg_ctx *ctx = vd->priv;
- bool eof = decode_frame(vd);
+ bool progress = decode_frame(vd);
if (ctx->hwdec_failed) {
// Failed hardware decoding? Try again in software.
@@ -953,30 +957,11 @@ static struct mp_image *receive_frame(struct dec_video *vd)
force_fallback(vd);
- struct mp_image *img = NULL;
-
- while (num_pkts > 0) {
- if (send_packet(vd, pkts[0])) {
- talloc_free(pkts[0]);
- MP_TARRAY_REMOVE_AT(pkts, num_pkts, 0);
- }
- if (decode_frame(vd)) {
- eof = true;
- break;
- }
- img = read_output(vd, eof);
- if (img)
- break;
- }
-
ctx->requeue_packets = pkts;
ctx->num_requeue_packets = num_pkts;
-
- if (img)
- return img;
}
- return read_output(vd, eof);
+ return read_output(vd, progress, out_image);
}
static int control(struct dec_video *vd, int cmd, void *arg)