[FFmpeg-cvslog] avcodec/error_resilience: Make applying decode_error_flags optional

2023-09-15 Thread Andreas Rheinhardt
ffmpeg | branch: master | Andreas Rheinhardt  | 
Tue Sep 12 15:47:42 2023 +0200| [d2bc039501cdfe2067365ca1bf4be7201f071c05] | 
committer: Andreas Rheinhardt

avcodec/error_resilience: Make applying decode_error_flags optional

Add a pointer parameter that if supplied will be used to return
the updated decode_error_flags. This will allow to fix several
races when using frame-threading; these resulted from AVFrame
that the earlier code updated concurrently being used as source
in an av_frame_ref() call in the decoder's update_thread_context.

Signed-off-by: Andreas Rheinhardt 

> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=d2bc039501cdfe2067365ca1bf4be7201f071c05
---

 libavcodec/error_resilience.c |  7 +--
 libavcodec/error_resilience.h | 12 +++-
 libavcodec/h263dec.c  |  2 +-
 libavcodec/h264dec.c  |  2 +-
 libavcodec/mpeg12dec.c|  2 +-
 libavcodec/mss2.c |  2 +-
 libavcodec/rv10.c |  4 ++--
 libavcodec/rv34.c |  6 +++---
 libavcodec/vc1dec.c   |  2 +-
 9 files changed, 26 insertions(+), 13 deletions(-)

diff --git a/libavcodec/error_resilience.c b/libavcodec/error_resilience.c
index 68e20925e0..880aea6f30 100644
--- a/libavcodec/error_resilience.c
+++ b/libavcodec/error_resilience.c
@@ -889,7 +889,7 @@ void ff_er_add_slice(ERContext *s, int startx, int starty,
 }
 }
 
