diff --git a/doc/APIchanges b/doc/APIchanges index efdb81c2d0..14b96ce122 100644 --- a/doc/APIchanges +++ b/doc/APIchanges @@ -20,6 +20,8 @@ API changes, most recent first: it resets the packet in a more consistent way. xxxxxx - Deprecate av_dup_packet(), it is a no-op for most cases. Use av_packet_ref() to make a non-refcounted AVPacket refcounted. + xxxxxx - Add av_packet_alloc(), av_packet_clone(), av_packet_free(). + They match the AVFrame functions with the same name. 2015-10-27 - xxxxxxx - lavu 55.5.100 - cpu.h Add AV_CPU_FLAG_AESNI. diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h index 936d9fe240..3a91cfd7f2 100644 --- a/libavcodec/avcodec.h +++ b/libavcodec/avcodec.h @@ -3847,6 +3847,40 @@ void avsubtitle_free(AVSubtitle *sub); * @{ */ +/** + * Allocate an AVPacket and set its fields to default values. The resulting + * struct must be freed using av_packet_free(). + * + * @return An AVPacket filled with default values or NULL on failure. + * + * @note this only allocates the AVPacket itself, not the data buffers. Those + * must be allocated through other means such as av_new_packet. + * + * @see av_new_packet + */ +AVPacket *av_packet_alloc(void); + +/** + * Create a new packet that references the same data as src. + * + * This is a shortcut for av_packet_alloc()+av_packet_ref(). + * + * @return newly created AVPacket on success, NULL on error. + * + * @see av_packet_alloc + * @see av_packet_ref + */ +AVPacket *av_packet_clone(AVPacket *src); + +/** + * Free the packet, if the packet is reference counted, it will be + * unreferenced first. + * + * @param packet packet to be freed. The pointer will be set to NULL. + * @note passing NULL is a no-op. + */ +void av_packet_free(AVPacket **pkt); + /** * Initialize optional fields of a packet with default values. * diff --git a/libavcodec/avpacket.c b/libavcodec/avpacket.c index 34ef2659ef..1cc10eba05 100644 --- a/libavcodec/avpacket.c +++ b/libavcodec/avpacket.c @@ -48,6 +48,26 @@ FF_ENABLE_DEPRECATION_WARNINGS pkt->side_data_elems = 0; } +AVPacket *av_packet_alloc(void) +{ + AVPacket *pkt = av_mallocz(sizeof(AVPacket)); + if (!pkt) + return pkt; + + av_packet_unref(pkt); + + return pkt; +} + +void av_packet_free(AVPacket **pkt) +{ + if (!pkt || !*pkt) + return; + + av_packet_unref(*pkt); + av_freep(pkt); +} + static int packet_alloc(AVBufferRef **buf, int size) { int ret; @@ -542,6 +562,19 @@ fail: return ret; } +AVPacket *av_packet_clone(AVPacket *src) +{ + AVPacket *ret = av_packet_alloc(); + + if (!ret) + return ret; + + if (av_packet_ref(ret, src)) + av_packet_free(&ret); + + return ret; +} + void av_packet_move_ref(AVPacket *dst, AVPacket *src) { *dst = *src;