X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavcodec%2Favpacket.c;h=e4ba403cf619eaa11326e3b44bbe4ffd3c8ca645;hb=57eee75c3fd075e555df122f1abc45ca636a2726;hp=8f0603df782380930ccff0674ba20102a35fbbc9;hpb=1c9ac700dd141e545538a824f5a8cb81bb0a375d;p=ffmpeg diff --git a/libavcodec/avpacket.c b/libavcodec/avpacket.c index 8f0603df782..e4ba403cf61 100644 --- a/libavcodec/avpacket.c +++ b/libavcodec/avpacket.c @@ -26,9 +26,11 @@ #include "libavutil/internal.h" #include "libavutil/mathematics.h" #include "libavutil/mem.h" -#include "avcodec.h" + #include "bytestream.h" #include "internal.h" +#include "packet.h" +#include "packet_internal.h" void av_init_packet(AVPacket *pkt) { @@ -54,7 +56,7 @@ AVPacket *av_packet_alloc(void) if (!pkt) return pkt; - av_packet_unref(pkt); + av_init_packet(pkt); return pkt; } @@ -127,7 +129,8 @@ int av_grow_packet(AVPacket *pkt, int grow_by) return AVERROR(ENOMEM); } - if (new_size + data_offset > pkt->buf->size) { + if (new_size + data_offset > pkt->buf->size || + !av_buffer_is_writable(pkt->buf)) { int ret = av_buffer_realloc(&pkt->buf, new_size + data_offset); if (ret < 0) { pkt->data = old_data; @@ -394,6 +397,10 @@ const char *av_packet_side_data_name(enum AVPacketSideDataType type) case AV_PKT_DATA_ENCRYPTION_INIT_INFO: return "Encryption initialization data"; case AV_PKT_DATA_ENCRYPTION_INFO: return "Encryption info"; case AV_PKT_DATA_AFD: return "Active Format Description data"; + case AV_PKT_DATA_PRFT: return "Producer Reference Time"; + case AV_PKT_DATA_ICC_PROFILE: return "ICC Profile"; + case AV_PKT_DATA_DOVI_CONF: return "DOVI configuration record"; + case AV_PKT_DATA_S12M_TIMECODE: return "SMPTE ST 12-1:2014 timecode"; } return NULL; } @@ -522,11 +529,12 @@ fail: int av_packet_unpack_dictionary(const uint8_t *data, int size, AVDictionary **dict) { - const uint8_t *end = data + size; - int ret = 0; + const uint8_t *end; + int ret; if (!dict || !data || !size) - return ret; + return 0; + end = data + size; if (size && end[-1]) return AVERROR_INVALIDDATA; while (data < end) { @@ -538,11 +546,11 @@ int av_packet_unpack_dictionary(const uint8_t *data, int size, AVDictionary **di ret = av_dict_set(dict, key, val, 0); if (ret < 0) - break; + return ret; data = val + strlen(val) + 1; } - return ret; + return 0; } int av_packet_shrink_side_data(AVPacket *pkt, enum AVPacketSideDataType type, @@ -608,9 +616,11 @@ int av_packet_ref(AVPacket *dst, const AVPacket *src) { int ret; + dst->buf = NULL; + ret = av_packet_copy_props(dst, src); if (ret < 0) - return ret; + goto fail; if (!src->buf) { ret = packet_alloc(&dst->buf, src->size); @@ -634,7 +644,7 @@ int av_packet_ref(AVPacket *dst, const AVPacket *src) return 0; fail: - av_packet_free_side_data(dst); + av_packet_unref(dst); return ret; } @@ -716,6 +726,73 @@ FF_ENABLE_DEPRECATION_WARNINGS #endif } +int avpriv_packet_list_put(AVPacketList **packet_buffer, + AVPacketList **plast_pktl, + AVPacket *pkt, + int (*copy)(AVPacket *dst, const AVPacket *src), + int flags) +{ + AVPacketList *pktl = av_mallocz(sizeof(AVPacketList)); + int ret; + + if (!pktl) + return AVERROR(ENOMEM); + + if (copy) { + ret = copy(&pktl->pkt, pkt); + if (ret < 0) { + av_free(pktl); + return ret; + } + } else { + ret = av_packet_make_refcounted(pkt); + if (ret < 0) { + av_free(pktl); + return ret; + } + av_packet_move_ref(&pktl->pkt, pkt); + } + + if (*packet_buffer) + (*plast_pktl)->next = pktl; + else + *packet_buffer = pktl; + + /* Add the packet in the buffered packet list. */ + *plast_pktl = pktl; + return 0; +} + +int avpriv_packet_list_get(AVPacketList **pkt_buffer, + AVPacketList **pkt_buffer_end, + AVPacket *pkt) +{ + AVPacketList *pktl; + if (!*pkt_buffer) + return AVERROR(EAGAIN); + pktl = *pkt_buffer; + *pkt = pktl->pkt; + *pkt_buffer = pktl->next; + if (!pktl->next) + *pkt_buffer_end = NULL; + av_freep(&pktl); + return 0; +} + +void avpriv_packet_list_free(AVPacketList **pkt_buf, AVPacketList **pkt_buf_end) +{ + AVPacketList *tmp = *pkt_buf; + + while (tmp) { + AVPacketList *pktl = tmp; + tmp = pktl->next; + av_packet_unref(&pktl->pkt); + av_freep(&pktl); + } + *pkt_buf = NULL; + *pkt_buf_end = NULL; +} + int ff_side_data_set_encoder_stats(AVPacket *pkt, int quality, int64_t *error, int error_count, int pict_type) { uint8_t *side_data; @@ -740,3 +817,25 @@ int ff_side_data_set_encoder_stats(AVPacket *pkt, int quality, int64_t *error, i return 0; } + +int ff_side_data_set_prft(AVPacket *pkt, int64_t timestamp) +{ + AVProducerReferenceTime *prft; + uint8_t *side_data; + int side_data_size; + + side_data = av_packet_get_side_data(pkt, AV_PKT_DATA_PRFT, &side_data_size); + if (!side_data) { + side_data_size = sizeof(AVProducerReferenceTime); + side_data = av_packet_new_side_data(pkt, AV_PKT_DATA_PRFT, side_data_size); + } + + if (!side_data || side_data_size < sizeof(AVProducerReferenceTime)) + return AVERROR(ENOMEM); + + prft = (AVProducerReferenceTime *)side_data; + prft->wallclock = timestamp; + prft->flags = 0; + + return 0; +}