demux: reclaim demux_packets to reduce memory allocator pressure

This update introduces a demux_packet_pool, allowing for the reuse of
previously allocated packets when needed.

sizeof(AVPacket) is not a part of the lavc public ABI, which prevents us
to allocate memory in larger blocks. However, we can substantially
decrease the amount of alloc/free operations during playback by reusing
both mpv's demux_packet and AVPacket.

This adjustment addresses the root cause of issue #12076, which,
although resolved upstream, did not fully tackle the persistent problem
of allocating small blocks of aligned memory. This issue largely stems
from the FFmpeg design of the AVPacket API. After this change memory
will no longer be allocated once cache limits is reached.

The demux_packet_pool is shared as a global pool of packets for a given
MPContext.

This change significantly speeds up the demuxer deinitialization,
benefiting file switching scenarios, especially when a large demuxer
cache is used.

See: #12294
See: #12563
This commit is contained in:
Kacper Michajłow 2023-10-05 18:05:44 +02:00
parent 805577c792
commit 90579391cd
19 changed files with 213 additions and 55 deletions

View File

@ -10,6 +10,7 @@ struct mpv_global {
struct mp_client_api *client_api;
char *configdir;
struct stats_base *stats;
struct demux_packet_pool *packet_pool;
};
#endif

View File

@ -412,7 +412,7 @@ void mp_recorder_feed_packet(struct mp_recorder_sink *rst,
return;
}
pkt = demux_copy_packet(pkt);
pkt = demux_copy_packet(rst->owner->global->packet_pool, pkt);
if (!pkt)
return;
MP_TARRAY_APPEND(rst, rst->packets, rst->num_packets, pkt);

View File

