1
0
mirror of https://github.com/FFmpeg/FFmpeg.git synced 2025-01-03 05:10:03 +02:00

fftools/ffmpeg_demux: add demuxing thread private data

To be used for data that never needs to be visible outside of the
demuxer thread, similarly as was previously done for other components.
This commit is contained in:
Anton Khirnov 2024-01-05 12:22:53 +01:00
parent 50448ca290
commit 6cb7295abf

View File

@ -115,6 +115,11 @@ typedef struct Demuxer {
int nb_streams_finished; int nb_streams_finished;
} Demuxer; } Demuxer;
typedef struct DemuxThreadContext {
// packet used for reading from the demuxer
AVPacket *pkt_demux;
} DemuxThreadContext;
static DemuxStream *ds_from_ist(InputStream *ist) static DemuxStream *ds_from_ist(InputStream *ist)
{ {
return (DemuxStream*)ist; return (DemuxStream*)ist;
@ -565,18 +570,36 @@ static void thread_set_name(InputFile *f)
ff_thread_setname(name); ff_thread_setname(name);
} }
static void demux_thread_uninit(DemuxThreadContext *dt)
{
av_packet_free(&dt->pkt_demux);
memset(dt, 0, sizeof(*dt));
}
static int demux_thread_init(DemuxThreadContext *dt)
{
memset(dt, 0, sizeof(*dt));
dt->pkt_demux = av_packet_alloc();
if (!dt->pkt_demux)
return AVERROR(ENOMEM);
return 0;
}
static void *input_thread(void *arg) static void *input_thread(void *arg)
{ {
Demuxer *d = arg; Demuxer *d = arg;
InputFile *f = &d->f; InputFile *f = &d->f;
AVPacket *pkt;
DemuxThreadContext dt;
int ret = 0; int ret = 0;
pkt = av_packet_alloc(); ret = demux_thread_init(&dt);
if (!pkt) { if (ret < 0)
ret = AVERROR(ENOMEM);
goto finish; goto finish;
}
thread_set_name(f); thread_set_name(f);
@ -589,7 +612,7 @@ static void *input_thread(void *arg)
DemuxStream *ds; DemuxStream *ds;
unsigned send_flags = 0; unsigned send_flags = 0;
ret = av_read_frame(f->ctx, pkt); ret = av_read_frame(f->ctx, dt.pkt_demux);
if (ret == AVERROR(EAGAIN)) { if (ret == AVERROR(EAGAIN)) {
av_usleep(10000); av_usleep(10000);
@ -598,12 +621,12 @@ static void *input_thread(void *arg)
if (ret < 0) { if (ret < 0) {
if (d->loop) { if (d->loop) {
/* signal looping to our consumers */ /* signal looping to our consumers */
pkt->stream_index = -1; dt.pkt_demux->stream_index = -1;
ret = sch_demux_send(d->sch, f->index, pkt, 0); ret = sch_demux_send(d->sch, f->index, dt.pkt_demux, 0);
if (ret >= 0) if (ret >= 0)
ret = seek_to_start(d, (Timestamp){ .ts = pkt->pts, ret = seek_to_start(d, (Timestamp){ .ts = dt.pkt_demux->pts,
.tb = pkt->time_base }); .tb = dt.pkt_demux->time_base });
if (ret >= 0) if (ret >= 0)
continue; continue;
@ -622,39 +645,39 @@ static void *input_thread(void *arg)
} }
if (do_pkt_dump) { if (do_pkt_dump) {
av_pkt_dump_log2(NULL, AV_LOG_INFO, pkt, do_hex_dump, av_pkt_dump_log2(NULL, AV_LOG_INFO, dt.pkt_demux, do_hex_dump,
f->ctx->streams[pkt->stream_index]); f->ctx->streams[dt.pkt_demux->stream_index]);
} }
/* the following test is needed in case new streams appear /* the following test is needed in case new streams appear
dynamically in stream : we ignore them */ dynamically in stream : we ignore them */
ds = pkt->stream_index < f->nb_streams ? ds = dt.pkt_demux->stream_index < f->nb_streams ?
ds_from_ist(f->streams[pkt->stream_index]) : NULL; ds_from_ist(f->streams[dt.pkt_demux->stream_index]) : NULL;
if (!ds || ds->discard || ds->finished) { if (!ds || ds->discard || ds->finished) {
report_new_stream(d, pkt); report_new_stream(d, dt.pkt_demux);
av_packet_unref(pkt); av_packet_unref(dt.pkt_demux);
continue; continue;
} }
if (pkt->flags & AV_PKT_FLAG_CORRUPT) { if (dt.pkt_demux->flags & AV_PKT_FLAG_CORRUPT) {
av_log(d, exit_on_error ? AV_LOG_FATAL : AV_LOG_WARNING, av_log(d, exit_on_error ? AV_LOG_FATAL : AV_LOG_WARNING,
"corrupt input packet in stream %d\n", "corrupt input packet in stream %d\n",
pkt->stream_index); dt.pkt_demux->stream_index);
if (exit_on_error) { if (exit_on_error) {
av_packet_unref(pkt); av_packet_unref(dt.pkt_demux);
ret = AVERROR_INVALIDDATA; ret = AVERROR_INVALIDDATA;
break; break;
} }
} }
ret = input_packet_process(d, pkt, &send_flags); ret = input_packet_process(d, dt.pkt_demux, &send_flags);
if (ret < 0) if (ret < 0)
break; break;
if (d->readrate) if (d->readrate)
readrate_sleep(d); readrate_sleep(d);
ret = demux_send(d, ds, pkt, send_flags); ret = demux_send(d, ds, dt.pkt_demux, send_flags);
if (ret < 0) if (ret < 0)
break; break;
} }
@ -664,7 +687,7 @@ static void *input_thread(void *arg)
ret = 0; ret = 0;
finish: finish:
av_packet_free(&pkt); demux_thread_uninit(&dt);
return (void*)(intptr_t)ret; return (void*)(intptr_t)ret;
} }