summaryrefslogtreecommitdiffstats
path: root/audio/decode/ad_spdif.c
diff options
context:
space:
mode:
authorPhilip Langdale <philipl@overt.org>2022-11-29 11:15:16 -0800
committerPhilip Langdale <github.philipl@overt.org>2022-12-03 14:44:18 -0800
commit4574dd5dc6ff75b1fc693afceec59fbcd51ccd4c (patch)
tree680ea541592dea8e356809e5dbdd5265781d72fe /audio/decode/ad_spdif.c
parent77e7f5de2c01361a88c501fcd78b51c2fe2d9df0 (diff)
downloadmpv-4574dd5dc6ff75b1fc693afceec59fbcd51ccd4c.tar.bz2
mpv-4574dd5dc6ff75b1fc693afceec59fbcd51ccd4c.tar.xz
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.
Diffstat (limited to 'audio/decode/ad_spdif.c')
-rw-r--r--audio/decode/ad_spdif.c15
1 files changed, 10 insertions, 5 deletions
diff --git a/audio/decode/ad_spdif.c b/audio/decode/ad_spdif.c
index 520803c4b0..3b799660c1 100644
--- a/audio/decode/ad_spdif.c
+++ b/audio/decode/ad_spdif.c
@@ -41,6 +41,7 @@ struct spdifContext {
struct mp_log *log;
enum AVCodecID codec_id;
AVFormatContext *lavf_ctx;
+ AVPacket *avpkt;
int out_buffer_len;
uint8_t out_buffer[OUTBUF_SIZE];
bool need_close;
@@ -82,6 +83,7 @@ static void destroy(struct mp_filter *da)
avformat_free_context(lavf_ctx);
spdif_ctx->lavf_ctx = NULL;
}
+ mp_free_av_packet(&spdif_ctx->avpkt);
}
static void determine_codec_params(struct mp_filter *da, AVPacket *pkt,
@@ -295,15 +297,14 @@ static void process(struct mp_filter *da)
struct mp_aframe *out = NULL;
double pts = mpkt->pts;
- AVPacket pkt;
- mp_set_av_packet(&pkt, mpkt, NULL);
- pkt.pts = pkt.dts = 0;
+ mp_set_av_packet(spdif_ctx->avpkt, mpkt, NULL);
+ spdif_ctx->avpkt->pts = spdif_ctx->avpkt->dts = 0;
if (!spdif_ctx->lavf_ctx) {
- if (init_filter(da, &pkt) < 0)
+ if (init_filter(da, spdif_ctx->avpkt) < 0)
goto done;
}
spdif_ctx->out_buffer_len = 0;
- int ret = av_write_frame(spdif_ctx->lavf_ctx, &pkt);
+ int ret = av_write_frame(spdif_ctx->lavf_ctx, spdif_ctx->avpkt);
avio_flush(spdif_ctx->lavf_ctx->pb);
if (ret < 0) {
MP_ERR(da, "spdif mux error: '%s'\n", mp_strerror(AVUNERROR(ret)));
@@ -424,6 +425,10 @@ static struct mp_decoder *create(struct mp_filter *parent,
talloc_free(da);
return NULL;
}
+
+ spdif_ctx->avpkt = av_packet_alloc();
+ MP_HANDLE_OOM(spdif_ctx->avpkt);
+
return &spdif_ctx->public;
}