diff --git a/doc/APIchanges b/doc/APIchanges index dc40bc3415..e3a64a020e 100644 --- a/doc/APIchanges +++ b/doc/APIchanges @@ -15,6 +15,10 @@ libavutil: 2012-10-22 API changes, most recent first: +2013-08-xx - xxxxxxx - lavc 55.16.0 - avcodec.h + Extend AVPacket API with av_packet_unref, av_packet_ref, + av_packet_move_ref, av_packet_copy_props, av_packet_free_side_data. + 2013-08-xx - xxxxxxx - lavc 55.13.0 - avcodec.h Deprecate the bitstream-related members from struct AVVDPAUContext. The bistream buffers no longer need to be explicitly freed. diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h index 2b98083020..6b37b8380f 100644 --- a/libavcodec/avcodec.h +++ b/libavcodec/avcodec.h @@ -3542,6 +3542,66 @@ int av_packet_merge_side_data(AVPacket *pkt); int av_packet_split_side_data(AVPacket *pkt); +/** + * Convenience function to free all the side data stored. + * All the other fields stay untouched. + * + * @param pkt packet + */ +void av_packet_free_side_data(AVPacket *pkt); + +/** + * Setup a new reference to the data described by a given packet + * + * If src is reference-counted, setup dst as a new reference to the + * buffer in src. Otherwise allocate a new buffer in dst and copy the + * data from src into it. + * + * All the other fields are copied from src. + * + * @see av_packet_unref + * + * @param dst Destination packet + * @param src Source packet + * + * @return 0 on success, a negative AVERROR on error. + */ +int av_packet_ref(AVPacket *dst, AVPacket *src); + +/** + * Wipe the packet. + * + * Unreference the buffer referenced by the packet and reset the + * remaining packet fields to their default values. + * + * @param pkt The packet to be unreferenced. + */ +void av_packet_unref(AVPacket *pkt); + +/** + * Move every field in src to dst and reset src. + * + * @see av_packet_unref + * + * @param src Source packet, will be reset + * @param dst Destination packet + */ +void av_packet_move_ref(AVPacket *dst, AVPacket *src); + +/** + * Copy only "properties" fields from src to dst. + * + * Properties for the purpose of this function are all the fields + * beside those related to the packet data (buf, data, size) + * + * @param dst Destination packet + * @param src Source packet + * + * @return 0 on success AVERROR on failure. + * + */ +int av_packet_copy_props(AVPacket *dst, const AVPacket *src); + /** * @} */ diff --git a/libavcodec/avpacket.c b/libavcodec/avpacket.c index faa42fe8b9..87d1507bc1 100644 --- a/libavcodec/avpacket.c +++ b/libavcodec/avpacket.c @@ -39,6 +39,7 @@ void ff_packet_free_side_data(AVPacket *pkt) } #if FF_API_DESTRUCT_PACKET + void av_destruct_packet(AVPacket *pkt) { av_free(pkt->data); @@ -73,18 +74,26 @@ FF_ENABLE_DEPRECATION_WARNINGS pkt->side_data_elems = 0; } -int av_new_packet(AVPacket *pkt, int size) +static int packet_alloc(AVBufferRef **buf, int size) { - AVBufferRef *buf = NULL; - if ((unsigned)size >= (unsigned)size + FF_INPUT_BUFFER_PADDING_SIZE) return AVERROR(EINVAL); - av_buffer_realloc(&buf, size + FF_INPUT_BUFFER_PADDING_SIZE); + av_buffer_realloc(buf, size + FF_INPUT_BUFFER_PADDING_SIZE); if (!buf) return AVERROR(ENOMEM); - memset(buf->data + size, 0, FF_INPUT_BUFFER_PADDING_SIZE); + memset((*buf)->data + size, 0, FF_INPUT_BUFFER_PADDING_SIZE); + + return 0; +} + +int av_new_packet(AVPacket *pkt, int size) +{ + AVBufferRef *buf = NULL; + int ret = packet_alloc(&buf, size); + if (ret < 0) + return ret; av_init_packet(pkt); pkt->buf = buf; @@ -264,11 +273,18 @@ int av_copy_packet(AVPacket *dst, AVPacket *src) return copy_packet_data(dst, src, 0); } +void av_packet_free_side_data(AVPacket *pkt) +{ + int i; + for (i = 0; i < pkt->side_data_elems; i++) + av_free(pkt->side_data[i].data); + av_freep(&pkt->side_data); + pkt->side_data_elems = 0; +} + void av_free_packet(AVPacket *pkt) { if (pkt) { - int i; - FF_DISABLE_DEPRECATION_WARNINGS if (pkt->buf) av_buffer_unref(&pkt->buf); @@ -281,10 +297,7 @@ FF_ENABLE_DEPRECATION_WARNINGS pkt->data = NULL; pkt->size = 0; - for (i = 0; i < pkt->side_data_elems; i++) - av_free(pkt->side_data[i].data); - av_freep(&pkt->side_data); - pkt->side_data_elems = 0; + av_packet_free_side_data(pkt); } } @@ -434,3 +447,71 @@ int av_packet_shrink_side_data(AVPacket *pkt, enum AVPacketSideDataType type, } return AVERROR(ENOENT); } + +int av_packet_copy_props(AVPacket *dst, const AVPacket *src) +{ + int i; + + dst->pts = src->pts; + dst->dts = src->dts; + dst->pos = src->pos; + dst->duration = src->duration; + dst->convergence_duration = src->convergence_duration; + dst->flags = src->flags; + dst->stream_index = src->stream_index; + dst->side_data_elems = src->side_data_elems; + + for (i = 0; i < src->side_data_elems; i++) { + enum AVPacketSideDataType type = src->side_data[i].type; + int size = src->side_data[i].size; + uint8_t *src_data = src->side_data[i].data; + uint8_t *dst_data = av_packet_new_side_data(dst, type, size); + + if (!dst_data) { + av_packet_free_side_data(dst); + return AVERROR(ENOMEM); + } + memcpy(dst_data, src_data, size); + } + + return 0; +} + +void av_packet_unref(AVPacket *pkt) +{ + av_packet_free_side_data(pkt); + av_buffer_unref(&pkt->buf); + av_init_packet(pkt); + pkt->data = NULL; + pkt->size = 0; +} + +int av_packet_ref(AVPacket *dst, AVPacket *src) +{ + int ret; + + ret = av_packet_copy_props(dst, src); + if (ret < 0) + return ret; + + if (!src->buf) { + ret = packet_alloc(&dst->buf, src->size); + if (ret < 0) + goto fail; + memcpy(dst->buf->data, src->data, src->size); + } else + dst->buf = av_buffer_ref(src->buf); + + dst->size = src->size; + dst->data = dst->buf->data; + return 0; +fail: + av_packet_free_side_data(dst); + return ret; +} + +void av_packet_move_ref(AVPacket *dst, AVPacket *src) +{ + *dst = *src; + av_init_packet(src); +} diff --git a/libavcodec/version.h b/libavcodec/version.h index 75b15a7465..ad8af90c51 100644 --- a/libavcodec/version.h +++ b/libavcodec/version.h @@ -29,7 +29,7 @@ #include "libavutil/avutil.h" #define LIBAVCODEC_VERSION_MAJOR 55 -#define LIBAVCODEC_VERSION_MINOR 24 +#define LIBAVCODEC_VERSION_MINOR 25 #define LIBAVCODEC_VERSION_MICRO 100 #define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \