much improved mmx yuv scaler
authorddennedy <ddennedy@d19143bc-622f-0410-bfdd-b5b2a6649095>
Mon, 1 Mar 2004 20:11:25 +0000 (20:11 +0000)
committerddennedy <ddennedy@d19143bc-622f-0410-bfdd-b5b2a6649095>
Mon, 1 Mar 2004 20:11:25 +0000 (20:11 +0000)
added producer_libdv quality property
improve avformat aspect_ratio and frame_rate reporting

git-svn-id: https://mlt.svn.sourceforge.net/svnroot/mlt/trunk/mlt@180 d19143bc-622f-0410-bfdd-b5b2a6649095

src/modules/avformat/producer_avformat.c
src/modules/dv/producer_libdv.c
src/modules/gtk2/scale_line_22_yuv_mmx.S

index 78aeb51..c8fe492 100644 (file)
@@ -558,29 +558,6 @@ static void producer_set_up_video( mlt_producer this, mlt_frame frame )
                        // If we don't have a codec and we can't initialise it, we can't do much more...
                        if ( codec != NULL && avcodec_open( codec_context, codec ) >= 0 )
                        {
-                               double aspect_ratio = 0;
-                               double source_fps = 0;
-
-                               // Set aspect ratio
-                               if ( codec_context->sample_aspect_ratio.num == 0 ) 
-                                       aspect_ratio = 0;
-                               else
-                                       aspect_ratio = av_q2d( codec_context->sample_aspect_ratio ) * codec_context->width / codec_context->height;
-
-                               // XXX: This assumes square pixels!
-                       if (aspect_ratio <= 0.0)
-                                       aspect_ratio = ( double )codec_context->width / ( double )codec_context->height;
-
-                               mlt_properties_set_double( properties, "aspect_ratio", aspect_ratio );
-                               fprintf( stderr, "AVFORMAT: sample aspect %f computed display aspect %f\n", av_q2d( codec_context->sample_aspect_ratio ), aspect_ratio );
-
-                               // Determine the fps
-                               source_fps = ( double )codec_context->frame_rate / codec_context->frame_rate_base;
-
-                               // We'll use fps if it's available
-                               if ( source_fps > 0 && source_fps < 30 )
-                                       mlt_properties_set_double( properties, "source_fps", source_fps );
-
                                // Now store the codec with its destructor
                                mlt_properties_set_data( properties, "video_codec", codec_context, 0, producer_codec_close, NULL );
                        }
