mirror of https://git.ffmpeg.org/ffmpeg.git
avfilter/yadif_common: Add field type tracking to help bwdif
The bwdif filter can use common yadif frame management if we track when a field is the first or last field in a sequence. While this information is not used by yadif, the added benefit of removing the duplicated frame management logic makes it worth tracking this state in the common code.
This commit is contained in:
parent
19d3d0c057
commit
fa74e4aef2
|
@ -41,6 +41,12 @@ enum YADIFDeint {
|
||||||
YADIF_DEINT_INTERLACED = 1, ///< only deinterlace frames marked as interlaced
|
YADIF_DEINT_INTERLACED = 1, ///< only deinterlace frames marked as interlaced
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum YADIFCurrentField {
|
||||||
|
YADIF_FIELD_BACK_END = -1, ///< The last frame in a sequence
|
||||||
|
YADIF_FIELD_END = 0, ///< The first or last field in a sequence
|
||||||
|
YADIF_FIELD_NORMAL = 1, ///< A normal field in the middle of a sequence
|
||||||
|
};
|
||||||
|
|
||||||
typedef struct YADIFContext {
|
typedef struct YADIFContext {
|
||||||
const AVClass *class;
|
const AVClass *class;
|
||||||
|
|
||||||
|
@ -70,6 +76,14 @@ typedef struct YADIFContext {
|
||||||
int eof;
|
int eof;
|
||||||
uint8_t *temp_line;
|
uint8_t *temp_line;
|
||||||
int temp_line_size;
|
int temp_line_size;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* An algorithm that treats first and/or last fields in a sequence
|
||||||
|
* differently can use this to detect those cases. It is the algorithm's
|
||||||
|
* responsibility to set the value to YADIF_FIELD_NORMAL after processing
|
||||||
|
* the first field.
|
||||||
|
*/
|
||||||
|
int current_field; ///< YADIFCurrentField
|
||||||
} YADIFContext;
|
} YADIFContext;
|
||||||
|
|
||||||
void ff_yadif_init_x86(YADIFContext *yadif);
|
void ff_yadif_init_x86(YADIFContext *yadif);
|
||||||
|
|
|
@ -44,6 +44,8 @@ static int return_frame(AVFilterContext *ctx, int is_second)
|
||||||
|
|
||||||
av_frame_copy_props(yadif->out, yadif->cur);
|
av_frame_copy_props(yadif->out, yadif->cur);
|
||||||
yadif->out->interlaced_frame = 0;
|
yadif->out->interlaced_frame = 0;
|
||||||
|
if (yadif->current_field == YADIF_FIELD_BACK_END)
|
||||||
|
yadif->current_field = YADIF_FIELD_END;
|
||||||
}
|
}
|
||||||
|
|
||||||
yadif->filter(ctx, yadif->out, tff ^ !is_second, tff);
|
yadif->filter(ctx, yadif->out, tff ^ !is_second, tff);
|
||||||
|
@ -103,9 +105,12 @@ int ff_yadif_filter_frame(AVFilterLink *link, AVFrame *frame)
|
||||||
yadif->cur = yadif->next;
|
yadif->cur = yadif->next;
|
||||||
yadif->next = frame;
|
yadif->next = frame;
|
||||||
|
|
||||||
if (!yadif->cur &&
|
if (!yadif->cur) {
|
||||||
!(yadif->cur = av_frame_clone(yadif->next)))
|
yadif->cur = av_frame_clone(yadif->next);
|
||||||
return AVERROR(ENOMEM);
|
if (!yadif->cur)
|
||||||
|
return AVERROR(ENOMEM);
|
||||||
|
yadif->current_field = YADIF_FIELD_END;
|
||||||
|
}
|
||||||
|
|
||||||
if (checkstride(yadif, yadif->next, yadif->cur)) {
|
if (checkstride(yadif, yadif->next, yadif->cur)) {
|
||||||
av_log(ctx, AV_LOG_VERBOSE, "Reallocating frame due to differing stride\n");
|
av_log(ctx, AV_LOG_VERBOSE, "Reallocating frame due to differing stride\n");
|
||||||
|
@ -173,6 +178,7 @@ int ff_yadif_request_frame(AVFilterLink *link)
|
||||||
if (!next)
|
if (!next)
|
||||||
return AVERROR(ENOMEM);
|
return AVERROR(ENOMEM);
|
||||||
|
|
||||||
|
yadif->current_field = YADIF_FIELD_BACK_END;
|
||||||
next->pts = yadif->next->pts * 2 - yadif->cur->pts;
|
next->pts = yadif->next->pts * 2 - yadif->cur->pts;
|
||||||
|
|
||||||
ff_yadif_filter_frame(ctx->inputs[0], next);
|
ff_yadif_filter_frame(ctx->inputs[0], next);
|
||||||
|
|
Loading…
Reference in New Issue