mirror of
https://github.com/LibreELEC/LibreELEC.tv.git
synced 2025-07-29 13:46:49 +00:00
Merge pull request #5054 from HiassofT/le10-ffmpeg-rpi-4
ffmpeg: update rpi patch
This commit is contained in:
commit
9655c7093a
@ -16116,7 +16116,7 @@ index 0000000000..13698d3f33
|
|||||||
+
|
+
|
||||||
+#endif
|
+#endif
|
||||||
diff --git a/libavcodec/hevcdec.c b/libavcodec/hevcdec.c
|
diff --git a/libavcodec/hevcdec.c b/libavcodec/hevcdec.c
|
||||||
index 0772608a30..91a7536ee5 100644
|
index 0772608a30..c30fb2a83f 100644
|
||||||
--- a/libavcodec/hevcdec.c
|
--- a/libavcodec/hevcdec.c
|
||||||
+++ b/libavcodec/hevcdec.c
|
+++ b/libavcodec/hevcdec.c
|
||||||
@@ -372,14 +372,20 @@ static enum AVPixelFormat get_format(HEVCContext *s, const HEVCSPS *sps)
|
@@ -372,14 +372,20 @@ static enum AVPixelFormat get_format(HEVCContext *s, const HEVCSPS *sps)
|
||||||
@ -16186,14 +16186,14 @@ index 0772608a30..91a7536ee5 100644
|
|||||||
#if CONFIG_HEVC_VIDEOTOOLBOX_HWACCEL
|
#if CONFIG_HEVC_VIDEOTOOLBOX_HWACCEL
|
||||||
HWACCEL_VIDEOTOOLBOX(hevc),
|
HWACCEL_VIDEOTOOLBOX(hevc),
|
||||||
+#endif
|
+#endif
|
||||||
+#if CONFIG_HEVC_V4L2REQUEST_HWACCEL
|
|
||||||
+ HWACCEL_V4L2REQUEST(hevc),
|
|
||||||
+#endif
|
|
||||||
+#if CONFIG_HEVC_RPI4_8_HWACCEL
|
+#if CONFIG_HEVC_RPI4_8_HWACCEL
|
||||||
+ HWACCEL_RPI4_8(hevc),
|
+ HWACCEL_RPI4_8(hevc),
|
||||||
+#endif
|
+#endif
|
||||||
+#if CONFIG_HEVC_RPI4_10_HWACCEL
|
+#if CONFIG_HEVC_RPI4_10_HWACCEL
|
||||||
+ HWACCEL_RPI4_10(hevc),
|
+ HWACCEL_RPI4_10(hevc),
|
||||||
|
+#endif
|
||||||
|
+#if CONFIG_HEVC_V4L2REQUEST_HWACCEL
|
||||||
|
+ HWACCEL_V4L2REQUEST(hevc),
|
||||||
#endif
|
#endif
|
||||||
NULL
|
NULL
|
||||||
},
|
},
|
||||||
@ -47232,7 +47232,7 @@ index 8dbc7fc104..46ca85ce65 100644
|
|||||||
* Extracts the data from an AVFrame to a V4L2Buffer
|
* Extracts the data from an AVFrame to a V4L2Buffer
|
||||||
*
|
*
|
||||||
diff --git a/libavcodec/v4l2_context.c b/libavcodec/v4l2_context.c
|
diff --git a/libavcodec/v4l2_context.c b/libavcodec/v4l2_context.c
|
||||||
index 29b144ed73..31b406769b 100644
|
index 29b144ed73..97956eeb2b 100644
|
||||||
--- a/libavcodec/v4l2_context.c
|
--- a/libavcodec/v4l2_context.c
|
||||||
+++ b/libavcodec/v4l2_context.c
|
+++ b/libavcodec/v4l2_context.c
|
||||||
@@ -173,7 +173,8 @@ static int v4l2_handle_event(V4L2Context *ctx)
|
@@ -173,7 +173,8 @@ static int v4l2_handle_event(V4L2Context *ctx)
|
||||||
@ -47347,15 +47347,18 @@ index 29b144ed73..31b406769b 100644
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -455,22 +498,54 @@ static int v4l2_release_buffers(V4L2Context* ctx)
|
@@ -452,25 +495,62 @@ static V4L2Buffer* v4l2_getfree_v4l2buf(V4L2Context *ctx)
|
||||||
struct v4l2_requestbuffers req = {
|
|
||||||
.memory = V4L2_MEMORY_MMAP,
|
static int v4l2_release_buffers(V4L2Context* ctx)
|
||||||
.type = ctx->type,
|
{
|
||||||
|
- struct v4l2_requestbuffers req = {
|
||||||
|
- .memory = V4L2_MEMORY_MMAP,
|
||||||
|
- .type = ctx->type,
|
||||||
- .count = 0, /* 0 -> unmaps buffers from the driver */
|
- .count = 0, /* 0 -> unmaps buffers from the driver */
|
||||||
+ .count = 0, /* 0 -> unmap all buffers from the driver */
|
- };
|
||||||
};
|
int i, j;
|
||||||
- int i, j;
|
+ int ret = 0;
|
||||||
+ int ret, i, j;
|
+ const int fd = ctx_to_m2mctx(ctx)->fd;
|
||||||
|
|
||||||
for (i = 0; i < ctx->num_buffers; i++) {
|
for (i = 0; i < ctx->num_buffers; i++) {
|
||||||
V4L2Buffer *buffer = &ctx->buffers[i];
|
V4L2Buffer *buffer = &ctx->buffers[i];
|
||||||
@ -47389,24 +47392,32 @@ index 29b144ed73..31b406769b 100644
|
|||||||
}
|
}
|
||||||
|
|
||||||
- return ioctl(ctx_to_m2mctx(ctx)->fd, VIDIOC_REQBUFS, &req);
|
- return ioctl(ctx_to_m2mctx(ctx)->fd, VIDIOC_REQBUFS, &req);
|
||||||
+ ret = ioctl(ctx_to_m2mctx(ctx)->fd, VIDIOC_REQBUFS, &req);
|
+ if (fd != -1) {
|
||||||
+ if (ret < 0) {
|
+ struct v4l2_requestbuffers req = {
|
||||||
+ av_log(logger(ctx), AV_LOG_ERROR, "release all %s buffers (%s)\n",
|
+ .memory = V4L2_MEMORY_MMAP,
|
||||||
+ ctx->name, av_err2str(AVERROR(errno)));
|
+ .type = ctx->type,
|
||||||
|
+ .count = 0, /* 0 -> unmap all buffers from the driver */
|
||||||
|
+ };
|
||||||
+
|
+
|
||||||
+ if (ctx_to_m2mctx(ctx)->output_drm)
|
+ ret = ioctl(fd, VIDIOC_REQBUFS, &req);
|
||||||
+ av_log(logger(ctx), AV_LOG_ERROR,
|
+ if (ret < 0) {
|
||||||
+ "Make sure the DRM client releases all FB/GEM objects before closing the codec (ie):\n"
|
+ av_log(logger(ctx), AV_LOG_ERROR, "release all %s buffers (%s)\n",
|
||||||
+ "for all buffers: \n"
|
+ ctx->name, av_err2str(AVERROR(errno)));
|
||||||
+ " 1. drmModeRmFB(..)\n"
|
+
|
||||||
+ " 2. drmIoctl(.., DRM_IOCTL_GEM_CLOSE,... )\n");
|
+ if (ctx_to_m2mctx(ctx)->output_drm)
|
||||||
|
+ av_log(logger(ctx), AV_LOG_ERROR,
|
||||||
|
+ "Make sure the DRM client releases all FB/GEM objects before closing the codec (ie):\n"
|
||||||
|
+ "for all buffers: \n"
|
||||||
|
+ " 1. drmModeRmFB(..)\n"
|
||||||
|
+ " 2. drmIoctl(.., DRM_IOCTL_GEM_CLOSE,... )\n");
|
||||||
|
+ }
|
||||||
+ }
|
+ }
|
||||||
+
|
+
|
||||||
+ return ret;
|
+ return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int v4l2_try_raw_format(V4L2Context* ctx, enum AVPixelFormat pixfmt)
|
static inline int v4l2_try_raw_format(V4L2Context* ctx, enum AVPixelFormat pixfmt)
|
||||||
@@ -499,6 +574,8 @@ static inline int v4l2_try_raw_format(V4L2Context* ctx, enum AVPixelFormat pixfm
|
@@ -499,6 +579,8 @@ static inline int v4l2_try_raw_format(V4L2Context* ctx, enum AVPixelFormat pixfm
|
||||||
|
|
||||||
static int v4l2_get_raw_format(V4L2Context* ctx, enum AVPixelFormat *p)
|
static int v4l2_get_raw_format(V4L2Context* ctx, enum AVPixelFormat *p)
|
||||||
{
|
{
|
||||||
@ -47415,7 +47426,7 @@ index 29b144ed73..31b406769b 100644
|
|||||||
enum AVPixelFormat pixfmt = ctx->av_pix_fmt;
|
enum AVPixelFormat pixfmt = ctx->av_pix_fmt;
|
||||||
struct v4l2_fmtdesc fdesc;
|
struct v4l2_fmtdesc fdesc;
|
||||||
int ret;
|
int ret;
|
||||||
@@ -517,6 +594,13 @@ static int v4l2_get_raw_format(V4L2Context* ctx, enum AVPixelFormat *p)
|
@@ -517,6 +599,13 @@ static int v4l2_get_raw_format(V4L2Context* ctx, enum AVPixelFormat *p)
|
||||||
if (ret)
|
if (ret)
|
||||||
return AVERROR(EINVAL);
|
return AVERROR(EINVAL);
|
||||||
|
|
||||||
@ -47429,7 +47440,7 @@ index 29b144ed73..31b406769b 100644
|
|||||||
pixfmt = ff_v4l2_format_v4l2_to_avfmt(fdesc.pixelformat, AV_CODEC_ID_RAWVIDEO);
|
pixfmt = ff_v4l2_format_v4l2_to_avfmt(fdesc.pixelformat, AV_CODEC_ID_RAWVIDEO);
|
||||||
ret = v4l2_try_raw_format(ctx, pixfmt);
|
ret = v4l2_try_raw_format(ctx, pixfmt);
|
||||||
if (ret){
|
if (ret){
|
||||||
@@ -575,10 +659,16 @@ int ff_v4l2_context_set_status(V4L2Context* ctx, uint32_t cmd)
|
@@ -575,10 +664,16 @@ int ff_v4l2_context_set_status(V4L2Context* ctx, uint32_t cmd)
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
ret = ioctl(ctx_to_m2mctx(ctx)->fd, cmd, &type);
|
ret = ioctl(ctx_to_m2mctx(ctx)->fd, cmd, &type);
|
||||||
@ -47448,7 +47459,7 @@ index 29b144ed73..31b406769b 100644
|
|||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -608,7 +698,8 @@ int ff_v4l2_context_enqueue_frame(V4L2Context* ctx, const AVFrame* frame)
|
@@ -608,7 +703,8 @@ int ff_v4l2_context_enqueue_frame(V4L2Context* ctx, const AVFrame* frame)
|
||||||
return ff_v4l2_buffer_enqueue(avbuf);
|
return ff_v4l2_buffer_enqueue(avbuf);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -47458,7 +47469,7 @@ index 29b144ed73..31b406769b 100644
|
|||||||
{
|
{
|
||||||
V4L2m2mContext *s = ctx_to_m2mctx(ctx);
|
V4L2m2mContext *s = ctx_to_m2mctx(ctx);
|
||||||
V4L2Buffer* avbuf;
|
V4L2Buffer* avbuf;
|
||||||
@@ -616,8 +707,9 @@ int ff_v4l2_context_enqueue_packet(V4L2Context* ctx, const AVPacket* pkt)
|
@@ -616,8 +712,9 @@ int ff_v4l2_context_enqueue_packet(V4L2Context* ctx, const AVPacket* pkt)
|
||||||
|
|
||||||
if (!pkt->size) {
|
if (!pkt->size) {
|
||||||
ret = v4l2_stop_decode(ctx);
|
ret = v4l2_stop_decode(ctx);
|
||||||
@ -47469,7 +47480,7 @@ index 29b144ed73..31b406769b 100644
|
|||||||
s->draining = 1;
|
s->draining = 1;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -626,14 +718,14 @@ int ff_v4l2_context_enqueue_packet(V4L2Context* ctx, const AVPacket* pkt)
|
@@ -626,14 +723,14 @@ int ff_v4l2_context_enqueue_packet(V4L2Context* ctx, const AVPacket* pkt)
|
||||||
if (!avbuf)
|
if (!avbuf)
|
||||||
return AVERROR(EAGAIN);
|
return AVERROR(EAGAIN);
|
||||||
|
|
||||||
@ -47486,7 +47497,7 @@ index 29b144ed73..31b406769b 100644
|
|||||||
{
|
{
|
||||||
V4L2Buffer *avbuf;
|
V4L2Buffer *avbuf;
|
||||||
|
|
||||||
@@ -650,7 +742,7 @@ int ff_v4l2_context_dequeue_frame(V4L2Context* ctx, AVFrame* frame, int timeout)
|
@@ -650,7 +747,7 @@ int ff_v4l2_context_dequeue_frame(V4L2Context* ctx, AVFrame* frame, int timeout)
|
||||||
return AVERROR(EAGAIN);
|
return AVERROR(EAGAIN);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -47496,20 +47507,19 @@ index 29b144ed73..31b406769b 100644
|
|||||||
|
|
||||||
int ff_v4l2_context_dequeue_packet(V4L2Context* ctx, AVPacket* pkt)
|
int ff_v4l2_context_dequeue_packet(V4L2Context* ctx, AVPacket* pkt)
|
||||||
diff --git a/libavcodec/v4l2_context.h b/libavcodec/v4l2_context.h
|
diff --git a/libavcodec/v4l2_context.h b/libavcodec/v4l2_context.h
|
||||||
index 22a9532444..3484a25a9c 100644
|
index 22a9532444..5588e4a460 100644
|
||||||
--- a/libavcodec/v4l2_context.h
|
--- a/libavcodec/v4l2_context.h
|
||||||
+++ b/libavcodec/v4l2_context.h
|
+++ b/libavcodec/v4l2_context.h
|
||||||
@@ -92,6 +92,9 @@ typedef struct V4L2Context {
|
@@ -92,6 +92,8 @@ typedef struct V4L2Context {
|
||||||
*/
|
*/
|
||||||
int done;
|
int done;
|
||||||
|
|
||||||
+ AVBufferRef *frames_ref;
|
+ AVBufferRef *frames_ref;
|
||||||
+ int q_count;
|
+ int q_count;
|
||||||
+
|
|
||||||
} V4L2Context;
|
} V4L2Context;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -156,9 +159,12 @@ int ff_v4l2_context_dequeue_packet(V4L2Context* ctx, AVPacket* pkt);
|
@@ -156,9 +158,12 @@ int ff_v4l2_context_dequeue_packet(V4L2Context* ctx, AVPacket* pkt);
|
||||||
* @param[in] ctx The V4L2Context to dequeue from.
|
* @param[in] ctx The V4L2Context to dequeue from.
|
||||||
* @param[inout] f The AVFrame to dequeue to.
|
* @param[inout] f The AVFrame to dequeue to.
|
||||||
* @param[in] timeout The timeout for dequeue (-1 to block, 0 to return immediately, or milliseconds)
|
* @param[in] timeout The timeout for dequeue (-1 to block, 0 to return immediately, or milliseconds)
|
||||||
@ -47523,7 +47533,7 @@ index 22a9532444..3484a25a9c 100644
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Enqueues a buffer to a V4L2Context from an AVPacket
|
* Enqueues a buffer to a V4L2Context from an AVPacket
|
||||||
@@ -170,7 +176,7 @@ int ff_v4l2_context_dequeue_frame(V4L2Context* ctx, AVFrame* f, int timeout);
|
@@ -170,7 +175,7 @@ int ff_v4l2_context_dequeue_frame(V4L2Context* ctx, AVFrame* f, int timeout);
|
||||||
* @param[in] pkt A pointer to an AVPacket.
|
* @param[in] pkt A pointer to an AVPacket.
|
||||||
* @return 0 in case of success, a negative error otherwise.
|
* @return 0 in case of success, a negative error otherwise.
|
||||||
*/
|
*/
|
||||||
@ -47533,10 +47543,22 @@ index 22a9532444..3484a25a9c 100644
|
|||||||
/**
|
/**
|
||||||
* Enqueues a buffer to a V4L2Context from an AVFrame
|
* Enqueues a buffer to a V4L2Context from an AVFrame
|
||||||
diff --git a/libavcodec/v4l2_m2m.c b/libavcodec/v4l2_m2m.c
|
diff --git a/libavcodec/v4l2_m2m.c b/libavcodec/v4l2_m2m.c
|
||||||
index e48b3a8ccf..cac2b3e2f2 100644
|
index e48b3a8ccf..b994e39ad6 100644
|
||||||
--- a/libavcodec/v4l2_m2m.c
|
--- a/libavcodec/v4l2_m2m.c
|
||||||
+++ b/libavcodec/v4l2_m2m.c
|
+++ b/libavcodec/v4l2_m2m.c
|
||||||
@@ -338,18 +338,30 @@ int ff_v4l2_m2m_codec_end(V4L2m2mPriv *priv)
|
@@ -328,7 +328,10 @@ static void v4l2_m2m_destroy_context(void *opaque, uint8_t *context)
|
||||||
|
ff_v4l2_context_release(&s->capture);
|
||||||
|
sem_destroy(&s->refsync);
|
||||||
|
|
||||||
|
- close(s->fd);
|
||||||
|
+ if (s->fd != -1)
|
||||||
|
+ close(s->fd);
|
||||||
|
+
|
||||||
|
+ av_log(s->avctx, AV_LOG_DEBUG, "V4L2 Context destroyed\n");
|
||||||
|
|
||||||
|
av_free(s);
|
||||||
|
}
|
||||||
|
@@ -338,17 +341,34 @@ int ff_v4l2_m2m_codec_end(V4L2m2mPriv *priv)
|
||||||
V4L2m2mContext *s = priv->context;
|
V4L2m2mContext *s = priv->context;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
@ -47549,6 +47571,8 @@ index e48b3a8ccf..cac2b3e2f2 100644
|
|||||||
- ret = ff_v4l2_context_set_status(&s->capture, VIDIOC_STREAMOFF);
|
- ret = ff_v4l2_context_set_status(&s->capture, VIDIOC_STREAMOFF);
|
||||||
- if (ret)
|
- if (ret)
|
||||||
- av_log(s->avctx, AV_LOG_ERROR, "VIDIOC_STREAMOFF %s\n", s->capture.name);
|
- av_log(s->avctx, AV_LOG_ERROR, "VIDIOC_STREAMOFF %s\n", s->capture.name);
|
||||||
|
+ av_log(s->avctx, AV_LOG_DEBUG, "V4L2 Codec end\n");
|
||||||
|
+
|
||||||
+ if (av_codec_is_decoder(s->avctx->codec))
|
+ if (av_codec_is_decoder(s->avctx->codec))
|
||||||
+ av_packet_unref(&s->buf_pkt);
|
+ av_packet_unref(&s->buf_pkt);
|
||||||
+
|
+
|
||||||
@ -47564,15 +47588,17 @@ index e48b3a8ccf..cac2b3e2f2 100644
|
|||||||
|
|
||||||
ff_v4l2_context_release(&s->output);
|
ff_v4l2_context_release(&s->output);
|
||||||
|
|
||||||
|
+ close(s->fd);
|
||||||
|
+ s->fd = -1;
|
||||||
|
+
|
||||||
s->self_ref = NULL;
|
s->self_ref = NULL;
|
||||||
+ // This is only called on avctx close so after this point we don't have that
|
+ // This is only called on avctx close so after this point we don't have that
|
||||||
+ // Crash sooner if we find we are using it (can still log with avctx = NULL)
|
+ // Crash sooner if we find we are using it (can still log with avctx = NULL)
|
||||||
+ s->avctx = NULL;
|
+ s->avctx = NULL;
|
||||||
av_buffer_unref(&priv->context_ref);
|
|
||||||
+ priv->context = NULL;
|
+ priv->context = NULL;
|
||||||
|
av_buffer_unref(&priv->context_ref);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
|
||||||
diff --git a/libavcodec/v4l2_m2m.h b/libavcodec/v4l2_m2m.h
|
diff --git a/libavcodec/v4l2_m2m.h b/libavcodec/v4l2_m2m.h
|
||||||
index 456281f48c..b08a5b38ac 100644
|
index 456281f48c..b08a5b38ac 100644
|
||||||
--- a/libavcodec/v4l2_m2m.h
|
--- a/libavcodec/v4l2_m2m.h
|
||||||
@ -47638,7 +47664,7 @@ index 456281f48c..b08a5b38ac 100644
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
diff --git a/libavcodec/v4l2_m2m_dec.c b/libavcodec/v4l2_m2m_dec.c
|
diff --git a/libavcodec/v4l2_m2m_dec.c b/libavcodec/v4l2_m2m_dec.c
|
||||||
index 3e17e0fcac..678d390103 100644
|
index 3e17e0fcac..e774532e36 100644
|
||||||
--- a/libavcodec/v4l2_m2m_dec.c
|
--- a/libavcodec/v4l2_m2m_dec.c
|
||||||
+++ b/libavcodec/v4l2_m2m_dec.c
|
+++ b/libavcodec/v4l2_m2m_dec.c
|
||||||
@@ -23,6 +23,10 @@
|
@@ -23,6 +23,10 @@
|
||||||
@ -47729,18 +47755,13 @@ index 3e17e0fcac..678d390103 100644
|
|||||||
|
|
||||||
/* 3. set the crop parameters */
|
/* 3. set the crop parameters */
|
||||||
selection.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
|
selection.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
|
||||||
@@ -133,54 +168,286 @@ static int v4l2_prepare_decoder(V4L2m2mContext *s)
|
@@ -133,54 +168,293 @@ static int v4l2_prepare_decoder(V4L2m2mContext *s)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
-static int v4l2_receive_frame(AVCodecContext *avctx, AVFrame *frame)
|
-static int v4l2_receive_frame(AVCodecContext *avctx, AVFrame *frame)
|
||||||
+static inline int64_t track_to_pts(AVCodecContext *avctx, unsigned int n)
|
+static inline int64_t track_to_pts(AVCodecContext *avctx, unsigned int n)
|
||||||
{
|
+{
|
||||||
- V4L2m2mContext *s = ((V4L2m2mPriv*)avctx->priv_data)->context;
|
|
||||||
- V4L2Context *const capture = &s->capture;
|
|
||||||
- V4L2Context *const output = &s->output;
|
|
||||||
- AVPacket avpkt = {0};
|
|
||||||
- int ret;
|
|
||||||
+ return (int64_t)n;
|
+ return (int64_t)n;
|
||||||
+}
|
+}
|
||||||
+
|
+
|
||||||
@ -47835,13 +47856,7 @@ index 3e17e0fcac..678d390103 100644
|
|||||||
+#define NQ_SRC_EMPTY 2
|
+#define NQ_SRC_EMPTY 2
|
||||||
+#define NQ_DRAINING 3
|
+#define NQ_DRAINING 3
|
||||||
+#define NQ_DEAD 4
|
+#define NQ_DEAD 4
|
||||||
|
+
|
||||||
- if (s->buf_pkt.size) {
|
|
||||||
- avpkt = s->buf_pkt;
|
|
||||||
- memset(&s->buf_pkt, 0, sizeof(AVPacket));
|
|
||||||
- } else {
|
|
||||||
- ret = ff_decode_get_packet(avctx, &avpkt);
|
|
||||||
- if (ret < 0 && ret != AVERROR_EOF)
|
|
||||||
+#define TRY_DQ(nq_status) ((nq_status) >= NQ_OK && (nq_status) <= NQ_DRAINING)
|
+#define TRY_DQ(nq_status) ((nq_status) >= NQ_OK && (nq_status) <= NQ_DRAINING)
|
||||||
+
|
+
|
||||||
+// AVERROR_EOF Flushing an already flushed stream
|
+// AVERROR_EOF Flushing an already flushed stream
|
||||||
@ -47853,10 +47868,22 @@ index 3e17e0fcac..678d390103 100644
|
|||||||
+// NQ_DEAD Not running (do not retry, do not attempt capture dQ)
|
+// NQ_DEAD Not running (do not retry, do not attempt capture dQ)
|
||||||
+
|
+
|
||||||
+static int try_enqueue_src(AVCodecContext * const avctx, V4L2m2mContext * const s)
|
+static int try_enqueue_src(AVCodecContext * const avctx, V4L2m2mContext * const s)
|
||||||
+{
|
{
|
||||||
+ int ret = 0;
|
- V4L2m2mContext *s = ((V4L2m2mPriv*)avctx->priv_data)->context;
|
||||||
+ int ret2 = 0;
|
- V4L2Context *const capture = &s->capture;
|
||||||
+
|
- V4L2Context *const output = &s->output;
|
||||||
|
- AVPacket avpkt = {0};
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
- if (s->buf_pkt.size) {
|
||||||
|
- avpkt = s->buf_pkt;
|
||||||
|
- memset(&s->buf_pkt, 0, sizeof(AVPacket));
|
||||||
|
- } else {
|
||||||
|
- ret = ff_decode_get_packet(avctx, &avpkt);
|
||||||
|
- if (ret < 0 && ret != AVERROR_EOF)
|
||||||
|
+ // If we don't already have a coded packet - get a new one
|
||||||
|
+ // We will already have a coded pkt if the output Q was full last time we
|
||||||
|
+ // tried to Q it
|
||||||
+ if (!s->buf_pkt.size) {
|
+ if (!s->buf_pkt.size) {
|
||||||
+ ret = ff_decode_get_packet(avctx, &s->buf_pkt);
|
+ ret = ff_decode_get_packet(avctx, &s->buf_pkt);
|
||||||
+
|
+
|
||||||
@ -47931,14 +47958,20 @@ index 3e17e0fcac..678d390103 100644
|
|||||||
+ return ret;
|
+ return ret;
|
||||||
+ }
|
+ }
|
||||||
+ }
|
+ }
|
||||||
+
|
|
||||||
|
- /* cant recover */
|
||||||
|
- if (ret == AVERROR(ENOMEM))
|
||||||
|
- return ret;
|
||||||
+ // Start if we haven't
|
+ // Start if we haven't
|
||||||
+ ret2 = v4l2_try_start(avctx);
|
+ {
|
||||||
+ if (ret2) {
|
+ const int ret2 = v4l2_try_start(avctx);
|
||||||
+ av_log(avctx, AV_LOG_DEBUG, "Start failure: err=%d\n", ret2);
|
+ if (ret2) {
|
||||||
+ ret = (ret2 == AVERROR(ENOMEM)) ? ret2 : NQ_DEAD;
|
+ av_log(avctx, AV_LOG_DEBUG, "Start failure: err=%d\n", ret2);
|
||||||
|
+ ret = (ret2 == AVERROR(ENOMEM)) ? ret2 : NQ_DEAD;
|
||||||
|
+ }
|
||||||
+ }
|
+ }
|
||||||
+
|
|
||||||
|
- return 0;
|
||||||
+ return ret;
|
+ return ret;
|
||||||
+}
|
+}
|
||||||
+
|
+
|
||||||
@ -47962,17 +47995,15 @@ index 3e17e0fcac..678d390103 100644
|
|||||||
+ av_log(avctx, AV_LOG_WARNING, "Poll says src Q has space but enqueue fail");
|
+ av_log(avctx, AV_LOG_WARNING, "Poll says src Q has space but enqueue fail");
|
||||||
+ src_rv = NQ_SRC_EMPTY; // If we can't enqueue pretend that there is nothing to enqueue
|
+ src_rv = NQ_SRC_EMPTY; // If we can't enqueue pretend that there is nothing to enqueue
|
||||||
+ }
|
+ }
|
||||||
|
+
|
||||||
- /* cant recover */
|
|
||||||
- if (ret == AVERROR(ENOMEM))
|
|
||||||
- return ret;
|
|
||||||
+ // Try to get a new frame if
|
+ // Try to get a new frame if
|
||||||
+ // (a) we haven't already got one AND
|
+ // (a) we haven't already got one AND
|
||||||
+ // (b) enqueue returned a status indicating that decode should be attempted
|
+ // (b) enqueue returned a status indicating that decode should be attempted
|
||||||
+ if (dst_rv != 0 && TRY_DQ(src_rv)) {
|
+ if (dst_rv != 0 && TRY_DQ(src_rv)) {
|
||||||
+ do {
|
+ do {
|
||||||
+ // Dequeue frame will unref any previous contents of frame
|
+ // Dequeue frame will unref any previous contents of frame
|
||||||
+ // so we don't need an explicit unref when discarding
|
+ // if it returns success so we don't need an explicit unref
|
||||||
|
+ // when discarding
|
||||||
+ // This returns AVERROR(EAGAIN) if there isn't a frame ready yet
|
+ // This returns AVERROR(EAGAIN) if there isn't a frame ready yet
|
||||||
+ // but there is room in the input Q
|
+ // but there is room in the input Q
|
||||||
+ dst_rv = ff_v4l2_context_dequeue_frame(&s->capture, frame, -1, 1);
|
+ dst_rv = ff_v4l2_context_dequeue_frame(&s->capture, frame, -1, 1);
|
||||||
@ -47987,13 +48018,14 @@ index 3e17e0fcac..678d390103 100644
|
|||||||
+ // Go again if we got a frame that we need to discard
|
+ // Go again if we got a frame that we need to discard
|
||||||
+ } while (dst_rv == 0 && xlat_pts_out(avctx, s, frame));
|
+ } while (dst_rv == 0 && xlat_pts_out(avctx, s, frame));
|
||||||
+ }
|
+ }
|
||||||
|
+
|
||||||
- return 0;
|
|
||||||
+ // Continue trying to enqueue packets if either
|
+ // Continue trying to enqueue packets if either
|
||||||
+ // (a) we succeeded last time OR
|
+ // (a) we succeeded last time OR
|
||||||
+ // (b) enqueue failed due to input Q full AND there is now room
|
+ // (b) enqueue failed due to input Q full AND there is now room
|
||||||
+ } while (src_rv == NQ_OK || (src_rv == NQ_Q_FULL && dst_rv == AVERROR(EAGAIN)) );
|
+ } while (src_rv == NQ_OK || (src_rv == NQ_Q_FULL && dst_rv == AVERROR(EAGAIN)) );
|
||||||
+
|
+
|
||||||
|
+ // Ensure that the frame contains nothing if we aren't returning a frame
|
||||||
|
+ // (might happen when discarding)
|
||||||
+ if (dst_rv)
|
+ if (dst_rv)
|
||||||
+ av_frame_unref(frame);
|
+ av_frame_unref(frame);
|
||||||
+
|
+
|
||||||
@ -48047,7 +48079,7 @@ index 3e17e0fcac..678d390103 100644
|
|||||||
static av_cold int v4l2_decode_init(AVCodecContext *avctx)
|
static av_cold int v4l2_decode_init(AVCodecContext *avctx)
|
||||||
{
|
{
|
||||||
V4L2Context *capture, *output;
|
V4L2Context *capture, *output;
|
||||||
@@ -188,6 +455,9 @@ static av_cold int v4l2_decode_init(AVCodecContext *avctx)
|
@@ -188,6 +462,9 @@ static av_cold int v4l2_decode_init(AVCodecContext *avctx)
|
||||||
V4L2m2mPriv *priv = avctx->priv_data;
|
V4L2m2mPriv *priv = avctx->priv_data;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
@ -48057,7 +48089,7 @@ index 3e17e0fcac..678d390103 100644
|
|||||||
ret = ff_v4l2_m2m_create_context(priv, &s);
|
ret = ff_v4l2_m2m_create_context(priv, &s);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return ret;
|
return ret;
|
||||||
@@ -208,13 +478,32 @@ static av_cold int v4l2_decode_init(AVCodecContext *avctx)
|
@@ -208,13 +485,32 @@ static av_cold int v4l2_decode_init(AVCodecContext *avctx)
|
||||||
capture->av_codec_id = AV_CODEC_ID_RAWVIDEO;
|
capture->av_codec_id = AV_CODEC_ID_RAWVIDEO;
|
||||||
capture->av_pix_fmt = avctx->pix_fmt;
|
capture->av_pix_fmt = avctx->pix_fmt;
|
||||||
|
|
||||||
@ -48093,7 +48125,7 @@ index 3e17e0fcac..678d390103 100644
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -223,10 +512,59 @@ static av_cold int v4l2_decode_init(AVCodecContext *avctx)
|
@@ -223,10 +519,59 @@ static av_cold int v4l2_decode_init(AVCodecContext *avctx)
|
||||||
|
|
||||||
static av_cold int v4l2_decode_close(AVCodecContext *avctx)
|
static av_cold int v4l2_decode_close(AVCodecContext *avctx)
|
||||||
{
|
{
|
||||||
@ -48156,7 +48188,7 @@ index 3e17e0fcac..678d390103 100644
|
|||||||
}
|
}
|
||||||
|
|
||||||
#define OFFSET(x) offsetof(V4L2m2mPriv, x)
|
#define OFFSET(x) offsetof(V4L2m2mPriv, x)
|
||||||
@@ -235,10 +573,16 @@ static av_cold int v4l2_decode_close(AVCodecContext *avctx)
|
@@ -235,10 +580,16 @@ static av_cold int v4l2_decode_close(AVCodecContext *avctx)
|
||||||
static const AVOption options[] = {
|
static const AVOption options[] = {
|
||||||
V4L_M2M_DEFAULT_OPTS,
|
V4L_M2M_DEFAULT_OPTS,
|
||||||
{ "num_capture_buffers", "Number of buffers in the capture context",
|
{ "num_capture_buffers", "Number of buffers in the capture context",
|
||||||
@ -48174,7 +48206,7 @@ index 3e17e0fcac..678d390103 100644
|
|||||||
#define M2MDEC_CLASS(NAME) \
|
#define M2MDEC_CLASS(NAME) \
|
||||||
static const AVClass v4l2_m2m_ ## NAME ## _dec_class = { \
|
static const AVClass v4l2_m2m_ ## NAME ## _dec_class = { \
|
||||||
.class_name = #NAME "_v4l2m2m_decoder", \
|
.class_name = #NAME "_v4l2m2m_decoder", \
|
||||||
@@ -259,9 +603,14 @@ static const AVOption options[] = {
|
@@ -259,9 +610,14 @@ static const AVOption options[] = {
|
||||||
.init = v4l2_decode_init, \
|
.init = v4l2_decode_init, \
|
||||||
.receive_frame = v4l2_receive_frame, \
|
.receive_frame = v4l2_receive_frame, \
|
||||||
.close = v4l2_decode_close, \
|
.close = v4l2_decode_close, \
|
||||||
|
Loading…
x
Reference in New Issue
Block a user