-void ff_er_frame_end(ERContext *s)
+void ff_er_frame_end(ERContext *s, int *decode_error_flags)
 {
 int *linesize = NULL;
 int i, mb_x, mb_y, error, error_type, dc_error, mv_error, ac_error;
@@ -1114,7 +1114,10 @@ void ff_er_frame_end(ERContext *s)
 av_log(s->avctx, AV_LOG_INFO, "concealing %d DC, %d AC, %d MV errors in %c 
frame\n",
dc_error, ac_error, mv_error, 
av_get_picture_type_char(s->cur_pic.f->pict_type));
 
-s->cur_pic.f->decode_error_flags |= FF_DECODE_ERROR_CONCEALMENT_ACTIVE;
+if (decode_error_flags)
+*decode_error_flags |= FF_DECODE_ERROR_CONCEALMENT_ACTIVE;
+else
+s->cur_pic.f->decode_error_flags |= FF_DECODE_ERROR_CONCEALMENT_ACTIVE;
 
 is_intra_likely = is_intra_more_likely(s);
 
diff --git a/libavcodec/error_resilience.h b/libavcodec/error_resilience.h
index 47cc8a4fc6..b03f8ec896 100644
--- a/libavcodec/error_resilience.h
+++ b/libavcodec/error_resilience.h
@@ -90,7 +90,17 @@ typedef struct ERContext {
 } ERContext;
 
 void ff_er_frame_start(ERContext *s);
-void ff_er_frame_end(ERContext *s);
+
+/**
+ * Indicate that a frame has finished decoding and perform error concealment
+ * in case it has been enabled and is necessary and supported.
+ *
+ * @param s  ERContext in use
+ * @param decode_error_flags pointer where updated decode_error_flags are 
written
+ *   if supplied; if not, the new flags are directly
+ *   applied to the AVFrame whose errors are concealed
+ */
+void ff_er_frame_end(ERContext *s, int *decode_error_flags);
 void ff_er_add_slice(ERContext *s, int startx, int starty, int endx, int endy,
  int status);
 
diff --git a/libavcodec/h263dec.c b/libavcodec/h263dec.c
index 52e51dd489..9f63f1a7cb 100644
--- a/libavcodec/h263dec.c
+++ b/libavcodec/h263dec.c
@@ -622,7 +622,7 @@ retry:
 av_assert1(s->bitstream_buffer_size == 0);
 frame_end:
 if (!s->studio_profile)
-ff_er_frame_end(&s->er);
+ff_er_frame_end(&s->er, NULL);
 
 if (avctx->hwaccel) {
 ret = FF_HW_SIMPLE_CALL(avctx, end_frame);
diff --git a/libavcodec/h264dec.c b/libavcodec/h264dec.c
index f13b1081fc..8e90678125 100644
--- a/libavcodec/h264dec.c
+++ b/libavcodec/h264dec.c
@@ -779,7 +779,7 @@ end:
 if (sl->ref_count[1])
 ff_h264_set_erpic(&h->er.next_pic, sl->ref_list[1][0].parent);
 
-ff_er_frame_end(&h->er);
+ff_er_frame_end(&h->er, NULL);
 if (use_last_pic)
 memset(&sl->ref_list[0][0], 0, sizeof(sl->ref_list[0][0]));
 }
diff --git a/libavcodec/mpeg12dec.c b/libavcodec/mpeg12dec.c
index 677360f954..92ef6944fa 100644
--- a/libavcodec/mpeg12dec.c
+++ b/libavcodec/mpeg12dec.c
@@ -2033,7 +2033,7 @@ static int slice_end(AVCodecContext *avctx, AVFrame *pict)
 if (/* s->mb_y << field_pic == s->mb_height && */ !s->first_field && 
!s1->first_slice) {
 /* end of image */
 
-ff_er_frame_end(&s->er);
+ff_er_frame_end(&s->er, NULL);
 
 ff_mpv_frame_end(s);
 
diff --git a/libavcodec/mss2.c b/libavcodec/mss2.c
index 70aa56cb84..2237cc8bb1 100644
--- a/libavcodec/mss2.c
+++ b/libavcodec/mss2.c
@@ -422,7 +422,7 @@ static int decode_wmv9(AVCodecContext *avctx, const uint8_t 
*buf, int buf_size,
 ff_vc1_decode_blocks(v);
 
 if (v->end_mb_x == s->mb_width && s->end_mb_y == s->mb_height) {
-ff_er_frame_end(&s->er);
+ff_er_frame_end(&s->er, NULL);
 } else {
 av_log(v->s.avctx, AV_LOG_WARNING,
"disabling error correction due to block count mismatch %dx%d 
!= 

[FFmpeg-cvslog] avcodec/h264dec: Fix data race when updating decode_error_flags

2023-09-15 Thread Andreas Rheinhardt
ffmpeg | branch: master | Andreas Rheinhardt  | 
Tue Sep 12 19:23:26 2023 +0200| [fa77cb258b29f636255ebf20c0a70b0dfc5e8a43] | 
committer: Andreas Rheinhardt

avcodec/h264dec: Fix data race when updating decode_error_flags

When using multi-threaded decoding, every decoding thread
has its own DBP consisting of H264Pictures and each of these
points to its own AVFrames. They are synced during
update_thread_context via av_frame_ref() and therefore
the threads actually decoding (as well as all the others)
must not modify any field that is copied by av_frame_ref()
after ff_thread_finish_setup().

Yet this is exactly what happens when an error occurs
during decoding and the AVFrame's decode_error_flags are updated.
Given that these errors only become apparent during decoding,
this can't be set before ff_thread_finish_setup() without
defeating the point of frame-threading; in practice,
this meant that the decoder did not set these flags correctly
in case frame-threading was in use. (This means that e.g.
the ffmpeg cli tool fails to output its "corrupt decoded frame"
message in a nondeterministic fashion.)

This commit fixes this by adding a new H264Picture field
that is actually propagated across threads; the field
is an AVBufferRef* whose data is an atomic_int; it is
atomic in order to allow multiple threads to update it
concurrently and not to provide synchronization
between the threads setting the field and the thread
ultimately returning the AVFrame.

This unfortunately has the overhead of one allocation
per H264Picture (both the original one as well as
creating a reference to an existing one), even in case
of no errors. In order to mitigate this, an AVBufferPool
has been used and only if frame-threading is actually
in use. This expense will be removed as soon as
a proper API for refcounted objects (not based upon
AVBuffer) is in place.

Signed-off-by: Andreas Rheinhardt 

> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=fa77cb258b29f636255ebf20c0a70b0dfc5e8a43
---

 libavcodec/h264_picture.c |  9 +
 libavcodec/h264_slice.c   |  7 +++
 libavcodec/h264dec.c  | 38 --
 libavcodec/h264dec.h  |  4 
 4 files changed, 56 insertions(+), 2 deletions(-)

diff --git a/libavcodec/h264_picture.c b/libavcodec/h264_picture.c
index bd31f700cb..31b5e231c2 100644
--- a/libavcodec/h264_picture.c
+++ b/libavcodec/h264_picture.c
@@ -54,6 +54,7 @@ void ff_h264_unref_picture(H264Context *h, H264Picture *pic)
 av_buffer_unref(&pic->motion_val_buf[i]);
 av_buffer_unref(&pic->ref_index_buf[i]);
 }
+av_buffer_unref(&pic->decode_error_flags);
 
 memset((uint8_t*)pic + off, 0, sizeof(*pic) - off);
 }
@@ -136,6 +137,10 @@ int ff_h264_ref_picture(H264Context *h, H264Picture *dst, 
H264Picture *src)
 dst->hwaccel_picture_private = dst->hwaccel_priv_buf->data;
 }
 
+ret = av_buffer_replace(&dst->decode_error_flags, src->decode_error_flags);
+if (ret < 0)
+goto fail;
+
 h264_copy_picture_params(dst, src);
 
 return 0;
@@ -186,6 +191,10 @@ int ff_h264_replace_picture(H264Context *h, H264Picture 
*dst, const H264Picture
 
 dst->hwaccel_picture_private = src->hwaccel_picture_private;
 
+ret = av_buffer_replace(&dst->decode_error_flags, src->decode_error_flags);
+if (ret < 0)
+goto fail;
+
 h264_copy_picture_params(dst, src);
 
 return 0;
diff --git a/libavcodec/h264_slice.c b/libavcodec/h264_slice.c
index f3af345c99..5657327f0c 100644
--- a/libavcodec/h264_slice.c
+++ b/libavcodec/h264_slice.c
@@ -210,6 +210,13 @@ static int alloc_picture(H264Context *h, H264Picture *pic)
 if (ret < 0)
 goto fail;
 
+if (h->decode_error_flags_pool) {
+pic->decode_error_flags = 
av_buffer_pool_get(h->decode_error_flags_pool);
+if (!pic->decode_error_flags)
+goto fail;
+atomic_init((atomic_int*)pic->decode_error_flags->data, 0);
+}
+
 if (CONFIG_GRAY && !h->avctx->hwaccel && h->flags & AV_CODEC_FLAG_GRAY && 
pic->f->data[2]) {
 int h_chroma_shift, v_chroma_shift;
 av_pix_fmt_get_chroma_sub_sample(pic->f->format,
diff --git a/libavcodec/h264dec.c b/libavcodec/h264dec.c
index 8e90678125..796f80be8d 100644
--- a/libavcodec/h264dec.c
+++ b/libavcodec/h264dec.c
@@ -307,6 +307,12 @@ static int h264_init_context(AVCodecContext *avctx, 
H264Context *h)
 
 ff_h264_sei_uninit(&h->sei);
 
+if (avctx->active_thread_type & FF_THREAD_FRAME) {
+h->decode_error_flags_pool = av_buffer_pool_init(sizeof(atomic_int), 
NULL);
+if (!h->decode_error_flags_pool)
+return AVERROR(ENOMEM);
+}
+
 h->nb_slice_ctx = (avctx->active_thread_type & FF_THREAD_SLICE) ? 
avctx->thread_count : 1;
 h->slice_ctx = av_calloc(h->nb_slice_ctx, sizeof(*h->slice_ctx));
 if (!h->slice_ctx) {
@@ -353,6 +359,8 @@ static av_cold int h264_decode_end(AVCodecContext *avctx)
 
 h->cur_pic_ptr = NULL;
 
+av_buffer_pool_unini

[FFmpeg-cvslog] avcodec/x86/mpegvideoenc_template: Disable dead code

2023-09-15 Thread Andreas Rheinhardt
ffmpeg | branch: master | Andreas Rheinhardt  | 
Mon Sep 11 23:36:08 2023 +0200| [27562bf0226b22b0dbc631f8177e17ef98028499] | 
committer: Andreas Rheinhardt

avcodec/x86/mpegvideoenc_template: Disable dead code

Since bfb28b5ce89f3e950214b67ea95b45e3355c2caf the permutation
type FF_IDCT_PERM_SIMPLE is ARCH_X86_32-only. So use this
knowledge to disable code for it when not on ARCH_X86_32.

Signed-off-by: Andreas Rheinhardt 

> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=27562bf0226b22b0dbc631f8177e17ef98028499
---

 libavcodec/x86/idctdsp_init.c  | 2 ++
 libavcodec/x86/mpegvideoenc_template.c | 3 ++-
 2 files changed, 4 insertions(+), 1 deletion(-)

diff --git a/libavcodec/x86/idctdsp_init.c b/libavcodec/x86/idctdsp_init.c
index f28a1ad744..2d165b975b 100644
--- a/libavcodec/x86/idctdsp_init.c
+++ b/libavcodec/x86/idctdsp_init.c
@@ -45,10 +45,12 @@ av_cold int ff_init_scantable_permutation_x86(uint8_t 
*idct_permutation,
 int i;
 
 switch (perm_type) {
+#if ARCH_X86_32
 case FF_IDCT_PERM_SIMPLE:
 for (i = 0; i < 64; i++)
 idct_permutation[i] = simple_mmx_permutation[i];
 return 1;
+#endif
 case FF_IDCT_PERM_SSE2:
 for (i = 0; i < 64; i++)
 idct_permutation[i] = (i & 0x38) | idct_sse2_row_perm[i & 7];
diff --git a/libavcodec/x86/mpegvideoenc_template.c 
b/libavcodec/x86/mpegvideoenc_template.c
index b5b0a5ffa2..5f013be7f5 100644
--- a/libavcodec/x86/mpegvideoenc_template.c
+++ b/libavcodec/x86/mpegvideoenc_template.c
@@ -225,7 +225,8 @@ static int RENAME(dct_quantize)(MpegEncContext *s,
 if(s->mb_intra) block[0]= level;
 elseblock[0]= temp_block[0];
 
-if (s->idsp.perm_type == FF_IDCT_PERM_SIMPLE) {
+av_assert2(ARCH_X86_32 || s->idsp.perm_type != FF_IDCT_PERM_SIMPLE);
+if (ARCH_X86_32 && s->idsp.perm_type == FF_IDCT_PERM_SIMPLE) {
 if(last_non_zero_p1 <= 1) goto end;
 block[0x08] = temp_block[0x01]; block[0x10] = temp_block[0x08];
 block[0x20] = temp_block[0x10];

___
ffmpeg-cvslog mailing list
ffmpeg-cvslog@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-cvslog

To unsubscribe, visit link above, or email
ffmpeg-cvslog-requ...@ffmpeg.org with subject "unsubscribe".


[FFmpeg-cvslog] lavc/videotoolboxenc: Get the encoder supported properties

2023-09-15 Thread Jun Zhao
ffmpeg | branch: master | Jun Zhao  | Mon Sep  4 10:48:01 
2023 +0800| [5c635b7d8c7c4a7fe0c93b5b3cefff3c72bff237] | committer: Jun Zhao

lavc/videotoolboxenc: Get the encoder supported properties

Get the encoder supported properties list, it will be used for
feature support checks.

Signed-off-by: Jun Zhao 

> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=5c635b7d8c7c4a7fe0c93b5b3cefff3c72bff237
---

 libavcodec/videotoolboxenc.c | 72 ++--
 1 file changed, 49 insertions(+), 23 deletions(-)

diff --git a/libavcodec/videotoolboxenc.c b/libavcodec/videotoolboxenc.c
index 2e96990741..1d1595329a 100644
--- a/libavcodec/videotoolboxenc.c
+++ b/libavcodec/videotoolboxenc.c
@@ -232,6 +232,7 @@ typedef struct VTEncContext {
 AVClass *class;
 enum AVCodecID codec_id;
 VTCompressionSessionRef session;
+CFDictionaryRef supported_props;
 CFStringRef ycbcr_matrix;
 CFStringRef color_primaries;
 CFStringRef transfer_function;
@@ -321,6 +322,34 @@ static void clear_frame_queue(VTEncContext *vtctx)
 set_async_error(vtctx, 0);
 }
 
+static void vtenc_reset(VTEncContext *vtctx)
+{
+if (vtctx->session) {
+CFRelease(vtctx->session);
+vtctx->session = NULL;
+}
+
+if (vtctx->supported_props) {
+CFRelease(vtctx->supported_props);
+vtctx->supported_props = NULL;
+}
+
+if (vtctx->color_primaries) {
+CFRelease(vtctx->color_primaries);
+vtctx->color_primaries = NULL;
+}
+
+if (vtctx->transfer_function) {
+CFRelease(vtctx->transfer_function);
+vtctx->transfer_function = NULL;
+}
+
+if (vtctx->ycbcr_matrix) {
+CFRelease(vtctx->ycbcr_matrix);
+vtctx->ycbcr_matrix = NULL;
+}
+}
+
 static int vtenc_q_pop(VTEncContext *vtctx, bool wait, CMSampleBufferRef *buf, 
ExtraSEI **sei)
 {
 BufNode *info;
@@ -1110,6 +1139,22 @@ static int vtenc_create_encoder(AVCodecContext   *avctx,
 return AVERROR_EXTERNAL;
 }
 
+#if defined (MAC_OS_X_VERSION_10_13) && (MAC_OS_X_VERSION_MAX_ALLOWED >= 
MAC_OS_X_VERSION_10_13)
+if (__builtin_available(macOS 10.13, *)) {
+status = VTCopySupportedPropertyDictionaryForEncoder(avctx->width,
+ avctx->height,
+ codec_type,
+ enc_info,
+ NULL,
+ 
&vtctx->supported_props);
+
+if (status != noErr) {
+av_log(avctx, AV_LOG_ERROR,"Error retrieving the supported 
property dictionary err=%"PRId64"\n", (int64_t)status);
+return AVERROR_EXTERNAL;
+}
+}
+#endif
+
 // Dump the init encoder
 {
 CFStringRef encoderID = NULL;
@@ -1662,7 +1707,6 @@ static av_cold int vtenc_init(AVCodecContext *avctx)
 // It can happen when user set avctx->profile directly.
 if (vtctx->profile == AV_PROFILE_UNKNOWN)
 vtctx->profile = avctx->profile;
-vtctx->session = NULL;
 status = vtenc_configure_encoder(avctx);
 if (status) return status;
 
@@ -2431,8 +2475,8 @@ static int create_cv_pixel_buffer(AVCodecContext   *avctx,
 
 vtstatus = VTCompressionSessionPrepareToEncodeFrames(vtctx->session);
 if (vtstatus == kVTInvalidSessionErr) {
-CFRelease(vtctx->session);
-vtctx->session = NULL;
+vtenc_reset(vtctx);
+
 status = vtenc_configure_encoder(avctx);
 if (status == 0)
 pix_buf_pool = 
VTCompressionSessionGetPixelBufferPool(vtctx->session);
@@ -2688,10 +2732,7 @@ static int vtenc_populate_extradata(AVCodecContext   
*avctx,
 
 pe_cleanup:
 CVPixelBufferRelease(pix_buf);
-if(vtctx->session)
-CFRelease(vtctx->session);
-
-vtctx->session = NULL;
+vtenc_reset(vtctx);
 vtctx->frame_ct_out = 0;
 
 av_assert0(status != 0 || (avctx->extradata && avctx->extradata_size > 0));
@@ -2714,23 +2755,8 @@ static av_cold int vtenc_close(AVCodecContext *avctx)
 clear_frame_queue(vtctx);
 pthread_cond_destroy(&vtctx->cv_sample_sent);
 pthread_mutex_destroy(&vtctx->lock);
-CFRelease(vtctx->session);
-vtctx->session = NULL;
-
-if (vtctx->color_primaries) {
-CFRelease(vtctx->color_primaries);
-vtctx->color_primaries = NULL;
-}
 
-if (vtctx->transfer_function) {
-CFRelease(vtctx->transfer_function);
-vtctx->transfer_function = NULL;
-}
-
-if (vtctx->ycbcr_matrix) {
-CFRelease(vtctx->ycbcr_matrix);
-vtctx->ycbcr_matrix = NULL;
-}
+vtenc_reset(vtctx);
 
 return 0;
 }

___
ffmpeg-cvslog mailing list
ffmpeg-cvslog@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-cvslog

To unsubscribe, visit link above, or 

[FFmpeg-cvslog] lavc/videotoolboxenc: Dump the encoder

2023-09-15 Thread Jun Zhao
ffmpeg | branch: master | Jun Zhao  | Sun Sep  3 23:06:21 
2023 +0800| [213cba9696c1525d5022d8c3597bddb6fab15379] | committer: Jun Zhao

lavc/videotoolboxenc: Dump the encoder

Dump the encoder, it's will help debug some case

Signed-off-by: Jun Zhao 

> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=213cba9696c1525d5022d8c3597bddb6fab15379
---

 libavcodec/videotoolboxenc.c | 28 
 1 file changed, 28 insertions(+)

diff --git a/libavcodec/videotoolboxenc.c b/libavcodec/videotoolboxenc.c
index d0a00347b5..2e96990741 100644
--- a/libavcodec/videotoolboxenc.c
+++ b/libavcodec/videotoolboxenc.c
@@ -1110,6 +1110,34 @@ static int vtenc_create_encoder(AVCodecContext   *avctx,
 return AVERROR_EXTERNAL;
 }
 
+// Dump the init encoder
+{
+CFStringRef encoderID = NULL;
+status = VTSessionCopyProperty(vtctx->session,
+   kVTCompressionPropertyKey_EncoderID,
+   kCFAllocatorDefault,
+   &encoderID);
+if (status == noErr) {
+CFIndex length   = CFStringGetLength(encoderID);
+CFIndex max_size = CFStringGetMaximumSizeForEncoding(length, 
kCFStringEncodingUTF8);
+char *name   = av_malloc(max_size);
+if (!name) {
+CFRelease(encoderID);
+return AVERROR(ENOMEM);
+}
+
+CFStringGetCString(encoderID,
+   name,
+   max_size,
+   kCFStringEncodingUTF8);
+av_log(avctx, AV_LOG_DEBUG, "Init the encoder: %s\n", name);
+
+av_freep(&name);
+}
+if (encoderID != NULL)
+CFRelease(encoderID);
+}
+
 if (avctx->flags & AV_CODEC_FLAG_QSCALE && !vtenc_qscale_enabled()) {
 av_log(avctx, AV_LOG_ERROR, "Error: -q:v qscale not available for 
encoder. Use -b:v bitrate instead.\n");
 return AVERROR_EXTERNAL;

___
ffmpeg-cvslog mailing list
ffmpeg-cvslog@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-cvslog

To unsubscribe, visit link above, or email
ffmpeg-cvslog-requ...@ffmpeg.org with subject "unsubscribe".


[FFmpeg-cvslog] avcodec/evc_ps: Check ref_pic_num and sps_max_dec_pic_buffering_minus1

2023-09-15 Thread Michael Niedermayer
ffmpeg | branch: master | Michael Niedermayer  | Tue 
Aug  1 00:56:34 2023 +0200| [4565747056a11356210ed8edcecb920105e40b60] | 
committer: Michael Niedermayer

avcodec/evc_ps: Check ref_pic_num and sps_max_dec_pic_buffering_minus1

Fixes: out of array write

Found-by: dongsoo...@korea.ac.kr
Reviewed-by: James Almer 
Signed-off-by: Michael Niedermayer 

> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=4565747056a11356210ed8edcecb920105e40b60
---

 libavcodec/evc_ps.c | 22 +-
 1 file changed, 17 insertions(+), 5 deletions(-)

diff --git a/libavcodec/evc_ps.c b/libavcodec/evc_ps.c
index 64384a392c..28cf5378e4 100644
--- a/libavcodec/evc_ps.c
+++ b/libavcodec/evc_ps.c
@@ -24,10 +24,14 @@
 #define EXTENDED_SAR 255
 
 // @see ISO_IEC_23094-1 (7.3.7 Reference picture list structure syntax)
-static int ref_pic_list_struct(GetBitContext *gb, RefPicListStruct *rpl)
+static int ref_pic_list_struct(EVCParserSPS *sps, GetBitContext *gb, 
RefPicListStruct *rpl)
 {
 uint32_t delta_poc_st, strp_entry_sign_flag = 0;
 rpl->ref_pic_num = get_ue_golomb_long(gb);
+
+if ((unsigned)rpl->ref_pic_num  > sps->sps_max_dec_pic_buffering_minus1)
+return AVERROR_INVALIDDATA;
+
 if (rpl->ref_pic_num > 0) {
 delta_poc_st = get_ue_golomb_long(gb);
 
@@ -239,6 +243,8 @@ int ff_evc_parse_sps(GetBitContext *gb, EVCParamSets *ps)
 sps->max_num_tid0_ref_pics = get_ue_golomb_31(gb);
 else {
 sps->sps_max_dec_pic_buffering_minus1 = get_ue_golomb_long(gb);
+if ((unsigned)sps->sps_max_dec_pic_buffering_minus1 > 16 - 1)
+return AVERROR_INVALIDDATA;
 sps->long_term_ref_pic_flag = get_bits1(gb);
 sps->rpl1_same_as_rpl0_flag = get_bits1(gb);
 sps->num_ref_pic_list_in_sps[0] = get_ue_golomb(gb);
@@ -248,8 +254,11 @@ int ff_evc_parse_sps(GetBitContext *gb, EVCParamSets *ps)
 goto fail;
 }
 
-for (int i = 0; i < sps->num_ref_pic_list_in_sps[0]; ++i)
-ref_pic_list_struct(gb, &sps->rpls[0][i]);
+for (int i = 0; i < sps->num_ref_pic_list_in_sps[0]; ++i) {
+ret = ref_pic_list_struct(sps, gb, &sps->rpls[0][i]);
+if (ret < 0)
+goto fail;
+}
 
 if (!sps->rpl1_same_as_rpl0_flag) {
 sps->num_ref_pic_list_in_sps[1] = get_ue_golomb(gb);
@@ -257,8 +266,11 @@ int ff_evc_parse_sps(GetBitContext *gb, EVCParamSets *ps)
 ret = AVERROR_INVALIDDATA;
 goto fail;
 }
-for (int i = 0; i < sps->num_ref_pic_list_in_sps[1]; ++i)
-ref_pic_list_struct(gb, &sps->rpls[1][i]);
+for (int i = 0; i < sps->num_ref_pic_list_in_sps[1]; ++i) {
+ret = ref_pic_list_struct(sps, gb, &sps->rpls[1][i]);
+if (ret < 0)
+goto fail;
+}
 }
 }
 

___
ffmpeg-cvslog mailing list
ffmpeg-cvslog@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-cvslog

To unsubscribe, visit link above, or email
ffmpeg-cvslog-requ...@ffmpeg.org with subject "unsubscribe".


[FFmpeg-cvslog] vulkan_hevc: switch from a buffer pool to a malloc and simplify

2023-09-15 Thread Lynne
ffmpeg | branch: master | Lynne  | Fri Sep 15 01:51:49 2023 
+0200| [552a5fa496933c2679cac6774e483bee3f5c2c53] | committer: Lynne

vulkan_hevc: switch from a buffer pool to a malloc and simplify

Simpler and more robust now that contexts are not shared between threads.

> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=552a5fa496933c2679cac6774e483bee3f5c2c53
---

 libavcodec/vulkan_decode.c |  2 +-
 libavcodec/vulkan_decode.h |  4 ++--
 libavcodec/vulkan_hevc.c   | 52 +++---
 3 files changed, 20 insertions(+), 38 deletions(-)

diff --git a/libavcodec/vulkan_decode.c b/libavcodec/vulkan_decode.c
index 534a76edda..21bebb1677 100644
--- a/libavcodec/vulkan_decode.c
+++ b/libavcodec/vulkan_decode.c
@@ -1104,7 +1104,7 @@ int ff_vk_decode_uninit(AVCodecContext *avctx)
 /* Wait on and free execution pool */
 ff_vk_exec_pool_free(&ctx->s, &dec->exec_pool);
 
-av_buffer_pool_uninit(&dec->tmp_pool);
+av_freep(&dec->hevc_headers);
 av_buffer_unref(&dec->session_params);
 av_buffer_unref(&dec->shared_ref);
 av_freep(&dec->slice_off);
diff --git a/libavcodec/vulkan_decode.h b/libavcodec/vulkan_decode.h
index abf08a98bf..71ba3dbd84 100644
--- a/libavcodec/vulkan_decode.h
+++ b/libavcodec/vulkan_decode.h
@@ -64,8 +64,8 @@ typedef struct FFVulkanDecodeContext {
 uint32_t frame_id_alloc_mask; /* For AV1 only */
 
 /* Thread-local state below */
-AVBufferPool *tmp_pool; /* Pool for temporary data, if needed (HEVC) */
-size_t tmp_pool_ele_size;
+struct HEVCHeaderSet *hevc_headers;
+size_t hevc_headers_size;
 
 uint32_t   *slice_off;
 unsigned intslice_off_max;
diff --git a/libavcodec/vulkan_hevc.c b/libavcodec/vulkan_hevc.c
index ef371bda67..52f223ceb2 100644
--- a/libavcodec/vulkan_hevc.c
+++ b/libavcodec/vulkan_hevc.c
@@ -68,49 +68,33 @@ typedef struct HEVCHeaderSet {
 HEVCHeaderVPS *hvps;
 } HEVCHeaderSet;
 
-static int get_data_set_buf(FFVulkanDecodeContext *s, AVBufferRef **data_buf,
-int nb_vps, AVBufferRef * const 
vps_list[HEVC_MAX_VPS_COUNT])
+static int alloc_hevc_header_structs(FFVulkanDecodeContext *s,
+ int nb_vps,
+ AVBufferRef * const 
vps_list[HEVC_MAX_VPS_COUNT])
 {
 uint8_t *data_ptr;
 HEVCHeaderSet *hdr;
 
-size_t base_size = 
sizeof(StdVideoH265SequenceParameterSet)*HEVC_MAX_SPS_COUNT +
-   sizeof(HEVCHeaderSPS)*HEVC_MAX_SPS_COUNT +
-   
sizeof(StdVideoH265PictureParameterSet)*HEVC_MAX_PPS_COUNT +
-   sizeof(HEVCHeaderPPS)*HEVC_MAX_PPS_COUNT +
-   
sizeof(StdVideoH265VideoParameterSet)*HEVC_MAX_VPS_COUNT +
-   sizeof(HEVCHeaderVPS *);
-
-size_t vps_size = sizeof(StdVideoH265ProfileTierLevel) +
-  sizeof(StdVideoH265DecPicBufMgr) +
-  sizeof(StdVideoH265HrdParameters)*HEVC_MAX_LAYER_SETS +
-  sizeof(HEVCHeaderVPSSet *);
-
-size_t buf_size = base_size + vps_size*nb_vps;
-
+size_t buf_size = sizeof(HEVCHeaderSet) + nb_vps*sizeof(HEVCHeaderVPS);
 for (int i = 0; i < nb_vps; i++) {
 const HEVCVPS *vps = (const HEVCVPS *)vps_list[i]->data;
 buf_size += sizeof(HEVCHeaderVPSSet)*vps->vps_num_hrd_parameters;
 }
 
-if (buf_size > s->tmp_pool_ele_size) {
-av_buffer_pool_uninit(&s->tmp_pool);
-s->tmp_pool_ele_size = 0;
-s->tmp_pool = av_buffer_pool_init(buf_size, NULL);
-if (!s->tmp_pool)
+if (buf_size > s->hevc_headers_size) {
+av_freep(&s->hevc_headers);
+s->hevc_headers_size = 0;
+s->hevc_headers = av_mallocz(buf_size);
+if (!s->hevc_headers)
 return AVERROR(ENOMEM);
-s->tmp_pool_ele_size = buf_size;
+s->hevc_headers_size = buf_size;
 }
 
-*data_buf = av_buffer_pool_get(s->tmp_pool);
-if (!(*data_buf))
-return AVERROR(ENOMEM);
-
-/* Setup pointers */
-data_ptr = (*data_buf)->data;
-hdr = (HEVCHeaderSet *)data_ptr;
-hdr->hvps = (HEVCHeaderVPS *)(data_ptr + base_size);
-data_ptr += base_size + vps_size*nb_vps;
+/* Setup struct pointers */
+hdr = s->hevc_headers;
+data_ptr = (uint8_t *)hdr;
+hdr->hvps = (HEVCHeaderVPS *)(data_ptr + sizeof(HEVCHeaderSet));
+data_ptr += sizeof(HEVCHeaderSet) + nb_vps*sizeof(HEVCHeaderVPS);
 for (int i = 0; i < nb_vps; i++) {
 const HEVCVPS *vps = (const HEVCVPS *)vps_list[i]->data;
 hdr->hvps[i].sls = (HEVCHeaderVPSSet *)data_ptr;
@@ -672,17 +656,16 @@ static int vk_hevc_create_params(AVCodecContext *avctx, 
AVBufferRef **buf)
 };
 
 int nb_vps = 0;
-AVBufferRef *data_set;
 HEVCHeaderSet *hdr;
 
 for (int i = 0; h->ps.vps_list[i]; i++)
 nb_vps++;
 
-err = get_data_set_buf(dec, &data_set, nb_vps, h->ps.vps_list);
+err = 

[FFmpeg-cvslog] vulkan_decode: don't call get_proc_addr on every frame's destruction

2023-09-15 Thread Lynne
ffmpeg | branch: master | Lynne  | Fri Sep 15 02:22:00 2023 
+0200| [9310ffc809d02d7bbc767555c2ed16311623ffe2] | committer: Lynne

vulkan_decode: don't call get_proc_addr on every frame's destruction

The issue is that we cannot rely on any context existing when we free
frames. The Vulkan functions are loaded in each context separately,
so until now, we've just been loading them on every frame's destruction.

Rather than do this, just save the function pointers we need in each
frame. The function pointers are guaranteed to not change and exist.

> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=9310ffc809d02d7bbc767555c2ed16311623ffe2
---

 libavcodec/vulkan_decode.c | 18 +++---
 libavcodec/vulkan_decode.h |  4 
 2 files changed, 11 insertions(+), 11 deletions(-)

diff --git a/libavcodec/vulkan_decode.c b/libavcodec/vulkan_decode.c
index 21bebb1677..ef4a1c3809 100644
--- a/libavcodec/vulkan_decode.c
+++ b/libavcodec/vulkan_decode.c
@@ -176,6 +176,7 @@ int ff_vk_decode_prepare_frame(FFVulkanDecodeContext *dec, 
AVFrame *pic,
 {
 int err;
 FFVulkanDecodeShared *ctx = (FFVulkanDecodeShared *)dec->shared_ref->data;
+FFVulkanFunctions *vk = &ctx->s.vkfn;
 
 vkpic->slices_size = 0;
 
@@ -189,6 +190,9 @@ int ff_vk_decode_prepare_frame(FFVulkanDecodeContext *dec, 
AVFrame *pic,
 vkpic->img_view_out  = NULL;
 vkpic->img_view_dest = NULL;
 
+vkpic->destroy_image_view = vk->DestroyImageView;
+vkpic->wait_semaphores = vk->WaitSemaphores;
+
 if (dec->layered_dpb && alloc_dpb) {
 vkpic->img_view_ref = ctx->layered_view;
 vkpic->img_aspect_ref = ctx->layered_aspect;
@@ -554,9 +558,6 @@ int ff_vk_decode_frame(AVCodecContext *avctx,
 void ff_vk_decode_free_frame(AVHWDeviceContext *dev_ctx, FFVulkanDecodePicture 
*vp)
 {
 AVVulkanDeviceContext *hwctx = dev_ctx->hwctx;
-PFN_vkGetDeviceProcAddr device_proc_addr;
-PFN_vkWaitSemaphores wait_semaphores;
-PFN_vkDestroyImageView destroy_image_view;
 
 VkSemaphoreWaitInfo sem_wait = (VkSemaphoreWaitInfo) {
 .sType = VK_STRUCTURE_TYPE_SEMAPHORE_WAIT_INFO,
@@ -565,27 +566,22 @@ void ff_vk_decode_free_frame(AVHWDeviceContext *dev_ctx, 
FFVulkanDecodePicture *
 .semaphoreCount = 1,
 };
 
-/* Guaranteed to exist */
-device_proc_addr = 
(PFN_vkGetDeviceProcAddr)hwctx->get_proc_addr(hwctx->inst, 
"vkGetDeviceProcAddr");
-destroy_image_view = 
(PFN_vkDestroyImageView)device_proc_addr(hwctx->act_dev, "vkDestroyImageView");
-wait_semaphores = (PFN_vkWaitSemaphores)device_proc_addr(hwctx->act_dev, 
"vkWaitSemaphores");
-
 /* We do not have to lock the frame here because we're not interested
  * in the actual current semaphore value, but only that it's later than
  * the time we submitted the image for decoding. */
 if (vp->sem)
-wait_semaphores(hwctx->act_dev, &sem_wait, UINT64_MAX);
+vp->wait_semaphores(hwctx->act_dev, &sem_wait, UINT64_MAX);
 
 /* Free slices data */
 av_buffer_unref(&vp->slices_buf);
 
 /* Destroy image view (out) */
 if (vp->img_view_out && vp->img_view_out != vp->img_view_dest)
-destroy_image_view(hwctx->act_dev, vp->img_view_out, hwctx->alloc);
+vp->destroy_image_view(hwctx->act_dev, vp->img_view_out, hwctx->alloc);
 
 /* Destroy image view (ref, unlayered) */
 if (vp->img_view_dest)
-destroy_image_view(hwctx->act_dev, vp->img_view_dest, hwctx->alloc);
+vp->destroy_image_view(hwctx->act_dev, vp->img_view_dest, 
hwctx->alloc);
 
 av_frame_free(&vp->dpb_frame);
 }
diff --git a/libavcodec/vulkan_decode.h b/libavcodec/vulkan_decode.h
index 71ba3dbd84..c983b44029 100644
--- a/libavcodec/vulkan_decode.h
+++ b/libavcodec/vulkan_decode.h
@@ -97,6 +97,10 @@ typedef struct FFVulkanDecodePicture {
 /* Slice data */
 AVBufferRef*slices_buf;
 size_t  slices_size;
+
+/* Vulkan functions needed for destruction, as no other context is 
guaranteed to exist */
+PFN_vkWaitSemaphoreswait_semaphores;
+PFN_vkDestroyImageView  destroy_image_view;
 } FFVulkanDecodePicture;
 
 /**

___
ffmpeg-cvslog mailing list
ffmpeg-cvslog@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-cvslog

To unsubscribe, visit link above, or email
ffmpeg-cvslog-requ...@ffmpeg.org with subject "unsubscribe".


[FFmpeg-cvslog] avcodec/evc_ps: make the sps parameter in ref_pic_list_struct const

2023-09-15 Thread James Almer
ffmpeg | branch: master | James Almer  | Fri Sep 15 16:33:13 
2023 -0300| [156f53e9879deefd845f1beffb5c1cadb5ad0ac3] | committer: James Almer

avcodec/evc_ps: make the sps parameter in ref_pic_list_struct const

It's not changed.

Signed-off-by: James Almer 

> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=156f53e9879deefd845f1beffb5c1cadb5ad0ac3
---

 libavcodec/evc_ps.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/libavcodec/evc_ps.c b/libavcodec/evc_ps.c
index 28cf5378e4..6f93f5b373 100644
--- a/libavcodec/evc_ps.c
+++ b/libavcodec/evc_ps.c
@@ -24,7 +24,7 @@
 #define EXTENDED_SAR 255
 
 // @see ISO_IEC_23094-1 (7.3.7 Reference picture list structure syntax)
-static int ref_pic_list_struct(EVCParserSPS *sps, GetBitContext *gb, 
RefPicListStruct *rpl)
+static int ref_pic_list_struct(const EVCParserSPS *sps, GetBitContext *gb, 
RefPicListStruct *rpl)
 {
 uint32_t delta_poc_st, strp_entry_sign_flag = 0;
 rpl->ref_pic_num = get_ue_golomb_long(gb);

___
ffmpeg-cvslog mailing list
ffmpeg-cvslog@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-cvslog

To unsubscribe, visit link above, or email
ffmpeg-cvslog-requ...@ffmpeg.org with subject "unsubscribe".