mirror of
https://github.com/mpv-player/mpv.git
synced 2025-12-28 05:33:14 +00:00
ffmpeg: update to handle deprecation of av_init_packet
This has been a long standing annoyance - ffmpeg is removing sizeof(AVPacket) from the API which means you cannot stack-allocate AVPacket anymore. However, that is something we take advantage of because we use short-lived AVPackets to bridge from native mpv packets in our main decoding paths. We don't think that switching these to `av_packet_alloc` is desirable, given the cost of heap allocation, so this change takes a different approach - allocating a single packet in the relevant context and reusing it over and over. That's fairly straight-forward, with the main caveat being that re-initialising the packet is unintuitive. There is no function that does exactly what we need (what `av_init_packet` did). The closest is `av_packet_unref`, which additionally frees buffers and side-data. However, we don't copy those things - we just assign them in from our own packet, so we have to explicitly clear the pointers before calling `av_packet_unref`. But at least we can make a wrapper function for that. The weirdest part of the change is the handling of the vtt subtitle conversion. This requires two packets, so I had to pre-allocate two in the context struct. That sounds excessive, but if allocating the primary packet is too expensive, then allocating the secondary one for vtt subtitles must also be too expensive. This change is not conditional as heap allocated AVPackets were available for years and years before the deprecation.
This commit is contained in:
committed by
Philip Langdale
parent
77e7f5de2c
commit
4574dd5dc6
@@ -196,7 +196,11 @@ double mp_pts_from_av(int64_t av_pts, AVRational *tb)
|
||||
// Set duration field only if tb is set.
|
||||
void mp_set_av_packet(AVPacket *dst, struct demux_packet *mpkt, AVRational *tb)
|
||||
{
|
||||
av_init_packet(dst);
|
||||
dst->side_data = NULL;
|
||||
dst->side_data_elems = 0;
|
||||
dst->buf = NULL;
|
||||
av_packet_unref(dst);
|
||||
|
||||
dst->data = mpkt ? mpkt->buffer : NULL;
|
||||
dst->size = mpkt ? mpkt->len : 0;
|
||||
/* Some codecs (ZeroCodec, some cases of PNG) may want keyframe info
|
||||
@@ -394,3 +398,21 @@ int mp_set_avopts_pos(struct mp_log *log, void *avobj, void *posargs, char **kv)
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
||||
/**
|
||||
* Must be used to free an AVPacket that was used with mp_set_av_packet().
|
||||
*
|
||||
* We have a particular pattern where we "borrow" buffers and set them
|
||||
* into an AVPacket to pass data to ffmpeg without extra copies.
|
||||
* This applies to buf and side_data, so this function clears them before
|
||||
* freeing.
|
||||
*/
|
||||
void mp_free_av_packet(AVPacket **pkt)
|
||||
{
|
||||
if (*pkt) {
|
||||
(*pkt)->side_data = NULL;
|
||||
(*pkt)->side_data_elems = 0;
|
||||
(*pkt)->buf = NULL;
|
||||
}
|
||||
av_packet_free(pkt);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user