mirror of
https://github.com/libretro/Lakka-LibreELEC.git
synced 2024-11-28 01:34:40 +00:00
66e50e96b9
* L4T: Fix/Enable NVV4l2 decoder in libreelec builds. * L4T: LibreELEC: Allow Kodi to run as root * L4T: Small Tree Cleanup * Bluez: Switch: LibreELEC: Fix fast connect on all switch builds, not just lakka. * L4T: Finish ffmpeg 6.0 patchset * L4T: Fix building newer libcec for switch * L4T: switch-bsp: Update dock hotplug to check distro stuff, before integrating CEC and bump version.
277 lines
11 KiB
Diff
277 lines
11 KiB
Diff
From 124b4a1c85f24a11de5710b8515648dae91000cf Mon Sep 17 00:00:00 2001
|
|
From: CTCaer <ctcaer@gmail.com>
|
|
Date: Fri, 18 Mar 2022 21:46:36 +0000
|
|
Subject: [PATCH 11/39] codecs: nvv4l2: various bugfixes
|
|
|
|
---
|
|
libavcodec/nvv4l2_dec.c | 105 ++++++++++++++++++++++------------------
|
|
1 file changed, 59 insertions(+), 46 deletions(-)
|
|
|
|
diff --git a/libavcodec/nvv4l2_dec.c b/libavcodec/nvv4l2_dec.c
|
|
index 640b6836de..0779f3a4bf 100644
|
|
--- a/libavcodec/nvv4l2_dec.c
|
|
+++ b/libavcodec/nvv4l2_dec.c
|
|
@@ -20,6 +20,7 @@
|
|
* DEALINGS IN THE SOFTWARE.
|
|
*/
|
|
|
|
+#include <stdatomic.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <stdint.h>
|
|
@@ -52,6 +53,15 @@
|
|
** NM12 (YUV 4:2:0)
|
|
*/
|
|
|
|
+/*
|
|
+ ** Output plane memory type support:
|
|
+ ** V4L2_MEMORY_MMAP
|
|
+ ** V4L2_MEMORY_USERPTR
|
|
+ ** Capture plane memory type support:
|
|
+ ** V4L2_MEMORY_MMAP
|
|
+ ** V4L2_MEMORY_DMABUF
|
|
+ */
|
|
+
|
|
#define DECODER_DEV "/dev/nvhost-nvdec"
|
|
#define OP_PLANE_REQ_SIZEIMAGE 4000000
|
|
|
|
@@ -138,6 +148,9 @@ static void query_set_capture(AVCodecContext *avctx, nvv4l2_ctx_t *ctx)
|
|
NvBufferCreateParams input_params = { 0 };
|
|
NvBufferCreateParams cap_params = { 0 };
|
|
|
|
+ if (ctx->in_error || ctx->eos)
|
|
+ return;
|
|
+
|
|
/* Get format on capture plane set by device.
|
|
** This may change after an resolution change event.
|
|
*/
|
|
@@ -235,13 +248,14 @@ static void query_set_capture(AVCodecContext *avctx, nvv4l2_ctx_t *ctx)
|
|
|
|
/* Destroy previous DMA buffers. */
|
|
for (uint32_t i = 0; i < ctx->cp_num_buffers; i++) {
|
|
- if (ctx->dmabuff_fd[i] != 0) {
|
|
+ if (ctx->dmabuff_fd[i] != -1) {
|
|
ret = NvBufferDestroy(ctx->dmabuff_fd[i]);
|
|
if (ret) {
|
|
av_log(avctx, AV_LOG_ERROR,
|
|
"Failed to Destroy NvBuffer!\n");
|
|
ctx->in_error = true;
|
|
}
|
|
+ ctx->dmabuff_fd[i] = -1;
|
|
}
|
|
}
|
|
|
|
@@ -339,8 +353,9 @@ static void query_set_capture(AVCodecContext *avctx, nvv4l2_ctx_t *ctx)
|
|
v4l2_buf.m.planes[0].m.fd = ctx->dmabuff_fd[i];
|
|
v4l2_buf.m.planes[1].m.fd = ctx->dmabuff_fd[i];
|
|
|
|
- ret = nvv4l2_q_buffer(ctx, &v4l2_buf, NULL, ctx->cp_buf_type,
|
|
- ctx->cp_mem_type, ctx->cp_num_planes);
|
|
+ ret = nvv4l2_q_buffer(ctx, &v4l2_buf, ctx->cp_buffers[i],
|
|
+ ctx->cp_buf_type, ctx->cp_mem_type,
|
|
+ ctx->cp_num_planes);
|
|
|
|
if (ret) {
|
|
av_log(avctx, AV_LOG_ERROR, "Qing failed on capture plane!\n");
|
|
@@ -407,9 +422,7 @@ static void *dec_capture_thread(void *arg)
|
|
/* Received first resolution change event
|
|
** Format and buffers are now set on capture.
|
|
*/
|
|
- if (!ctx->in_error) {
|
|
- query_set_capture(ctx->avctx, ctx);
|
|
- }
|
|
+ query_set_capture(ctx->avctx, ctx);
|
|
|
|
/* Check for resolution event to again
|
|
** set format and buffers on capture plane.
|
|
@@ -429,16 +442,15 @@ static void *dec_capture_thread(void *arg)
|
|
struct v4l2_buffer v4l2_cp_buf;
|
|
struct v4l2_plane capture_planes[NV_MAX_PLANES];
|
|
NvBufferRect src_rect, dest_rect;
|
|
- NvBufferParams parm;
|
|
+ NvBufferParams buf_params;
|
|
NvBufferTransformParams transform_params;
|
|
- NvBuffer *cp_buffer = NULL;
|
|
|
|
memset(&v4l2_cp_buf, 0, sizeof(v4l2_cp_buf));
|
|
memset(capture_planes, 0, sizeof(capture_planes));
|
|
v4l2_cp_buf.m.planes = capture_planes;
|
|
|
|
/* Dequeue the filled buffer. */
|
|
- if (nvv4l2_dq_buffer(ctx, &v4l2_cp_buf, &cp_buffer,
|
|
+ if (nvv4l2_dq_buffer(ctx, &v4l2_cp_buf, NULL,
|
|
ctx->cp_buf_type, ctx->cp_mem_type, 0)) {
|
|
if (errno == EAGAIN) {
|
|
usleep(1000);
|
|
@@ -463,7 +475,7 @@ static void *dec_capture_thread(void *arg)
|
|
|
|
/* @transform_flag defines the flags for enabling the
|
|
** valid transforms. All the valid parameters are
|
|
- ** present in the nvbuf_utils header.
|
|
+ ** present in the nvv4l2_ext_utils header.
|
|
*/
|
|
transform_params.transform_flag = NVBUFFER_TRANSFORM_FILTER;
|
|
transform_params.transform_flip = NvBufferTransform_None;
|
|
@@ -472,9 +484,6 @@ static void *dec_capture_thread(void *arg)
|
|
transform_params.src_rect = src_rect;
|
|
transform_params.dst_rect = dest_rect;
|
|
|
|
- /* Set DMA plane handle. */
|
|
- cp_buffer->planes[0].fd = ctx->dmabuff_fd[v4l2_cp_buf.index];
|
|
-
|
|
pthread_mutex_lock(&ctx->queue_lock);
|
|
|
|
buf_index = nvv4l2_pool_idx_next(ctx, ctx->export_pool);
|
|
@@ -482,34 +491,37 @@ static void *dec_capture_thread(void *arg)
|
|
/* Blocklinear to Pitch transformation is required
|
|
** to dump the raw decoded buffer data.
|
|
*/
|
|
- ret = NvBufferTransform(cp_buffer->planes[0].fd,
|
|
- ctx->plane_dma_fd[buf_index], &transform_params);
|
|
- if (ret == -1) {
|
|
- ctx->in_error = true;
|
|
- av_log(ctx->avctx, AV_LOG_ERROR, "Transform failed!\n");
|
|
- pthread_mutex_unlock(&ctx->queue_lock);
|
|
- break;
|
|
- }
|
|
+ if (buf_index >= 0) {
|
|
+ ret = NvBufferTransform(ctx->dmabuff_fd[v4l2_cp_buf.index],
|
|
+ ctx->plane_dma_fd[buf_index],
|
|
+ &transform_params);
|
|
+ if (ret == -1) {
|
|
+ ctx->in_error = true;
|
|
+ av_log(ctx->avctx, AV_LOG_ERROR, "Transform failed!\n");
|
|
+ pthread_mutex_unlock(&ctx->queue_lock);
|
|
+ break;
|
|
+ }
|
|
|
|
- ret = NvBufferGetParams(ctx->plane_dma_fd[buf_index], &parm);
|
|
- if (ret) {
|
|
- ctx->in_error = true;
|
|
- av_log(ctx->avctx, AV_LOG_ERROR, "GetParams failed!\n");
|
|
- pthread_mutex_unlock(&ctx->queue_lock);
|
|
- goto error;
|
|
+ ret = NvBufferGetParams(ctx->plane_dma_fd[buf_index],
|
|
+ &buf_params);
|
|
+ if (ret) {
|
|
+ ctx->in_error = true;
|
|
+ av_log(ctx->avctx, AV_LOG_ERROR, "GetParams failed!\n");
|
|
+ pthread_mutex_unlock(&ctx->queue_lock);
|
|
+ break;
|
|
+ }
|
|
}
|
|
|
|
- ctx->plane_width[0] = parm.width[0];
|
|
- ctx->plane_height[0] = parm.height[0];
|
|
- ctx->plane_width[1] = parm.width[1];
|
|
- ctx->plane_height[1] = parm.height[1];
|
|
+ ctx->plane_width[0] = buf_params.width[0];
|
|
+ ctx->plane_height[0] = buf_params.height[0];
|
|
+ ctx->plane_width[1] = buf_params.width[1];
|
|
+ ctx->plane_height[1] = buf_params.height[1];
|
|
if (ctx->cp_pixfmt == V4L2_PIX_FMT_YUV420M) {
|
|
- ctx->plane_width[2] = parm.width[2];
|
|
- ctx->plane_height[2] = parm.height[2];
|
|
- } else if (ctx->cp_pixfmt == V4L2_PIX_FMT_NV12M) {
|
|
- ctx->plane_width[1] *= 2;
|
|
+ ctx->plane_width[2] = buf_params.width[2];
|
|
+ ctx->plane_height[2] = buf_params.height[2];
|
|
}
|
|
|
|
+ /* Set timestamp based on origin pts flags */
|
|
if (buf_index >= 0) {
|
|
ctx->frame_pts[buf_index] =
|
|
v4l2_cp_buf.timestamp.tv_usec +
|
|
@@ -547,7 +559,6 @@ static void *dec_capture_thread(void *arg)
|
|
}
|
|
}
|
|
|
|
-error:
|
|
if (ctx->low_latency) {
|
|
pthread_mutex_lock(&ctx->frame_lock);
|
|
pthread_cond_broadcast(&ctx->frame_cond);
|
|
@@ -559,7 +570,6 @@ error:
|
|
return NULL;
|
|
}
|
|
|
|
-
|
|
int
|
|
nvv4l2_decoder_get_frame(AVCodecContext *avctx, nvv4l2_ctx_t *ctx,
|
|
int *buf_index, NvFrame *frame)
|
|
@@ -572,8 +582,8 @@ nvv4l2_decoder_get_frame(AVCodecContext *avctx, nvv4l2_ctx_t *ctx,
|
|
/* In low latency mode, block until a decoded frame is ready. */
|
|
if (ctx->low_latency) {
|
|
pthread_mutex_lock(&ctx->frame_lock);
|
|
- while (ctx->export_pool->capacity == 0 && !ctx->eos &&
|
|
- !ctx->in_error && ret != ETIMEDOUT) {
|
|
+ while (atomic_load(&ctx->export_pool->capacity) == 0 &&
|
|
+ !ctx->eos && !ctx->in_error && ret != ETIMEDOUT) {
|
|
/* 500ms timeout */
|
|
gettimeofday(&now, NULL);
|
|
timeout.tv_nsec = (now.tv_usec + 500000L) * 1000L;
|
|
@@ -703,8 +713,10 @@ nvv4l2_ctx_t *nvv4l2_create_decoder(AVCodecContext *avctx,
|
|
ctx->op_buf_type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
|
|
ctx->cp_buf_type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
|
|
|
|
- for (uint32_t i = 0; i < NV_MAX_BUFFERS; i++)
|
|
+ for (uint32_t i = 0; i < NV_MAX_BUFFERS; i++) {
|
|
+ ctx->dmabuff_fd[i] = -1;
|
|
ctx->plane_dma_fd[i] = -1;
|
|
+ }
|
|
|
|
/* Allocate packet pool. */
|
|
ctx->export_pool = (NvQueues *)NVCALLOC(1, sizeof(NvQueues));
|
|
@@ -821,13 +833,13 @@ int nvv4l2_decoder_close(AVCodecContext *avctx, nvv4l2_ctx_t *ctx)
|
|
|
|
/* All allocated DMA buffers must be destroyed. */
|
|
for (uint32_t i = 0; i < ctx->cp_num_buffers; i++) {
|
|
- if (ctx->dmabuff_fd[i] != 0) {
|
|
+ if (ctx->dmabuff_fd[i] != -1) {
|
|
ret = NvBufferDestroy(ctx->dmabuff_fd[i]);
|
|
- ctx->dmabuff_fd[i] = 0;
|
|
if (ret < 0) {
|
|
av_log(avctx, AV_LOG_ERROR,
|
|
"Failed to destroy dma buffer!\n");
|
|
}
|
|
+ ctx->dmabuff_fd[i] = -1;
|
|
}
|
|
}
|
|
|
|
@@ -835,11 +847,11 @@ int nvv4l2_decoder_close(AVCodecContext *avctx, nvv4l2_ctx_t *ctx)
|
|
for (uint32_t i = 0; i < NV_MAX_BUFFERS; i++) {
|
|
if (ctx->plane_dma_fd[i] != -1) {
|
|
ret = NvBufferDestroy(ctx->plane_dma_fd[i]);
|
|
- ctx->plane_dma_fd[i] = -1;
|
|
if (ret < 0) {
|
|
av_log(avctx, AV_LOG_ERROR,
|
|
"Failed to destroy plane buffer!\n");
|
|
}
|
|
+ ctx->plane_dma_fd[i] = -1;
|
|
}
|
|
}
|
|
|
|
@@ -862,7 +874,7 @@ int nvv4l2_decoder_close(AVCodecContext *avctx, nvv4l2_ctx_t *ctx)
|
|
if (ctx->in_error) {
|
|
av_log(avctx, AV_LOG_VERBOSE, "Decoder Run failed\n");
|
|
} else {
|
|
- av_log(avctx, AV_LOG_VERBOSE, "Decoder Run is successful\n");
|
|
+ av_log(avctx, AV_LOG_VERBOSE, "Decoder Run was successful\n");
|
|
}
|
|
|
|
NVFREE(ctx);
|
|
@@ -985,8 +997,9 @@ static void nvv4l2dec_flush(AVCodecContext *avctx)
|
|
v4l2_buf.m.planes[1].m.fd = ctx->dmabuff_fd[i];
|
|
|
|
pthread_mutex_unlock(&ctx->queue_lock);
|
|
- ret = nvv4l2_q_buffer(ctx, &v4l2_buf, NULL, ctx->cp_buf_type,
|
|
- ctx->cp_mem_type, ctx->cp_num_planes);
|
|
+ ret = nvv4l2_q_buffer(ctx, &v4l2_buf, ctx->cp_buffers[i],
|
|
+ ctx->cp_buf_type, ctx->cp_mem_type,
|
|
+ ctx->cp_num_planes);
|
|
pthread_mutex_lock(&ctx->queue_lock);
|
|
|
|
if (ret) {
|
|
--
|
|
2.25.1
|
|
|