gst/deinterlace2/tvtime/greedy.c: Don't use scanlines function from gstdeinterlace2 as it's not appropiate for this m...

Original commit message from CVS:
* gst/deinterlace2/tvtime/greedy.c:
(deinterlace_greedy_packed422_scanline_c),
(deinterlace_greedy_packed422_scanline_mmx),
(deinterlace_greedy_packed422_scanline_mmxext),
(deinterlace_frame_di_greedy):
Don't use scanlines function from gstdeinterlace2 as it's
not appropiate for this method. Instead implement deinterlace_frame
function by taking the one from greedyh.
* gst/deinterlace2/tvtime/greedyh.c: (greedyDScaler_C):
Small fix for the C implementation.
* gst/deinterlace2/tvtime/vfir.c: (deinterlace_frame_vfir):
Don't use the scanlines function from gstdeinterlace2 as it's only
used for this method and will be removed. Instead implement
deinterlace_frame function and make it a bit more efficient.
* gst/deinterlace2/gstdeinterlace2.c:
(gst_deinterlace2_class_init), (gst_deinterlace2_set_method),
(gst_deinterlace2_push_history), (gst_deinterlace2_chain),
(gst_deinterlace2_setcaps), (gst_deinterlace2_sink_event),
(gst_deinterlace2_change_state), (gst_deinterlace2_src_event),
(gst_deinterlace2_src_query):
Fix coding style and remove scanlines function as it's unused now.
This commit is contained in:
Sebastian Dröge 2008-06-28 18:10:52 +00:00
parent aae071d922
commit f30962901c
5 changed files with 172 additions and 200 deletions

View file

@ -1,3 +1,30 @@
2008-06-28 Sebastian Dröge <sebastian.droege@collabora.co.uk>
* gst/deinterlace2/tvtime/greedy.c:
(deinterlace_greedy_packed422_scanline_c),
(deinterlace_greedy_packed422_scanline_mmx),
(deinterlace_greedy_packed422_scanline_mmxext),
(deinterlace_frame_di_greedy):
Don't use scanlines function from gstdeinterlace2 as it's
not appropiate for this method. Instead implement deinterlace_frame
function by taking the one from greedyh.
* gst/deinterlace2/tvtime/greedyh.c: (greedyDScaler_C):
Small fix for the C implementation.
* gst/deinterlace2/tvtime/vfir.c: (deinterlace_frame_vfir):
Don't use the scanlines function from gstdeinterlace2 as it's only
used for this method and will be removed. Instead implement
deinterlace_frame function and make it a bit more efficient.
* gst/deinterlace2/gstdeinterlace2.c:
(gst_deinterlace2_class_init), (gst_deinterlace2_set_method),
(gst_deinterlace2_push_history), (gst_deinterlace2_chain),
(gst_deinterlace2_setcaps), (gst_deinterlace2_sink_event),
(gst_deinterlace2_change_state), (gst_deinterlace2_src_event),
(gst_deinterlace2_src_query):
Fix coding style and remove scanlines function as it's unused now.
2008-06-28 Sebastian Dröge <sebastian.droege@collabora.co.uk> 2008-06-28 Sebastian Dröge <sebastian.droege@collabora.co.uk>
* gst/deinterlace2/tvtime/greedyh.asm: * gst/deinterlace2/tvtime/greedyh.asm:

View file

