diff options
author | Sebastian Dröge <slomo@circular-chaos.org> | 2008-06-28 18:10:52 +0000 |
---|---|---|
committer | Sebastian Dröge <slomo@circular-chaos.org> | 2008-06-28 18:10:52 +0000 |
commit | f30962901cd5528b2d3951591789ff079e03f95b (patch) | |
tree | 6452716e95a31d39036f3aee132e8cfc1ed86fea /gst/deinterlace2/tvtime | |
parent | aae071d922ffabcade0315e2691d671e4cb85478 (diff) | |
download | gst-plugins-bad-f30962901cd5528b2d3951591789ff079e03f95b.tar.gz gst-plugins-bad-f30962901cd5528b2d3951591789ff079e03f95b.tar.bz2 gst-plugins-bad-f30962901cd5528b2d3951591789ff079e03f95b.zip |
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.
Diffstat (limited to 'gst/deinterlace2/tvtime')
-rw-r--r-- | gst/deinterlace2/tvtime/greedy.c | 114 | ||||
-rw-r--r-- | gst/deinterlace2/tvtime/greedyh.c | 5 | ||||
-rw-r--r-- | gst/deinterlace2/tvtime/vfir.c | 90 |
3 files changed, 144 insertions, 65 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", diff --git a/gst/deinterlace2/tvtime/greedyh.c b/gst/deinterlace2/tvtime/greedyh.c index f9d33e74..5cda7d53 100644 --- a/gst/deinterlace2/tvtime/greedyh.c +++ b/gst/deinterlace2/tvtime/greedyh.c @@ -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; diff --git a/gst/deinterlace2/tvtime/vfir.c b/gst/deinterlace2/tvtime/vfir.c index 4b7a0c09..53d233e1 100644 --- a/gst/deinterlace2/tvtime/vfir.c +++ b/gst/deinterlace2/tvtime/vfir.c @@ -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", |