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,
|
||||
};
|
||||
|
||||
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 {
|
||||
const char *name;
|
||||
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_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);
|
||||
|
||||
/**
|
||||
|
|
|
@ -147,11 +147,12 @@ fail:
|
|||
|
||||
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++) {
|
||||
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)
|
||||
ret = 0; /* ignore */
|
||||
if (ret < 0) {
|
||||
|
@ -380,15 +381,6 @@ static int video_frame_process(InputStream *ist, AVFrame *frame)
|
|||
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)
|
||||
{
|
||||
Decoder *d = ist->decoder;
|
||||
|
@ -426,14 +418,9 @@ static int process_subtitle(InputStream *ist, AVFrame *frame)
|
|||
if (!subtitle)
|
||||
return 0;
|
||||
|
||||
for (int i = 0; i < ist->nb_filters; i++) {
|
||||
ret = ifilter_sub2video(ist->filters[i], frame);
|
||||
if (ret < 0) {
|
||||
av_log(ist, AV_LOG_ERROR, "Error sending a subtitle for filtering: %s\n",
|
||||
av_err2str(ret));
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
ret = send_frame_to_filters(ist, frame);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
subtitle = (AVSubtitle*)frame->buf[0]->data;
|
||||
if (!subtitle->num_rects)
|
||||
|
@ -824,14 +811,10 @@ finish:
|
|||
return ret;
|
||||
|
||||
// signal EOF to our downstreams
|
||||
if (ist->dec->type == AVMEDIA_TYPE_SUBTITLE)
|
||||
sub2video_flush(ist);
|
||||
else {
|
||||
ret = send_filter_eof(ist);
|
||||
if (ret < 0) {
|
||||
av_log(NULL, AV_LOG_FATAL, "Error marking filters as finished\n");
|
||||
return ret;
|
||||
}
|
||||
ret = send_filter_eof(ist);
|
||||
if (ret < 0) {
|
||||
av_log(NULL, AV_LOG_FATAL, "Error marking filters as finished\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
return AVERROR_EOF;
|
||||
|
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue