X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavcodec%2Favpacket.c;h=e4ba403cf619eaa11326e3b44bbe4ffd3c8ca645;hb=f1700bd8bb983bb3b56c3a1f8b9078cb62a44f65;hp=99a0c1383bd1bd10b47b82dfb33f715a8c80d8b0;hpb=f4cf6ba8c9646814af842a99335c6ee312ded299;p=ffmpeg diff --git a/libavcodec/avpacket.c b/libavcodec/avpacket.c index 99a0c1383bd..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; } @@ -112,7 +114,7 @@ int av_grow_packet(AVPacket *pkt, int grow_by) av_assert0((unsigned)pkt->size <= INT_MAX - AV_INPUT_BUFFER_PADDING_SIZE); if ((unsigned)grow_by > INT_MAX - (pkt->size + AV_INPUT_BUFFER_PADDING_SIZE)) - return -1; + return AVERROR(ENOMEM); new_size = pkt->size + grow_by + AV_INPUT_BUFFER_PADDING_SIZE; if (pkt->buf) { @@ -124,10 +126,11 @@ int av_grow_packet(AVPacket *pkt, int grow_by) } else { data_offset = pkt->data - pkt->buf->data; if (data_offset > INT_MAX - new_size) - return -1; + 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; @@ -375,6 +378,9 @@ const char *av_packet_side_data_name(enum AVPacketSideDataType type) case AV_PKT_DATA_DISPLAYMATRIX: return "Display Matrix"; case AV_PKT_DATA_STEREO3D: return "Stereo 3D"; case AV_PKT_DATA_AUDIO_SERVICE_TYPE: return "Audio Service Type"; + case AV_PKT_DATA_QUALITY_STATS: return "Quality stats"; + case AV_PKT_DATA_FALLBACK_TRACK: return "Fallback track"; + case AV_PKT_DATA_CPB_PROPERTIES: return "CPB properties"; case AV_PKT_DATA_SKIP_SAMPLES: return "Skip Samples"; case AV_PKT_DATA_JP_DUALMONO: return "JP Dual Mono"; case AV_PKT_DATA_STRINGS_METADATA: return "Strings Metadata"; @@ -388,6 +394,13 @@ const char *av_packet_side_data_name(enum AVPacketSideDataType type) case AV_PKT_DATA_CONTENT_LIGHT_LEVEL: return "Content light level metadata"; case AV_PKT_DATA_SPHERICAL: return "Spherical Mapping"; case AV_PKT_DATA_A53_CC: return "A53 Closed Captions"; + 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; } @@ -516,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) { @@ -532,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, @@ -574,10 +588,10 @@ FF_ENABLE_DEPRECATION_WARNINGS dst->side_data = NULL; dst->side_data_elems = 0; 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); + 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); @@ -602,14 +616,17 @@ 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); if (ret < 0) goto fail; + av_assert1(!src->size || src->data); if (src->size) memcpy(dst->buf->data, src->data, src->size); @@ -627,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; } @@ -662,6 +679,7 @@ int av_packet_make_refcounted(AVPacket *pkt) ret = packet_alloc(&pkt->buf, pkt->size); if (ret < 0) return ret; + av_assert1(!pkt->size || pkt->data); if (pkt->size) memcpy(pkt->buf->data, pkt->data, pkt->size); @@ -681,6 +699,7 @@ int av_packet_make_writable(AVPacket *pkt) ret = packet_alloc(&buf, pkt->size); if (ret < 0) return ret; + av_assert1(!pkt->size || pkt->data); if (pkt->size) memcpy(buf->data, pkt->data, pkt->size); @@ -707,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; @@ -731,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; +}