mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-01-11 18:05: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 */
|
* returns it */
|
||||||
static GstBuffer *
|
static GstBuffer *
|
||||||
gst_field_analysis_decorate (GstFieldAnalysis * filter, gboolean tff,
|
gst_field_analysis_decorate (GstFieldAnalysis * filter, gboolean tff,
|
||||||
gboolean onefield, FieldAnalysisConclusion conclusion, gboolean gap)
|
gboolean onefield, FieldAnalysisConclusion conclusion, gboolean drop)
|
||||||
{
|
{
|
||||||
GstBuffer *buf = NULL;
|
GstBuffer *buf = NULL;
|
||||||
GstCaps *caps;
|
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_ONEFIELD);
|
||||||
}
|
}
|
||||||
|
|
||||||
GST_BUFFER_FLAG_UNSET (buf, GST_VIDEO_BUFFER_RFF);
|
if (drop) {
|
||||||
|
GST_BUFFER_FLAG_SET (buf, GST_VIDEO_BUFFER_RFF);
|
||||||
if (gap)
|
} else {
|
||||||
GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_GAP);
|
GST_BUFFER_FLAG_UNSET (buf, GST_VIDEO_BUFFER_RFF);
|
||||||
|
}
|
||||||
|
|
||||||
if (conclusion == FIELD_ANALYSIS_TELECINE_PROGRESSIVE || (filter->is_telecine
|
if (conclusion == FIELD_ANALYSIS_TELECINE_PROGRESSIVE || (filter->is_telecine
|
||||||
&& conclusion == FIELD_ANALYSIS_PROGRESSIVE))
|
&& conclusion == FIELD_ANALYSIS_PROGRESSIVE))
|
||||||
|
@ -706,12 +707,12 @@ gst_field_analysis_decorate (GstFieldAnalysis * filter, gboolean tff,
|
||||||
gst_caps_unref (caps);
|
gst_caps_unref (caps);
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (filter,
|
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_DATA (buf), buf,
|
||||||
GST_BUFFER_FLAG_IS_SET (buf, GST_VIDEO_BUFFER_PROGRESSIVE),
|
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_TFF),
|
||||||
GST_BUFFER_FLAG_IS_SET (buf, GST_VIDEO_BUFFER_ONEFIELD),
|
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;
|
return buf;
|
||||||
}
|
}
|
||||||
|
@ -1399,7 +1400,7 @@ gst_field_analysis_process_buffer (GstFieldAnalysis * filter,
|
||||||
res0->conclusion = FIELD_ANALYSIS_INTERLACED;
|
res0->conclusion = FIELD_ANALYSIS_INTERLACED;
|
||||||
}
|
}
|
||||||
res0->holding = -1; /* needed fields unknown */
|
res0->holding = -1; /* needed fields unknown */
|
||||||
res0->gap = FALSE;
|
res0->drop = FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (n_queued >= 2) {
|
if (n_queued >= 2) {
|
||||||
|
@ -1454,11 +1455,11 @@ gst_field_analysis_process_buffer (GstFieldAnalysis * filter,
|
||||||
/* prev P, cur repeated => cur P */
|
/* prev P, cur repeated => cur P */
|
||||||
res0->conclusion = FIELD_ANALYSIS_TELECINE_PROGRESSIVE;
|
res0->conclusion = FIELD_ANALYSIS_TELECINE_PROGRESSIVE;
|
||||||
res0->holding = 1 + BOTH_FIELDS;
|
res0->holding = 1 + BOTH_FIELDS;
|
||||||
/* push prev P, GAP */
|
/* push prev P, RFF */
|
||||||
res1->gap = TRUE;
|
res1->drop = TRUE;
|
||||||
outbuf =
|
outbuf =
|
||||||
gst_field_analysis_decorate (filter, -1, FALSE, res1->conclusion,
|
gst_field_analysis_decorate (filter, -1, FALSE, res1->conclusion,
|
||||||
res1->gap);
|
res1->drop);
|
||||||
} else {
|
} else {
|
||||||
/* prev P, cur t xor b matches => cur TCM */
|
/* prev P, cur t xor b matches => cur TCM */
|
||||||
res0->conclusion = FIELD_ANALYSIS_TELECINE_MIXED;
|
res0->conclusion = FIELD_ANALYSIS_TELECINE_MIXED;
|
||||||
|
@ -1467,7 +1468,7 @@ gst_field_analysis_process_buffer (GstFieldAnalysis * filter,
|
||||||
/* push prev P */
|
/* push prev P */
|
||||||
outbuf =
|
outbuf =
|
||||||
gst_field_analysis_decorate (filter, -1, FALSE, res1->conclusion,
|
gst_field_analysis_decorate (filter, -1, FALSE, res1->conclusion,
|
||||||
res1->gap);
|
res1->drop);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
/* prev !P */
|
/* prev !P */
|
||||||
|
@ -1508,7 +1509,7 @@ gst_field_analysis_process_buffer (GstFieldAnalysis * filter,
|
||||||
/* push 1F held field */
|
/* push 1F held field */
|
||||||
outbuf =
|
outbuf =
|
||||||
gst_field_analysis_decorate (filter, !(res1->holding - 1), TRUE,
|
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
|
} else if (res0->f > filter->frame_thresh && ((t
|
||||||
&& telecine_matches & FIELD_ANALYSIS_BOTTOM_TOP) || (b
|
&& telecine_matches & FIELD_ANALYSIS_BOTTOM_TOP) || (b
|
||||||
&& telecine_matches & FIELD_ANALYSIS_TOP_BOTTOM))) {
|
&& telecine_matches & FIELD_ANALYSIS_TOP_BOTTOM))) {
|
||||||
|
@ -1523,7 +1524,7 @@ gst_field_analysis_process_buffer (GstFieldAnalysis * filter,
|
||||||
/* push 1F held field */
|
/* push 1F held field */
|
||||||
outbuf =
|
outbuf =
|
||||||
gst_field_analysis_decorate (filter, !(res1->holding - 1), TRUE,
|
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
|
} else if (first_buffer && (telecine_matches & FIELD_ANALYSIS_BOTTOM_TOP
|
||||||
|| telecine_matches & FIELD_ANALYSIS_TOP_BOTTOM)) {
|
|| telecine_matches & FIELD_ANALYSIS_TOP_BOTTOM)) {
|
||||||
/* non-matched field is an orphan in the first buffer - push orphan as 1F */
|
/* 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 */
|
/* push 1F held field */
|
||||||
outbuf =
|
outbuf =
|
||||||
gst_field_analysis_decorate (filter, !(res1->holding - 1), TRUE,
|
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) {
|
} else if (res1->holding == 1 + BOTH_FIELDS || res1->holding == -1) {
|
||||||
/* holding both fields, push prev as is */
|
/* holding both fields, push prev as is */
|
||||||
outbuf =
|
outbuf =
|
||||||
gst_field_analysis_decorate (filter, -1, FALSE, res1->conclusion,
|
gst_field_analysis_decorate (filter, -1, FALSE, res1->conclusion,
|
||||||
res1->gap);
|
res1->drop);
|
||||||
} else {
|
} else {
|
||||||
/* push prev as is with GAP */
|
/* push prev as is with RFF */
|
||||||
res1->gap = TRUE;
|
res1->drop = TRUE;
|
||||||
outbuf =
|
outbuf =
|
||||||
gst_field_analysis_decorate (filter, -1, FALSE, res1->conclusion,
|
gst_field_analysis_decorate (filter, -1, FALSE, res1->conclusion,
|
||||||
res1->gap);
|
res1->drop);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (res0->f <= filter->frame_thresh) {
|
} 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 */
|
/* holding both fields, push prev as is */
|
||||||
outbuf =
|
outbuf =
|
||||||
gst_field_analysis_decorate (filter, -1, FALSE, res1->conclusion,
|
gst_field_analysis_decorate (filter, -1, FALSE, res1->conclusion,
|
||||||
res1->gap);
|
res1->drop);
|
||||||
} else if (res1->holding > 0) {
|
} else if (res1->holding > 0) {
|
||||||
/* holding one field, push prev 1F held */
|
/* holding one field, push prev 1F held */
|
||||||
outbuf =
|
outbuf =
|
||||||
gst_field_analysis_decorate (filter, !(res1->holding - 1), TRUE,
|
gst_field_analysis_decorate (filter, !(res1->holding - 1), TRUE,
|
||||||
res1->conclusion, res1->gap);
|
res1->conclusion, res1->drop);
|
||||||
} else {
|
} else {
|
||||||
/* unknown or no fields held, push prev as is with GAP */
|
/* unknown or no fields held, push prev as is with RFF */
|
||||||
/* this will push unknown as gap - should be pushed as not gap? */
|
/* this will push unknown as drop - should be pushed as not drop? */
|
||||||
res1->gap = TRUE;
|
res1->drop = TRUE;
|
||||||
outbuf =
|
outbuf =
|
||||||
gst_field_analysis_decorate (filter, -1, FALSE, res1->conclusion,
|
gst_field_analysis_decorate (filter, -1, FALSE, res1->conclusion,
|
||||||
res1->gap);
|
res1->drop);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
/* cur !P */
|
/* cur !P */
|
||||||
|
@ -1590,7 +1591,7 @@ gst_field_analysis_process_buffer (GstFieldAnalysis * filter,
|
||||||
/* push prev as is */
|
/* push prev as is */
|
||||||
outbuf =
|
outbuf =
|
||||||
gst_field_analysis_decorate (filter, -1, FALSE, res1->conclusion,
|
gst_field_analysis_decorate (filter, -1, FALSE, res1->conclusion,
|
||||||
res1->gap);
|
res1->drop);
|
||||||
} else if ((t && telecine_matches & FIELD_ANALYSIS_TOP_BOTTOM) || (b
|
} else if ((t && telecine_matches & FIELD_ANALYSIS_TOP_BOTTOM) || (b
|
||||||
&& telecine_matches & FIELD_ANALYSIS_BOTTOM_TOP)) {
|
&& telecine_matches & FIELD_ANALYSIS_BOTTOM_TOP)) {
|
||||||
/* held is opposite to matched => need both field from prev */
|
/* held is opposite to matched => need both field from prev */
|
||||||
|
@ -1600,47 +1601,47 @@ gst_field_analysis_process_buffer (GstFieldAnalysis * filter,
|
||||||
/* push prev TCM */
|
/* push prev TCM */
|
||||||
outbuf =
|
outbuf =
|
||||||
gst_field_analysis_decorate (filter, -1, FALSE, res1->conclusion,
|
gst_field_analysis_decorate (filter, -1, FALSE, res1->conclusion,
|
||||||
res1->gap);
|
res1->drop);
|
||||||
} else if ((res1->holding > 0 && res1->holding != 1 + BOTH_FIELDS) || (t
|
} else if ((res1->holding > 0 && res1->holding != 1 + BOTH_FIELDS) || (t
|
||||||
&& telecine_matches & FIELD_ANALYSIS_BOTTOM_TOP) || (b
|
&& telecine_matches & FIELD_ANALYSIS_BOTTOM_TOP) || (b
|
||||||
&& telecine_matches & FIELD_ANALYSIS_TOP_BOTTOM)) {
|
&& telecine_matches & FIELD_ANALYSIS_TOP_BOTTOM)) {
|
||||||
/* held field is needed, push prev 1F held */
|
/* held field is needed, push prev 1F held */
|
||||||
outbuf =
|
outbuf =
|
||||||
gst_field_analysis_decorate (filter, !(res1->holding - 1), TRUE,
|
gst_field_analysis_decorate (filter, !(res1->holding - 1), TRUE,
|
||||||
res1->conclusion, res1->gap);
|
res1->conclusion, res1->drop);
|
||||||
} else {
|
} else {
|
||||||
/* holding none or unknown */
|
/* holding none or unknown */
|
||||||
/* push prev as is with GAP */
|
/* push prev as is with RFF */
|
||||||
res1->gap = TRUE;
|
res1->drop = TRUE;
|
||||||
outbuf =
|
outbuf =
|
||||||
gst_field_analysis_decorate (filter, -1, FALSE, res1->conclusion,
|
gst_field_analysis_decorate (filter, -1, FALSE, res1->conclusion,
|
||||||
res1->gap);
|
res1->drop);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
/* cur I */
|
/* cur I */
|
||||||
res0->conclusion = FIELD_ANALYSIS_INTERLACED;
|
res0->conclusion = FIELD_ANALYSIS_INTERLACED;
|
||||||
res0->holding = 1 + BOTH_FIELDS;
|
res0->holding = 1 + BOTH_FIELDS;
|
||||||
/* push prev appropriately */
|
/* push prev appropriately */
|
||||||
res1->gap = res1->holding <= 0;
|
res1->drop = res1->holding <= 0;
|
||||||
if (res1->holding != 0) {
|
if (res1->holding != 0) {
|
||||||
res1->gap = FALSE;
|
res1->drop = FALSE;
|
||||||
if (res1->holding == 1 + BOTH_FIELDS || res1->holding == -1) {
|
if (res1->holding == 1 + BOTH_FIELDS || res1->holding == -1) {
|
||||||
/* push prev as is */
|
/* push prev as is */
|
||||||
outbuf =
|
outbuf =
|
||||||
gst_field_analysis_decorate (filter, -1, FALSE,
|
gst_field_analysis_decorate (filter, -1, FALSE,
|
||||||
res1->conclusion, res1->gap);
|
res1->conclusion, res1->drop);
|
||||||
} else {
|
} else {
|
||||||
/* push prev 1F held */
|
/* push prev 1F held */
|
||||||
outbuf =
|
outbuf =
|
||||||
gst_field_analysis_decorate (filter, !(res1->holding - 1), TRUE,
|
gst_field_analysis_decorate (filter, !(res1->holding - 1), TRUE,
|
||||||
res1->conclusion, res1->gap);
|
res1->conclusion, res1->drop);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
/* push prev as is with GAP */
|
/* push prev as is with RFF */
|
||||||
res1->gap = TRUE;
|
res1->drop = TRUE;
|
||||||
outbuf =
|
outbuf =
|
||||||
gst_field_analysis_decorate (filter, -1, FALSE, res1->conclusion,
|
gst_field_analysis_decorate (filter, -1, FALSE, res1->conclusion,
|
||||||
res1->gap);
|
res1->drop);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -91,7 +91,7 @@ struct _FieldAnalysis
|
||||||
FieldAnalysisConclusion conclusion;
|
FieldAnalysisConclusion conclusion;
|
||||||
/* -1 - unknown; 0 - holding none; 1 - top field; 2 - bottom field; 3 - both */
|
/* -1 - unknown; 0 - holding none; 1 - top field; 2 - bottom field; 3 - both */
|
||||||
gint holding;
|
gint holding;
|
||||||
gboolean gap;
|
gboolean drop;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef enum
|
typedef enum
|
||||||
|
|
Loading…
Reference in a new issue