[FFmpeg-devel] [PATCH] avcodec/avpacket: add av_packet_make_writable()

James Almer jamrial at gmail.com
Thu Mar 22 03:19:40 EET 2018


On 3/21/2018 2:14 PM, James Almer wrote:
> On 3/19/2018 1:49 PM, James Almer wrote:
>> On 3/19/2018 1:32 PM, wm4 wrote:
>>> On Mon, 19 Mar 2018 12:42:16 -0300
>>> James Almer <jamrial at gmail.com> wrote:
>>>
>>>> Useful as well to quickly make a packet reference counted when it
>>>> isn't already so.
>>>>
>>>> Signed-off-by: James Almer <jamrial at gmail.com>
>>>> ---
>>>>  libavcodec/avcodec.h  | 11 +++++++++++
>>>>  libavcodec/avpacket.c | 24 ++++++++++++++++++++++++
>>>>  2 files changed, 35 insertions(+)
>>>>
>>>> diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h
>>>> index a8322fb62a..a78017f1fb 100644
>>>> --- a/libavcodec/avcodec.h
>>>> +++ b/libavcodec/avcodec.h
>>>> @@ -4518,6 +4518,17 @@ void av_packet_move_ref(AVPacket *dst, AVPacket *src);
>>>>   */
>>>>  int av_packet_copy_props(AVPacket *dst, const AVPacket *src);
>>>>  
>>>> +/**
>>>> + * Create a writable reference for the data described by a given packet,
>>>> + * avoiding data copy if possible.
>>>> + *
>>>> + * @param pkt Packet whose data should be made writable.
>>>> + *
>>>> + * @return 0 on success, a negative AVERROR on failure. On failure, the
>>>> + *         packet is unchanged.
>>>> + */
>>>> +int av_packet_make_writable(AVPacket *pkt);
>>>> +
>>>>  /**
>>>>   * Convert valid timing fields (timestamps / durations) in a packet from one
>>>>   * timebase to another. Timestamps with unknown values (AV_NOPTS_VALUE) will be
>>>> diff --git a/libavcodec/avpacket.c b/libavcodec/avpacket.c
>>>> index fe8113ab76..0693ca6f62 100644
>>>> --- a/libavcodec/avpacket.c
>>>> +++ b/libavcodec/avpacket.c
>>>> @@ -652,6 +652,30 @@ void av_packet_move_ref(AVPacket *dst, AVPacket *src)
>>>>      src->size = 0;
>>>>  }
>>>>  
>>>> +int av_packet_make_writable(AVPacket *pkt)
>>>> +{
>>>> +    AVBufferRef *buf = NULL;
>>>> +    int ret;
>>>> +
>>>> +    if (pkt->buf && av_buffer_is_writable(pkt->buf))
>>>> +        return 0;
>>>> +
>>>> +    if (!pkt->data)
>>>> +        return AVERROR(EINVAL);
>>>> +
>>>> +    ret = packet_alloc(&buf, pkt->size);
>>>> +    if (ret < 0)
>>>> +        return ret;
>>>> +    if (pkt->size)
>>>> +        memcpy(buf->data, pkt->data, pkt->size);
>>>> +
>>>> +    av_buffer_unref(&pkt->buf);
>>>> +    pkt->buf  = buf;
>>>> +    pkt->data = buf->data;
>>>> +
>>>> +    return 0;
>>>> +}
>>>> +
>>>>  void av_packet_rescale_ts(AVPacket *pkt, AVRational src_tb, AVRational dst_tb)
>>>>  {
>>>>      if (pkt->pts != AV_NOPTS_VALUE)
>>>
>>> Why not just call av_buffer_make_writable()? This code seems fine too,
>>> though.
>>
>> That would require duplicating all or most of these checks every time
>> you need to make sure a packet is writable. pkt->buf may be NULL,
>> pkt->buf may already be writable, pkt->data may be NULL, the like.
>>
>> I figured a helper function like this where you just call one function
>> that is "make this packet writable, whatever the current state is" would
>> come in handy and simplify some parts of the tree. See the two commits i
>> mentioned in my reply to Paul, or the mpeg4_unpack_bframes patch i sent
>> last night.
> 
> I'll apply this later today or tomorrow unless someone objects.

Pushed.


More information about the ffmpeg-devel mailing list