From: ddennedy Date: Mon, 1 Mar 2004 20:11:25 +0000 (+0000) Subject: much improved mmx yuv scaler X-Git-Url: http://research.m1stereo.tv/gitweb?a=commitdiff_plain;h=49098d3d331a1b5ee630472773c9b8ef416a0642;p=melted much improved mmx yuv scaler 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 --- diff --git a/src/modules/avformat/producer_avformat.c b/src/modules/avformat/producer_avformat.c index 78aeb51..c8fe492 100644 --- a/src/modules/avformat/producer_avformat.c +++ b/src/modules/avformat/producer_avformat.c @@ -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 { diff --git a/src/modules/dv/producer_libdv.c b/src/modules/dv/producer_libdv.c index 3249cd0..8b77b2b 100644 --- a/src/modules/dv/producer_libdv.c +++ b/src/modules/dv/producer_libdv.c @@ -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 ); diff --git a/src/modules/gtk2/scale_line_22_yuv_mmx.S b/src/modules/gtk2/scale_line_22_yuv_mmx.S index 2420c40..0759587 100644 --- a/src/modules/gtk2/scale_line_22_yuv_mmx.S +++ b/src/modules/gtk2/scale_line_22_yuv_mmx.S @@ -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: