0
0
mirror of https://github.com/libretro/Lakka-LibreELEC.git synced 2025-01-09 13:45:21 +00:00
Lakka-LibreELEC/packages/multimedia/ffmpeg/patches/L4T/0014-codecs-nvv4l2-support-all-different-timestamps.patch
GavinDarkglider 600e246a94 L4T/Ayn: upstream changes from 5.x
Lakka 5.x Switch changes (#1853)
Lakka v5.x switchroot 5.1.2 (#1871)
Fix Switch Issue's in upstream 5.x (#1888)
Minor Switch Changes (#1893)
Lakka v5.x switch 3 (#1895)
Lakka v5.x switch 4 (#1898)
L4T: Xorg-server: Fix build issue (#1924)
Switch: remove ra patch
Lakka v5.x switch 6 (#1926)
Cleanups, More LibreELEC Stuff, more permission fixes, Misc switch stuff. (#1930)
Switch: U-Boot: bump version to 2024-NX02 (#1946)

L4T/Ayn post-upstreaming fixes
- retroarch_joypad_autoconfig: remove spaces from file names
- retroarch: remove Switch specific patch merged upstream
- libXv: move to L4T packages folder (package removed in upstream)
- bring some packages from v5.x to L4T packages
- ffmpeg: remove vulkan
- remove stella core from Switch build (missing C++ headers)
- Ayn/Odin: use proper kernel arg to not hide kernel messages in console
- connman: add wpa_supplicant support back
2024-05-21 15:41:36 +02:00

118 lines
5.1 KiB
Diff

From 95ed6f305a76c588f8264406e69123e3775e6c36 Mon Sep 17 00:00:00 2001
From: CTCaer <ctcaer@gmail.com>
Date: Fri, 18 Mar 2022 21:57:58 +0000
Subject: [PATCH 14/39] codecs: nvv4l2: support all different timestamps
Various packets and players have different timestamps defined.
For example old mpeg videos do not have PTS and many streaming apps or other players do not have or remove PTS.
In such cases if user pts (reordered_opaque) is not set, set AV_NOPTS_VALUE instead of 0.
In cases where user PTS is provided, use a flag so we know in capture plane that this is the case. Then set pts to AV_NOPTS_VALUE and reordered opaque properly.
That works quite well with NVV4L2 because it reorders the frames automatically.
And so we just need to set the proper timestamp on queued buffer, along with a flag to identify it's not PTS but user based PTS.
---
libavcodec/nvv4l2_dec.c | 51 +++++++++++++++++++++++++++++++++++++----
1 file changed, 46 insertions(+), 5 deletions(-)
diff --git a/libavcodec/nvv4l2_dec.c b/libavcodec/nvv4l2_dec.c
index 05ae7997fc..bd4650ac7a 100644
--- a/libavcodec/nvv4l2_dec.c
+++ b/libavcodec/nvv4l2_dec.c
@@ -523,9 +523,27 @@ static void *dec_capture_thread(void *arg)
/* Set timestamp based on origin pts flags */
if (buf_index >= 0) {
- ctx->frame_pts[buf_index] =
+ if (v4l2_cp_buf.timestamp.tv_usec == 0 &&
+ v4l2_cp_buf.timestamp.tv_sec == NV_V4L2_NOPTS_VALUE) {
+ /* Origin packet had no pts and user pts values. */
+ ctx->frame_pts[buf_index] = AV_NOPTS_VALUE;
+ ctx->frame_user_pts[buf_index] = AV_NOPTS_VALUE;
+ } else if (v4l2_cp_buf.timestamp.tv_sec &
+ NV_V4L2_REORDERED_OPAQUE_FLAG) {
+ /* Origin packet had only user pts value. */
+ v4l2_cp_buf.timestamp.tv_sec &=
+ (~NV_V4L2_REORDERED_OPAQUE_FLAG);
+ ctx->frame_pts[buf_index] = AV_NOPTS_VALUE;
+ ctx->frame_user_pts[buf_index] =
v4l2_cp_buf.timestamp.tv_usec +
(v4l2_cp_buf.timestamp.tv_sec * AV_TIME_BASE);
+ } else {
+ /* Origin packet had pts value. */
+ ctx->frame_pts[buf_index] =
+ v4l2_cp_buf.timestamp.tv_usec +
+ (v4l2_cp_buf.timestamp.tv_sec * AV_TIME_BASE);
+ ctx->frame_user_pts[buf_index] = AV_NOPTS_VALUE;
+ }
}
nvv4l2_pool_push(ctx, ctx->export_pool);
@@ -604,6 +622,7 @@ nvv4l2_decoder_get_frame(AVCodecContext *avctx, nvv4l2_ctx_t *ctx,
frame->width = ctx->codec_width;
frame->height = ctx->codec_height;
frame->pts = ctx->frame_pts[_buf_index];
+ frame->user_pts = ctx->frame_user_pts[_buf_index];
*buf_index = _buf_index;
@@ -648,10 +667,22 @@ nvv4l2_decoder_put_packet(AVCodecContext *avctx, nvv4l2_ctx_t *ctx,
v4l2_buf_op.m.planes[0].bytesused = buffer->planes[0].bytesused;
- /* Set timestamp */
+ /* Set timestamp based on packet flags. */
v4l2_buf_op.flags |= V4L2_BUF_FLAG_TIMESTAMP_COPY;
- v4l2_buf_op.timestamp.tv_sec = packet->pts / AV_TIME_BASE;
- v4l2_buf_op.timestamp.tv_usec = packet->pts % AV_TIME_BASE;
+ if (packet->pts != AV_NOPTS_VALUE) {
+ /* Packet pts is valid */
+ v4l2_buf_op.timestamp.tv_sec = packet->pts / AV_TIME_BASE;
+ v4l2_buf_op.timestamp.tv_usec = packet->pts % AV_TIME_BASE;
+ } else if (packet->user_pts != AV_NOPTS_VALUE) {
+ /* User pts is valid */
+ v4l2_buf_op.timestamp.tv_sec = packet->user_pts / AV_TIME_BASE;
+ v4l2_buf_op.timestamp.tv_usec = packet->user_pts % AV_TIME_BASE;
+ v4l2_buf_op.timestamp.tv_sec |= NV_V4L2_REORDERED_OPAQUE_FLAG;
+ } else {
+ /* No valid pts or user pts */
+ v4l2_buf_op.timestamp.tv_sec = NV_V4L2_NOPTS_VALUE;
+ v4l2_buf_op.timestamp.tv_usec = 0;
+ }
/* Queue packet on output plane. */
ret = nvv4l2_q_buffer(ctx, &v4l2_buf_op, buffer,
@@ -1066,6 +1097,7 @@ nvv4l2dec_decode(AVCodecContext *avctx, void *data, int *got_frame,
packet.payload_size = avpkt->size;
packet.payload = avpkt->data;
packet.pts = avpkt->pts;
+ packet.user_pts = avctx->reordered_opaque;
if (!nvv4l2_decoder_put_packet(avctx, ctx, &packet)) {
processed_size = avpkt->size;
@@ -1106,9 +1138,18 @@ nvv4l2dec_decode(AVCodecContext *avctx, void *data, int *got_frame,
avframe->height = _nvframe.height;
avframe->format = avctx->pix_fmt;
- avframe->pts = _nvframe.pts;
avframe->pkt_dts = AV_NOPTS_VALUE;
+ /* Decide which timestamps to set. */
+ if (_nvframe.pts != AV_NOPTS_VALUE) {
+ avframe->pts = _nvframe.pts;
+ } else {
+ avframe->pts = _nvframe.pts;
+ avframe->reordered_opaque = _nvframe.user_pts;
+ }
+
+ avframe->key_frame = 0;
+
avctx->coded_width = _nvframe.width;
avctx->coded_height = _nvframe.height;
avctx->width = _nvframe.width;
--
2.25.1