@@ -594,8 +571,32 @@ static void producer_set_up_video( mlt_producer this, mlt_frame frame )
                // No codec, no show...
                if ( codec != NULL )
                {
+                       double aspect_ratio = 0;
+                       double source_fps = 0;
+
+                       // Set aspect ratio
+                       if ( codec_context->sample_aspect_ratio.num == 0 )
+                               aspect_ratio = 0;
+                       else
+                               aspect_ratio = av_q2d( codec_context->sample_aspect_ratio ) * codec_context->width / codec_context->height;
+
+                       // XXX: This assumes square pixels!
+                       if (aspect_ratio <= 0.0)
+                               aspect_ratio = ( double )codec_context->width / ( double )codec_context->height;
+                               
+                       mlt_properties_set_double( properties, "aspect_ratio", aspect_ratio );
+                       //fprintf( stderr, "AVFORMAT: sample aspect %f computed display aspect %f\n", av_q2d( codec_context->sample_aspect_ratio ), aspect_ratio );
+
+                       // Determine the fps
+                       source_fps = ( double )codec_context->frame_rate / codec_context->frame_rate_base;
+
+                       // We'll use fps if it's available
+                       if ( source_fps > 0 && source_fps < 30 )
+                               mlt_properties_set_double( properties, "source_fps", source_fps );
+
                        mlt_frame_push_get_image( frame, producer_get_image );
                        mlt_properties_set_data( frame_properties, "avformat_producer", this, 0, NULL, NULL );
+
                }
                else
                {
index 3249cd0..8b77b2b 100644 (file)
@@ -301,6 +301,17 @@ static int producer_get_frame( mlt_producer producer, mlt_frame_ptr frame, int i
                mlt_properties_set_int( properties, "width", 720 );
                mlt_properties_set_int( properties, "height", this->is_pal ? 576 : 480 );
                mlt_properties_set_int( properties, "top_field_first", 0 );
+
+               char *quality = mlt_properties_get( mlt_producer_properties( producer ), "quality" );
+               if ( quality != NULL )
+               {
+                       if ( strncmp( quality, "fast", 4 ) == 0 )
+                               this->dv_decoder->quality = ( DV_QUALITY_COLOR | DV_QUALITY_DC );
+                       else if ( strncmp( quality, "best", 4 ) == 0 )
+                               this->dv_decoder->quality = ( DV_QUALITY_COLOR | DV_QUALITY_AC_2 );
+                       else
+                               this->dv_decoder->quality = ( DV_QUALITY_COLOR | DV_QUALITY_AC_1 );
+               }
                
                // Parse the header for meta info
                dv_parse_header( this->dv_decoder, data );
index 2420c40..0759587 100644 (file)
@@ -25,16 +25,16 @@ _pixops_scale_line_22_yuv_mmx:
 /*
  * Arguments
  *             
- * weights:     8(%ebp)
+ * weights:         8(%ebp)
  * p (dest):    12(%ebp)       %esi
  * q1 (src0):   16(%ebp)       
  * q2 (src1):   20(%ebp)       
  * xstep:       24(%ebp)       
  * p_end:       28(%ebp)
  * xinit:       32(%ebp)
- * destx:       36(%ebp)
+ * dest_x:      36(%ebp)
  *
-*/
+ */
 
 /*
  * Function call entry
@@ -63,76 +63,45 @@ _pixops_scale_line_22_yuv_mmx:
        cmpl 28(%ebp),%esi # dest == dest_end ?
        jnb  .out
 
-       addl $65536, %ebx
-       .p2align 4,,7
-       pxor %mm4, %mm4
-
 /* For the body of this loop, %mm0, %mm1, %mm2, %mm3 hold the 4 adjoining
  * points we are interpolating between, as:
  *
- *  00UV00Y200UV00Y1
+ *  00VV00Y200UU00Y1
  */
 
-.loop:
-
+       pxor %mm4, %mm4
 /*
- * Load current values from pixel 1
+ * Load next component values into mm1 (src0) and mm3 (src1)
  */
-       movl %ebx, %edx          # x_scaled = x ...
-       sarl $15, %edx           # >> 16
-       andl $-2, %edx           # x_scaled *= channels
-       movl %edx, -24(%ebp)     # save x_scaled
+       movl %ebx, %eax          # x_scaled
+       sarl $15, %eax
+       andl $0xfffffffe, %eax
+       movl %eax, %edx          # x_aligned
+       andl $0xfffffffc, %edx
 
        movl 16(%ebp), %edi      # get src0
-       movzbl (%edi,%edx), %ecx # current y = src0[ x_scaled ]
-
-       andl $-4, %edx           # x_aligned
-
-       movl 36(%ebp), %eax      # uv_index = dest_x ...
-       andl $1, %eax            # ( dest_x & 1 ) ...
-       sall $1, %eax            # << 1
-       addl %eax, %edx          # x_aligned += uv_index
-       movl %edx, -20(%ebp)     # save x_aligned
-
-       movzbl 1(%edi,%edx), %eax # uv = src0[ x_aligned + 1 ]
-       shll $8, %eax           # position uv
-       orl %eax, %ecx           # store uv
-
-       movd %ecx, %mm0          # move to mmx0
-       punpcklbw %mm4, %mm0
-
-       /* this is the next x, not simply x_scaled again */
-       movl %ebx, %edx          # x_scaled = x ...
-       addl 24(%ebp), %edx      # + x_step
-       sarl $15, %edx           # >> 16
-       andl $-2, %edx           # x_scaled *= channels
-       movl %edx, -16(%ebp)     # save next x_scaled
-
-       movzbl (%edi,%edx), %ecx # next y = src0[ x_scaled ]
-       orl %eax, %ecx           # store uv
-
+       movl (%edi,%eax), %ecx   # get y
+       andl $0x00ff00ff, %ecx   # mask off y
+       movl (%edi,%edx), %eax   # get uv
+       andl $0xff00ff00, %eax   # mask off uv
+       orl %eax, %ecx           # composite y, uv
        movd %ecx, %mm1          # move to mmx1
        punpcklbw %mm4, %mm1
 
        movl 20(%ebp), %edi      # get src1
-       movl -24(%ebp), %edx     # restore x_scaled
-       movzbl (%edi,%edx), %ecx # current y = src1[ x_scaled ]
-
-       movl -20(%ebp), %edx     # restore x_aligned
-       movzbl 1(%edi,%edx), %eax # uv = src1[ x_aligned + 1 ]
-       shll $8, %eax            # position uv
-       orl %eax, %ecx           # store uv
-
-       movd %ecx, %mm2          # move to mmx2
-       punpcklbw %mm4, %mm2
-
-       movl -16(%ebp), %edx     # restore next x_scaled
-       movzbl (%edi,%edx), %ecx # next y = src0[ x_scaled ]
-       orl %eax, %ecx           # store uv
-
+       movl (%edi,%edx), %ecx   # get y
+       andl $0x00ff00ff, %ecx   # mask off y
+       movl (%edi,%edx), %eax   # get uv
+       andl $0xff00ff00, %eax   # mask off uv
+       orl %eax, %ecx           # composite y, uv
        movd %ecx, %mm3          # move to mmx3
        punpcklbw %mm4, %mm3
 
+       jmp .newx
+
+       .p2align 4,,7
+.loop:
+
 /* short *pixel_weights = weights + ((x >> (SCALE_SHIFT - SUBSAMPLE_BITS)) & SUBSAMPLE_MASK) * n_x * n_y
  *                                             16             4                  0xf            2     2
  */
@@ -171,18 +140,60 @@ _pixops_scale_line_22_yuv_mmx:
        packuswb %mm7, %mm7
        movd %mm7, %eax
 
-       movb %al, 0(%esi)        # dest[ 0 ] = y
-       shrl $8, %eax
-       movb %al, 1(%esi)        # dest[ 1 ] = uv
+       movb %al, (%esi)         # *dest = y
+       
+       movl 36(%ebp), %ecx      # get dest_x
+       andl $1, %ecx            # select u or v
+       sall $1, %ecx            # determine offset
+       addl $1, %ecx            # relative to x_aligned
+       sall $3, %ecx            # offset * 8 bits/byte
 
-       addl $2, %esi            # dest += 2
+       movd %mm7, %eax
+       shrl %cl, %eax
+       movb %al, 1(%esi)        # *dest = uv
 
+       addl $2, %esi            # dest += 2
        cmpl %esi,28(%ebp)       # if dest == dest_end
        je   .out                # then exit
 
-       addl 24(%ebp), %ebx      # x += x_step
        addl $1, 36(%ebp)        # dest_x++
 
+.newx:
+
+       addl 24(%ebp), %ebx      # x += x_step
+/*
+ * Load current component values into mm0 (src0) and mm2 (src1)
+ */
+       movq %mm1, %mm0
+       movq %mm3, %mm2
+
+/*
+ * Load next component values into mm1 (src0) and mm3 (src1)
+ */
+       movl %ebx, %eax          # x_scaled
+       sarl $15, %eax
+       andl $0xfffffffe, %eax
+       movl %eax, %edx          # x_aligned
+       andl $0xfffffffc, %edx
+
+       movl 16(%ebp), %edi      # get src0
+       movl (%edi,%eax), %ecx   # get y
+       andl $0x00ff00ff, %ecx   # mask off y
+       movl (%edi,%edx), %eax   # get uv
+       andl $0xff00ff00, %eax   # mask off uv
+       orl %eax, %ecx           # composite y, uv
+       movd %ecx, %mm1          # move to mmx1
+       punpcklbw %mm4, %mm1
+
+       movl 20(%ebp), %edi      # get src1
+       movl (%edi,%edx), %ecx   # get y
+       andl $0x00ff00ff, %ecx   # mask off y
+       movl (%edi,%edx), %eax   # get uv
+       andl $0xff00ff00, %eax   # mask off uv
+       orl %eax, %ecx           # composite y, uv
+       movd %ecx, %mm3          # move to mmx3
+       punpcklbw %mm4, %mm3
+
        jmp .loop
 
 .out: