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

James Almer jamrial at gmail.com
Wed Mar 21 19:14:18 EET 2018


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.


More information about the ffmpeg-devel mailing list