mirror of https://git.ffmpeg.org/ffmpeg.git
fftools/ffmpeg_filter: move filtering to a separate thread
As previously for decoding, this is merely "scaffolding" for moving to a fully threaded architecture and does not yet make filtering truly parallel - the main thread will currently wait for the filtering thread to finish its work before continuing. That will change in future commits after encoders are also moved to threads and a thread-aware scheduler is added.
This commit is contained in:
parent
4b8a171beb
commit
d35c05cb9e
|
@ -80,6 +80,14 @@ enum HWAccelID {
|
||||||
HWACCEL_GENERIC,
|
HWACCEL_GENERIC,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum FrameOpaque {
|
||||||
|
FRAME_OPAQUE_REAP_FILTERS = 1,
|
||||||
|
FRAME_OPAQUE_CHOOSE_INPUT,
|
||||||
|
FRAME_OPAQUE_SUB_HEARTBEAT,
|
||||||
|
FRAME_OPAQUE_EOF,
|
||||||
|
FRAME_OPAQUE_SEND_COMMAND,
|
||||||
|
};
|
||||||
|
|
||||||
typedef struct HWDevice {
|
typedef struct HWDevice {
|
||||||
const char *name;
|
const char *name;
|
||||||
enum AVHWDeviceType type;
|
enum AVHWDeviceType type;
|
||||||
|
@ -730,7 +738,6 @@ const FrameData *frame_data_c(AVFrame *frame);
|
||||||
|
|
||||||
int ifilter_send_frame(InputFilter *ifilter, AVFrame *frame, int keep_reference);
|
int ifilter_send_frame(InputFilter *ifilter, AVFrame *frame, int keep_reference);
|
||||||
int ifilter_send_eof(InputFilter *ifilter, int64_t pts, AVRational tb);
|
int ifilter_send_eof(InputFilter *ifilter, int64_t pts, AVRational tb);
|
||||||
int ifilter_sub2video(InputFilter *ifilter, const AVFrame *frame);
|
|
||||||
void ifilter_sub2video_heartbeat(InputFilter *ifilter, int64_t pts, AVRational tb);
|
void ifilter_sub2video_heartbeat(InputFilter *ifilter, int64_t pts, AVRational tb);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -147,11 +147,12 @@ fail:
|
||||||
|
|
||||||
static int send_frame_to_filters(InputStream *ist, AVFrame *decoded_frame)
|
static int send_frame_to_filters(InputStream *ist, AVFrame *decoded_frame)
|
||||||
{
|
{
|
||||||
int i, ret;
|
int i, ret = 0;
|
||||||
|
|
||||||
av_assert1(ist->nb_filters > 0); /* ensure ret is initialized */
|
|
||||||
for (i = 0; i < ist->nb_filters; i++) {
|
for (i = 0; i < ist->nb_filters; i++) {
|
||||||
ret = ifilter_send_frame(ist->filters[i], decoded_frame, i < ist->nb_filters - 1);
|
ret = ifilter_send_frame(ist->filters[i], decoded_frame,
|
||||||
|
i < ist->nb_filters - 1 ||
|
||||||
|
ist->dec->type == AVMEDIA_TYPE_SUBTITLE);
|
||||||
if (ret == AVERROR_EOF)
|
if (ret == AVERROR_EOF)
|
||||||
ret = 0; /* ignore */
|
ret = 0; /* ignore */
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
|
@ -380,15 +381,6 @@ static int video_frame_process(InputStream *ist, AVFrame *frame)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void sub2video_flush(InputStream *ist)
|
|
||||||
{
|
|
||||||
for (int i = 0; i < ist->nb_filters; i++) {
|
|
||||||
int ret = ifilter_sub2video(ist->filters[i], NULL);
|
|
||||||
if (ret != AVERROR_EOF && ret < 0)
|
|
||||||
av_log(NULL, AV_LOG_WARNING, "Flush the frame error.\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static int process_subtitle(InputStream *ist, AVFrame *frame)
|
static int process_subtitle(InputStream *ist, AVFrame *frame)
|
||||||
{
|
{
|
||||||
Decoder *d = ist->decoder;
|
Decoder *d = ist->decoder;
|
||||||
|
@ -426,14 +418,9 @@ static int process_subtitle(InputStream *ist, AVFrame *frame)
|
||||||
if (!subtitle)
|
if (!subtitle)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
for (int i = 0; i < ist->nb_filters; i++) {
|
ret = send_frame_to_filters(ist, frame);
|
||||||
ret = ifilter_sub2video(ist->filters[i], frame);
|
if (ret < 0)
|
||||||
if (ret < 0) {
|
return ret;
|
||||||
av_log(ist, AV_LOG_ERROR, "Error sending a subtitle for filtering: %s\n",
|
|
||||||
av_err2str(ret));
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
subtitle = (AVSubtitle*)frame->buf[0]->data;
|
subtitle = (AVSubtitle*)frame->buf[0]->data;
|
||||||
if (!subtitle->num_rects)
|
if (!subtitle->num_rects)
|
||||||
|
@ -824,14 +811,10 @@ finish:
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
// signal EOF to our downstreams
|
// signal EOF to our downstreams
|
||||||
if (ist->dec->type == AVMEDIA_TYPE_SUBTITLE)
|
ret = send_filter_eof(ist);
|
||||||
sub2video_flush(ist);
|
if (ret < 0) {
|
||||||
else {
|
av_log(NULL, AV_LOG_FATAL, "Error marking filters as finished\n");
|
||||||
ret = send_filter_eof(ist);
|
return ret;
|
||||||
if (ret < 0) {
|
|
||||||
av_log(NULL, AV_LOG_FATAL, "Error marking filters as finished\n");
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return AVERROR_EOF;
|
return AVERROR_EOF;
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue