mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-19 08:11:16 +00:00
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:
parent
aae071d922
commit
f30962901c
5 changed files with 172 additions and 200 deletions
27
ChangeLog
27
ChangeLog
|
@ -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>
|
||||
|
||||
* gst/deinterlace2/tvtime/greedyh.asm:
|
||||
|
|
|
@ -125,29 +125,21 @@ static GstStaticPadTemplate sink_templ = GST_STATIC_PAD_TEMPLATE ("sink",
|
|||
);
|
||||
|
||||
static void gst_deinterlace2_finalize (GObject * object);
|
||||
|
||||
static void gst_deinterlace2_set_property (GObject * object, guint prop_id,
|
||||
const GValue * value, GParamSpec * pspec);
|
||||
static void gst_deinterlace2_get_property (GObject * object, guint prop_id,
|
||||
GValue * value, GParamSpec * pspec);
|
||||
|
||||
static gboolean gst_deinterlace2_setcaps (GstPad * pad, GstCaps * caps);
|
||||
|
||||
static gboolean gst_deinterlace2_sink_event (GstPad * pad, GstEvent * event);
|
||||
|
||||
static GstFlowReturn gst_deinterlace2_chain (GstPad * pad, GstBuffer * buffer);
|
||||
|
||||
static GstStateChangeReturn gst_deinterlace2_change_state (GstElement * element,
|
||||
GstStateChange transition);
|
||||
|
||||
static gboolean gst_deinterlace2_src_event (GstPad * pad, GstEvent * event);
|
||||
|
||||
static gboolean gst_deinterlace2_src_query (GstPad * pad, GstQuery * query);
|
||||
|
||||
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);
|
||||
|
||||
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)
|
||||
);
|
||||
|
||||
|
||||
g_object_class_install_property (gobject_class, ARG_FIELDS,
|
||||
g_param_spec_enum ("tff",
|
||||
"tff",
|
||||
|
@ -314,14 +305,9 @@ gst_deinterlace2_set_method (GstDeinterlace2 * object,
|
|||
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,
|
||||
pop the diff from field_history.
|
||||
*/
|
||||
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -422,9 +408,7 @@ static void
|
|||
gst_deinterlace2_push_history (GstDeinterlace2 * object, GstBuffer * buffer)
|
||||
{
|
||||
int i = 1;
|
||||
|
||||
GstClockTime timestamp;
|
||||
|
||||
GstClockTime field_diff;
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
/* 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
|
||||
gst_deinterlace2_chain (GstPad * pad, GstBuffer * buf)
|
||||
{
|
||||
GstDeinterlace2 *object = NULL;
|
||||
|
||||
GstClockTime timestamp;
|
||||
|
||||
GstFlowReturn ret = GST_FLOW_OK;
|
||||
|
||||
object = GST_DEINTERLACE2 (GST_PAD_PARENT (pad));
|
||||
|
@ -750,8 +623,7 @@ gst_deinterlace2_setcaps (GstPad * pad, GstCaps * caps)
|
|||
othercaps = gst_caps_ref (caps);
|
||||
}
|
||||
|
||||
if ( /*!gst_pad_accept_caps (otherpad, othercaps)
|
||||
|| */ !gst_pad_set_caps (otherpad, othercaps))
|
||||
if (!gst_pad_set_caps (otherpad, othercaps))
|
||||
goto caps_not_accepted;
|
||||
gst_caps_unref (othercaps);
|
||||
|
||||
|
@ -797,7 +669,6 @@ static gboolean
|
|||
gst_deinterlace2_sink_event (GstPad * pad, GstEvent * event)
|
||||
{
|
||||
gboolean res = TRUE;
|
||||
|
||||
GstDeinterlace2 *object = GST_DEINTERLACE2 (gst_pad_get_parent (pad));
|
||||
|
||||
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)
|
||||
{
|
||||
GstStateChangeReturn ret;
|
||||
|
||||
GstDeinterlace2 *object = GST_DEINTERLACE2 (element);
|
||||
|
||||
switch (transition) {
|
||||
|
@ -858,7 +728,6 @@ static gboolean
|
|||
gst_deinterlace2_src_event (GstPad * pad, GstEvent * event)
|
||||
{
|
||||
GstDeinterlace2 *object = GST_DEINTERLACE2 (gst_pad_get_parent (pad));
|
||||
|
||||
gboolean res;
|
||||
|
||||
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)
|
||||
{
|
||||
GstDeinterlace2 *object = GST_DEINTERLACE2 (gst_pad_get_parent (pad));
|
||||
|
||||
gboolean res = FALSE;
|
||||
|
||||
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:
|
||||
{
|
||||
GstClockTime min, max;
|
||||
|
||||
gboolean live;
|
||||
|
||||
GstPad *peer;
|
||||
|
||||
if ((peer = gst_pad_get_peer (object->sinkpad))) {
|
||||
|
|
|
@ -53,19 +53,11 @@
|
|||
// 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.
|
||||
|
||||
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 inline void
|
||||
deinterlace_greedy_packed422_scanline_c (GstDeinterlace2 * object,
|
||||
uint8_t * m0, uint8_t * t1, uint8_t * b1, uint8_t * m2, uint8_t * output,
|
||||
int width)
|
||||
deinterlace_greedy_packed422_scanline_c (uint8_t * m0, uint8_t * t1,
|
||||
uint8_t * b1, uint8_t * m2, uint8_t * output, int width)
|
||||
{
|
||||
int avg, l2_diff, lp2_diff, max, min, best;
|
||||
|
||||
|
@ -112,9 +104,8 @@ deinterlace_greedy_packed422_scanline_c (GstDeinterlace2 * object,
|
|||
#ifdef HAVE_CPU_I386
|
||||
#include "mmx.h"
|
||||
static void
|
||||
deinterlace_greedy_packed422_scanline_mmx (GstDeinterlace2 * object,
|
||||
uint8_t * m0, uint8_t * t1, uint8_t * b1, uint8_t * m2, uint8_t * output,
|
||||
int width)
|
||||
deinterlace_greedy_packed422_scanline_mmx (uint8_t * m0, uint8_t * t1,
|
||||
uint8_t * b1, uint8_t * m2, uint8_t * output, int width)
|
||||
{
|
||||
mmx_t MaxComb;
|
||||
|
||||
|
@ -222,16 +213,14 @@ deinterlace_greedy_packed422_scanline_mmx (GstDeinterlace2 * object,
|
|||
}
|
||||
emms ();
|
||||
if (width > 0)
|
||||
deinterlace_greedy_packed422_scanline_c (object, m0, t1, b1, m2, output,
|
||||
width);
|
||||
deinterlace_greedy_packed422_scanline_c (m0, t1, b1, m2, output, width);
|
||||
}
|
||||
|
||||
#include "sse.h"
|
||||
|
||||
static void
|
||||
deinterlace_greedy_packed422_scanline_mmxext (GstDeinterlace2 * object,
|
||||
uint8_t * m0, uint8_t * t1, uint8_t * b1, uint8_t * m2, uint8_t * output,
|
||||
int width)
|
||||
deinterlace_greedy_packed422_scanline_mmxext (uint8_t * m0, uint8_t * t1,
|
||||
uint8_t * b1, uint8_t * m2, uint8_t * output, int width)
|
||||
{
|
||||
mmx_t MaxComb;
|
||||
|
||||
|
@ -316,47 +305,104 @@ deinterlace_greedy_packed422_scanline_mmxext (GstDeinterlace2 * object,
|
|||
emms ();
|
||||
|
||||
if (width > 0)
|
||||
deinterlace_greedy_packed422_scanline_c (object, m0, t1, b1, m2, output,
|
||||
width);
|
||||
deinterlace_greedy_packed422_scanline_c (m0, t1, b1, m2, output, width);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
static void
|
||||
deinterlace_greedy_packed422_scanline (GstDeinterlace2 * object,
|
||||
deinterlace_scanline_data_t * data, uint8_t * output)
|
||||
deinterlace_frame_di_greedy (GstDeinterlace2 * object)
|
||||
{
|
||||
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
|
||||
if (object->cpu_feature_flags & OIL_IMPL_FLAG_MMXEXT) {
|
||||
deinterlace_greedy_packed422_scanline_mmxext (object, data->m0, data->t1,
|
||||
data->b1, data->m2, output, 2 * object->frame_width);
|
||||
func = deinterlace_greedy_packed422_scanline_mmxext;
|
||||
} else if (object->cpu_feature_flags & OIL_IMPL_FLAG_MMX) {
|
||||
deinterlace_greedy_packed422_scanline_mmx (object, data->m0, data->t1,
|
||||
data->b1, data->m2, output, 2 * object->frame_width);
|
||||
func = deinterlace_greedy_packed422_scanline_mmx;
|
||||
} else {
|
||||
deinterlace_greedy_packed422_scanline_c (object, data->m0, data->t1,
|
||||
data->b1, data->m2, output, 2 * object->frame_width);
|
||||
func = deinterlace_greedy_packed422_scanline_c;
|
||||
}
|
||||
#else
|
||||
deinterlace_greedy_packed422_scanline_c (object, data->m0, data->t1, data->b1,
|
||||
data->m2, output, 2 * object->frame_width);
|
||||
func = deinterlace_greedy_packed422_scanline_c;
|
||||
#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 = {
|
||||
0, //DEINTERLACE_PLUGIN_API_VERSION,
|
||||
"Motion Adaptive: Simple Detection",
|
||||
"AdaptiveSimple",
|
||||
3,
|
||||
4,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
copy_scanline,
|
||||
deinterlace_greedy_packed422_scanline,
|
||||
0,
|
||||
0,
|
||||
deinterlace_frame_di_greedy,
|
||||
{"Uses heuristics to detect motion in the input",
|
||||
"frames and reconstruct image detail where",
|
||||
"possible. Use this for high quality output",
|
||||
|
|
|
@ -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_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 */
|
||||
avg_l_1 = (l1_1_l + l3_1_l) / 2;
|
||||
avg_c_1 = (l1_1_c + l3_1_c) / 2;
|
||||
|
|
|
@ -127,45 +127,73 @@ deinterlace_line_mmx (uint8_t * dst, uint8_t * lum_m4,
|
|||
}
|
||||
#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
|
||||
deinterlace_scanline_vfir (GstDeinterlace2 * object,
|
||||
deinterlace_scanline_data_t * data, uint8_t * output)
|
||||
deinterlace_frame_vfir (GstDeinterlace2 * object)
|
||||
{
|
||||
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
|
||||
if (object->cpu_feature_flags & OIL_IMPL_FLAG_MMX) {
|
||||
deinterlace_line_mmx (output, data->tt1, data->t0, data->m1, data->b0,
|
||||
data->bb1, object->frame_width * 2);
|
||||
func = deinterlace_line_mmx;
|
||||
} else {
|
||||
deinterlace_line_c (output, data->tt1, data->t0, data->m1, data->b0,
|
||||
data->bb1, object->frame_width * 2);
|
||||
func = deinterlace_line_c;
|
||||
}
|
||||
#else
|
||||
deinterlace_line_c (output, data->tt1, data->t0, data->m1, data->b0,
|
||||
data->bb1, object->frame_width * 2);
|
||||
func = deinterlace_line_c;
|
||||
#endif
|
||||
// blit_packed422_scanline( output, data->m1, width );
|
||||
}
|
||||
|
||||
static void
|
||||
copy_scanline (GstDeinterlace2 * object,
|
||||
deinterlace_scanline_data_t * data, uint8_t * output)
|
||||
{
|
||||
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 );
|
||||
}
|
||||
*/
|
||||
}
|
||||
cur_field =
|
||||
GST_BUFFER_DATA (object->field_history[object->history_count - 2].buf);
|
||||
last_field =
|
||||
GST_BUFFER_DATA (object->field_history[object->history_count - 1].buf);
|
||||
|
||||
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 = {
|
||||
0, //DEINTERLACE_PLUGIN_API_VERSION,
|
||||
|
@ -177,9 +205,9 @@ static deinterlace_method_t vfirmethod = {
|
|||
0,
|
||||
0,
|
||||
1,
|
||||
deinterlace_scanline_vfir,
|
||||
copy_scanline,
|
||||
0,
|
||||
0,
|
||||
deinterlace_frame_vfir,
|
||||
{"Avoids flicker by blurring consecutive frames",
|
||||
"of input. Use this if you want to run your",
|
||||
"monitor at an arbitrary refresh rate and not",
|
||||
|
|
Loading…
Reference in a new issue