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:
parent
50448ca290
commit
6cb7295abf
@ -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;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user