mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-01-19 13:55:41 +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>
|
2008-06-28 Sebastian Dröge <sebastian.droege@collabora.co.uk>
|
||||||
|
|
||||||
* gst/deinterlace2/tvtime/greedyh.asm:
|
* 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_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))) {
|
||||||
|
|
|
@ -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",
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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 );
|
|
||||||
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
blit_packed422_scanline (out_data, cur_field, object->frame_width);
|
||||||
copy_scanline (GstDeinterlace2 * object,
|
out_data += object->output_stride;
|
||||||
deinterlace_scanline_data_t * data, uint8_t * output)
|
line++;
|
||||||
{
|
|
||||||
blit_packed422_scanline (output, data->m0, object->frame_width);
|
for (; line < object->field_height; line++) {
|
||||||
/*
|
t0 = cur_field;
|
||||||
if( data->bottom_field ) {
|
b0 = cur_field + object->field_stride;
|
||||||
deinterlace_line( output, data->tt2, data->t1, data->m2, data->b1, data->bb2, width*2 );
|
|
||||||
} else {
|
tt1 = last_field;
|
||||||
deinterlace_line( output, data->tt0, data->t1, data->m0, data->b1, data->bb0, width*2 );
|
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",
|
||||||
|
|
Loading…
Reference in a new issue