mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-21 15:56:42 +00:00
Merge branch 'master' into 0.11
This commit is contained in:
commit
d6908f1a2d
16 changed files with 327 additions and 193 deletions
|
@ -157,7 +157,6 @@ static void
|
|||
gst_break_my_data_init (GstBreakMyData * bmd)
|
||||
{
|
||||
gst_base_transform_set_in_place (GST_BASE_TRANSFORM (bmd), TRUE);
|
||||
gst_base_transform_set_passthrough (GST_BASE_TRANSFORM (bmd), TRUE);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
|
@ -765,6 +765,7 @@ gst_deinterlace_reset_history (GstDeinterlace * self, gboolean drop_all)
|
|||
self->state_count = 0;
|
||||
self->pattern_lock = FALSE;
|
||||
self->pattern_refresh = TRUE;
|
||||
self->cur_field_idx = -1;
|
||||
|
||||
if (!self->still_frame_mode && self->last_buffer) {
|
||||
gst_buffer_unref (self->last_buffer);
|
||||
|
@ -1183,9 +1184,10 @@ gst_deinterlace_push_history (GstDeinterlace * self, GstBuffer * buffer)
|
|||
}
|
||||
|
||||
self->history_count += fields_to_push;
|
||||
self->cur_field_idx += fields_to_push;
|
||||
|
||||
GST_DEBUG_OBJECT (self, "Pushed buffer -- current history size %d",
|
||||
self->history_count);
|
||||
GST_DEBUG_OBJECT (self, "Pushed buffer -- current history size %d, index %d",
|
||||
self->history_count, self->cur_field_idx);
|
||||
|
||||
if (self->last_buffer)
|
||||
gst_buffer_unref (self->last_buffer);
|
||||
|
@ -1456,7 +1458,6 @@ gst_deinterlace_output_frame (GstDeinterlace * self, gboolean flushing)
|
|||
GstClockTime timestamp;
|
||||
GstFlowReturn ret;
|
||||
gint fields_required;
|
||||
gint cur_field_idx;
|
||||
GstBuffer *buf, *outbuf;
|
||||
GstDeinterlaceField *field1, *field2;
|
||||
GstDeinterlaceInterlacingMethod interlacing_method;
|
||||
|
@ -1471,7 +1472,6 @@ gst_deinterlace_output_frame (GstDeinterlace * self, gboolean flushing)
|
|||
restart:
|
||||
ret = GST_FLOW_OK;
|
||||
fields_required = 0;
|
||||
cur_field_idx = 0;
|
||||
hl_no_lock = FALSE;
|
||||
same_buffer = FALSE;
|
||||
flush_one = FALSE;
|
||||
|
@ -1530,6 +1530,7 @@ restart:
|
|||
|
||||
if (flush_one && self->drop_orphans) {
|
||||
GST_DEBUG_OBJECT (self, "Dropping orphan first field");
|
||||
self->cur_field_idx--;
|
||||
gst_buffer_unref (gst_deinterlace_pop_history (self));
|
||||
goto restart;
|
||||
}
|
||||
|
@ -1558,7 +1559,7 @@ restart:
|
|||
fields_required = 2;
|
||||
if (!flushing && self->history_count < fields_required) {
|
||||
GST_DEBUG_OBJECT (self, "Need more fields (have %d, need %d)",
|
||||
self->history_count, fields_required);
|
||||
self->history_count, self->cur_field_idx + fields_required);
|
||||
goto need_more;
|
||||
}
|
||||
|
||||
|
@ -1573,9 +1574,11 @@ restart:
|
|||
GST_DEBUG_OBJECT (self,
|
||||
"Frame type: Telecine Progressive; pushing buffer as a frame");
|
||||
/* pop and push */
|
||||
self->cur_field_idx--;
|
||||
field1_buf = gst_deinterlace_pop_history (self);
|
||||
/* field2 is the same buffer as field1, but we need to remove it from
|
||||
* the history anyway */
|
||||
self->cur_field_idx--;
|
||||
gst_buffer_unref (gst_deinterlace_pop_history (self));
|
||||
/* set the caps from the src pad on the buffer as they should be correct */
|
||||
gst_buffer_set_caps (field1_buf, GST_PAD_CAPS (self->srcpad));
|
||||
|
@ -1617,9 +1620,9 @@ restart:
|
|||
}
|
||||
|
||||
/* Not enough fields in the history */
|
||||
if (self->history_count < fields_required) {
|
||||
if (!flushing && self->history_count < fields_required) {
|
||||
GST_DEBUG_OBJECT (self, "Need more fields (have %d, need %d)",
|
||||
self->history_count, fields_required);
|
||||
self->history_count, self->cur_field_idx + fields_required);
|
||||
goto need_more;
|
||||
}
|
||||
|
||||
|
@ -1633,9 +1636,9 @@ restart:
|
|||
fields_required = 2;
|
||||
|
||||
/* Not enough fields in the history */
|
||||
if (self->history_count < fields_required) {
|
||||
if (!flushing && self->history_count < fields_required) {
|
||||
GST_DEBUG_OBJECT (self, "Need more fields (have %d, need %d)",
|
||||
self->history_count, fields_required);
|
||||
self->history_count, self->cur_field_idx + fields_required);
|
||||
goto need_more;
|
||||
}
|
||||
|
||||
|
@ -1649,9 +1652,11 @@ restart:
|
|||
GST_DEBUG_OBJECT (self,
|
||||
"Frame type: Progressive; pushing buffer as a frame");
|
||||
/* pop and push */
|
||||
self->cur_field_idx--;
|
||||
field1_buf = gst_deinterlace_pop_history (self);
|
||||
/* field2 is the same buffer as field1, but we need to remove it from the
|
||||
* history anyway */
|
||||
self->cur_field_idx--;
|
||||
gst_buffer_unref (gst_deinterlace_pop_history (self));
|
||||
GST_DEBUG_OBJECT (self,
|
||||
"[OUT] ts %" GST_TIME_FORMAT ", dur %" GST_TIME_FORMAT ", end %"
|
||||
|
@ -1662,6 +1667,10 @@ restart:
|
|||
return gst_pad_push (self->srcpad, field1_buf);
|
||||
}
|
||||
|
||||
if (!flushing && self->cur_field_idx < 1) {
|
||||
goto need_more;
|
||||
}
|
||||
|
||||
if (self->fields == GST_DEINTERLACE_ALL
|
||||
|| interlacing_method == GST_DEINTERLACE_TELECINE)
|
||||
GST_DEBUG_OBJECT (self, "All fields");
|
||||
|
@ -1670,9 +1679,7 @@ restart:
|
|||
else if (self->fields == GST_DEINTERLACE_BF)
|
||||
GST_DEBUG_OBJECT (self, "Bottom fields");
|
||||
|
||||
cur_field_idx = self->history_count - fields_required;
|
||||
|
||||
if ((self->field_history[cur_field_idx].flags == PICTURE_INTERLACED_TOP
|
||||
if ((self->field_history[self->cur_field_idx].flags == PICTURE_INTERLACED_TOP
|
||||
&& (self->fields == GST_DEINTERLACE_TF
|
||||
|| interlacing_method == GST_DEINTERLACE_TELECINE))
|
||||
|| self->fields == GST_DEINTERLACE_ALL) {
|
||||
|
@ -1723,16 +1730,37 @@ restart:
|
|||
|
||||
/* Check if we need to drop the frame because of QoS */
|
||||
if (!gst_deinterlace_do_qos (self, GST_BUFFER_TIMESTAMP (buf))) {
|
||||
self->cur_field_idx--;
|
||||
gst_buffer_unref (gst_deinterlace_pop_history (self));
|
||||
gst_buffer_unref (outbuf);
|
||||
outbuf = NULL;
|
||||
ret = GST_FLOW_OK;
|
||||
} else {
|
||||
if (self->cur_field_idx < 0 && flushing) {
|
||||
if (self->history_count == 1) {
|
||||
gst_buffer_unref (gst_deinterlace_pop_history (self));
|
||||
goto need_more;
|
||||
}
|
||||
self->cur_field_idx++;
|
||||
}
|
||||
if (self->cur_field_idx < 0) {
|
||||
goto need_more;
|
||||
}
|
||||
if (!flushing && self->cur_field_idx < 1) {
|
||||
goto need_more;
|
||||
}
|
||||
|
||||
/* do magic calculus */
|
||||
gst_deinterlace_method_deinterlace_frame (self->method,
|
||||
self->field_history, self->history_count, outbuf);
|
||||
self->field_history, self->history_count, outbuf,
|
||||
self->cur_field_idx);
|
||||
|
||||
gst_buffer_unref (gst_deinterlace_pop_history (self));
|
||||
self->cur_field_idx--;
|
||||
if (self->cur_field_idx + 1 +
|
||||
gst_deinterlace_method_get_latency (self->method)
|
||||
< self->history_count || flushing) {
|
||||
gst_buffer_unref (gst_deinterlace_pop_history (self));
|
||||
}
|
||||
|
||||
if (gst_deinterlace_clip_buffer (self, outbuf)) {
|
||||
GST_DEBUG_OBJECT (self,
|
||||
|
@ -1755,6 +1783,7 @@ restart:
|
|||
/* pop off the second field */
|
||||
GST_DEBUG_OBJECT (self, "Removing unused field (count: %d)",
|
||||
self->history_count);
|
||||
self->cur_field_idx--;
|
||||
gst_buffer_unref (gst_deinterlace_pop_history (self));
|
||||
interlacing_method = GST_DEINTERLACE_INTERLACED;
|
||||
return ret;
|
||||
|
@ -1767,10 +1796,11 @@ restart:
|
|||
}
|
||||
}
|
||||
/* no calculation done: remove excess field */
|
||||
else if (self->field_history[cur_field_idx].flags ==
|
||||
else if (self->field_history[self->cur_field_idx].flags ==
|
||||
PICTURE_INTERLACED_TOP && (self->fields == GST_DEINTERLACE_BF
|
||||
&& interlacing_method != GST_DEINTERLACE_TELECINE)) {
|
||||
GST_DEBUG_OBJECT (self, "Removing unused top field");
|
||||
self->cur_field_idx--;
|
||||
gst_buffer_unref (gst_deinterlace_pop_history (self));
|
||||
|
||||
if (flush_one && !self->drop_orphans) {
|
||||
|
@ -1779,13 +1809,19 @@ restart:
|
|||
}
|
||||
}
|
||||
|
||||
cur_field_idx = self->history_count - fields_required;
|
||||
if (self->history_count < fields_required)
|
||||
return ret;
|
||||
|
||||
if (self->cur_field_idx < 0)
|
||||
return ret;
|
||||
|
||||
if (!flushing && self->cur_field_idx < 1) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* deinterlace bottom_field */
|
||||
if ((self->field_history[cur_field_idx].flags == PICTURE_INTERLACED_BOTTOM
|
||||
&& (self->fields == GST_DEINTERLACE_BF
|
||||
if ((self->field_history[self->cur_field_idx].flags ==
|
||||
PICTURE_INTERLACED_BOTTOM && (self->fields == GST_DEINTERLACE_BF
|
||||
|| interlacing_method == GST_DEINTERLACE_TELECINE))
|
||||
|| self->fields == GST_DEINTERLACE_ALL) {
|
||||
GST_DEBUG_OBJECT (self, "deinterlacing bottom field");
|
||||
|
@ -1834,6 +1870,7 @@ restart:
|
|||
|
||||
/* Check if we need to drop the frame because of QoS */
|
||||
if (!gst_deinterlace_do_qos (self, GST_BUFFER_TIMESTAMP (buf))) {
|
||||
self->cur_field_idx--;
|
||||
gst_buffer_unref (gst_deinterlace_pop_history (self));
|
||||
gst_buffer_unref (outbuf);
|
||||
outbuf = NULL;
|
||||
|
@ -1841,9 +1878,15 @@ restart:
|
|||
} else {
|
||||
/* do magic calculus */
|
||||
gst_deinterlace_method_deinterlace_frame (self->method,
|
||||
self->field_history, self->history_count, outbuf);
|
||||
self->field_history, self->history_count, outbuf,
|
||||
self->cur_field_idx);
|
||||
|
||||
gst_buffer_unref (gst_deinterlace_pop_history (self));
|
||||
self->cur_field_idx--;
|
||||
if (self->cur_field_idx + 1 +
|
||||
gst_deinterlace_method_get_latency (self->method)
|
||||
< self->history_count) {
|
||||
gst_buffer_unref (gst_deinterlace_pop_history (self));
|
||||
}
|
||||
|
||||
if (gst_deinterlace_clip_buffer (self, outbuf)) {
|
||||
GST_DEBUG_OBJECT (self,
|
||||
|
@ -1866,6 +1909,7 @@ restart:
|
|||
/* pop off the second field */
|
||||
GST_DEBUG_OBJECT (self, "Removing unused field (count: %d)",
|
||||
self->history_count);
|
||||
self->cur_field_idx--;
|
||||
gst_buffer_unref (gst_deinterlace_pop_history (self));
|
||||
interlacing_method = GST_DEINTERLACE_INTERLACED;
|
||||
return ret;
|
||||
|
@ -1878,10 +1922,11 @@ restart:
|
|||
}
|
||||
}
|
||||
/* no calculation done: remove excess field */
|
||||
else if (self->field_history[cur_field_idx].flags ==
|
||||
else if (self->field_history[self->cur_field_idx].flags ==
|
||||
PICTURE_INTERLACED_BOTTOM && (self->fields == GST_DEINTERLACE_TF
|
||||
&& interlacing_method != GST_DEINTERLACE_TELECINE)) {
|
||||
GST_DEBUG_OBJECT (self, "Removing unused bottom field");
|
||||
self->cur_field_idx--;
|
||||
gst_buffer_unref (gst_deinterlace_pop_history (self));
|
||||
|
||||
if (flush_one && !self->drop_orphans) {
|
||||
|
|
|
@ -146,6 +146,7 @@ struct _GstDeinterlace
|
|||
*/
|
||||
GstDeinterlaceField field_history[GST_DEINTERLACE_MAX_FIELD_HISTORY];
|
||||
guint history_count;
|
||||
int cur_field_idx;
|
||||
|
||||
/* Set to TRUE if we're in still frame mode,
|
||||
i.e. just forward all buffers
|
||||
|
|
|
@ -206,10 +206,10 @@ gst_deinterlace_method_init (GstDeinterlaceMethod * self)
|
|||
void
|
||||
gst_deinterlace_method_deinterlace_frame (GstDeinterlaceMethod * self,
|
||||
const GstDeinterlaceField * history, guint history_count,
|
||||
GstBuffer * outbuf)
|
||||
GstBuffer * outbuf, int cur_field_idx)
|
||||
{
|
||||
g_assert (self->deinterlace_frame != NULL);
|
||||
self->deinterlace_frame (self, history, history_count, outbuf);
|
||||
self->deinterlace_frame (self, history, history_count, outbuf, cur_field_idx);
|
||||
}
|
||||
|
||||
gint
|
||||
|
@ -318,14 +318,13 @@ gst_deinterlace_simple_method_copy_scanline_packed (GstDeinterlaceSimpleMethod *
|
|||
static void
|
||||
gst_deinterlace_simple_method_deinterlace_frame_packed (GstDeinterlaceMethod *
|
||||
method, const GstDeinterlaceField * history, guint history_count,
|
||||
GstBuffer * outbuf)
|
||||
GstBuffer * outbuf, gint cur_field_idx)
|
||||
{
|
||||
GstDeinterlaceSimpleMethod *self = GST_DEINTERLACE_SIMPLE_METHOD (method);
|
||||
GstDeinterlaceMethodClass *dm_class = GST_DEINTERLACE_METHOD_GET_CLASS (self);
|
||||
GstDeinterlaceScanlineData scanlines;
|
||||
guint8 *dest;
|
||||
const guint8 *field0, *field1, *field2, *field3;
|
||||
gint cur_field_idx = history_count - dm_class->fields_required;
|
||||
const guint8 *field0, *field1, *field2, *fieldp;
|
||||
guint cur_field_flags = history[cur_field_idx].flags;
|
||||
gint i;
|
||||
gint frame_height = self->parent.frame_height;
|
||||
|
@ -334,29 +333,29 @@ gst_deinterlace_simple_method_deinterlace_frame_packed (GstDeinterlaceMethod *
|
|||
g_assert (self->interpolate_scanline_packed != NULL);
|
||||
g_assert (self->copy_scanline_packed != NULL);
|
||||
|
||||
if (cur_field_idx > 0) {
|
||||
fieldp = GST_BUFFER_DATA (history[cur_field_idx - 1].buf);
|
||||
} else {
|
||||
fieldp = NULL;
|
||||
}
|
||||
|
||||
dest = GST_BUFFER_DATA (outbuf);
|
||||
field0 = GST_BUFFER_DATA (history[cur_field_idx].buf);
|
||||
|
||||
g_assert (dm_class->fields_required <= 4);
|
||||
|
||||
if (dm_class->fields_required >= 2) {
|
||||
if (cur_field_idx + 1 < history_count) {
|
||||
field1 = GST_BUFFER_DATA (history[cur_field_idx + 1].buf);
|
||||
} else {
|
||||
field1 = NULL;
|
||||
}
|
||||
|
||||
if (dm_class->fields_required >= 3) {
|
||||
if (cur_field_idx + 2 < history_count) {
|
||||
field2 = GST_BUFFER_DATA (history[cur_field_idx + 2].buf);
|
||||
} else {
|
||||
field2 = NULL;
|
||||
}
|
||||
|
||||
if (dm_class->fields_required >= 4) {
|
||||
field3 = GST_BUFFER_DATA (history[cur_field_idx + 3].buf);
|
||||
} else {
|
||||
field3 = NULL;
|
||||
}
|
||||
|
||||
#define CLAMP_LOW(i) (((i)<0) ? (i+2) : (i))
|
||||
#define CLAMP_HI(i) (((i)>=(frame_height)) ? (i-2) : (i))
|
||||
#define LINE(x,i) ((x) + CLAMP_HI(CLAMP_LOW(i)) * (stride))
|
||||
|
@ -368,6 +367,9 @@ gst_deinterlace_simple_method_deinterlace_frame_packed (GstDeinterlaceMethod *
|
|||
|
||||
if (!((i & 1) ^ scanlines.bottom_field)) {
|
||||
/* copying */
|
||||
scanlines.tp = LINE2 (fieldp, i - 1);
|
||||
scanlines.bp = LINE2 (fieldp, i + 1);
|
||||
|
||||
scanlines.tt0 = LINE2 (field0, (i - 2 >= 0) ? i - 2 : i);
|
||||
scanlines.m0 = LINE2 (field0, i);
|
||||
scanlines.bb0 = LINE2 (field0, (i + 2 < frame_height ? i + 2 : i));
|
||||
|
@ -379,12 +381,13 @@ gst_deinterlace_simple_method_deinterlace_frame_packed (GstDeinterlaceMethod *
|
|||
scanlines.m2 = LINE2 (field2, i);
|
||||
scanlines.bb2 = LINE2 (field2, (i + 2 < frame_height ? i + 2 : i));
|
||||
|
||||
scanlines.t3 = LINE2 (field3, i - 1);
|
||||
scanlines.b3 = LINE2 (field3, i + 1);
|
||||
|
||||
self->copy_scanline_packed (self, LINE (dest, i), &scanlines);
|
||||
} else {
|
||||
/* interpolating */
|
||||
scanlines.ttp = LINE2 (fieldp, (i - 2 >= 0) ? i - 2 : i);
|
||||
scanlines.mp = LINE2 (fieldp, i);
|
||||
scanlines.bbp = LINE2 (fieldp, (i + 2 < frame_height ? i + 2 : i));
|
||||
|
||||
scanlines.t0 = LINE2 (field0, i - 1);
|
||||
scanlines.b0 = LINE2 (field0, i + 1);
|
||||
|
||||
|
@ -395,10 +398,6 @@ gst_deinterlace_simple_method_deinterlace_frame_packed (GstDeinterlaceMethod *
|
|||
scanlines.t2 = LINE2 (field2, i - 1);
|
||||
scanlines.b2 = LINE2 (field2, i + 1);
|
||||
|
||||
scanlines.tt3 = LINE2 (field3, (i - 2 >= 0) ? i - 2 : i);
|
||||
scanlines.m3 = LINE2 (field3, i);
|
||||
scanlines.bb3 = LINE2 (field3, (i + 2 < frame_height ? i + 2 : i));
|
||||
|
||||
self->interpolate_scanline_packed (self, LINE (dest, i), &scanlines);
|
||||
}
|
||||
}
|
||||
|
@ -452,7 +451,7 @@ gst_deinterlace_simple_method_copy_scanline_planar_v (GstDeinterlaceSimpleMethod
|
|||
static void
|
||||
gst_deinterlace_simple_method_deinterlace_frame_planar_plane
|
||||
(GstDeinterlaceSimpleMethod * self, guint8 * dest, const guint8 * field0,
|
||||
const guint8 * field1, const guint8 * field2, const guint8 * field3,
|
||||
const guint8 * field1, const guint8 * field2, const guint8 * fieldp,
|
||||
guint cur_field_flags,
|
||||
gint plane, GstDeinterlaceSimpleMethodFunction copy_scanline,
|
||||
GstDeinterlaceSimpleMethodFunction interpolate_scanline)
|
||||
|
@ -471,6 +470,9 @@ static void
|
|||
|
||||
if (!((i & 1) ^ scanlines.bottom_field)) {
|
||||
/* copying */
|
||||
scanlines.tp = LINE2 (fieldp, i - 1);
|
||||
scanlines.bp = LINE2 (fieldp, i + 1);
|
||||
|
||||
scanlines.tt0 = LINE2 (field0, (i - 2 >= 0) ? i - 2 : i);
|
||||
scanlines.m0 = LINE2 (field0, i);
|
||||
scanlines.bb0 = LINE2 (field0, (i + 2 < frame_height ? i + 2 : i));
|
||||
|
@ -482,12 +484,13 @@ static void
|
|||
scanlines.m2 = LINE2 (field2, i);
|
||||
scanlines.bb2 = LINE2 (field2, (i + 2 < frame_height ? i + 2 : i));
|
||||
|
||||
scanlines.t3 = LINE2 (field3, i - 1);
|
||||
scanlines.b3 = LINE2 (field3, i + 1);
|
||||
|
||||
copy_scanline (self, LINE (dest, i), &scanlines);
|
||||
} else {
|
||||
/* interpolating */
|
||||
scanlines.ttp = LINE2 (fieldp, (i - 2 >= 0) ? i - 2 : i);
|
||||
scanlines.mp = LINE2 (fieldp, i);
|
||||
scanlines.bbp = LINE2 (fieldp, (i + 2 < frame_height ? i + 2 : i));
|
||||
|
||||
scanlines.t0 = LINE2 (field0, i - 1);
|
||||
scanlines.b0 = LINE2 (field0, i + 1);
|
||||
|
||||
|
@ -498,10 +501,6 @@ static void
|
|||
scanlines.t2 = LINE2 (field2, i - 1);
|
||||
scanlines.b2 = LINE2 (field2, i + 1);
|
||||
|
||||
scanlines.tt3 = LINE2 (field3, (i - 2 >= 0) ? i - 2 : i);
|
||||
scanlines.m3 = LINE2 (field3, i);
|
||||
scanlines.bb3 = LINE2 (field3, (i + 2 < frame_height ? i + 2 : i));
|
||||
|
||||
interpolate_scanline (self, LINE (dest, i), &scanlines);
|
||||
}
|
||||
}
|
||||
|
@ -510,13 +509,12 @@ static void
|
|||
static void
|
||||
gst_deinterlace_simple_method_deinterlace_frame_planar (GstDeinterlaceMethod *
|
||||
method, const GstDeinterlaceField * history, guint history_count,
|
||||
GstBuffer * outbuf)
|
||||
GstBuffer * outbuf, gint cur_field_idx)
|
||||
{
|
||||
GstDeinterlaceSimpleMethod *self = GST_DEINTERLACE_SIMPLE_METHOD (method);
|
||||
GstDeinterlaceMethodClass *dm_class = GST_DEINTERLACE_METHOD_GET_CLASS (self);
|
||||
guint8 *out;
|
||||
const guint8 *field0, *field1, *field2, *field3;
|
||||
gint cur_field_idx = history_count - dm_class->fields_required;
|
||||
const guint8 *field0, *field1, *field2, *fieldp;
|
||||
guint cur_field_flags = history[cur_field_idx].flags;
|
||||
gint i, offset;
|
||||
GstDeinterlaceSimpleMethodFunction copy_scanline;
|
||||
|
@ -536,27 +534,27 @@ gst_deinterlace_simple_method_deinterlace_frame_planar (GstDeinterlaceMethod *
|
|||
|
||||
out = GST_BUFFER_DATA (outbuf) + offset;
|
||||
|
||||
fieldp = NULL;
|
||||
if (cur_field_idx > 0) {
|
||||
fieldp = GST_BUFFER_DATA (history[cur_field_idx - 1].buf) + offset;
|
||||
}
|
||||
|
||||
field0 = GST_BUFFER_DATA (history[cur_field_idx].buf) + offset;
|
||||
|
||||
g_assert (dm_class->fields_required <= 4);
|
||||
|
||||
field1 = NULL;
|
||||
if (dm_class->fields_required >= 2) {
|
||||
if (cur_field_idx + 1 < history_count) {
|
||||
field1 = GST_BUFFER_DATA (history[cur_field_idx + 1].buf) + offset;
|
||||
}
|
||||
|
||||
field2 = NULL;
|
||||
if (dm_class->fields_required >= 3) {
|
||||
if (cur_field_idx + 2 < history_count) {
|
||||
field2 = GST_BUFFER_DATA (history[cur_field_idx + 2].buf) + offset;
|
||||
}
|
||||
|
||||
field3 = NULL;
|
||||
if (dm_class->fields_required >= 4) {
|
||||
field3 = GST_BUFFER_DATA (history[cur_field_idx + 3].buf) + offset;
|
||||
}
|
||||
|
||||
gst_deinterlace_simple_method_deinterlace_frame_planar_plane (self, out,
|
||||
field0, field1, field2, field3, cur_field_flags, i, copy_scanline,
|
||||
field0, field1, field2, fieldp, cur_field_flags, i, copy_scanline,
|
||||
interpolate_scanline);
|
||||
}
|
||||
}
|
||||
|
@ -564,13 +562,12 @@ gst_deinterlace_simple_method_deinterlace_frame_planar (GstDeinterlaceMethod *
|
|||
static void
|
||||
gst_deinterlace_simple_method_deinterlace_frame_nv12 (GstDeinterlaceMethod *
|
||||
method, const GstDeinterlaceField * history, guint history_count,
|
||||
GstBuffer * outbuf)
|
||||
GstBuffer * outbuf, gint cur_field_idx)
|
||||
{
|
||||
GstDeinterlaceSimpleMethod *self = GST_DEINTERLACE_SIMPLE_METHOD (method);
|
||||
GstDeinterlaceMethodClass *dm_class = GST_DEINTERLACE_METHOD_GET_CLASS (self);
|
||||
guint8 *out;
|
||||
const guint8 *field0, *field1, *field2, *field3;
|
||||
gint cur_field_idx = history_count - dm_class->fields_required;
|
||||
const guint8 *field0, *field1, *field2, *fieldp;
|
||||
guint cur_field_flags = history[cur_field_idx].flags;
|
||||
gint i, offset;
|
||||
|
||||
|
@ -582,27 +579,27 @@ gst_deinterlace_simple_method_deinterlace_frame_nv12 (GstDeinterlaceMethod *
|
|||
|
||||
out = GST_BUFFER_DATA (outbuf) + offset;
|
||||
|
||||
fieldp = NULL;
|
||||
if (cur_field_idx > 0) {
|
||||
fieldp = GST_BUFFER_DATA (history[cur_field_idx - 1].buf) + offset;
|
||||
}
|
||||
|
||||
field0 = GST_BUFFER_DATA (history[cur_field_idx].buf) + offset;
|
||||
|
||||
g_assert (dm_class->fields_required <= 4);
|
||||
|
||||
field1 = NULL;
|
||||
if (dm_class->fields_required >= 2) {
|
||||
if (cur_field_idx + 1 < history_count) {
|
||||
field1 = GST_BUFFER_DATA (history[cur_field_idx + 1].buf) + offset;
|
||||
}
|
||||
|
||||
field2 = NULL;
|
||||
if (dm_class->fields_required >= 3) {
|
||||
if (cur_field_idx + 2 < history_count) {
|
||||
field2 = GST_BUFFER_DATA (history[cur_field_idx + 2].buf) + offset;
|
||||
}
|
||||
|
||||
field3 = NULL;
|
||||
if (dm_class->fields_required >= 4) {
|
||||
field3 = GST_BUFFER_DATA (history[cur_field_idx + 3].buf) + offset;
|
||||
}
|
||||
|
||||
gst_deinterlace_simple_method_deinterlace_frame_planar_plane (self, out,
|
||||
field0, field1, field2, field3, cur_field_flags, i,
|
||||
field0, field1, field2, fieldp, cur_field_flags, i,
|
||||
self->copy_scanline_packed, self->interpolate_scanline_packed);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -61,7 +61,9 @@ typedef struct
|
|||
* This structure defines the deinterlacer plugin.
|
||||
*/
|
||||
|
||||
typedef void (*GstDeinterlaceMethodDeinterlaceFunction) (GstDeinterlaceMethod *self, const GstDeinterlaceField *history, guint history_count, GstBuffer *outbuf);
|
||||
typedef void (*GstDeinterlaceMethodDeinterlaceFunction) (
|
||||
GstDeinterlaceMethod *self, const GstDeinterlaceField *history,
|
||||
guint history_count, GstBuffer *outbuf, int cur_field_idx);
|
||||
|
||||
struct _GstDeinterlaceMethod {
|
||||
GstObject parent;
|
||||
|
@ -112,7 +114,8 @@ GType gst_deinterlace_method_get_type (void);
|
|||
|
||||
gboolean gst_deinterlace_method_supported (GType type, GstVideoFormat format, gint width, gint height);
|
||||
void gst_deinterlace_method_setup (GstDeinterlaceMethod * self, GstVideoFormat format, gint width, gint height);
|
||||
void gst_deinterlace_method_deinterlace_frame (GstDeinterlaceMethod * self, const GstDeinterlaceField * history, guint history_count, GstBuffer * outbuf);
|
||||
void gst_deinterlace_method_deinterlace_frame (GstDeinterlaceMethod * self, const GstDeinterlaceField * history, guint history_count, GstBuffer * outbuf,
|
||||
int cur_field_idx);
|
||||
gint gst_deinterlace_method_get_fields_required (GstDeinterlaceMethod * self);
|
||||
gint gst_deinterlace_method_get_latency (GstDeinterlaceMethod * self);
|
||||
|
||||
|
@ -133,32 +136,32 @@ typedef struct _GstDeinterlaceScanlineData GstDeinterlaceScanlineData;
|
|||
*/
|
||||
|
||||
struct _GstDeinterlaceScanlineData {
|
||||
const guint8 *ttp, *tp, *mp, *bp, *bbp;
|
||||
const guint8 *tt0, *t0, *m0, *b0, *bb0;
|
||||
const guint8 *tt1, *t1, *m1, *b1, *bb1;
|
||||
const guint8 *tt2, *t2, *m2, *b2, *bb2;
|
||||
const guint8 *tt3, *t3, *m3, *b3, *bb3;
|
||||
gboolean bottom_field;
|
||||
};
|
||||
|
||||
/*
|
||||
* For interpolate_scanline the input is:
|
||||
*
|
||||
* | t-3 t-2 t-1 t
|
||||
* | Field 3 | Field 2 | Field 1 | Field 0 |
|
||||
* | TT3 | | TT1 | |
|
||||
* | t-3 t-2 t-1 t t+1
|
||||
* | Field 3 | Field 2 | Field 1 | Field 0 | Field -1
|
||||
* | TT3 | | TT1 | | TTp
|
||||
* | | T2 | | T0 |
|
||||
* | M3 | | M1 | |
|
||||
* | M3 | | M1 | | Mp
|
||||
* | | B2 | | B0 |
|
||||
* | BB3 | | BB1 | |
|
||||
* | BB3 | | BB1 | | BBp
|
||||
*
|
||||
* For copy_scanline the input is:
|
||||
*
|
||||
* | t-3 t-2 t-1 t
|
||||
* | Field 3 | Field 2 | Field 1 | Field 0 |
|
||||
* | t-3 t-2 t-1 t t+1
|
||||
* | Field 3 | Field 2 | Field 1 | Field 0 | Field -1
|
||||
* | | TT2 | | TT0 |
|
||||
* | T3 | | T1 | |
|
||||
* | T3 | | T1 | | Tp
|
||||
* | | M2 | | M0 |
|
||||
* | B3 | | B1 | |
|
||||
* | B3 | | B1 | | Bp
|
||||
* | | BB2 | | BB0 |
|
||||
*
|
||||
* All other values are NULL.
|
||||
|
|
|
@ -72,54 +72,69 @@ static inline void
|
|||
deinterlace_greedy_interpolate_scanline_orc (GstDeinterlaceSimpleMethod * self,
|
||||
guint8 * out, const GstDeinterlaceScanlineData * scanlines)
|
||||
{
|
||||
/* FIXME - is this safe or just a hack? */
|
||||
guint max_comb = GST_DEINTERLACE_METHOD_GREEDY_L (self)->max_comb;
|
||||
|
||||
deinterlace_line_greedy (out, scanlines->m3, scanlines->t2, scanlines->b2,
|
||||
scanlines->m1, max_comb, self->parent.row_stride[0]);
|
||||
if (scanlines->m1 == NULL || scanlines->mp == NULL) {
|
||||
deinterlace_line_linear (out, scanlines->t0, scanlines->b0,
|
||||
self->parent.row_stride[0]);
|
||||
} else {
|
||||
deinterlace_line_greedy (out, scanlines->m1, scanlines->t0, scanlines->b0,
|
||||
scanlines->mp ? scanlines->mp : scanlines->m1,
|
||||
max_comb, self->parent.row_stride[0]);
|
||||
}
|
||||
}
|
||||
|
||||
static inline void
|
||||
deinterlace_greedy_interpolate_scanline_orc_planar_u (GstDeinterlaceSimpleMethod
|
||||
* self, guint8 * out, const GstDeinterlaceScanlineData * scanlines)
|
||||
{
|
||||
/* FIXME - is this safe or just a hack? */
|
||||
guint max_comb = GST_DEINTERLACE_METHOD_GREEDY_L (self)->max_comb;
|
||||
|
||||
deinterlace_line_greedy (out, scanlines->m3, scanlines->t2, scanlines->b2,
|
||||
scanlines->m1, max_comb, self->parent.row_stride[1]);
|
||||
if (scanlines->m1 == NULL || scanlines->mp == NULL) {
|
||||
deinterlace_line_linear (out, scanlines->t0, scanlines->b0,
|
||||
self->parent.row_stride[1]);
|
||||
} else {
|
||||
deinterlace_line_greedy (out, scanlines->m1, scanlines->t0, scanlines->b0,
|
||||
scanlines->mp ? scanlines->mp : scanlines->m1,
|
||||
max_comb, self->parent.row_stride[1]);
|
||||
}
|
||||
}
|
||||
|
||||
static inline void
|
||||
deinterlace_greedy_interpolate_scanline_orc_planar_v (GstDeinterlaceSimpleMethod
|
||||
* self, guint8 * out, const GstDeinterlaceScanlineData * scanlines)
|
||||
{
|
||||
/* FIXME - is this safe or just a hack? */
|
||||
guint max_comb = GST_DEINTERLACE_METHOD_GREEDY_L (self)->max_comb;
|
||||
|
||||
deinterlace_line_greedy (out, scanlines->m3, scanlines->t2, scanlines->b2,
|
||||
scanlines->m1, max_comb, self->parent.row_stride[2]);
|
||||
if (scanlines->m1 == NULL || scanlines->mp == NULL) {
|
||||
deinterlace_line_linear (out, scanlines->t0, scanlines->b0,
|
||||
self->parent.row_stride[2]);
|
||||
} else {
|
||||
deinterlace_line_greedy (out, scanlines->m1, scanlines->t0, scanlines->b0,
|
||||
scanlines->mp ? scanlines->mp : scanlines->m1,
|
||||
max_comb, self->parent.row_stride[2]);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
deinterlace_greedy_copy_scanline (GstDeinterlaceSimpleMethod * self,
|
||||
guint8 * out, const GstDeinterlaceScanlineData * scanlines)
|
||||
{
|
||||
memcpy (out, scanlines->m2, self->parent.row_stride[0]);
|
||||
memcpy (out, scanlines->m0, self->parent.row_stride[0]);
|
||||
}
|
||||
|
||||
static void
|
||||
deinterlace_greedy_copy_scanline_planar_u (GstDeinterlaceSimpleMethod * self,
|
||||
guint8 * out, const GstDeinterlaceScanlineData * scanlines)
|
||||
{
|
||||
memcpy (out, scanlines->m2, self->parent.row_stride[1]);
|
||||
memcpy (out, scanlines->m0, self->parent.row_stride[1]);
|
||||
}
|
||||
|
||||
static void
|
||||
deinterlace_greedy_copy_scanline_planar_v (GstDeinterlaceSimpleMethod * self,
|
||||
guint8 * out, const GstDeinterlaceScanlineData * scanlines)
|
||||
{
|
||||
memcpy (out, scanlines->m2, self->parent.row_stride[2]);
|
||||
memcpy (out, scanlines->m0, self->parent.row_stride[2]);
|
||||
}
|
||||
|
||||
G_DEFINE_TYPE (GstDeinterlaceMethodGreedyL, gst_deinterlace_method_greedy_l,
|
||||
|
@ -179,7 +194,7 @@ gst_deinterlace_method_greedy_l_class_init (GstDeinterlaceMethodGreedyLClass *
|
|||
"Max Comb", 0, 255, 15, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)
|
||||
);
|
||||
|
||||
dim_class->fields_required = 4;
|
||||
dim_class->fields_required = 2;
|
||||
dim_class->name = "Motion Adaptive: Simple Detection";
|
||||
dim_class->nick = "greedyl";
|
||||
dim_class->latency = 1;
|
||||
|
|
|
@ -719,7 +719,7 @@ greedyh_scanline_C_planar_uv (GstDeinterlaceMethodGreedyH * self,
|
|||
static void
|
||||
deinterlace_frame_di_greedyh_packed (GstDeinterlaceMethod * method,
|
||||
const GstDeinterlaceField * history, guint history_count,
|
||||
GstBuffer * outbuf)
|
||||
GstBuffer * outbuf, int cur_field_idx)
|
||||
{
|
||||
GstDeinterlaceMethodGreedyH *self = GST_DEINTERLACE_METHOD_GREEDY_H (method);
|
||||
GstDeinterlaceMethodGreedyHClass *klass =
|
||||
|
@ -736,6 +736,23 @@ deinterlace_frame_di_greedyh_packed (GstDeinterlaceMethod * method,
|
|||
guint8 *Dest = GST_BUFFER_DATA (outbuf);
|
||||
ScanlineFunction scanline;
|
||||
|
||||
if (cur_field_idx + 2 > history_count || cur_field_idx < 1) {
|
||||
GstDeinterlaceMethod *backup_method;
|
||||
|
||||
backup_method = g_object_new (gst_deinterlace_method_linear_get_type (),
|
||||
NULL);
|
||||
|
||||
gst_deinterlace_method_setup (backup_method, method->format,
|
||||
method->frame_width, method->frame_height);
|
||||
gst_deinterlace_method_deinterlace_frame (backup_method,
|
||||
history, history_count, outbuf, cur_field_idx);
|
||||
|
||||
g_object_unref (backup_method);
|
||||
return;
|
||||
}
|
||||
|
||||
cur_field_idx += 2;
|
||||
|
||||
switch (method->format) {
|
||||
case GST_VIDEO_FORMAT_YUY2:
|
||||
case GST_VIDEO_FORMAT_YVYU:
|
||||
|
@ -755,20 +772,20 @@ deinterlace_frame_di_greedyh_packed (GstDeinterlaceMethod * method,
|
|||
// copy first even line no matter what, and the first odd line if we're
|
||||
// processing an EVEN field. (note diff from other deint rtns.)
|
||||
|
||||
if (history[history_count - 1].flags == PICTURE_INTERLACED_BOTTOM) {
|
||||
if (history[cur_field_idx - 1].flags == PICTURE_INTERLACED_BOTTOM) {
|
||||
InfoIsOdd = 1;
|
||||
|
||||
L1 = GST_BUFFER_DATA (history[history_count - 2].buf);
|
||||
if (history[history_count - 2].flags & PICTURE_INTERLACED_BOTTOM)
|
||||
L1 = GST_BUFFER_DATA (history[cur_field_idx - 2].buf);
|
||||
if (history[cur_field_idx - 2].flags & PICTURE_INTERLACED_BOTTOM)
|
||||
L1 += RowStride;
|
||||
|
||||
L2 = GST_BUFFER_DATA (history[history_count - 1].buf);
|
||||
if (history[history_count - 1].flags & PICTURE_INTERLACED_BOTTOM)
|
||||
L2 = GST_BUFFER_DATA (history[cur_field_idx - 1].buf);
|
||||
if (history[cur_field_idx - 1].flags & PICTURE_INTERLACED_BOTTOM)
|
||||
L2 += RowStride;
|
||||
|
||||
L3 = L1 + Pitch;
|
||||
L2P = GST_BUFFER_DATA (history[history_count - 3].buf);
|
||||
if (history[history_count - 3].flags & PICTURE_INTERLACED_BOTTOM)
|
||||
L2P = GST_BUFFER_DATA (history[cur_field_idx - 3].buf);
|
||||
if (history[cur_field_idx - 3].flags & PICTURE_INTERLACED_BOTTOM)
|
||||
L2P += RowStride;
|
||||
|
||||
// copy first even line
|
||||
|
@ -776,17 +793,17 @@ deinterlace_frame_di_greedyh_packed (GstDeinterlaceMethod * method,
|
|||
Dest += RowStride;
|
||||
} else {
|
||||
InfoIsOdd = 0;
|
||||
L1 = GST_BUFFER_DATA (history[history_count - 2].buf);
|
||||
if (history[history_count - 2].flags & PICTURE_INTERLACED_BOTTOM)
|
||||
L1 = GST_BUFFER_DATA (history[cur_field_idx - 2].buf);
|
||||
if (history[cur_field_idx - 2].flags & PICTURE_INTERLACED_BOTTOM)
|
||||
L1 += RowStride;
|
||||
|
||||
L2 = GST_BUFFER_DATA (history[history_count - 1].buf) + Pitch;
|
||||
if (history[history_count - 1].flags & PICTURE_INTERLACED_BOTTOM)
|
||||
L2 = GST_BUFFER_DATA (history[cur_field_idx - 1].buf) + Pitch;
|
||||
if (history[cur_field_idx - 1].flags & PICTURE_INTERLACED_BOTTOM)
|
||||
L2 += RowStride;
|
||||
|
||||
L3 = L1 + Pitch;
|
||||
L2P = GST_BUFFER_DATA (history[history_count - 3].buf) + Pitch;
|
||||
if (history[history_count - 3].flags & PICTURE_INTERLACED_BOTTOM)
|
||||
L2P = GST_BUFFER_DATA (history[cur_field_idx - 3].buf) + Pitch;
|
||||
if (history[cur_field_idx - 3].flags & PICTURE_INTERLACED_BOTTOM)
|
||||
L2P += RowStride;
|
||||
|
||||
// copy first even line
|
||||
|
@ -858,7 +875,7 @@ deinterlace_frame_di_greedyh_planar_plane (GstDeinterlaceMethodGreedyH * self,
|
|||
static void
|
||||
deinterlace_frame_di_greedyh_planar (GstDeinterlaceMethod * method,
|
||||
const GstDeinterlaceField * history, guint history_count,
|
||||
GstBuffer * outbuf)
|
||||
GstBuffer * outbuf, int cur_field_idx)
|
||||
{
|
||||
GstDeinterlaceMethodGreedyH *self = GST_DEINTERLACE_METHOD_GREEDY_H (method);
|
||||
GstDeinterlaceMethodGreedyHClass *klass =
|
||||
|
@ -876,10 +893,27 @@ deinterlace_frame_di_greedyh_planar (GstDeinterlaceMethod * method,
|
|||
gint Offset;
|
||||
ScanlineFunction scanline;
|
||||
|
||||
if (cur_field_idx + 2 > history_count || cur_field_idx < 1) {
|
||||
GstDeinterlaceMethod *backup_method;
|
||||
|
||||
backup_method = g_object_new (gst_deinterlace_method_linear_get_type (),
|
||||
NULL);
|
||||
|
||||
gst_deinterlace_method_setup (backup_method, method->format,
|
||||
method->frame_width, method->frame_height);
|
||||
gst_deinterlace_method_deinterlace_frame (backup_method,
|
||||
history, history_count, outbuf, cur_field_idx);
|
||||
|
||||
g_object_unref (backup_method);
|
||||
return;
|
||||
}
|
||||
|
||||
cur_field_idx += 2;
|
||||
|
||||
for (i = 0; i < 3; i++) {
|
||||
Offset = method->offset[i];
|
||||
|
||||
InfoIsOdd = (history[history_count - 1].flags == PICTURE_INTERLACED_BOTTOM);
|
||||
InfoIsOdd = (history[cur_field_idx - 1].flags == PICTURE_INTERLACED_BOTTOM);
|
||||
RowStride = method->row_stride[i];
|
||||
FieldHeight = method->height[i] / 2;
|
||||
Pitch = method->row_stride[i] * 2;
|
||||
|
@ -891,17 +925,17 @@ deinterlace_frame_di_greedyh_planar (GstDeinterlaceMethod * method,
|
|||
|
||||
Dest = GST_BUFFER_DATA (outbuf) + Offset;
|
||||
|
||||
L1 = GST_BUFFER_DATA (history[history_count - 2].buf) + Offset;
|
||||
if (history[history_count - 2].flags & PICTURE_INTERLACED_BOTTOM)
|
||||
L1 = GST_BUFFER_DATA (history[cur_field_idx - 2].buf) + Offset;
|
||||
if (history[cur_field_idx - 2].flags & PICTURE_INTERLACED_BOTTOM)
|
||||
L1 += RowStride;
|
||||
|
||||
L2 = GST_BUFFER_DATA (history[history_count - 1].buf) + Offset;
|
||||
if (history[history_count - 1].flags & PICTURE_INTERLACED_BOTTOM)
|
||||
L2 = GST_BUFFER_DATA (history[cur_field_idx - 1].buf) + Offset;
|
||||
if (history[cur_field_idx - 1].flags & PICTURE_INTERLACED_BOTTOM)
|
||||
L2 += RowStride;
|
||||
|
||||
L3 = L1 + Pitch;
|
||||
L2P = GST_BUFFER_DATA (history[history_count - 3].buf) + Offset;
|
||||
if (history[history_count - 3].flags & PICTURE_INTERLACED_BOTTOM)
|
||||
L2P = GST_BUFFER_DATA (history[cur_field_idx - 3].buf) + Offset;
|
||||
if (history[cur_field_idx - 3].flags & PICTURE_INTERLACED_BOTTOM)
|
||||
L2P += RowStride;
|
||||
|
||||
deinterlace_frame_di_greedyh_planar_plane (self, L1, L2, L3, L2P, Dest,
|
||||
|
|
|
@ -56,7 +56,11 @@ deinterlace_scanline_linear_blend_c (GstDeinterlaceSimpleMethod * self,
|
|||
guint8 * out, const guint8 * t0, const guint8 * b0, const guint8 * m1,
|
||||
gint size)
|
||||
{
|
||||
deinterlace_line_linear_blend (out, t0, b0, m1, size);
|
||||
if (m1 == NULL) {
|
||||
deinterlace_line_linear (out, t0, b0, size);
|
||||
} else {
|
||||
deinterlace_line_linear_blend (out, t0, b0, m1, size);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -96,7 +100,11 @@ deinterlace_scanline_linear_blend2_c (GstDeinterlaceSimpleMethod * self,
|
|||
guint8 * out, const guint8 * m0, const guint8 * t1, const guint8 * b1,
|
||||
gint size)
|
||||
{
|
||||
deinterlace_line_linear_blend (out, t1, b1, m0, size);
|
||||
if (t1 == NULL) {
|
||||
memcpy (out, m0, size);
|
||||
} else {
|
||||
deinterlace_line_linear_blend (out, t1, b1, m0, size);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -145,7 +153,7 @@ static void
|
|||
dim_class->fields_required = 2;
|
||||
dim_class->name = "Blur: Temporal";
|
||||
dim_class->nick = "linearblend";
|
||||
dim_class->latency = 0;
|
||||
dim_class->latency = 1;
|
||||
|
||||
dism_class->interpolate_scanline_yuy2 =
|
||||
deinterlace_scanline_linear_blend_packed_c;
|
||||
|
|
|
@ -77,10 +77,10 @@ gst_deinterlace_method_scaler_bob_class_init (GstDeinterlaceMethodScalerBobClass
|
|||
GstDeinterlaceSimpleMethodClass *dism_class =
|
||||
(GstDeinterlaceSimpleMethodClass *) klass;
|
||||
|
||||
dim_class->fields_required = 1;
|
||||
dim_class->fields_required = 2;
|
||||
dim_class->name = "Double lines";
|
||||
dim_class->nick = "scalerbob";
|
||||
dim_class->latency = 0;
|
||||
dim_class->latency = 1;
|
||||
|
||||
dism_class->interpolate_scanline_ayuv =
|
||||
deinterlace_scanline_scaler_bob_packed;
|
||||
|
|
|
@ -61,7 +61,9 @@
|
|||
#define SEFUNC(x) Search_Effort_C_##x(src_pitch, dst_pitch, rowsize, pWeaveSrc, pWeaveSrcP, pWeaveDest, IsOdd, pCopySrc, pCopySrcP, FldHeight)
|
||||
#endif
|
||||
|
||||
static void FUNCT_NAME(GstDeinterlaceMethod *d_method, const GstDeinterlaceField* history, guint history_count, GstBuffer *outbuf)
|
||||
static void FUNCT_NAME(GstDeinterlaceMethod *d_method,
|
||||
const GstDeinterlaceField* history, guint history_count,
|
||||
GstBuffer *outbuf, int cur_field_idx)
|
||||
{
|
||||
GstDeinterlaceMethodTomsMoComp *self = GST_DEINTERLACE_METHOD_TOMSMOCOMP (d_method);
|
||||
glong SearchEffort = self->search_effort;
|
||||
|
@ -78,6 +80,21 @@ static void FUNCT_NAME(GstDeinterlaceMethod *d_method, const GstDeinterlaceField
|
|||
gint rowsize;
|
||||
gint FldHeight;
|
||||
|
||||
if (cur_field_idx + 2 > history_count || cur_field_idx < 1) {
|
||||
GstDeinterlaceMethod *backup_method;
|
||||
|
||||
backup_method = g_object_new (gst_deinterlace_method_linear_get_type(),
|
||||
NULL);
|
||||
|
||||
gst_deinterlace_method_setup (backup_method, d_method->format,
|
||||
d_method->frame_width, d_method->frame_height);
|
||||
gst_deinterlace_method_deinterlace_frame (backup_method,
|
||||
history, history_count, outbuf, cur_field_idx);
|
||||
|
||||
g_object_unref (backup_method);
|
||||
return;
|
||||
}
|
||||
|
||||
/* double stride do address just every odd/even scanline */
|
||||
src_pitch = self->parent.row_stride[0]*2;
|
||||
dst_pitch = self->parent.row_stride[0];
|
||||
|
|
|
@ -68,7 +68,11 @@ static inline void
|
|||
deinterlace_c (guint8 * dst, const guint8 * lum_m4, const guint8 * lum_m3,
|
||||
const guint8 * lum_m2, const guint8 * lum_m1, const guint8 * lum, gint size)
|
||||
{
|
||||
deinterlace_line_vfir (dst, lum_m4, lum_m3, lum_m2, lum_m1, lum, size);
|
||||
if (lum_m2 == NULL) {
|
||||
deinterlace_line_linear (dst, lum_m1, lum_m3, size);
|
||||
} else {
|
||||
deinterlace_line_vfir (dst, lum_m4, lum_m3, lum_m2, lum_m1, lum, size);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -127,6 +131,8 @@ deinterlace_line_planar_v_c (GstDeinterlaceSimpleMethod * self, guint8 * dst,
|
|||
deinterlace_c (dst, lum_m4, lum_m3, lum_m2, lum_m1, lum, size);
|
||||
}
|
||||
|
||||
#undef BUILD_X86_ASM
|
||||
|
||||
#ifdef BUILD_X86_ASM
|
||||
#include "mmx.h"
|
||||
static void
|
||||
|
@ -251,7 +257,7 @@ gst_deinterlace_method_vfir_class_init (GstDeinterlaceMethodVFIRClass * klass)
|
|||
dim_class->fields_required = 2;
|
||||
dim_class->name = "Blur Vertical";
|
||||
dim_class->nick = "vfir";
|
||||
dim_class->latency = 0;
|
||||
dim_class->latency = 1;
|
||||
|
||||
#ifdef BUILD_X86_ASM
|
||||
if (cpu_flags & ORC_TARGET_MMX_MMX) {
|
||||
|
|
|
@ -48,28 +48,44 @@ static void
|
|||
deinterlace_scanline_weave_packed (GstDeinterlaceSimpleMethod * self,
|
||||
guint8 * out, const GstDeinterlaceScanlineData * scanlines)
|
||||
{
|
||||
memcpy (out, scanlines->m1, self->parent.row_stride[0]);
|
||||
if (scanlines->m1 == NULL) {
|
||||
memcpy (out, scanlines->t0, self->parent.row_stride[0]);
|
||||
} else {
|
||||
memcpy (out, scanlines->m1, self->parent.row_stride[0]);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
deinterlace_scanline_weave_planar_y (GstDeinterlaceSimpleMethod * self,
|
||||
guint8 * out, const GstDeinterlaceScanlineData * scanlines)
|
||||
{
|
||||
memcpy (out, scanlines->m1, self->parent.row_stride[0]);
|
||||
if (scanlines->m1 == NULL) {
|
||||
memcpy (out, scanlines->t0, self->parent.row_stride[0]);
|
||||
} else {
|
||||
memcpy (out, scanlines->m1, self->parent.row_stride[0]);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
deinterlace_scanline_weave_planar_u (GstDeinterlaceSimpleMethod * self,
|
||||
guint8 * out, const GstDeinterlaceScanlineData * scanlines)
|
||||
{
|
||||
memcpy (out, scanlines->m1, self->parent.row_stride[1]);
|
||||
if (scanlines->m1 == NULL) {
|
||||
memcpy (out, scanlines->t0, self->parent.row_stride[1]);
|
||||
} else {
|
||||
memcpy (out, scanlines->m1, self->parent.row_stride[1]);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
deinterlace_scanline_weave_planar_v (GstDeinterlaceSimpleMethod * self,
|
||||
guint8 * out, const GstDeinterlaceScanlineData * scanlines)
|
||||
{
|
||||
memcpy (out, scanlines->m1, self->parent.row_stride[2]);
|
||||
if (scanlines->m1 == NULL) {
|
||||
memcpy (out, scanlines->t0, self->parent.row_stride[2]);
|
||||
} else {
|
||||
memcpy (out, scanlines->m1, self->parent.row_stride[2]);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -113,7 +129,7 @@ gst_deinterlace_method_weave_class_init (GstDeinterlaceMethodWeaveClass * klass)
|
|||
dim_class->fields_required = 2;
|
||||
dim_class->name = "Weave";
|
||||
dim_class->nick = "weave";
|
||||
dim_class->latency = 0;
|
||||
dim_class->latency = 1;
|
||||
|
||||
dism_class->interpolate_scanline_ayuv = deinterlace_scanline_weave_packed;
|
||||
dism_class->interpolate_scanline_yuy2 = deinterlace_scanline_weave_packed;
|
||||
|
|
|
@ -48,76 +48,72 @@ static void
|
|||
deinterlace_scanline_weave_packed (GstDeinterlaceSimpleMethod * self,
|
||||
guint8 * out, const GstDeinterlaceScanlineData * scanlines)
|
||||
{
|
||||
memcpy (out, scanlines->m1, self->parent.row_stride[0]);
|
||||
if (scanlines->m1 == NULL) {
|
||||
memcpy (out, scanlines->b0, self->parent.row_stride[0]);
|
||||
} else {
|
||||
memcpy (out, scanlines->m1, self->parent.row_stride[0]);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
deinterlace_scanline_weave_planar_y (GstDeinterlaceSimpleMethod * self,
|
||||
guint8 * out, const GstDeinterlaceScanlineData * scanlines)
|
||||
{
|
||||
memcpy (out, scanlines->m1, self->parent.row_stride[0]);
|
||||
if (scanlines->m1 == NULL) {
|
||||
memcpy (out, scanlines->b0, self->parent.row_stride[0]);
|
||||
} else {
|
||||
memcpy (out, scanlines->m1, self->parent.row_stride[0]);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
deinterlace_scanline_weave_planar_u (GstDeinterlaceSimpleMethod * self,
|
||||
guint8 * out, const GstDeinterlaceScanlineData * scanlines)
|
||||
{
|
||||
memcpy (out, scanlines->m1, self->parent.row_stride[1]);
|
||||
if (scanlines->m1 == NULL) {
|
||||
memcpy (out, scanlines->b0, self->parent.row_stride[1]);
|
||||
} else {
|
||||
memcpy (out, scanlines->m1, self->parent.row_stride[1]);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
deinterlace_scanline_weave_planar_v (GstDeinterlaceSimpleMethod * self,
|
||||
guint8 * out, const GstDeinterlaceScanlineData * scanlines)
|
||||
{
|
||||
memcpy (out, scanlines->m1, self->parent.row_stride[2]);
|
||||
if (scanlines->m1 == NULL) {
|
||||
memcpy (out, scanlines->b0, self->parent.row_stride[2]);
|
||||
} else {
|
||||
memcpy (out, scanlines->m1, self->parent.row_stride[2]);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
copy_scanline_packed (GstDeinterlaceSimpleMethod * self, guint8 * out,
|
||||
const GstDeinterlaceScanlineData * scanlines)
|
||||
{
|
||||
/* FIXME: original code used m2 and m0 but this looks really bad */
|
||||
if (scanlines->bottom_field) {
|
||||
memcpy (out, scanlines->bb2, self->parent.row_stride[0]);
|
||||
} else {
|
||||
memcpy (out, scanlines->bb0, self->parent.row_stride[0]);
|
||||
}
|
||||
memcpy (out, scanlines->m0, self->parent.row_stride[0]);
|
||||
}
|
||||
|
||||
static void
|
||||
copy_scanline_planar_y (GstDeinterlaceSimpleMethod * self, guint8 * out,
|
||||
const GstDeinterlaceScanlineData * scanlines)
|
||||
{
|
||||
/* FIXME: original code used m2 and m0 but this looks really bad */
|
||||
if (scanlines->bottom_field) {
|
||||
memcpy (out, scanlines->bb2, self->parent.row_stride[0]);
|
||||
} else {
|
||||
memcpy (out, scanlines->bb0, self->parent.row_stride[0]);
|
||||
}
|
||||
memcpy (out, scanlines->m0, self->parent.row_stride[0]);
|
||||
}
|
||||
|
||||
static void
|
||||
copy_scanline_planar_u (GstDeinterlaceSimpleMethod * self, guint8 * out,
|
||||
const GstDeinterlaceScanlineData * scanlines)
|
||||
{
|
||||
/* FIXME: original code used m2 and m0 but this looks really bad */
|
||||
if (scanlines->bottom_field) {
|
||||
memcpy (out, scanlines->bb2, self->parent.row_stride[1]);
|
||||
} else {
|
||||
memcpy (out, scanlines->bb0, self->parent.row_stride[1]);
|
||||
}
|
||||
memcpy (out, scanlines->m0, self->parent.row_stride[1]);
|
||||
}
|
||||
|
||||
static void
|
||||
copy_scanline_planar_v (GstDeinterlaceSimpleMethod * self, guint8 * out,
|
||||
const GstDeinterlaceScanlineData * scanlines)
|
||||
{
|
||||
/* FIXME: original code used m2 and m0 but this looks really bad */
|
||||
if (scanlines->bottom_field) {
|
||||
memcpy (out, scanlines->bb2, self->parent.row_stride[2]);
|
||||
} else {
|
||||
memcpy (out, scanlines->bb0, self->parent.row_stride[2]);
|
||||
}
|
||||
memcpy (out, scanlines->m0, self->parent.row_stride[2]);
|
||||
}
|
||||
|
||||
G_DEFINE_TYPE (GstDeinterlaceMethodWeaveBFF, gst_deinterlace_method_weave_bff,
|
||||
|
@ -131,10 +127,10 @@ gst_deinterlace_method_weave_bff_class_init (GstDeinterlaceMethodWeaveBFFClass *
|
|||
GstDeinterlaceSimpleMethodClass *dism_class =
|
||||
(GstDeinterlaceSimpleMethodClass *) klass;
|
||||
|
||||
dim_class->fields_required = 3;
|
||||
dim_class->fields_required = 2;
|
||||
dim_class->name = "Progressive: Bottom Field First";
|
||||
dim_class->nick = "weavebff";
|
||||
dim_class->latency = 0;
|
||||
dim_class->latency = 1;
|
||||
|
||||
dism_class->interpolate_scanline_ayuv = deinterlace_scanline_weave_packed;
|
||||
dism_class->interpolate_scanline_yuy2 = deinterlace_scanline_weave_packed;
|
||||
|
|
|
@ -49,76 +49,72 @@ static void
|
|||
deinterlace_scanline_weave_packed (GstDeinterlaceSimpleMethod * self,
|
||||
guint8 * out, const GstDeinterlaceScanlineData * scanlines)
|
||||
{
|
||||
memcpy (out, scanlines->m1, self->parent.row_stride[0]);
|
||||
if (scanlines->m1 == NULL) {
|
||||
memcpy (out, scanlines->t0, self->parent.row_stride[0]);
|
||||
} else {
|
||||
memcpy (out, scanlines->m1, self->parent.row_stride[0]);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
deinterlace_scanline_weave_planar_y (GstDeinterlaceSimpleMethod * self,
|
||||
guint8 * out, const GstDeinterlaceScanlineData * scanlines)
|
||||
{
|
||||
memcpy (out, scanlines->m1, self->parent.row_stride[0]);
|
||||
if (scanlines->m1 == NULL) {
|
||||
memcpy (out, scanlines->t0, self->parent.row_stride[0]);
|
||||
} else {
|
||||
memcpy (out, scanlines->m1, self->parent.row_stride[0]);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
deinterlace_scanline_weave_planar_u (GstDeinterlaceSimpleMethod * self,
|
||||
guint8 * out, const GstDeinterlaceScanlineData * scanlines)
|
||||
{
|
||||
memcpy (out, scanlines->m1, self->parent.row_stride[1]);
|
||||
if (scanlines->m1 == NULL) {
|
||||
memcpy (out, scanlines->t0, self->parent.row_stride[1]);
|
||||
} else {
|
||||
memcpy (out, scanlines->m1, self->parent.row_stride[1]);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
deinterlace_scanline_weave_planar_v (GstDeinterlaceSimpleMethod * self,
|
||||
guint8 * out, const GstDeinterlaceScanlineData * scanlines)
|
||||
{
|
||||
memcpy (out, scanlines->m1, self->parent.row_stride[2]);
|
||||
if (scanlines->m1 == NULL) {
|
||||
memcpy (out, scanlines->t0, self->parent.row_stride[2]);
|
||||
} else {
|
||||
memcpy (out, scanlines->m1, self->parent.row_stride[2]);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
copy_scanline_packed (GstDeinterlaceSimpleMethod * self,
|
||||
guint8 * out, const GstDeinterlaceScanlineData * scanlines)
|
||||
{
|
||||
/* FIXME: original code used m2 and m0 but this looks really bad */
|
||||
if (scanlines->bottom_field) {
|
||||
memcpy (out, scanlines->bb0, self->parent.row_stride[0]);
|
||||
} else {
|
||||
memcpy (out, scanlines->bb2, self->parent.row_stride[0]);
|
||||
}
|
||||
memcpy (out, scanlines->m0, self->parent.row_stride[0]);
|
||||
}
|
||||
|
||||
static void
|
||||
copy_scanline_planar_y (GstDeinterlaceSimpleMethod * self,
|
||||
guint8 * out, const GstDeinterlaceScanlineData * scanlines)
|
||||
{
|
||||
/* FIXME: original code used m2 and m0 but this looks really bad */
|
||||
if (scanlines->bottom_field) {
|
||||
memcpy (out, scanlines->bb0, self->parent.row_stride[0]);
|
||||
} else {
|
||||
memcpy (out, scanlines->bb2, self->parent.row_stride[0]);
|
||||
}
|
||||
memcpy (out, scanlines->m0, self->parent.row_stride[0]);
|
||||
}
|
||||
|
||||
static void
|
||||
copy_scanline_planar_u (GstDeinterlaceSimpleMethod * self,
|
||||
guint8 * out, const GstDeinterlaceScanlineData * scanlines)
|
||||
{
|
||||
/* FIXME: original code used m2 and m0 but this looks really bad */
|
||||
if (scanlines->bottom_field) {
|
||||
memcpy (out, scanlines->bb0, self->parent.row_stride[1]);
|
||||
} else {
|
||||
memcpy (out, scanlines->bb2, self->parent.row_stride[1]);
|
||||
}
|
||||
memcpy (out, scanlines->m0, self->parent.row_stride[1]);
|
||||
}
|
||||
|
||||
static void
|
||||
copy_scanline_planar_v (GstDeinterlaceSimpleMethod * self,
|
||||
guint8 * out, const GstDeinterlaceScanlineData * scanlines)
|
||||
{
|
||||
/* FIXME: original code used m2 and m0 but this looks really bad */
|
||||
if (scanlines->bottom_field) {
|
||||
memcpy (out, scanlines->bb0, self->parent.row_stride[2]);
|
||||
} else {
|
||||
memcpy (out, scanlines->bb2, self->parent.row_stride[2]);
|
||||
}
|
||||
memcpy (out, scanlines->m0, self->parent.row_stride[2]);
|
||||
}
|
||||
|
||||
G_DEFINE_TYPE (GstDeinterlaceMethodWeaveTFF, gst_deinterlace_method_weave_tff,
|
||||
|
@ -132,10 +128,10 @@ gst_deinterlace_method_weave_tff_class_init (GstDeinterlaceMethodWeaveTFFClass *
|
|||
GstDeinterlaceSimpleMethodClass *dism_class =
|
||||
(GstDeinterlaceSimpleMethodClass *) klass;
|
||||
|
||||
dim_class->fields_required = 3;
|
||||
dim_class->fields_required = 2;
|
||||
dim_class->name = "Progressive: Top Field First";
|
||||
dim_class->nick = "weavetff";
|
||||
dim_class->latency = 0;
|
||||
dim_class->latency = 1;
|
||||
|
||||
dism_class->interpolate_scanline_ayuv = deinterlace_scanline_weave_packed;
|
||||
dism_class->interpolate_scanline_yuy2 = deinterlace_scanline_weave_packed;
|
||||
|
|
|
@ -374,6 +374,7 @@ gst_multi_file_sink_stop (GstBaseSink * sink)
|
|||
gst_buffer_unref (multifilesink->streamheaders[i]);
|
||||
}
|
||||
g_free (multifilesink->streamheaders);
|
||||
multifilesink->streamheaders = NULL;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
|
|
|
@ -322,7 +322,7 @@ gst_multi_file_src_get_filename (GstMultiFileSrc * multifilesrc)
|
|||
{
|
||||
gchar *filename;
|
||||
|
||||
GST_ERROR ("%d", multifilesrc->index);
|
||||
GST_DEBUG ("%d", multifilesrc->index);
|
||||
filename = g_strdup_printf (multifilesrc->filename, multifilesrc->index);
|
||||
|
||||
return filename;
|
||||
|
|
Loading…
Reference in a new issue