8 Jul 2021, 21:20 by andreas.rheinha...@outlook.com:

> Lynne:
>
>> Apr 26, 2021, 03:27 by andreas.rheinha...@outlook.com:
>>
>>> Lynne:
>>>
>>>> From 097aed2ac33dda0bb2052d8b0402711ce95079ba Mon Sep 17 00:00:00 2001
>>>> From: Lynne <d...@lynne.ee>
>>>> Date: Sat, 23 Jan 2021 19:56:18 +0100
>>>> Subject: [PATCH] avpacket: ABI bump additions
>>>>
>>>> ---
>>>>  libavcodec/avpacket.c |  5 +++++
>>>>  libavcodec/packet.h   | 21 +++++++++++++++++++++
>>>>  2 files changed, 26 insertions(+)
>>>>
>>>> diff --git a/libavcodec/avpacket.c b/libavcodec/avpacket.c
>>>> index e32c467586..03b73b3b53 100644
>>>> --- a/libavcodec/avpacket.c
>>>> +++ b/libavcodec/avpacket.c
>>>> @@ -382,6 +382,10 @@ int av_packet_copy_props(AVPacket *dst, const 
>>>> AVPacket *src)
>>>>  dst->flags                = src->flags;
>>>>  dst->stream_index         = src->stream_index;
>>>>  
>>>> +    i = av_buffer_replace(&dst->opaque_ref, src->opaque_ref);
>>>> +    if (i < 0)
>>>> +        return i;
>>>>
>>>
>>> 1. Don't use i here; add a new variable.
>>> 2. Up until now, av_packet_ref() and av_packet_copy_props() treat the
>>> destination packet as uninitialized and make no attempt at unreferencing
>>> its content; yet you try to reuse opaque_ref. Even worse, you might
>>> return potentially dangerous packets: If the properties were
>>> uninitialized and av_packet_copy_props() failed, then the caller were
>>> not allowed to unreference the packet even when the non-properties were
>>> set to sane values. The easiest way to fix this is to move setting
>>> opaque ref to the place after initializing side_data below and either
>>> set dst->opaque_ref to NULL before av_buffer_replace() or to not use
>>> av_buffer_replace(). It may also be best to unref it again if copying
>>> side data fails.
>>>
>>>> +
>>>>  dst->side_data            = NULL;
>>>>  dst->side_data_elems      = 0;
>>>>  for (i = 0; i < src->side_data_elems; i++) {
>>>> @@ -403,6 +407,7 @@ int av_packet_copy_props(AVPacket *dst, const AVPacket 
>>>> *src)
>>>>  void av_packet_unref(AVPacket *pkt)
>>>>  {
>>>>  av_packet_free_side_data(pkt);
>>>> +    av_buffer_unref(&pkt->opaque_ref);
>>>>  av_buffer_unref(&pkt->buf);
>>>>  get_packet_defaults(pkt);
>>>>  }
>>>> diff --git a/libavcodec/packet.h b/libavcodec/packet.h
>>>> index fad8341c12..c29ad18a2b 100644
>>>> --- a/libavcodec/packet.h
>>>> +++ b/libavcodec/packet.h
>>>> @@ -383,6 +383,27 @@ typedef struct AVPacket {
>>>>  int64_t duration;
>>>>  
>>>>  int64_t pos;                            ///< byte position in stream, -1 
>>>> if unknown
>>>> +
>>>> +    /**
>>>> +     * for some private data of the user
>>>> +     */
>>>> +    void *opaque;
>>>>
>>>
>>> The corresponding AVFrame field is copied when copying props.
>>>
>>
>> Fixed both, thanks. Also copied the time_base field and made av_init_packet()
>> initialize all fields.
>>
>
> Your new version is still not correct: If copying side data fails, the
> function returns without initializing opaque_ref at all, thereby making
> it dangerous to unref the packet (which e.g. av_packet_ref() does).
>
> - Andreas
>

Fixed, and made sure to unref it if copying side data fails.
>From 2b252692ead788faf81b104ebda041ff18a06191 Mon Sep 17 00:00:00 2001
From: Lynne <d...@lynne.ee>
Date: Sat, 23 Jan 2021 19:56:18 +0100
Subject: [PATCH v2] avpacket: ABI bump additions

---
 libavcodec/avpacket.c | 17 +++++++++++++++--
 libavcodec/packet.h   | 21 +++++++++++++++++++++
 2 files changed, 36 insertions(+), 2 deletions(-)

diff --git a/libavcodec/avpacket.c b/libavcodec/avpacket.c
index 800bee3489..075b219475 100644
--- a/libavcodec/avpacket.c
+++ b/libavcodec/avpacket.c
@@ -26,6 +26,7 @@
 #include "libavutil/internal.h"
 #include "libavutil/mathematics.h"
 #include "libavutil/mem.h"
+#include "libavutil/rational.h"
 
 #include "bytestream.h"
 #include "internal.h"
@@ -44,6 +45,9 @@ void av_init_packet(AVPacket *pkt)
     pkt->buf                  = NULL;
     pkt->side_data            = NULL;
     pkt->side_data_elems      = 0;
+    pkt->opaque               = NULL;
+    pkt->opaque_ref           = NULL;
+    pkt->time_base            = av_make_q(0, 0);
 }
 #endif
 
@@ -374,7 +378,7 @@ int av_packet_shrink_side_data(AVPacket *pkt, enum AVPacketSideDataType type,
 
 int av_packet_copy_props(AVPacket *dst, const AVPacket *src)
 {
-    int i;
+    int i, ret;
 
     dst->pts                  = src->pts;
     dst->dts                  = src->dts;
@@ -382,9 +386,16 @@ int av_packet_copy_props(AVPacket *dst, const AVPacket *src)
     dst->duration             = src->duration;
     dst->flags                = src->flags;
     dst->stream_index         = src->stream_index;
-
+    dst->opaque               = src->opaque;
+    dst->time_base            = src->time_base;
+    dst->opaque_ref           = NULL;
     dst->side_data            = NULL;
     dst->side_data_elems      = 0;
+
+    ret = av_buffer_replace(&dst->opaque_ref, src->opaque_ref);
+    if (ret < 0)
+        return ret;
+
     for (i = 0; i < src->side_data_elems; i++) {
         enum AVPacketSideDataType type = src->side_data[i].type;
         size_t size = src->side_data[i].size;
@@ -392,6 +403,7 @@ int av_packet_copy_props(AVPacket *dst, const AVPacket *src)
         uint8_t *dst_data = av_packet_new_side_data(dst, type, size);
 
         if (!dst_data) {
+            av_buffer_unref(&dst->opaque_ref);
             av_packet_free_side_data(dst);
             return AVERROR(ENOMEM);
         }
@@ -404,6 +416,7 @@ int av_packet_copy_props(AVPacket *dst, const AVPacket *src)
 void av_packet_unref(AVPacket *pkt)
 {
     av_packet_free_side_data(pkt);
+    av_buffer_unref(&pkt->opaque_ref);
     av_buffer_unref(&pkt->buf);
     get_packet_defaults(pkt);
 }
diff --git a/libavcodec/packet.h b/libavcodec/packet.h
index a9d3a9b596..9baff24635 100644
--- a/libavcodec/packet.h
+++ b/libavcodec/packet.h
@@ -391,6 +391,27 @@ typedef struct AVPacket {
     int64_t duration;
 
     int64_t pos;                            ///< byte position in stream, -1 if unknown
+
+    /**
+     * for some private data of the user
+     */
+    void *opaque;
+
+    /**
+     * AVBufferRef for free use by the API user. FFmpeg will never check the
+     * contents of the buffer ref. FFmpeg calls av_buffer_unref() on it when
+     * the packet is unreferenced. av_packet_copy_props() calls create a new
+     * reference with av_buffer_ref() for the target packet's opaque_ref field.
+     *
+     * This is unrelated to the opaque field, although it serves a similar
+     * purpose.
+     */
+    AVBufferRef *opaque_ref;
+
+    /**
+     * Time base of the packet's timestamps.
+     */
+    AVRational time_base;
 } AVPacket;
 
 #if FF_API_INIT_PACKET
-- 
2.32.0.272.g935e593368

_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

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

Reply via email to