@ -25,6 +25,7 @@
#include "cache.h"
#include "common/msg.h"
#include "common/av_common.h"
#include "common/global.h"
#include "demux.h"
#include "misc/io_utils.h"
#include "options/path.h"
@ -57,6 +58,7 @@ const struct m_sub_options demux_cache_conf = {
struct demux_cache {
struct mp_log *log;
struct demux_packet_pool *packet_pool;
struct demux_cache_opts *opts;
char *filename;
@ -100,6 +102,7 @@ struct demux_cache *demux_cache_create(struct mpv_global *global,
talloc_set_destructor(cache, cache_destroy);
cache->opts = mp_get_config_group(cache, global, &demux_cache_conf);
cache->log = log;
cache->packet_pool = global->packet_pool;
cache->fd = -1;
char *cache_dir = cache->opts->cache_dir;
@ -294,7 +297,7 @@ struct demux_packet *demux_cache_read(struct demux_cache *cache, uint64_t pos)
if (!read_raw(cache, &hd, sizeof(hd)))
return NULL;
struct demux_packet *dp = new_demux_packet(hd.data_len);
struct demux_packet *dp = new_demux_packet(cache->packet_pool, hd.data_len);
if (!dp)
goto fail;

View File

@ -45,6 +45,7 @@
#include "stream/stream.h"
#include "demux.h"
#include "packet_pool.h"
#include "timeline.h"
#include "stheader.h"
#include "cue.h"
@ -698,7 +699,7 @@ static void remove_head_packet(struct demux_queue *queue)
if (!queue->head)
queue->tail = NULL;
talloc_free(dp);
demux_packet_pool_push(queue->ds->in->global->packet_pool, dp);
}
static void free_index(struct demux_queue *queue)
@ -723,13 +724,7 @@ static void clear_queue(struct demux_queue *queue)
free_index(queue);
struct demux_packet *dp = queue->head;
while (dp) {
struct demux_packet *dn = dp->next;
assert(ds->reader_head != dp);
talloc_free(dp);
dp = dn;
}
demux_packet_pool_prepend(in->global->packet_pool, queue->head, queue->tail);
queue->head = queue->tail = NULL;
queue->keyframe_first = NULL;
queue->keyframe_latest = NULL;
@ -2040,7 +2035,7 @@ static void add_packet_locked(struct sh_stream *stream, demux_packet_t *dp)
}
if (drop) {
talloc_free(dp);
demux_packet_pool_push(in->global->packet_pool, dp);
return;
}
@ -2610,7 +2605,7 @@ static struct demux_packet *read_packet_from_cache(struct demux_internal *in,
}
} else {
// The returned packet is mutated etc. and will be owned by the user.
pkt = demux_copy_packet(pkt);
pkt = demux_copy_packet(in->global->packet_pool, pkt);
}
return pkt;
@ -2635,7 +2630,8 @@ static int dequeue_packet(struct demux_stream *ds, double min_pts,
if (ds->attached_picture_added)
return -1;
ds->attached_picture_added = true;
struct demux_packet *pkt = demux_copy_packet(ds->sh->attached_picture);
struct demux_packet *pkt = demux_copy_packet(in->global->packet_pool,
ds->sh->attached_picture);
MP_HANDLE_OOM(pkt);
pkt->stream = ds->sh->index;
*res = pkt;

View File

@ -44,6 +44,7 @@
#include "common/msg.h"
#include "common/tags.h"
#include "common/av_common.h"
#include "common/global.h"
#include "misc/bstr.h"
#include "misc/charset_conv.h"
#include "misc/thread_tools.h"
@ -747,7 +748,7 @@ static void handle_new_stream(demuxer_t *demuxer, int i)
!(st->disposition & AV_DISPOSITION_TIMED_THUMBNAILS))
{
sh->attached_picture =
new_demux_packet_from_avpacket(&st->attached_pic);
new_demux_packet_from_avpacket(demuxer->global->packet_pool, &st->attached_pic);
if (sh->attached_picture) {
sh->attached_picture->pts = 0;
talloc_steal(sh, sh->attached_picture);
@ -1256,7 +1257,7 @@ static bool demux_lavf_read_packet(struct demuxer *demux,
return true; // don't signal EOF if skipping a packet
}
struct demux_packet *dp = new_demux_packet_from_avpacket(pkt);
struct demux_packet *dp = new_demux_packet_from_avpacket(demux->global->packet_pool, pkt);
if (!dp) {
av_packet_unref(pkt);
return true;

View File

@ -27,6 +27,7 @@
#include "osdep/io.h"
#include "mpv_talloc.h"
#include "common/global.h"
#include "common/msg.h"
#include "options/options.h"
#include "options/m_config.h"
@ -258,7 +259,7 @@ static bool demux_mf_read_packet(struct demuxer *demuxer,
stream_seek(stream, 0);
bstr data = stream_read_complete(stream, NULL, MF_MAX_FILE_SIZE);
if (data.len) {
demux_packet_t *dp = new_demux_packet(data.len);
demux_packet_t *dp = new_demux_packet(demuxer->global->packet_pool, data.len);
if (dp) {
memcpy(dp->buffer, data.start, data.len);
dp->pts = mf->curr_frame / mf->sh->codec->fps;

View File

@ -46,6 +46,7 @@
#include "mpv_talloc.h"
#include "common/av_common.h"
#include "common/global.h"
#include "options/m_config.h"
#include "options/m_option.h"
#include "options/options.h"
@ -54,6 +55,7 @@
#include "video/csputils.h"
#include "video/mp_image.h"
#include "demux.h"
#include "packet_pool.h"
#include "stheader.h"
#include "ebml.h"
#include "matroska.h"
@ -1397,7 +1399,8 @@ static void add_coverart(struct demuxer *demuxer)
continue;
struct sh_stream *sh = demux_alloc_sh_stream(STREAM_VIDEO);
sh->codec->codec = codec;
sh->attached_picture = new_demux_packet_from(att->data, att->data_size);
sh->attached_picture = new_demux_packet_from(demuxer->global->packet_pool,
att->data, att->data_size);
if (sh->attached_picture) {
sh->attached_picture->pts = 0;
talloc_steal(sh, sh->attached_picture);
@ -2097,7 +2100,8 @@ static void probe_x264_garbage(demuxer_t *demuxer)
if (!nblock.len)
continue;
sh->codec->first_packet = new_demux_packet_from(nblock.start, nblock.len);
sh->codec->first_packet = new_demux_packet_from(demuxer->global->packet_pool,
nblock.start, nblock.len);
talloc_steal(mkv_d, sh->codec->first_packet);
if (nblock.start != sblock.start)
@ -2497,8 +2501,9 @@ static bool handle_realaudio(demuxer_t *demuxer, mkv_track_t *track,
goto error;
// Release all the audio packets
for (int x = 0; x < sph * w / apk_usize; x++) {
dp = new_demux_packet_from(track->audio_buf + x * apk_usize,
apk_usize);
dp = new_demux_packet_from(demuxer->global->packet_pool,
track->audio_buf + x * apk_usize,
apk_usize);
if (!dp)
goto error;
/* Put timestamp only on packets that correspond to original
@ -2635,7 +2640,8 @@ static void mkv_parse_and_add_packet(demuxer_t *demuxer, mkv_track_t *track,
int size = dp->len;
uint8_t *parsed;
if (libav_parse_wavpack(track, dp->buffer, &parsed, &size) >= 0) {
struct demux_packet *new = new_demux_packet_from(parsed, size);
struct demux_packet *new = new_demux_packet_from(demuxer->global->packet_pool,
parsed, size);
if (new) {
demux_packet_copy_attribs(new, dp);
talloc_free(dp);
@ -2647,7 +2653,7 @@ static void mkv_parse_and_add_packet(demuxer_t *demuxer, mkv_track_t *track,
if (strcmp(stream->codec->codec, "prores") == 0) {
size_t newlen = dp->len + 8;
struct demux_packet *new = new_demux_packet(newlen);
struct demux_packet *new = new_demux_packet(demuxer->global->packet_pool, newlen);
if (new) {
AV_WB32(new->buffer + 0, newlen);
AV_WB32(new->buffer + 4, MKBETAG('i', 'c', 'p', 'f'));
@ -2689,7 +2695,8 @@ static void mkv_parse_and_add_packet(demuxer_t *demuxer, mkv_track_t *track,
dp->len -= len;
dp->pos += len;
if (size) {
struct demux_packet *new = new_demux_packet_from(data, size);
struct demux_packet *new = new_demux_packet_from(demuxer->global->packet_pool,
data, size);
if (!new)
break;
if (copy_sidedata)
@ -2710,7 +2717,7 @@ static void mkv_parse_and_add_packet(demuxer_t *demuxer, mkv_track_t *track,
if (dp->len) {
add_packet(demuxer, stream, dp);
} else {
talloc_free(dp);
demux_packet_pool_push(demuxer->global->packet_pool, dp);
}
}
@ -2863,9 +2870,9 @@ static int handle_block(demuxer_t *demuxer, struct block_info *block_info)
if (block.start != nblock.start || block.len != nblock.len) {
// (avoidable copy of the entire data)
dp = new_demux_packet_from(nblock.start, nblock.len);
dp = new_demux_packet_from(demuxer->global->packet_pool, nblock.start, nblock.len);
} else {
dp = new_demux_packet_from_buf(data);
dp = new_demux_packet_from_buf(demuxer->global->packet_pool, data);
}
if (!dp)
break;

View File

@ -24,6 +24,7 @@
#include <libavutil/common.h>
#include "common/av_common.h"
#include "common/global.h"
#include "options/m_config.h"
#include "options/m_option.h"
@ -273,7 +274,8 @@ static bool raw_read_packet(struct demuxer *demuxer, struct demux_packet **pkt)
if (demuxer->stream->eof)
return false;
struct demux_packet *dp = new_demux_packet(p->frame_size * p->read_frames);
struct demux_packet *dp = new_demux_packet(demuxer->global->packet_pool,
p->frame_size * p->read_frames);
if (!dp) {
MP_ERR(demuxer, "Can't read packet.\n");
return true;

View File

@ -26,6 +26,7 @@
#include "common/av_common.h"
#include "common/common.h"
#include "demux.h"
#include "packet_pool.h"
#include "packet.h"
@ -49,9 +50,18 @@ static void packet_destroy(void *ptr)
demux_packet_unref_contents(dp);
}
static struct demux_packet *packet_create(void)
static struct demux_packet *packet_create(struct demux_packet_pool *pool)
{
struct demux_packet *dp = talloc(NULL, struct demux_packet);
struct demux_packet *dp = pool ? demux_packet_pool_pop(pool) : NULL;
struct AVPacket *avpkt = NULL;
if (dp) {
avpkt = dp->avpacket;
if (avpkt)
av_packet_unref(avpkt);
ta_free_children(dp);
} else {
dp = talloc(NULL, struct demux_packet);
}
talloc_set_destructor(dp, packet_destroy);
*dp = (struct demux_packet) {
.pts = MP_NOPTS_VALUE,
@ -61,8 +71,8 @@ static struct demux_packet *packet_create(void)
.start = MP_NOPTS_VALUE,
.end = MP_NOPTS_VALUE,
.stream = -1,
.avpacket = av_packet_alloc(),
};
dp->avpacket = avpkt ? avpkt : av_packet_alloc();
MP_HANDLE_OOM(dp->avpacket);
return dp;
}
@ -70,11 +80,12 @@ static struct demux_packet *packet_create(void)
// 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)
struct demux_packet *new_demux_packet_from_avpacket(struct demux_packet_pool *pool,
struct AVPacket *avpkt)
{
if (avpkt->size > 1000000000)
return NULL;
struct demux_packet *dp = packet_create();
struct demux_packet *dp = packet_create(pool);
int r = -1;
if (avpkt->data) {
// We hope that this function won't need/access AVPacket input padding,
@ -93,14 +104,15 @@ struct demux_packet *new_demux_packet_from_avpacket(struct AVPacket *avpkt)
}
// (buf must include proper padding)
struct demux_packet *new_demux_packet_from_buf(struct AVBufferRef *buf)
struct demux_packet *new_demux_packet_from_buf(struct demux_packet_pool *pool,
struct AVBufferRef *buf)
{
if (!buf)
return NULL;
if (buf->size > 1000000000)
return NULL;
struct demux_packet *dp = packet_create();
struct demux_packet *dp = packet_create(pool);
dp->avpacket->buf = av_buffer_ref(buf);
if (!dp->avpacket->buf) {
talloc_free(dp);
@ -112,21 +124,21 @@ struct demux_packet *new_demux_packet_from_buf(struct AVBufferRef *buf)
}
// Input data doesn't need to be padded.
struct demux_packet *new_demux_packet_from(void *data, size_t len)
struct demux_packet *new_demux_packet_from(struct demux_packet_pool *pool, void *data, size_t len)
{
struct demux_packet *dp = new_demux_packet(len);
struct demux_packet *dp = new_demux_packet(pool, len);
if (!dp)
return NULL;
memcpy(dp->avpacket->data, data, len);
return dp;
}
struct demux_packet *new_demux_packet(size_t len)
struct demux_packet *new_demux_packet(struct demux_packet_pool *pool, size_t len)
{
if (len > INT_MAX)
return NULL;
struct demux_packet *dp = packet_create();
struct demux_packet *dp = packet_create(pool);
int r = av_new_packet(dp->avpacket, len);
if (r < 0) {
talloc_free(dp);
@ -167,14 +179,14 @@ void demux_packet_copy_attribs(struct demux_packet *dst, struct demux_packet *sr
dst->stream = src->stream;
}
struct demux_packet *demux_copy_packet(struct demux_packet *dp)
struct demux_packet *demux_copy_packet(struct demux_packet_pool *pool, struct demux_packet *dp)
{
struct demux_packet *new = NULL;
if (dp->avpacket) {
new = new_demux_packet_from_avpacket(dp->avpacket);
new = new_demux_packet_from_avpacket(pool, dp->avpacket);
} else {
// Some packets might be not created by new_demux_packet*().
new = new_demux_packet_from(dp->buffer, dp->len);
new = new_demux_packet_from(pool, dp->buffer, dp->len);
}
if (!new)
return NULL;

View File

@ -71,14 +71,18 @@ typedef struct demux_packet {
} demux_packet_t;
struct AVBufferRef;
struct demux_packet_pool;
struct demux_packet *new_demux_packet(size_t len);
struct demux_packet *new_demux_packet_from_avpacket(struct AVPacket *avpkt);
struct demux_packet *new_demux_packet_from(void *data, size_t len);
struct demux_packet *new_demux_packet_from_buf(struct AVBufferRef *buf);
struct demux_packet *new_demux_packet(struct demux_packet_pool *pool, size_t len);
struct demux_packet *new_demux_packet_from_avpacket(struct demux_packet_pool *pool,
struct AVPacket *avpkt);
struct demux_packet *new_demux_packet_from(struct demux_packet_pool *pool,
void *data, size_t len);
struct demux_packet *new_demux_packet_from_buf(struct demux_packet_pool *pool,
struct AVBufferRef *buf);
void demux_packet_shorten(struct demux_packet *dp, size_t len);
void free_demux_packet(struct demux_packet *dp);
struct demux_packet *demux_copy_packet(struct demux_packet *dp);
struct demux_packet *demux_copy_packet(struct demux_packet_pool *pool, struct demux_packet *dp);
size_t demux_packet_estimate_total_size(struct demux_packet *dp);
void demux_packet_copy_attribs(struct demux_packet *dst, struct demux_packet *src);

82
demux/packet_pool.c Normal file
View File

@ -0,0 +1,82 @@
/*
* This file is part of mpv.
*
* mpv is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* mpv is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with mpv. If not, see <http://www.gnu.org/licenses/>.
*/
#include "packet_pool.h"
#include "osdep/threads.h"
#include "packet.h"
void demux_packet_pool_init(struct demux_packet_pool *pool)
{
mp_mutex_init(&pool->lock);
pool->packets = NULL;
}
void demux_packet_pool_uninit(void *p)
{
struct demux_packet_pool *pool = p;
demux_packet_pool_clear(pool);
mp_mutex_destroy(&pool->lock);
}
void demux_packet_pool_clear(struct demux_packet_pool *pool)
{
mp_mutex_lock(&pool->lock);
struct demux_packet *dp = pool->packets;
while (dp) {
struct demux_packet *next = dp->next;
free_demux_packet(dp);
dp = next;
}
pool->packets = NULL;
mp_mutex_unlock(&pool->lock);
}
void demux_packet_pool_push(struct demux_packet_pool *pool,
struct demux_packet *dp)
{
if (!dp)
return;
dp->next = NULL;
demux_packet_pool_prepend(pool, dp, dp);
}
void demux_packet_pool_prepend(struct demux_packet_pool *pool,
struct demux_packet *head, struct demux_packet *tail)
{
if (!head)
return;
assert(tail);
assert(head != tail ? !!head->next : !head->next);
mp_mutex_lock(&pool->lock);
tail->next = pool->packets;
pool->packets = head;
mp_mutex_unlock(&pool->lock);
}
struct demux_packet *demux_packet_pool_pop(struct demux_packet_pool *pool)
{
mp_mutex_lock(&pool->lock);
struct demux_packet *dp = pool->packets;
if (dp) {
pool->packets = dp->next;
dp->next = NULL;
}
mp_mutex_unlock(&pool->lock);
return dp;
}

36
demux/packet_pool.h Normal file
View File

@ -0,0 +1,36 @@
/*
* This file is part of mpv.
*
* mpv is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* mpv is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with mpv. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include "osdep/threads.h"
struct demux_packet;
struct demux_packet_pool {
mp_mutex lock;
struct demux_packet *packets;
};
void demux_packet_pool_init(struct demux_packet_pool *pool);
void demux_packet_pool_uninit(void *p);
void demux_packet_pool_clear(struct demux_packet_pool *pool);
void demux_packet_pool_push(struct demux_packet_pool *pool,
struct demux_packet *dp);
void demux_packet_pool_prepend(struct demux_packet_pool *pool,
struct demux_packet *head, struct demux_packet *tail);
struct demux_packet *demux_packet_pool_pop(struct demux_packet_pool *pool);

View File

@ -34,6 +34,7 @@
#include "demux/demux.h"
#include "demux/packet.h"
#include "demux/packet_pool.h"
#include "common/codecs.h"
#include "common/global.h"
@ -703,7 +704,8 @@ static bool process_decoded_frame(struct priv *p, struct mp_frame *frame)
crazy_video_pts_stuff(p, mpi);
struct demux_packet *ccpkt = new_demux_packet_from_buf(mpi->a53_cc);
struct demux_packet *ccpkt = new_demux_packet_from_buf(p->public.f->global->packet_pool,
mpi->a53_cc);
if (ccpkt) {
av_buffer_unref(&mpi->a53_cc);
ccpkt->pts = mpi->pts;
@ -1325,7 +1327,7 @@ void lavc_process(struct mp_filter *f, struct lavc_state *state,
return;
}
state->packets_sent = true;
talloc_free(pkt);
demux_packet_pool_push(f->global->packet_pool, pkt);
mp_filter_internal_mark_progress(f);
} else {
// Decoding error, or hwdec fallback recovery. Just try again.

View File

@ -82,7 +82,7 @@ static void *audio_from_av_ref(AVFrame *data)
static void *packet_ref(void *data)
{
return demux_copy_packet(data);
return demux_copy_packet(NULL, data);
}
static const struct frame_handler frame_handlers[] = {

View File

@ -104,6 +104,7 @@ sources = files(
'demux/demux_timeline.c',
'demux/ebml.c',
'demux/packet.c',
'demux/packet_pool.c',
'demux/timeline.c',
## Filters

View File

@ -55,6 +55,7 @@
#include "options/options.h"
#include "options/path.h"
#include "input/input.h"
#include "demux/packet_pool.h"
#include "audio/out/ao.h"
#include "misc/thread_tools.h"
@ -273,6 +274,10 @@ struct MPContext *mp_create(void)
mpctx->global = talloc_zero(mpctx, struct mpv_global);
mpctx->global->packet_pool = talloc(mpctx->global, struct demux_packet_pool);
demux_packet_pool_init(mpctx->global->packet_pool);
talloc_set_destructor(mpctx->global->packet_pool, demux_packet_pool_uninit);
stats_global_init(mpctx->global);
// Nothing must call mp_msg*() and related before this

View File

@ -23,6 +23,7 @@
#include <limits.h>
#include "demux/demux.h"
#include "demux/packet_pool.h"
#include "sd.h"
#include "dec_sub.h"
#include "options/m_config.h"
@ -127,7 +128,8 @@ static void destroy_cached_pkts(struct dec_sub *sub)
{
int index = 0;
while (index < sub->num_cached_pkts) {
TA_FREEP(&sub->cached_pkts[index]);
demux_packet_pool_push(sub->global->packet_pool, sub->cached_pkts[index]);
sub->cached_pkts[index] = NULL;
++index;
}
sub->cached_pkt_pos = 0;
@ -375,7 +377,7 @@ void sub_read_packets(struct dec_sub *sub, double video_pts, bool force,
MP_TARRAY_APPEND(sub, sub->cached_pkts, sub->num_cached_pkts, pkt);
if (is_new_segment(sub, pkt)) {
sub->new_segment = demux_copy_packet(pkt);
sub->new_segment = demux_copy_packet(sub->global->packet_pool, pkt);
// Note that this can be delayed to a much later point in time.
update_segment(sub);
break;
@ -480,7 +482,8 @@ void sub_reset(struct dec_sub *sub)
sub->last_pkt_pts = MP_NOPTS_VALUE;
sub->last_vo_pts = MP_NOPTS_VALUE;
destroy_cached_pkts(sub);
TA_FREEP(&sub->new_segment);
demux_packet_pool_push(sub->global->packet_pool, sub->new_segment);
sub->new_segment = NULL;
mp_mutex_unlock(&sub->lock);
}

View File

@ -23,6 +23,7 @@
#include "misc/ctype.h"
#include "common/common.h"
#include "common/global.h"
#include "common/msg.h"
#include "options/options.h"
#include "sd.h"
@ -483,7 +484,7 @@ static struct demux_packet *sdh_filter(struct sd_filter *ft,
// Stupidly, this copies it again. One could possibly allocate the packet
// for writing in the first place (new_demux_packet()) and use
// demux_packet_shorten().
struct demux_packet *npkt = new_demux_packet_from(line, strlen(line));
struct demux_packet *npkt = new_demux_packet_from(ft->global->packet_pool, line, strlen(line));
if (npkt)
demux_packet_copy_attribs(npkt, pkt);

View File

@ -50,6 +50,7 @@
#include "demux/demux.h"
#include "demux/stheader.h"
#include "demux/packet.h"
#include "demux/packet_pool.h"
#include "video/csputils.h"
#include "video/sws_utils.h"
#include "video/out/vo.h"
@ -1162,7 +1163,7 @@ static int send_packet(struct mp_filter *vd, struct demux_packet *pkt)
if (ctx->hw_probing && ctx->num_sent_packets < 32 &&
ctx->opts->software_fallback <= 32)
{
pkt = pkt ? demux_copy_packet(pkt) : NULL;
pkt = pkt ? demux_copy_packet(vd->global->packet_pool, pkt) : NULL;
MP_TARRAY_APPEND(ctx, ctx->sent_packets, ctx->num_sent_packets, pkt);
}
@ -1325,7 +1326,7 @@ static int receive_frame(struct mp_filter *vd, struct mp_frame *out_frame)
if (ctx->hw_probing) {
for (int n = 0; n < ctx->num_sent_packets; n++)
talloc_free(ctx->sent_packets[n]);
demux_packet_pool_push(vd->global->packet_pool, ctx->sent_packets[n]);
ctx->num_sent_packets = 0;
ctx->hw_probing = false;
}