diff options
Diffstat (limited to 'demux/packet.c')
-rw-r--r-- | demux/packet.c | 75 |
1 files changed, 32 insertions, 43 deletions
diff --git a/demux/packet.c b/demux/packet.c index 77ea78f7cc..2008113600 100644 --- a/demux/packet.c +++ b/demux/packet.c @@ -29,55 +29,58 @@ static void packet_destroy(void *ptr) { struct demux_packet *dp = ptr; - talloc_free(dp->avpacket); - av_free(dp->allocation); + av_packet_unref(dp->avpacket); } -static struct demux_packet *create_packet(size_t len) +// This actually preserves only data and side data, not PTS/DTS/pos/etc. +// It also allows avpkt->data==NULL with avpkt->size!=0 - the libavcodec API +// does not allow it, but we do it to simplify new_demux_packet(). +struct demux_packet *new_demux_packet_from_avpacket(struct AVPacket *avpkt) { - if (len > 1000000000) { + if (avpkt->size > 1000000000) { fprintf(stderr, "Attempt to allocate demux packet over 1 GB!\n"); abort(); } struct demux_packet *dp = talloc(NULL, struct demux_packet); talloc_set_destructor(dp, packet_destroy); *dp = (struct demux_packet) { - .len = len, .pts = MP_NOPTS_VALUE, .dts = MP_NOPTS_VALUE, .duration = -1, .pos = -1, .stream = -1, + .avpacket = talloc_zero(dp, AVPacket), }; - return dp; -} - -struct demux_packet *new_demux_packet(size_t len) -{ - struct demux_packet *dp = create_packet(len); - dp->buffer = av_malloc(len + FF_INPUT_BUFFER_PADDING_SIZE); - if (!dp->buffer) { - fprintf(stderr, "Memory allocation failure!\n"); + av_init_packet(dp->avpacket); + int r = -1; + if (avpkt->data) { + // We hope that this function won't need/access AVPacket input padding, + // because otherwise new_demux_packet_from() wouldn't work. + r = av_packet_ref(dp->avpacket, avpkt); + } else { + r = av_new_packet(dp->avpacket, avpkt->size); + } + if (r < 0) { + fprintf(stderr, "Out of memory when referencing packet.\n"); abort(); } - memset(dp->buffer + len, 0, FF_INPUT_BUFFER_PADDING_SIZE); - dp->allocation = dp->buffer; + dp->buffer = dp->avpacket->data; + dp->len = dp->avpacket->size; return dp; } -// data must already have suitable padding, and does not copy the data -struct demux_packet *new_demux_packet_fromdata(void *data, size_t len) +// Input data doesn't need to be padded. +struct demux_packet *new_demux_packet_from(void *data, size_t len) { - struct demux_packet *dp = create_packet(len); - dp->buffer = data; - return dp; + AVPacket pkt = { .data = data, .size = len }; + return new_demux_packet_from_avpacket(&pkt); } -struct demux_packet *new_demux_packet_from(void *data, size_t len) +struct demux_packet *new_demux_packet(size_t len) { - struct demux_packet *dp = new_demux_packet(len); - memcpy(dp->buffer, data, len); - return dp; + assert(len <= INT_MAX); + AVPacket pkt = { .data = NULL, .size = len }; + return new_demux_packet_from_avpacket(&pkt); } void demux_packet_shorten(struct demux_packet *dp, size_t len) @@ -92,28 +95,14 @@ void free_demux_packet(struct demux_packet *dp) talloc_free(dp); } -static void destroy_avpacket(void *pkt) -{ - av_free_packet(pkt); -} - struct demux_packet *demux_copy_packet(struct demux_packet *dp) { struct demux_packet *new = NULL; if (dp->avpacket) { - assert(dp->buffer == dp->avpacket->data); - assert(dp->len == dp->avpacket->size); - AVPacket *newavp = talloc_zero(NULL, AVPacket); - talloc_set_destructor(newavp, destroy_avpacket); - av_init_packet(newavp); - if (av_packet_ref(newavp, dp->avpacket) < 0) - abort(); - new = new_demux_packet_fromdata(newavp->data, newavp->size); - new->avpacket = newavp; - } - if (!new) { - new = new_demux_packet(dp->len); - memcpy(new->buffer, dp->buffer, new->len); + new = new_demux_packet_from_avpacket(dp->avpacket); + } else { + // Some packets might be not created by new_demux_packet*(). + new = new_demux_packet_from(dp->buffer, dp->len); } new->pts = dp->pts; new->dts = dp->dts; |