X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=modules%2Fcodec%2Frawvideo.c;h=86c20a86ac9c7ede060cb611e1d8b5a91b2fca95;hb=8b045cacc9cb8202d62196b83ee6497f077d96aa;hp=ce5a62740d2149c265010a4b0df0555e50dd530f;hpb=8ca6f29c3aa74031f4e7626637942df6ac519502;p=vlc diff --git a/modules/codec/rawvideo.c b/modules/codec/rawvideo.c index ce5a62740d..86c20a86ac 100644 --- a/modules/codec/rawvideo.c +++ b/modules/codec/rawvideo.c @@ -40,6 +40,7 @@ struct decoder_sys_t * Input properties */ int i_raw_size; + vlc_bool_t b_invert; /* * Common properties @@ -119,9 +120,17 @@ static int OpenDecoder( vlc_object_t *p_this ) /* Misc init */ p_dec->p_sys->b_packetizer = VLC_FALSE; p_sys->i_pts = 0; + p_sys->b_invert = 0; - if( p_dec->fmt_in.video.i_width <= 0 || - p_dec->fmt_in.video.i_height <= 0 ) + if( (int)p_dec->fmt_in.video.i_height < 0 ) + { + /* Frames are coded from bottom to top */ + p_dec->fmt_in.video.i_height = + (unsigned int)(-(int)p_dec->fmt_in.video.i_height); + p_sys->b_invert = VLC_TRUE; + } + + if( p_dec->fmt_in.video.i_width <= 0 || p_dec->fmt_in.video.i_height <= 0 ) { msg_Err( p_dec, "invalid display size %dx%d", p_dec->fmt_in.video.i_width, p_dec->fmt_in.video.i_height ); @@ -234,8 +243,9 @@ static void FillPicture( decoder_t *p_dec, block_t *p_block, picture_t *p_pic ) { uint8_t *p_src, *p_dst; int i_src, i_plane, i_line, i_width; + decoder_sys_t *p_sys = p_dec->p_sys; - p_src = p_block->p_buffer; + p_src = p_block->p_buffer; i_src = p_block->i_buffer; for( i_plane = 0; i_plane < p_pic->i_planes; i_plane++ ) @@ -243,12 +253,18 @@ static void FillPicture( decoder_t *p_dec, block_t *p_block, picture_t *p_pic ) p_dst = p_pic->p[i_plane].p_pixels; i_width = p_pic->p[i_plane].i_visible_pitch; + if( p_sys->b_invert ) + p_src += (i_width * (p_pic->p[i_plane].i_visible_lines - 1)); + for( i_line = 0; i_line < p_pic->p[i_plane].i_visible_lines; i_line++ ) { p_dec->p_vlc->pf_memcpy( p_dst, p_src, i_width ); - p_src += i_width; + p_src += p_sys->b_invert ? -i_width : i_width; p_dst += p_pic->p[i_plane].i_pitch; } + + if( p_sys->b_invert ) + p_src += (i_width * (p_pic->p[i_plane].i_visible_lines + 1)); } } @@ -285,6 +301,49 @@ static block_t *SendFrame( decoder_t *p_dec, block_t *p_block ) p_block->i_dts = p_block->i_pts = p_sys->i_pts; + if( p_sys->b_invert ) + { + picture_t pic; + uint8_t *p_tmp, *p_pixels; + int i, j; + + /* Fill in picture_t fields */ + vout_InitPicture( VLC_OBJECT(p_dec), &pic, p_dec->fmt_out.i_codec, + p_dec->fmt_out.video.i_width, + p_dec->fmt_out.video.i_height, VOUT_ASPECT_FACTOR ); + + if( !pic.i_planes ) + { + msg_Err( p_dec, "unsupported chroma" ); + return p_block; + } + + p_tmp = malloc( pic.p[0].i_visible_pitch ); + p_pixels = p_block->p_buffer; + for( i = 0; i < pic.i_planes; i++ ) + { + int i_pitch = pic.p[i].i_visible_pitch; + uint8_t *p_top = p_pixels; + uint8_t *p_bottom = p_pixels + i_pitch * + (pic.p[i].i_visible_lines - 1); + + for( j = 0; j < pic.p[i].i_visible_lines / 2; j++ ) + { + p_dec->p_vlc->pf_memcpy( p_tmp, p_bottom, + pic.p[i].i_visible_pitch ); + p_dec->p_vlc->pf_memcpy( p_bottom, p_top, + pic.p[i].i_visible_pitch ); + p_dec->p_vlc->pf_memcpy( p_top, p_tmp, + pic.p[i].i_visible_pitch ); + p_top += i_pitch; + p_bottom -= i_pitch; + } + + p_pixels += i_pitch * pic.p[i].i_lines; + } + free( p_tmp ); + } + return p_block; }