diff mbox series

[FFmpeg-devel,04/13] fftools/ffmpeg: make sure FrameData is writable when we modify it

Message ID 20231123191524.11296-6-anton@khirnov.net
State New
Headers show
Series [FFmpeg-devel,01/13] lavfi/buffersink: avoid leaking peeked_frame on uninit | expand

Checks

Context Check Description
yinshiyou/make_loongarch64 success Make finished
yinshiyou/make_fate_loongarch64 success Make fate finished
andriy/make_x86 success Make finished
andriy/make_fate_x86 success Make fate finished

Commit Message

Anton Khirnov Nov. 23, 2023, 7:14 p.m. UTC
Also, add a function that returns const FrameData* for cases that only
read from it.
---
 fftools/ffmpeg.c        | 21 +++++++++++++++++----
 fftools/ffmpeg.h        |  2 ++
 fftools/ffmpeg_filter.c |  4 ++--
 3 files changed, 21 insertions(+), 6 deletions(-)
diff mbox series

Patch

diff --git a/fftools/ffmpeg.c b/fftools/ffmpeg.c
index cdb16ef90b..61fcda2526 100644
--- a/fftools/ffmpeg.c
+++ b/fftools/ffmpeg.c
@@ -427,21 +427,34 @@  InputStream *ist_iter(InputStream *prev)
     return NULL;
 }
 
-FrameData *frame_data(AVFrame *frame)
+static int frame_data_ensure(AVFrame *frame, int writable)
 {
     if (!frame->opaque_ref) {
         FrameData *fd;
 
         frame->opaque_ref = av_buffer_allocz(sizeof(*fd));
         if (!frame->opaque_ref)
-            return NULL;
+            return AVERROR(ENOMEM);
         fd = (FrameData*)frame->opaque_ref->data;
 
         fd->dec.frame_num = UINT64_MAX;
         fd->dec.pts       = AV_NOPTS_VALUE;
-    }
+    } else if (writable)
+        return av_buffer_make_writable(&frame->opaque_ref);
 
-    return (FrameData*)frame->opaque_ref->data;
+    return 0;
+}
+
+FrameData *frame_data(AVFrame *frame)
+{
+    int ret = frame_data_ensure(frame, 1);
+    return ret < 0 ? NULL : (FrameData*)frame->opaque_ref->data;
+}
+
+const FrameData *frame_data_c(AVFrame *frame)
+{
+    int ret = frame_data_ensure(frame, 0);
+    return ret < 0 ? NULL : (const FrameData*)frame->opaque_ref->data;
 }
 
 void remove_avoptions(AVDictionary **a, AVDictionary *b)
diff --git a/fftools/ffmpeg.h b/fftools/ffmpeg.h
index 41935d39d5..1f11a2f002 100644
--- a/fftools/ffmpeg.h
+++ b/fftools/ffmpeg.h
@@ -726,6 +726,8 @@  int subtitle_wrap_frame(AVFrame *frame, AVSubtitle *subtitle, int copy);
  */
 FrameData *frame_data(AVFrame *frame);
 
+const FrameData *frame_data_c(AVFrame *frame);
+
 int ifilter_send_frame(InputFilter *ifilter, AVFrame *frame, int keep_reference);
 int ifilter_send_eof(InputFilter *ifilter, int64_t pts, AVRational tb);
 int ifilter_sub2video(InputFilter *ifilter, const AVFrame *frame);
diff --git a/fftools/ffmpeg_filter.c b/fftools/ffmpeg_filter.c
index f942c97c40..69c28a6b2b 100644
--- a/fftools/ffmpeg_filter.c
+++ b/fftools/ffmpeg_filter.c
@@ -1859,9 +1859,9 @@  static int choose_out_timebase(OutputFilterPriv *ofp, AVFrame *frame)
     FPSConvContext   *fps = &ofp->fps;
     AVRational        tb = (AVRational){ 0, 0 };
     AVRational fr;
-    FrameData *fd;
+    const FrameData *fd;
 
-    fd = frame_data(frame);
+    fd = frame_data_c(frame);
 
     // apply -enc_time_base
     if (ofp->enc_timebase.num == ENC_TIME_BASE_DEMUX &&