Don't like ads? PRO users don't see any ads ;-)
Guest

yadif10bit.diff

By: a guest on Apr 18th, 2012  |  syntax: Diff  |  size: 10.54 KB  |  hits: 21  |  expires: Never
download  |  raw  |  embed  |  report abuse  |  print
Text below is selected. Please press Ctrl+C to copy to your clipboard. (⌘+C on Mac)
  1. diff --git a/modules/video_filter/deinterlace/algo_yadif.c b/modules/video_filter/deinterlace/algo_yadif.c
  2. index 0a9efdb..aaf48e4 100644
  3. --- a/modules/video_filter/deinterlace/algo_yadif.c
  4. +++ b/modules/video_filter/deinterlace/algo_yadif.c
  5. @@ -108,19 +108,33 @@ int RenderYadif( filter_t *p_filter, picture_t *p_dst, picture_t *p_src,
  6.          void (*filter)(uint8_t *dst, uint8_t *prev, uint8_t *cur, uint8_t *next,
  7.                         int w, int prefs, int mrefs, int parity, int mode);
  8.  
  9. -        filter = yadif_filter_line_c;
  10. -#if defined(HAVE_YADIF_MMX)
  11. -        if( vlc_CPU() & CPU_CAPABILITY_MMX )
  12. -            filter = yadif_filter_line_mmx;
  13. +        bool b_bit_depth_not_8bit =
  14. +            ( p_filter->fmt_in.video.i_chroma == VLC_CODEC_I420_10L ||
  15. +              p_filter->fmt_in.video.i_chroma == VLC_CODEC_I422_10L );
  16. +
  17. +#if defined(HAVE_YADIF_SSSE3)
  18. +        if( vlc_CPU() & CPU_CAPABILITY_SSSE3 )
  19. +            filter = yadif_filter_line_ssse3;
  20. +        else
  21.  #endif
  22.  #if defined(HAVE_YADIF_SSE2)
  23.          if( vlc_CPU() & CPU_CAPABILITY_SSE2 )
  24.              filter = yadif_filter_line_sse2;
  25. +        else
  26.  #endif
  27. -#if defined(HAVE_YADIF_SSSE3)
  28. -        if( vlc_CPU() & CPU_CAPABILITY_SSSE3 )
  29. -            filter = yadif_filter_line_ssse3;
  30. +#if defined(HAVE_YADIF_MMX)
  31. +        if( vlc_CPU() & CPU_CAPABILITY_MMX )
  32. +            filter = yadif_filter_line_mmx;
  33. +        else
  34.  #endif
  35. +        {
  36. +            filter = yadif_filter_line_c;
  37. +        }
  38. +
  39. +        // FIXME: Currenyly filter method for 10-bit and 16-bit chroma
  40. +        // implemented in C, asm code needed!
  41. +        if( b_bit_depth_not_8bit )
  42. +            filter = yadif_filter_line_c_16bit;
  43.  
  44.          for( int n = 0; n < p_dst->i_planes; n++ )
  45.          {
  46. diff --git a/modules/video_filter/deinterlace/deinterlace.c b/modules/video_filter/deinterlace/deinterlace.c
  47. index 60b5f45..743982a 100644
  48. --- a/modules/video_filter/deinterlace/deinterlace.c
  49. +++ b/modules/video_filter/deinterlace/deinterlace.c
  50. @@ -280,13 +280,51 @@ void GetOutputFormat( filter_t *p_filter,
  51.  bool IsChromaSupported( vlc_fourcc_t i_chroma )
  52.  {
  53.      return i_chroma == VLC_CODEC_I420 ||
  54. +           i_chroma == VLC_CODEC_I420_10L ||
  55.             i_chroma == VLC_CODEC_J420 ||
  56.             i_chroma == VLC_CODEC_YV12 ||
  57.             i_chroma == VLC_CODEC_I422 ||
  58. +           i_chroma == VLC_CODEC_I422_10L ||
  59.             i_chroma == VLC_CODEC_J422;
  60.  }
  61.  
  62.  /*****************************************************************************
  63. + * IsChromaSupportedForMode:
  64. + * return whether the specified chroma is implemented in the specific
  65. + * deinterlace filter.
  66. + *****************************************************************************/
  67. +
  68. +bool IsChromaSupportedForMode( vlc_fourcc_t i_chroma, int i_mode )
  69. +{
  70. +    switch( i_mode )
  71. +    {
  72. +        case DEINTERLACE_YADIF:
  73. +        case DEINTERLACE_YADIF2X:
  74. +            return  ( i_chroma == VLC_CODEC_I420 ||
  75. +                      i_chroma == VLC_CODEC_I420_10L ||
  76. +                      i_chroma == VLC_CODEC_J420 ||
  77. +                      i_chroma == VLC_CODEC_YV12 ||
  78. +                      i_chroma == VLC_CODEC_I422 ||
  79. +                      i_chroma == VLC_CODEC_I422_10L ||
  80. +                      i_chroma == VLC_CODEC_J422 );
  81. +        case DEINTERLACE_DISCARD:
  82. +        case DEINTERLACE_MEAN:
  83. +        case DEINTERLACE_BLEND:
  84. +        case DEINTERLACE_BOB:
  85. +        case DEINTERLACE_LINEAR:
  86. +        case DEINTERLACE_X:
  87. +        case DEINTERLACE_PHOSPHOR:
  88. +        case DEINTERLACE_IVTC:
  89. +        default:
  90. +            return ( i_chroma == VLC_CODEC_I420 ||
  91. +                     i_chroma == VLC_CODEC_J420 ||
  92. +                     i_chroma == VLC_CODEC_YV12 ||
  93. +                     i_chroma == VLC_CODEC_I422 ||
  94. +                     i_chroma == VLC_CODEC_J422 );
  95. +    }
  96. +}
  97. +
  98. +/*****************************************************************************
  99.   * video filter2 functions
  100.   *****************************************************************************/
  101.  
  102. @@ -701,6 +739,14 @@ int Open( vlc_object_t *p_this )
  103.  
  104.      char *psz_mode = var_GetNonEmptyString( p_filter, FILTER_CFG_PREFIX "mode" );
  105.      SetFilterMethod( p_filter, psz_mode, p_filter->fmt_in.video.i_chroma );
  106. +    if( !IsChromaSupportedForMode( p_filter->fmt_in.video.i_chroma, p_sys->i_mode ) )
  107. +    {
  108. +        char chroma[5] = { 0 };
  109. +        vlc_fourcc_to_char( p_filter->fmt_in.video.i_chroma, chroma );
  110. +        msg_Err( p_filter, "%s is not supported for %s.", psz_mode,  chroma );
  111. +        free( psz_mode );
  112. +        return VLC_EGENERIC;
  113. +    }
  114.      free( psz_mode );
  115.  
  116.      if( p_sys->i_mode == DEINTERLACE_PHOSPHOR )
  117. diff --git a/modules/video_filter/deinterlace/deinterlace.h b/modules/video_filter/deinterlace/deinterlace.h
  118. index 844a59d..8068b54 100644
  119. --- a/modules/video_filter/deinterlace/deinterlace.h
  120. +++ b/modules/video_filter/deinterlace/deinterlace.h
  121. @@ -158,6 +158,8 @@ void GetOutputFormat( filter_t *p_filter,
  122.   *
  123.   * Currently, supported chromas are I420, J420 (4:2:0 full scale),
  124.   * YV12 (like I420, but YVU), I422 and J422.
  125. + * Additionaly, I0AL (YUV 4:2:0 10-bit) and I2AL (YUV 4:2:2 10-bit) are
  126. + * supported for yadif/yadif2x deinerlace filter.
  127.   *
  128.   * Note for deinterlace hackers: adding support for a new chroma typically
  129.   * requires changes to all low-level functions across all the algorithms.
  130. @@ -166,6 +168,16 @@ void GetOutputFormat( filter_t *p_filter,
  131.   */
  132.  bool IsChromaSupported( vlc_fourcc_t i_chroma );
  133.  
  134. +/**
  135. + * Returns whether the specified chroma is implemented in the specified
  136. + * deinterlace filter.
  137. + *
  138. + * Currently, I0AL (YUV 4:2:0 10-bit) and I2AL (YUV 4:2:2 10-bit) are
  139. + * only supported for yadif/yadif2x deinterlace filter.
  140. + *
  141. + */
  142. +bool IsChromaSupportedForMode( vlc_fourcc_t i_chroma, int i_mode );
  143. +
  144.  /*****************************************************************************
  145.   * video filter2 functions
  146.   *****************************************************************************/
  147. diff --git a/modules/video_filter/deinterlace/yadif.h b/modules/video_filter/deinterlace/yadif.h
  148. index a2fccac..ec4c2ca 100644
  149. --- a/modules/video_filter/deinterlace/yadif.h
  150. +++ b/modules/video_filter/deinterlace/yadif.h
  151. @@ -80,62 +80,68 @@ DECLARE_ASM_CONST(16, const xmm_reg, pw_1) = {0x0001000100010001ULL, 0x000100010
  152.  #endif
  153.  #endif
  154.  
  155. +#define CHECK(j)\
  156. +    {   int score = FFABS(cur[mrefs-1+(j)] - cur[prefs-1-(j)])\
  157. +                  + FFABS(cur[mrefs  +(j)] - cur[prefs  -(j)])\
  158. +                  + FFABS(cur[mrefs+1+(j)] - cur[prefs+1-(j)]);\
  159. +        if (score < spatial_score) {\
  160. +            spatial_score= score;\
  161. +            spatial_pred= (cur[mrefs  +(j)] + cur[prefs  -(j)])>>1;\
  162. +
  163. +#define FILTER \
  164. +    for (x = 0;  x < w; x++) { \
  165. +        int c = cur[mrefs]; \
  166. +        int d = (prev2[0] + next2[0])>>1; \
  167. +        int e = cur[prefs]; \
  168. +        int temporal_diff0 = FFABS(prev2[0] - next2[0]); \
  169. +        int temporal_diff1 =(FFABS(prev[mrefs] - c) + FFABS(prev[prefs] - e) )>>1; \
  170. +        int temporal_diff2 =(FFABS(next[mrefs] - c) + FFABS(next[prefs] - e) )>>1; \
  171. +        int diff = FFMAX3(temporal_diff0>>1, temporal_diff1, temporal_diff2); \
  172. +        int spatial_pred = (c+e)>>1; \
  173. +        int spatial_score = FFABS(cur[mrefs-1] - cur[prefs-1]) + FFABS(c-e) \
  174. +                          + FFABS(cur[mrefs+1] - cur[prefs+1]) - 1; \
  175. + \
  176. +        CHECK(-1) CHECK(-2) }} }} \
  177. +        CHECK( 1) CHECK( 2) }} }} \
  178. + \
  179. +        if (mode < 2) { \
  180. +            int b = (prev2[2*mrefs] + next2[2*mrefs])>>1; \
  181. +            int f = (prev2[2*prefs] + next2[2*prefs])>>1; \
  182. +            int max = FFMAX3(d-e, d-c, FFMIN(b-c, f-e)); \
  183. +            int min = FFMIN3(d-e, d-c, FFMAX(b-c, f-e)); \
  184. + \
  185. +            diff = FFMAX3(diff, min, -max); \
  186. +        } \
  187. + \
  188. +        if (spatial_pred > d + diff) \
  189. +           spatial_pred = d + diff; \
  190. +        else if (spatial_pred < d - diff) \
  191. +           spatial_pred = d - diff; \
  192. + \
  193. +        dst[0] = spatial_pred; \
  194. + \
  195. +        dst++; \
  196. +        cur++; \
  197. +        prev++; \
  198. +        next++; \
  199. +        prev2++; \
  200. +        next2++; \
  201. +    }
  202. +
  203.  static void yadif_filter_line_c(uint8_t *dst, uint8_t *prev, uint8_t *cur, uint8_t *next, int w, int prefs, int mrefs, int parity, int mode) {
  204.      int x;
  205.      uint8_t *prev2= parity ? prev : cur ;
  206.      uint8_t *next2= parity ? cur  : next;
  207. -    for(x=0; x<w; x++){
  208. -        int c= cur[mrefs];
  209. -        int d= (prev2[0] + next2[0])>>1;
  210. -        int e= cur[prefs];
  211. -        int temporal_diff0= FFABS(prev2[0] - next2[0]);
  212. -        int temporal_diff1=( FFABS(prev[mrefs] - c) + FFABS(prev[prefs] - e) )>>1;
  213. -        int temporal_diff2=( FFABS(next[mrefs] - c) + FFABS(next[prefs] - e) )>>1;
  214. -        int diff= FFMAX3(temporal_diff0>>1, temporal_diff1, temporal_diff2);
  215. -        int spatial_pred= (c+e)>>1;
  216. -        int spatial_score= FFABS(cur[mrefs-1] - cur[prefs-1]) + FFABS(c-e)
  217. -                         + FFABS(cur[mrefs+1] - cur[prefs+1]) - 1;
  218. -
  219. -#define CHECK(j)\
  220. -    {   int score= FFABS(cur[mrefs-1+j] - cur[prefs-1-j])\
  221. -                 + FFABS(cur[mrefs  +j] - cur[prefs  -j])\
  222. -                 + FFABS(cur[mrefs+1+j] - cur[prefs+1-j]);\
  223. -        if(score < spatial_score){\
  224. -            spatial_score= score;\
  225. -            spatial_pred= (cur[mrefs  +j] + cur[prefs  -j])>>1;\
  226. -
  227. -        CHECK(-1) CHECK(-2) }} }}
  228. -        CHECK( 1) CHECK( 2) }} }}
  229.  
  230. -        if(mode<2){
  231. -            int b= (prev2[2*mrefs] + next2[2*mrefs])>>1;
  232. -            int f= (prev2[2*prefs] + next2[2*prefs])>>1;
  233. -#if 0
  234. -            int a= cur[3*mrefs];
  235. -            int g= cur[3*prefs];
  236. -            int max= FFMAX3(d-e, d-c, FFMIN3(FFMAX(b-c,f-e),FFMAX(b-c,b-a),FFMAX(f-g,f-e)) );
  237. -            int min= FFMIN3(d-e, d-c, FFMAX3(FFMIN(b-c,f-e),FFMIN(b-c,b-a),FFMIN(f-g,f-e)) );
  238. -#else
  239. -            int max= FFMAX3(d-e, d-c, FFMIN(b-c, f-e));
  240. -            int min= FFMIN3(d-e, d-c, FFMAX(b-c, f-e));
  241. -#endif
  242. -
  243. -            diff= FFMAX3(diff, min, -max);
  244. -        }
  245. -
  246. -        if(spatial_pred > d + diff)
  247. -           spatial_pred = d + diff;
  248. -        else if(spatial_pred < d - diff)
  249. -           spatial_pred = d - diff;
  250. +    FILTER
  251. +}
  252.  
  253. -        dst[0] = spatial_pred;
  254. +static void yadif_filter_line_c_16bit(uint16_t *dst, uint16_t *prev, uint16_t *cur, uint16_t *next, int w, int prefs, int mrefs, int parity, int mode) {
  255. +    int x;
  256. +    uint16_t *prev2= parity ? prev : cur ;
  257. +    uint16_t *next2= parity ? cur  : next;
  258. +    mrefs /= 2;
  259. +    prefs /= 2;
  260.  
  261. -        dst++;
  262. -        cur++;
  263. -        prev++;
  264. -        next++;
  265. -        prev2++;
  266. -        next2++;
  267. -    }
  268. +    FILTER
  269.  }
  270. -