diff options
author | wm4 <wm4@nowhere> | 2014-08-24 17:45:28 +0200 |
---|---|---|
committer | wm4 <wm4@nowhere> | 2014-08-25 00:46:26 +0200 |
commit | 758f8f7bd46388cba9330ad47701c0ebacc2d963 (patch) | |
tree | 5fcecbf5218d13888af60251c8f8fd821c983cfd /demux/demux_lavf.c | |
parent | ef1c6e9295f40a4633685eeae3c12706f8290bb0 (diff) | |
download | mpv-758f8f7bd46388cba9330ad47701c0ebacc2d963.tar.bz2 mpv-758f8f7bd46388cba9330ad47701c0ebacc2d963.tar.xz |
demux: always use AVPacket
This is a simplification, because it lets us use the AVPacket
functions, instead of handling the details manually.
It also allows the libavcodec rawvideo decoder to use reference
counting, so it doesn't have to memcpy() the full image data. The change
in av_common.c enables this.
This change is somewhat risky, because we rely on the following AVPacket
implementation details and assumptions:
- av_packet_ref() doesn't access the input padding, and just copies the
data. By the API, AVPacket is always padded, and we violate this. The
lavc implementation would have to go out of its way to make this a
real problem, though.
- We hope that the way we make the AVPacket refcountable in av_common.c
is actually supported API-usage. It's hard to tell whether it is.
Of course we still use our own "old" demux_packet struct, just so that
libav* API usage is somewhat isolated.
Diffstat (limited to 'demux/demux_lavf.c')
-rw-r--r-- | demux/demux_lavf.c | 23 |
1 files changed, 5 insertions, 18 deletions
diff --git a/demux/demux_lavf.c b/demux/demux_lavf.c index d8d177e27e..16a06829d4 100644 --- a/demux/demux_lavf.c +++ b/demux/demux_lavf.c @@ -780,23 +780,16 @@ static int demux_open_lavf(demuxer_t *demuxer, enum demux_check check) return 0; } -static void destroy_avpacket(void *pkt) -{ - av_free_packet(pkt); -} - static int demux_lavf_fill_buffer(demuxer_t *demux) { lavf_priv_t *priv = demux->priv; - demux_packet_t *dp; - AVPacket *pkt = talloc(NULL, AVPacket); + AVPacket *pkt = &(AVPacket){0}; int r = av_read_frame(priv->avfc, pkt); if (r < 0) { - talloc_free(pkt); + av_free_packet(pkt); return r == AVERROR(EAGAIN) ? 1 : -1; // eof } - talloc_set_destructor(pkt, destroy_avpacket); add_new_streams(demux); update_metadata(demux, pkt); @@ -806,18 +799,11 @@ static int demux_lavf_fill_buffer(demuxer_t *demux) AVStream *st = priv->avfc->streams[pkt->stream_index]; if (!demux_stream_is_selected(stream)) { - talloc_free(pkt); + av_free_packet(pkt); return 1; // don't signal EOF if skipping a packet } - // If the packet has pointers to temporary fields that could be - // overwritten/freed by next av_read_frame(), copy them to persistent - // allocations so we can safely queue the packet for any length of time. - if (av_dup_packet(pkt) < 0) - abort(); - - dp = new_demux_packet_fromdata(pkt->data, pkt->size); - dp->avpacket = talloc_steal(dp, pkt); + struct demux_packet *dp = new_demux_packet_from_avpacket(pkt); if (pkt->pts != AV_NOPTS_VALUE) dp->pts = pkt->pts * av_q2d(st->time_base); @@ -833,6 +819,7 @@ static int demux_lavf_fill_buffer(demuxer_t *demux) } else if (dp->dts != MP_NOPTS_VALUE) { priv->last_pts = dp->dts * AV_TIME_BASE; } + av_free_packet(pkt); demux_add_packet(stream, dp); return 1; } |