summaryrefslogtreecommitdiffstats
path: root/gst/deinterlace2/tvtime/greedy.c
diff options
context:
space:
mode:
Diffstat (limited to 'gst/deinterlace2/tvtime/greedy.c')
-rw-r--r--gst/deinterlace2/tvtime/greedy.c114
1 files changed, 80 insertions, 34 deletions
diff --git a/gst/deinterlace2/tvtime/greedy.c b/gst/deinterlace2/tvtime/greedy.c
index 16b98312..2448d1dc 100644
--- a/gst/deinterlace2/tvtime/greedy.c
+++ b/gst/deinterlace2/tvtime/greedy.c
@@ -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",