@ -125,29 +125,21 @@ static GstStaticPadTemplate sink_templ = GST_STATIC_PAD_TEMPLATE ("sink",
); );
static void gst_deinterlace2_finalize (GObject * object); static void gst_deinterlace2_finalize (GObject * object);
static void gst_deinterlace2_set_property (GObject * object, guint prop_id, static void gst_deinterlace2_set_property (GObject * object, guint prop_id,
const GValue * value, GParamSpec * pspec); const GValue * value, GParamSpec * pspec);
static void gst_deinterlace2_get_property (GObject * object, guint prop_id, static void gst_deinterlace2_get_property (GObject * object, guint prop_id,
GValue * value, GParamSpec * pspec); GValue * value, GParamSpec * pspec);
static gboolean gst_deinterlace2_setcaps (GstPad * pad, GstCaps * caps); static gboolean gst_deinterlace2_setcaps (GstPad * pad, GstCaps * caps);
static gboolean gst_deinterlace2_sink_event (GstPad * pad, GstEvent * event); static gboolean gst_deinterlace2_sink_event (GstPad * pad, GstEvent * event);
static GstFlowReturn gst_deinterlace2_chain (GstPad * pad, GstBuffer * buffer); static GstFlowReturn gst_deinterlace2_chain (GstPad * pad, GstBuffer * buffer);
static GstStateChangeReturn gst_deinterlace2_change_state (GstElement * element, static GstStateChangeReturn gst_deinterlace2_change_state (GstElement * element,
GstStateChange transition); GstStateChange transition);
static gboolean gst_deinterlace2_src_event (GstPad * pad, GstEvent * event); static gboolean gst_deinterlace2_src_event (GstPad * pad, GstEvent * event);
static gboolean gst_deinterlace2_src_query (GstPad * pad, GstQuery * query); static gboolean gst_deinterlace2_src_query (GstPad * pad, GstQuery * query);
static const GstQueryType *gst_deinterlace2_src_query_types (GstPad * pad); static const GstQueryType *gst_deinterlace2_src_query_types (GstPad * pad);
static void gst_deinterlace2_deinterlace_scanlines (GstDeinterlace2 * object);
static void gst_deinterlace2_reset (GstDeinterlace2 * object); static void gst_deinterlace2_reset (GstDeinterlace2 * object);
GST_BOILERPLATE (GstDeinterlace2, gst_deinterlace2, GstElement, GST_BOILERPLATE (GstDeinterlace2, gst_deinterlace2, GstElement,
@ -198,7 +190,6 @@ gst_deinterlace2_class_init (GstDeinterlace2Class * klass)
GST_DEINTERLACE2_ALL, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS) GST_DEINTERLACE2_ALL, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)
); );
g_object_class_install_property (gobject_class, ARG_FIELDS, g_object_class_install_property (gobject_class, ARG_FIELDS,
g_param_spec_enum ("tff", g_param_spec_enum ("tff",
"tff", "tff",
@ -314,14 +305,9 @@ gst_deinterlace2_set_method (GstDeinterlace2 * object,
GST_WARNING ("Invalid Deinterlacer Method"); GST_WARNING ("Invalid Deinterlacer Method");
} }
if (object->method->deinterlace_frame == NULL)
object->method->deinterlace_frame = gst_deinterlace2_deinterlace_scanlines;
/* TODO: if current method requires less fields in the history, /* TODO: if current method requires less fields in the history,
pop the diff from field_history. pop the diff from field_history.
*/ */
} }
static void static void
@ -422,9 +408,7 @@ static void
gst_deinterlace2_push_history (GstDeinterlace2 * object, GstBuffer * buffer) gst_deinterlace2_push_history (GstDeinterlace2 * object, GstBuffer * buffer)
{ {
int i = 1; int i = 1;
GstClockTime timestamp; GstClockTime timestamp;
GstClockTime field_diff; GstClockTime field_diff;
g_assert (object->history_count < MAX_FIELD_HISTORY - 2); g_assert (object->history_count < MAX_FIELD_HISTORY - 2);
@ -470,122 +454,11 @@ gst_deinterlace2_push_history (GstDeinterlace2 * object, GstBuffer * buffer)
GST_DEBUG ("push, size(history): %d", object->history_count); GST_DEBUG ("push, size(history): %d", object->history_count);
} }
/* some methods support only deinterlace_/copy_scanline functions.
This funtion calls them in the right manner. */
static void
gst_deinterlace2_deinterlace_scanlines (GstDeinterlace2 * object)
{
gint line = 1;
gint cur_field_idx = object->history_count - object->method->fields_required;
GST_INFO ("cur_field_idx: %d", cur_field_idx);
guint8 *out_data = GST_BUFFER_DATA (object->out_buf);
guint8 *cur_field =
GST_BUFFER_DATA (object->field_history[cur_field_idx].buf);
guint8 *last_field = NULL;
guint8 *second_last_field = NULL;
/* method can just handle up to 3 history fields,
bcs until now there isn't a plugin (with interp./copy scanline methods)
that uses more */
g_assert (object->method->fields_required <= 3);
if (object->method->fields_required >= 2) {
last_field = GST_BUFFER_DATA (object->field_history[cur_field_idx + 1].buf);
}
if (object->method->fields_required >= 3) {
second_last_field =
GST_BUFFER_DATA (object->field_history[cur_field_idx + 2].buf);
}
if (object->field_history[cur_field_idx].flags == PICTURE_INTERLACED_BOTTOM) {
/* double the first scanline of the bottom field */
blit_packed422_scanline (out_data, cur_field, object->frame_width);
out_data += object->output_stride;
}
blit_packed422_scanline (out_data, cur_field, object->frame_width);
out_data += object->output_stride;
line++;
for (; line <= object->field_height;) {
deinterlace_scanline_data_t data;
/* interp. scanline */
data.t0 = cur_field;
data.b0 = cur_field + object->field_stride;
if (last_field != NULL) {
data.tt1 = last_field;
data.m1 = last_field + object->field_stride;
data.bb1 = last_field + (object->field_stride * 2);
last_field += object->field_stride;
}
if (second_last_field != NULL) {
data.t2 = second_last_field;
data.b2 = second_last_field + object->field_stride;
}
/* set valid data for corner cases */
if (line == 2) {
data.tt1 = data.bb1;
} else if (line == object->field_height) {
data.bb1 = data.tt1;
}
object->method->interpolate_scanline (object, &data, out_data);
out_data += object->output_stride;
/* copy a scanline */
data.tt0 = cur_field;
data.m0 = cur_field + (object->field_stride);
data.bb0 = cur_field + (object->field_stride * 2);
cur_field += object->field_stride;
if (last_field != NULL) {
data.t1 = last_field;
data.b1 = last_field + object->field_stride;
}
if (second_last_field != NULL) {
data.tt2 = second_last_field;
data.m2 = second_last_field + (object->field_stride);
data.bb2 = second_last_field + (object->field_stride * 2);
second_last_field += object->field_stride;
}
/* set valid data for corner cases */
if (line == object->field_height) {
data.bb0 = data.tt0;
data.bb2 = data.tt2;
data.b1 = data.t1;
}
object->method->copy_scanline (object, &data, out_data);
out_data += object->output_stride;
line++;
}
if (object->field_history[cur_field_idx].flags == PICTURE_INTERLACED_TOP) {
/* double the last scanline of the top field */
blit_packed422_scanline (out_data, cur_field, object->frame_width);
}
}
static GstFlowReturn static GstFlowReturn
gst_deinterlace2_chain (GstPad * pad, GstBuffer * buf) gst_deinterlace2_chain (GstPad * pad, GstBuffer * buf)
{ {
GstDeinterlace2 *object = NULL; GstDeinterlace2 *object = NULL;
GstClockTime timestamp; GstClockTime timestamp;
GstFlowReturn ret = GST_FLOW_OK; GstFlowReturn ret = GST_FLOW_OK;
object = GST_DEINTERLACE2 (GST_PAD_PARENT (pad)); object = GST_DEINTERLACE2 (GST_PAD_PARENT (pad));
@ -750,8 +623,7 @@ gst_deinterlace2_setcaps (GstPad * pad, GstCaps * caps)
othercaps = gst_caps_ref (caps); othercaps = gst_caps_ref (caps);
} }
if ( /*!gst_pad_accept_caps (otherpad, othercaps) if (!gst_pad_set_caps (otherpad, othercaps))
|| */ !gst_pad_set_caps (otherpad, othercaps))
goto caps_not_accepted; goto caps_not_accepted;
gst_caps_unref (othercaps); gst_caps_unref (othercaps);
@ -797,7 +669,6 @@ static gboolean
gst_deinterlace2_sink_event (GstPad * pad, GstEvent * event) gst_deinterlace2_sink_event (GstPad * pad, GstEvent * event)
{ {
gboolean res = TRUE; gboolean res = TRUE;
GstDeinterlace2 *object = GST_DEINTERLACE2 (gst_pad_get_parent (pad)); GstDeinterlace2 *object = GST_DEINTERLACE2 (gst_pad_get_parent (pad));
GST_LOG_OBJECT (pad, "received %s event", GST_EVENT_TYPE_NAME (event)); GST_LOG_OBJECT (pad, "received %s event", GST_EVENT_TYPE_NAME (event));
@ -822,7 +693,6 @@ static GstStateChangeReturn
gst_deinterlace2_change_state (GstElement * element, GstStateChange transition) gst_deinterlace2_change_state (GstElement * element, GstStateChange transition)
{ {
GstStateChangeReturn ret; GstStateChangeReturn ret;
GstDeinterlace2 *object = GST_DEINTERLACE2 (element); GstDeinterlace2 *object = GST_DEINTERLACE2 (element);
switch (transition) { switch (transition) {
@ -858,7 +728,6 @@ static gboolean
gst_deinterlace2_src_event (GstPad * pad, GstEvent * event) gst_deinterlace2_src_event (GstPad * pad, GstEvent * event)
{ {
GstDeinterlace2 *object = GST_DEINTERLACE2 (gst_pad_get_parent (pad)); GstDeinterlace2 *object = GST_DEINTERLACE2 (gst_pad_get_parent (pad));
gboolean res; gboolean res;
GST_DEBUG_OBJECT (pad, "received %s event", GST_EVENT_TYPE_NAME (event)); GST_DEBUG_OBJECT (pad, "received %s event", GST_EVENT_TYPE_NAME (event));
@ -878,7 +747,6 @@ static gboolean
gst_deinterlace2_src_query (GstPad * pad, GstQuery * query) gst_deinterlace2_src_query (GstPad * pad, GstQuery * query)
{ {
GstDeinterlace2 *object = GST_DEINTERLACE2 (gst_pad_get_parent (pad)); GstDeinterlace2 *object = GST_DEINTERLACE2 (gst_pad_get_parent (pad));
gboolean res = FALSE; gboolean res = FALSE;
GST_LOG_OBJECT (object, "%s query", GST_QUERY_TYPE_NAME (query)); GST_LOG_OBJECT (object, "%s query", GST_QUERY_TYPE_NAME (query));
@ -887,9 +755,7 @@ gst_deinterlace2_src_query (GstPad * pad, GstQuery * query)
case GST_QUERY_LATENCY: case GST_QUERY_LATENCY:
{ {
GstClockTime min, max; GstClockTime min, max;
gboolean live; gboolean live;
GstPad *peer; GstPad *peer;
if ((peer = gst_pad_get_peer (object->sinkpad))) { if ((peer = gst_pad_get_peer (object->sinkpad))) {

View file

@ -53,19 +53,11 @@
// I'd intended this to be part of a larger more elaborate method added to // I'd intended this to be part of a larger more elaborate method added to
// Blended Clip but this give too good results for the CPU to ignore here. // Blended Clip but this give too good results for the CPU to ignore here.
static void
copy_scanline (GstDeinterlace2 * object,
deinterlace_scanline_data_t * data, uint8_t * output)
{
blit_packed422_scanline (output, data->m1, object->frame_width);
}
static const int GreedyMaxComb = 15; static const int GreedyMaxComb = 15;
static inline void static inline void
deinterlace_greedy_packed422_scanline_c (GstDeinterlace2 * object, deinterlace_greedy_packed422_scanline_c (uint8_t * m0, uint8_t * t1,
uint8_t * m0, uint8_t * t1, uint8_t * b1, uint8_t * m2, uint8_t * output, uint8_t * b1, uint8_t * m2, uint8_t * output, int width)
int width)
{ {
int avg, l2_diff, lp2_diff, max, min, best; int avg, l2_diff, lp2_diff, max, min, best;
@ -112,9 +104,8 @@ deinterlace_greedy_packed422_scanline_c (GstDeinterlace2 * object,
#ifdef HAVE_CPU_I386 #ifdef HAVE_CPU_I386
#include "mmx.h" #include "mmx.h"
static void static void
deinterlace_greedy_packed422_scanline_mmx (GstDeinterlace2 * object, deinterlace_greedy_packed422_scanline_mmx (uint8_t * m0, uint8_t * t1,
uint8_t * m0, uint8_t * t1, uint8_t * b1, uint8_t * m2, uint8_t * output, uint8_t * b1, uint8_t * m2, uint8_t * output, int width)
int width)
{ {
mmx_t MaxComb; mmx_t MaxComb;
@ -222,16 +213,14 @@ deinterlace_greedy_packed422_scanline_mmx (GstDeinterlace2 * object,
} }
emms (); emms ();
if (width > 0) if (width > 0)
deinterlace_greedy_packed422_scanline_c (object, m0, t1, b1, m2, output, deinterlace_greedy_packed422_scanline_c (m0, t1, b1, m2, output, width);
width);
} }
#include "sse.h" #include "sse.h"
static void static void
deinterlace_greedy_packed422_scanline_mmxext (GstDeinterlace2 * object, deinterlace_greedy_packed422_scanline_mmxext (uint8_t * m0, uint8_t * t1,
uint8_t * m0, uint8_t * t1, uint8_t * b1, uint8_t * m2, uint8_t * output, uint8_t * b1, uint8_t * m2, uint8_t * output, int width)
int width)
{ {
mmx_t MaxComb; mmx_t MaxComb;
@ -316,47 +305,104 @@ deinterlace_greedy_packed422_scanline_mmxext (GstDeinterlace2 * object,
emms (); emms ();
if (width > 0) if (width > 0)
deinterlace_greedy_packed422_scanline_c (object, m0, t1, b1, m2, output, deinterlace_greedy_packed422_scanline_c (m0, t1, b1, m2, output, width);
width);
} }
#endif #endif
static void static void
deinterlace_greedy_packed422_scanline (GstDeinterlace2 * object, deinterlace_frame_di_greedy (GstDeinterlace2 * object)
deinterlace_scanline_data_t * data, uint8_t * output)
{ {
void (*func) (uint8_t * L2, uint8_t * L1, uint8_t * L3, uint8_t * L2P,
uint8_t * Dest, int size);
int InfoIsOdd = 0;
int Line;
unsigned int Pitch = object->field_stride;
unsigned char *L1; // ptr to Line1, of 3
unsigned char *L2; // ptr to Line2, the weave line
unsigned char *L3; // ptr to Line3
unsigned char *L2P; // ptr to prev Line2
unsigned char *Dest = GST_BUFFER_DATA (object->out_buf);
#ifdef HAVE_CPU_I386 #ifdef HAVE_CPU_I386
if (object->cpu_feature_flags & OIL_IMPL_FLAG_MMXEXT) { if (object->cpu_feature_flags & OIL_IMPL_FLAG_MMXEXT) {
deinterlace_greedy_packed422_scanline_mmxext (object, data->m0, data->t1, func = deinterlace_greedy_packed422_scanline_mmxext;
data->b1, data->m2, output, 2 * object->frame_width);
} else if (object->cpu_feature_flags & OIL_IMPL_FLAG_MMX) { } else if (object->cpu_feature_flags & OIL_IMPL_FLAG_MMX) {
deinterlace_greedy_packed422_scanline_mmx (object, data->m0, data->t1, func = deinterlace_greedy_packed422_scanline_mmx;
data->b1, data->m2, output, 2 * object->frame_width);
} else { } else {
deinterlace_greedy_packed422_scanline_c (object, data->m0, data->t1, func = deinterlace_greedy_packed422_scanline_c;
data->b1, data->m2, output, 2 * object->frame_width);
} }
#else #else
deinterlace_greedy_packed422_scanline_c (object, data->m0, data->t1, data->b1, func = deinterlace_greedy_packed422_scanline_c;
data->m2, output, 2 * object->frame_width);
#endif #endif
}
// 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 (object->field_history[object->history_count - 1].flags ==
PICTURE_INTERLACED_BOTTOM) {
InfoIsOdd = 1;
L1 = GST_BUFFER_DATA (object->field_history[object->history_count - 2].buf);
L2 = GST_BUFFER_DATA (object->field_history[object->history_count - 1].buf);
L3 = L1 + Pitch;
L2P =
GST_BUFFER_DATA (object->field_history[object->history_count - 3].buf);
// copy first even line
object->pMemcpy (Dest, L1, object->line_length);
Dest += object->output_stride;
} else {
InfoIsOdd = 0;
L1 = GST_BUFFER_DATA (object->field_history[object->history_count - 2].buf);
L2 = GST_BUFFER_DATA (object->field_history[object->history_count -
1].buf) + Pitch;
L3 = L1 + Pitch;
L2P =
GST_BUFFER_DATA (object->field_history[object->history_count - 3].buf) +
Pitch;
// copy first even line
object->pMemcpy (Dest, GST_BUFFER_DATA (object->field_history[0].buf),
object->line_length);
Dest += object->output_stride;
// then first odd line
object->pMemcpy (Dest, L1, object->line_length);
Dest += object->output_stride;
}
for (Line = 0; Line < (object->field_height - 1); ++Line) {
func (L2, L1, L3, L2P, Dest, object->line_length);
Dest += object->output_stride;
object->pMemcpy (Dest, L3, object->line_length);
Dest += object->output_stride;
L1 += Pitch;
L2 += Pitch;
L3 += Pitch;
L2P += Pitch;
}
if (InfoIsOdd) {
object->pMemcpy (Dest, L2, object->line_length);
}
}
static deinterlace_method_t greedyl_method = { static deinterlace_method_t greedyl_method = {
0, //DEINTERLACE_PLUGIN_API_VERSION, 0, //DEINTERLACE_PLUGIN_API_VERSION,
"Motion Adaptive: Simple Detection", "Motion Adaptive: Simple Detection",
"AdaptiveSimple", "AdaptiveSimple",
3, 4,
0, 0,
0, 0,
0, 0,
0, 0,
1, 1,
copy_scanline,
deinterlace_greedy_packed422_scanline,
0, 0,
0,
deinterlace_frame_di_greedy,
{"Uses heuristics to detect motion in the input", {"Uses heuristics to detect motion in the input",
"frames and reconstruct image detail where", "frames and reconstruct image detail where",
"possible. Use this for high quality output", "possible. Use this for high quality output",

View file

@ -85,6 +85,11 @@ greedyDScaler_C (uint8_t * L1, uint8_t * L2, uint8_t * L3, uint8_t * L2P,
avg_l = (l1_l + l3_l) / 2; avg_l = (l1_l + l3_l) / 2;
avg_c = (l1_c + l3_c) / 2; avg_c = (l1_c + l3_c) / 2;
if (Pos == 0) {
avg_l__1 = avg_l;
avg_c__1 = avg_c;
}
/* Average of next L1 and next L3 */ /* Average of next L1 and next L3 */
avg_l_1 = (l1_1_l + l3_1_l) / 2; avg_l_1 = (l1_1_l + l3_1_l) / 2;
avg_c_1 = (l1_1_c + l3_1_c) / 2; avg_c_1 = (l1_1_c + l3_1_c) / 2;

View file

@ -127,45 +127,73 @@ deinterlace_line_mmx (uint8_t * dst, uint8_t * lum_m4,
} }
#endif #endif
/*
* The commented-out method below that uses the bottom_field member is more
* like the filter as specified in the MPEG2 spec, but it doesn't seem to
* have the desired effect.
*/
static void static void
deinterlace_scanline_vfir (GstDeinterlace2 * object, deinterlace_frame_vfir (GstDeinterlace2 * object)
deinterlace_scanline_data_t * data, uint8_t * output)
{ {
void (*func) (uint8_t * dst, uint8_t * lum_m4,
uint8_t * lum_m3, uint8_t * lum_m2,
uint8_t * lum_m1, uint8_t * lum, int size);
gint line = 0;
uint8_t *cur_field, *last_field;
uint8_t *t0, *b0, *tt1, *m1, *bb1, *out_data;
#ifdef HAVE_CPU_I386 #ifdef HAVE_CPU_I386
if (object->cpu_feature_flags & OIL_IMPL_FLAG_MMX) { if (object->cpu_feature_flags & OIL_IMPL_FLAG_MMX) {
deinterlace_line_mmx (output, data->tt1, data->t0, data->m1, data->b0, func = deinterlace_line_mmx;
data->bb1, object->frame_width * 2);
} else { } else {
deinterlace_line_c (output, data->tt1, data->t0, data->m1, data->b0, func = deinterlace_line_c;
data->bb1, object->frame_width * 2);
} }
#else #else
deinterlace_line_c (output, data->tt1, data->t0, data->m1, data->b0, func = deinterlace_line_c;
data->bb1, object->frame_width * 2);
#endif #endif
// blit_packed422_scanline( output, data->m1, width );
}
static void cur_field =
copy_scanline (GstDeinterlace2 * object, GST_BUFFER_DATA (object->field_history[object->history_count - 2].buf);
deinterlace_scanline_data_t * data, uint8_t * output) last_field =
{ GST_BUFFER_DATA (object->field_history[object->history_count - 1].buf);
blit_packed422_scanline (output, data->m0, object->frame_width);
/*
if( data->bottom_field ) {
deinterlace_line( output, data->tt2, data->t1, data->m2, data->b1, data->bb2, width*2 );
} else {
deinterlace_line( output, data->tt0, data->t1, data->m0, data->b1, data->bb0, width*2 );
}
*/
}
out_data = GST_BUFFER_DATA (object->out_buf);
if (object->field_history[object->history_count - 2].flags ==
PICTURE_INTERLACED_BOTTOM) {
blit_packed422_scanline (out_data, cur_field, object->frame_width);
out_data += object->output_stride;
}
blit_packed422_scanline (out_data, cur_field, object->frame_width);
out_data += object->output_stride;
line++;
for (; line < object->field_height; line++) {
t0 = cur_field;
b0 = cur_field + object->field_stride;
tt1 = last_field;
m1 = last_field + object->field_stride;
bb1 = last_field + (object->field_stride * 2);
/* set valid data for corner cases */
if (line == 1) {
tt1 = bb1;
} else if (line == object->field_height - 1) {
bb1 = tt1;
}
func (out_data, tt1, t0, m1, b0, bb1, object->line_length);
out_data += object->output_stride;
cur_field += object->field_stride;
last_field += object->field_stride;
blit_packed422_scanline (out_data, cur_field, object->frame_width);
out_data += object->output_stride;
}
if (object->field_history[object->history_count - 2].flags ==
PICTURE_INTERLACED_TOP) {
/* double the last scanline of the top field */
blit_packed422_scanline (out_data, cur_field, object->frame_width);
}
}
static deinterlace_method_t vfirmethod = { static deinterlace_method_t vfirmethod = {
0, //DEINTERLACE_PLUGIN_API_VERSION, 0, //DEINTERLACE_PLUGIN_API_VERSION,
@ -177,9 +205,9 @@ static deinterlace_method_t vfirmethod = {
0, 0,
0, 0,
1, 1,
deinterlace_scanline_vfir,
copy_scanline,
0, 0,
0,
deinterlace_frame_vfir,
{"Avoids flicker by blurring consecutive frames", {"Avoids flicker by blurring consecutive frames",
"of input. Use this if you want to run your", "of input. Use this if you want to run your",
"monitor at an arbitrary refresh rate and not", "monitor at an arbitrary refresh rate and not",