mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-24 01:00:37 +00:00
fieldanalysis: Use RFF flag to indicate buffers to drop downstream
Use of the GAP flag is not really correct here and makes it difficult to handle real GAP buffers in deinterlace. The RFF flag is unused and can be reused with similar semantics - the buffers marked with RFF that are in a telecine state contain only unneeded repeated fields and so can be dropped.
This commit is contained in:
parent
a34108899e
commit
4cd15193bb
2 changed files with 40 additions and 39 deletions
|
@ -632,7 +632,7 @@ gst_field_analysis_set_caps (GstPad * pad, GstCaps * caps)
|
|||
* returns it */
|
||||
static GstBuffer *
|
||||
gst_field_analysis_decorate (GstFieldAnalysis * filter, gboolean tff,
|
||||
gboolean onefield, FieldAnalysisConclusion conclusion, gboolean gap)
|
||||
gboolean onefield, FieldAnalysisConclusion conclusion, gboolean drop)
|
||||
{
|
||||
GstBuffer *buf = NULL;
|
||||
GstCaps *caps;
|
||||
|
@ -676,10 +676,11 @@ gst_field_analysis_decorate (GstFieldAnalysis * filter, gboolean tff,
|
|||
GST_BUFFER_FLAG_UNSET (buf, GST_VIDEO_BUFFER_ONEFIELD);
|
||||
}
|
||||
|
||||
GST_BUFFER_FLAG_UNSET (buf, GST_VIDEO_BUFFER_RFF);
|
||||
|
||||
if (gap)
|
||||
GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_GAP);
|
||||
if (drop) {
|
||||
GST_BUFFER_FLAG_SET (buf, GST_VIDEO_BUFFER_RFF);
|
||||
} else {
|
||||
GST_BUFFER_FLAG_UNSET (buf, GST_VIDEO_BUFFER_RFF);
|
||||
}
|
||||
|
||||
if (conclusion == FIELD_ANALYSIS_TELECINE_PROGRESSIVE || (filter->is_telecine
|
||||
&& conclusion == FIELD_ANALYSIS_PROGRESSIVE))
|
||||
|
@ -706,12 +707,12 @@ gst_field_analysis_decorate (GstFieldAnalysis * filter, gboolean tff,
|
|||
gst_caps_unref (caps);
|
||||
|
||||
GST_DEBUG_OBJECT (filter,
|
||||
"Pushing buffer with flags: %p (%p), p %d, tff %d, 1f %d, gap %d; conc %d",
|
||||
"Pushing buffer with flags: %p (%p), p %d, tff %d, 1f %d, drop %d; conc %d",
|
||||
GST_BUFFER_DATA (buf), buf,
|
||||
GST_BUFFER_FLAG_IS_SET (buf, GST_VIDEO_BUFFER_PROGRESSIVE),
|
||||
GST_BUFFER_FLAG_IS_SET (buf, GST_VIDEO_BUFFER_TFF),
|
||||
GST_BUFFER_FLAG_IS_SET (buf, GST_VIDEO_BUFFER_ONEFIELD),
|
||||
GST_BUFFER_FLAG_IS_SET (buf, GST_BUFFER_FLAG_GAP), conclusion);
|
||||
GST_BUFFER_FLAG_IS_SET (buf, GST_VIDEO_BUFFER_RFF), conclusion);
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
@ -1399,7 +1400,7 @@ gst_field_analysis_process_buffer (GstFieldAnalysis * filter,
|
|||
res0->conclusion = FIELD_ANALYSIS_INTERLACED;
|
||||
}
|
||||
res0->holding = -1; /* needed fields unknown */
|
||||
res0->gap = FALSE;
|
||||
res0->drop = FALSE;
|
||||
}
|
||||
|
||||
if (n_queued >= 2) {
|
||||
|
@ -1454,11 +1455,11 @@ gst_field_analysis_process_buffer (GstFieldAnalysis * filter,
|
|||
/* prev P, cur repeated => cur P */
|
||||
res0->conclusion = FIELD_ANALYSIS_TELECINE_PROGRESSIVE;
|
||||
res0->holding = 1 + BOTH_FIELDS;
|
||||
/* push prev P, GAP */
|
||||
res1->gap = TRUE;
|
||||
/* push prev P, RFF */
|
||||
res1->drop = TRUE;
|
||||
outbuf =
|
||||
gst_field_analysis_decorate (filter, -1, FALSE, res1->conclusion,
|
||||
res1->gap);
|
||||
res1->drop);
|
||||
} else {
|
||||
/* prev P, cur t xor b matches => cur TCM */
|
||||
res0->conclusion = FIELD_ANALYSIS_TELECINE_MIXED;
|
||||
|
@ -1467,7 +1468,7 @@ gst_field_analysis_process_buffer (GstFieldAnalysis * filter,
|
|||
/* push prev P */
|
||||
outbuf =
|
||||
gst_field_analysis_decorate (filter, -1, FALSE, res1->conclusion,
|
||||
res1->gap);
|
||||
res1->drop);
|
||||
}
|
||||
} else {
|
||||
/* prev !P */
|
||||
|
@ -1508,7 +1509,7 @@ gst_field_analysis_process_buffer (GstFieldAnalysis * filter,
|
|||
/* push 1F held field */
|
||||
outbuf =
|
||||
gst_field_analysis_decorate (filter, !(res1->holding - 1), TRUE,
|
||||
res1->conclusion, res1->gap);
|
||||
res1->conclusion, res1->drop);
|
||||
} else if (res0->f > filter->frame_thresh && ((t
|
||||
&& telecine_matches & FIELD_ANALYSIS_BOTTOM_TOP) || (b
|
||||
&& telecine_matches & FIELD_ANALYSIS_TOP_BOTTOM))) {
|
||||
|
@ -1523,7 +1524,7 @@ gst_field_analysis_process_buffer (GstFieldAnalysis * filter,
|
|||
/* push 1F held field */
|
||||
outbuf =
|
||||
gst_field_analysis_decorate (filter, !(res1->holding - 1), TRUE,
|
||||
res1->conclusion, res1->gap);
|
||||
res1->conclusion, res1->drop);
|
||||
} else if (first_buffer && (telecine_matches & FIELD_ANALYSIS_BOTTOM_TOP
|
||||
|| telecine_matches & FIELD_ANALYSIS_TOP_BOTTOM)) {
|
||||
/* non-matched field is an orphan in the first buffer - push orphan as 1F */
|
||||
|
@ -1533,18 +1534,18 @@ gst_field_analysis_process_buffer (GstFieldAnalysis * filter,
|
|||
/* push 1F held field */
|
||||
outbuf =
|
||||
gst_field_analysis_decorate (filter, !(res1->holding - 1), TRUE,
|
||||
res1->conclusion, res1->gap);
|
||||
res1->conclusion, res1->drop);
|
||||
} else if (res1->holding == 1 + BOTH_FIELDS || res1->holding == -1) {
|
||||
/* holding both fields, push prev as is */
|
||||
outbuf =
|
||||
gst_field_analysis_decorate (filter, -1, FALSE, res1->conclusion,
|
||||
res1->gap);
|
||||
res1->drop);
|
||||
} else {
|
||||
/* push prev as is with GAP */
|
||||
res1->gap = TRUE;
|
||||
/* push prev as is with RFF */
|
||||
res1->drop = TRUE;
|
||||
outbuf =
|
||||
gst_field_analysis_decorate (filter, -1, FALSE, res1->conclusion,
|
||||
res1->gap);
|
||||
res1->drop);
|
||||
}
|
||||
}
|
||||
} else if (res0->f <= filter->frame_thresh) {
|
||||
|
@ -1555,19 +1556,19 @@ gst_field_analysis_process_buffer (GstFieldAnalysis * filter,
|
|||
/* holding both fields, push prev as is */
|
||||
outbuf =
|
||||
gst_field_analysis_decorate (filter, -1, FALSE, res1->conclusion,
|
||||
res1->gap);
|
||||
res1->drop);
|
||||
} else if (res1->holding > 0) {
|
||||
/* holding one field, push prev 1F held */
|
||||
outbuf =
|
||||
gst_field_analysis_decorate (filter, !(res1->holding - 1), TRUE,
|
||||
res1->conclusion, res1->gap);
|
||||
res1->conclusion, res1->drop);
|
||||
} else {
|
||||
/* unknown or no fields held, push prev as is with GAP */
|
||||
/* this will push unknown as gap - should be pushed as not gap? */
|
||||
res1->gap = TRUE;
|
||||
/* unknown or no fields held, push prev as is with RFF */
|
||||
/* this will push unknown as drop - should be pushed as not drop? */
|
||||
res1->drop = TRUE;
|
||||
outbuf =
|
||||
gst_field_analysis_decorate (filter, -1, FALSE, res1->conclusion,
|
||||
res1->gap);
|
||||
res1->drop);
|
||||
}
|
||||
} else {
|
||||
/* cur !P */
|
||||
|
@ -1590,7 +1591,7 @@ gst_field_analysis_process_buffer (GstFieldAnalysis * filter,
|
|||
/* push prev as is */
|
||||
outbuf =
|
||||
gst_field_analysis_decorate (filter, -1, FALSE, res1->conclusion,
|
||||
res1->gap);
|
||||
res1->drop);
|
||||
} else if ((t && telecine_matches & FIELD_ANALYSIS_TOP_BOTTOM) || (b
|
||||
&& telecine_matches & FIELD_ANALYSIS_BOTTOM_TOP)) {
|
||||
/* held is opposite to matched => need both field from prev */
|
||||
|
@ -1600,47 +1601,47 @@ gst_field_analysis_process_buffer (GstFieldAnalysis * filter,
|
|||
/* push prev TCM */
|
||||
outbuf =
|
||||
gst_field_analysis_decorate (filter, -1, FALSE, res1->conclusion,
|
||||
res1->gap);
|
||||
res1->drop);
|
||||
} else if ((res1->holding > 0 && res1->holding != 1 + BOTH_FIELDS) || (t
|
||||
&& telecine_matches & FIELD_ANALYSIS_BOTTOM_TOP) || (b
|
||||
&& telecine_matches & FIELD_ANALYSIS_TOP_BOTTOM)) {
|
||||
/* held field is needed, push prev 1F held */
|
||||
outbuf =
|
||||
gst_field_analysis_decorate (filter, !(res1->holding - 1), TRUE,
|
||||
res1->conclusion, res1->gap);
|
||||
res1->conclusion, res1->drop);
|
||||
} else {
|
||||
/* holding none or unknown */
|
||||
/* push prev as is with GAP */
|
||||
res1->gap = TRUE;
|
||||
/* push prev as is with RFF */
|
||||
res1->drop = TRUE;
|
||||
outbuf =
|
||||
gst_field_analysis_decorate (filter, -1, FALSE, res1->conclusion,
|
||||
res1->gap);
|
||||
res1->drop);
|
||||
}
|
||||
} else {
|
||||
/* cur I */
|
||||
res0->conclusion = FIELD_ANALYSIS_INTERLACED;
|
||||
res0->holding = 1 + BOTH_FIELDS;
|
||||
/* push prev appropriately */
|
||||
res1->gap = res1->holding <= 0;
|
||||
res1->drop = res1->holding <= 0;
|
||||
if (res1->holding != 0) {
|
||||
res1->gap = FALSE;
|
||||
res1->drop = FALSE;
|
||||
if (res1->holding == 1 + BOTH_FIELDS || res1->holding == -1) {
|
||||
/* push prev as is */
|
||||
outbuf =
|
||||
gst_field_analysis_decorate (filter, -1, FALSE,
|
||||
res1->conclusion, res1->gap);
|
||||
res1->conclusion, res1->drop);
|
||||
} else {
|
||||
/* push prev 1F held */
|
||||
outbuf =
|
||||
gst_field_analysis_decorate (filter, !(res1->holding - 1), TRUE,
|
||||
res1->conclusion, res1->gap);
|
||||
res1->conclusion, res1->drop);
|
||||
}
|
||||
} else {
|
||||
/* push prev as is with GAP */
|
||||
res1->gap = TRUE;
|
||||
/* push prev as is with RFF */
|
||||
res1->drop = TRUE;
|
||||
outbuf =
|
||||
gst_field_analysis_decorate (filter, -1, FALSE, res1->conclusion,
|
||||
res1->gap);
|
||||
res1->drop);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -91,7 +91,7 @@ struct _FieldAnalysis
|
|||
FieldAnalysisConclusion conclusion;
|
||||
/* -1 - unknown; 0 - holding none; 1 - top field; 2 - bottom field; 3 - both */
|
||||
gint holding;
|
||||
gboolean gap;
|
||||
gboolean drop;
|
||||
};
|
||||
|
||||
typedef enum
|
||||
|
|
Loading…
Reference in a new issue