xyuv.c
资源名称:chapter15.rar [点击查看]
上传用户:hjq518
上传日期:2021-12-09
资源大小:5084k
文件大小:25k
源码类别:
Audio
开发平台:
Visual C++
- /*****************************************************************************
- * xyuv.c: a SDL yuv 420 planer viewer.
- *****************************************************************************
- * Copyright (C) 2004 Laurent Aimar
- * $Id: xyuv.c,v 1.1 2004/06/03 19:27:08 fenrir Exp $
- *
- * Authors: Laurent Aimar <fenrir@via.ecp.fr>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
- *****************************************************************************/
- #include <stdlib.h>
- #include <stdio.h>
- #include <string.h>
- #include <stdint.h>
- #include <SDL/SDL.h>
- #define YUV_MAX 20
- #define SDL_TITLE "xyuv: %s - %d/%d - %.2ffps"
- typedef struct
- {
- /* globals */
- int i_width;
- int i_height;
- int i_frame_size;
- int i_frame;
- int i_frames;
- float f_fps;
- float f_y;
- int b_pause;
- int b_grid;
- int b_split;
- int b_diff;
- int i_join;
- /* Constructed picture */
- int i_wall_width; /* in picture count */
- /* YUV files */
- int i_yuv;
- struct
- {
- char *name;
- FILE *f; /* handles */
- int i_frames; /* frames count */
- /* Position in the whole picture */
- int x, y;
- } yuv[YUV_MAX];
- /* SDL */
- int i_sdl_width;
- int i_sdl_height;
- int i_display_width;
- int i_display_height;
- char *title;
- SDL_Surface *screen;
- SDL_Overlay *overlay;
- /* */
- uint8_t *pic;
- } xyuv_t;
- xyuv_t xyuv = {
- .i_width = 0,
- .i_height = 0,
- .i_frame = 1,
- .i_frames = 0,
- .f_fps = 25.0,
- .f_y = 0.0,
- .i_wall_width = 0,
- .i_yuv = 0,
- .b_pause = 0,
- .b_split = 0,
- .b_diff = 0,
- .i_join = -1,
- .title = NULL,
- .pic = NULL,
- };
- static void help( void )
- {
- fprintf( stderr,
- "Syntax: xyuv [options] file [file2 ...]n"
- "n"
- " --help Print this helpn"
- "n"
- " -s, --size <WIDTHxHEIGHT> Set input sizen"
- " -w, --width <integer> Set widthn"
- " -h, --height <integer> Set heightn"
- "n"
- " -S, --split Show splited Y/U/V planesn"
- " -d, --diff Show difference (only 2 files) in split moden"
- " -j, --joint <integer>n"
- "n"
- " -y <float> Set Y factorn"
- "n"
- " -g, --grid Show a grid (macroblock 16x16)n"
- " -W <integer> Set wall width (in picture count)n"
- " -f, --fps <float> Set fpsn"
- "n" );
- }
- static void xyuv_count_frames( xyuv_t *xyuv );
- static void xyuv_detect( int *pi_width, int *pi_height );
- static void xyuv_display( xyuv_t *xyuv, int i_frame );
- int main( int argc, char **argv )
- {
- int i;
- /* Parse commande line */
- for( i = 1; i < argc; i++ ) {
- if( !strcasecmp( argv[i], "--help" ) ) {
- help();
- return 0;
- }
- if( !strcmp( argv[i], "-d" ) || !strcasecmp( argv[i], "--diff" ) ) {
- xyuv.b_diff = 1;
- } else if( !strcmp( argv[i], "-S" ) || !strcasecmp( argv[i], "--split" ) ) {
- xyuv.b_split = 1;
- } else if( !strcmp( argv[i], "-f" ) || !strcasecmp( argv[i], "--fps" ) ) {
- if( i >= argc -1 ) goto err_missing_arg;
- xyuv.f_fps = atof( argv[++i] );
- } else if( !strcmp( argv[i], "-h" ) || !strcasecmp( argv[i], "--height" ) ) {
- if( i >= argc -1 ) goto err_missing_arg;
- xyuv.i_height = atoi( argv[++i] );
- } else if( !strcmp( argv[i], "-w" ) || !strcasecmp( argv[i], "--width" ) ) {
- if( i >= argc -1 ) goto err_missing_arg;
- xyuv.i_width = atoi( argv[++i] );
- } else if( !strcmp( argv[i], "-s" ) || !strcasecmp( argv[i], "--size" ) ) {
- char *p;
- if( i >= argc -1 ) goto err_missing_arg;
- xyuv.i_width = strtol( argv[++i], &p, 0 );
- p++;
- xyuv.i_height = atoi( p );
- } else if( !strcmp( argv[i], "-W" ) ) {
- if( i >= argc -1 ) goto err_missing_arg;
- xyuv.i_wall_width = atoi( argv[++i] );
- } else if( !strcmp( argv[i], "-y" ) ) {
- if( i >= argc -1 ) goto err_missing_arg;
- xyuv.f_y = atof( argv[++i] );
- } else if( !strcmp( argv[i], "-j" ) || !strcasecmp( argv[i], "--join" ) ) {
- if( i >= argc -1 ) goto err_missing_arg;
- xyuv.i_join = atoi( argv[++i] );
- } else if( !strcmp( argv[i], "-g" ) || !strcasecmp( argv[i], "--grid" ) ) {
- xyuv.b_grid = 1;
- } else {
- FILE *f = fopen( argv[i], "rb" );
- if( !f ) {
- fprintf( stderr, "cannot open YUV %sn", argv[i] );
- } else {
- xyuv.yuv[xyuv.i_yuv].name = strdup( argv[i] );
- xyuv.yuv[xyuv.i_yuv].f = f;
- xyuv.yuv[xyuv.i_yuv].i_frames = 0;
- xyuv.i_yuv++;
- }
- }
- }
- if( xyuv.i_yuv == 0 ) {
- fprintf( stderr, "no file to displayn" );
- return -1;
- }
- if( xyuv.i_width == 0 || xyuv.i_height == 0 ) {
- char *psz = xyuv.yuv[0].name;
- char *num;
- char *x;
- /* See if we find widthxheight in the file name */
- for( ;; ) {
- if( !( x = strchr( psz+1, 'x' ) ) ) {
- break;
- }
- num = x;
- while( num > psz && num[-1] >= '0' && num[-1] <= '9' )
- num--;
- if( num != x && x[1] >= '0' && x[1] <= '9' ) {
- xyuv.i_width = atoi( num );
- xyuv.i_height = atoi( x+1 );
- break;
- }
- psz = x;
- }
- fprintf( stderr, "file name gives %dx%dn", xyuv.i_width, xyuv.i_height );
- }
- if( xyuv.i_width == 0 || xyuv.i_height == 0 ) {
- xyuv_detect( &xyuv.i_width, &xyuv.i_height );
- }
- if( xyuv.i_width == 0 || xyuv.i_height == 0 ) {
- fprintf( stderr, "invalid or missing frames sizen" );
- return -1;
- }
- if( xyuv.b_diff && xyuv.i_yuv != 2 ) {
- fprintf( stderr, "--diff works only with 2 filesn" );
- return -1;
- }
- if( (xyuv.i_join == 0 || xyuv.i_join >= xyuv.i_width) && xyuv.i_yuv != 2 ) {
- fprintf( stderr, "--join woeks only with two files and range is [1, width-1]n" );
- return -1;
- }
- if( xyuv.i_join % 2 != 0 ) {
- if( xyuv.i_join + 1 < xyuv.i_width )
- xyuv.i_join++;
- else
- xyuv.i_join--;
- }
- /* Now check frames */
- fprintf( stderr, "displaying :n" );
- xyuv.i_frame_size = 3 * xyuv.i_width * xyuv.i_height / 2;
- xyuv_count_frames( &xyuv );
- for( i = 0; i < xyuv.i_yuv; i++ ) {
- fprintf( stderr, " - '%s' : %d framesn", xyuv.yuv[i].name, xyuv.yuv[i].i_frames );
- }
- if( xyuv.i_frames == 0 ) {
- fprintf( stderr, "no frames to displayn" );
- }
- xyuv.pic = malloc( xyuv.i_frame_size );
- /* calculate SDL view */
- if( xyuv.i_wall_width > xyuv.i_yuv ) {
- xyuv.i_wall_width = xyuv.i_yuv;
- }
- if( xyuv.i_wall_width == 0 ) {
- while( xyuv.i_wall_width < xyuv.i_yuv && xyuv.i_wall_width * xyuv.i_wall_width < xyuv.i_yuv ) {
- xyuv.i_wall_width++;
- }
- }
- for( i = 0; i < xyuv.i_yuv; i++ ) {
- if( xyuv.b_diff || xyuv.i_join > 0 ) {
- xyuv.yuv[i].x = 0;
- xyuv.yuv[i].y = 0;
- } else if( xyuv.b_split ) {
- xyuv.yuv[i].x = (i%xyuv.i_wall_width) * 3 * xyuv.i_width / 2;
- xyuv.yuv[i].y = (i/xyuv.i_wall_width) * xyuv.i_height;
- } else {
- xyuv.yuv[i].x = (i%xyuv.i_wall_width) * xyuv.i_width;
- xyuv.yuv[i].y = (i/xyuv.i_wall_width) * xyuv.i_height;
- }
- }
- if( xyuv.b_diff ) {
- xyuv.i_sdl_width = 3 * xyuv.i_width / 2;
- xyuv.i_sdl_height= xyuv.i_height;
- } else if( xyuv.i_join > 0 ) {
- xyuv.i_sdl_width = xyuv.i_width;
- xyuv.i_sdl_height= xyuv.i_height;
- } else if( xyuv.b_split ) {
- xyuv.i_sdl_width = xyuv.i_wall_width * 3 * xyuv.i_width / 2;
- xyuv.i_sdl_height= xyuv.i_height * ( ( xyuv.i_yuv + xyuv.i_wall_width - 1 ) / xyuv.i_wall_width );
- } else {
- xyuv.i_sdl_width = xyuv.i_wall_width * xyuv.i_width;
- xyuv.i_sdl_height= xyuv.i_height * ( ( xyuv.i_yuv + xyuv.i_wall_width - 1 ) / xyuv.i_wall_width );
- }
- xyuv.i_display_width = xyuv.i_sdl_width;
- xyuv.i_display_height = xyuv.i_sdl_height;
- /* Open SDL */
- if( SDL_Init( SDL_INIT_EVENTTHREAD|SDL_INIT_NOPARACHUTE|SDL_INIT_VIDEO) ) {
- fprintf( stderr, "cannot init SDLn" );
- return -1;
- }
- SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY, 100 );
- SDL_EventState( SDL_KEYUP, SDL_IGNORE );
- xyuv.screen = SDL_SetVideoMode( xyuv.i_sdl_width, xyuv.i_sdl_height, 0,
- SDL_HWSURFACE|SDL_RESIZABLE|
- SDL_ASYNCBLIT|SDL_HWACCEL );
- if( xyuv.screen == NULL ) {
- fprintf( stderr, "SDL_SetVideoMode failedn" );
- return -1;
- }
- SDL_LockSurface( xyuv.screen );
- xyuv.overlay = SDL_CreateYUVOverlay( xyuv.i_sdl_width, xyuv.i_sdl_height,
- SDL_YV12_OVERLAY,
- xyuv.screen );
- /* reset with black */
- memset( xyuv.overlay->pixels[0], 0, xyuv.overlay->pitches[0] * xyuv.i_sdl_height );
- memset( xyuv.overlay->pixels[1], 128, xyuv.overlay->pitches[1] * xyuv.i_sdl_height / 2);
- memset( xyuv.overlay->pixels[2], 128, xyuv.overlay->pitches[2] * xyuv.i_sdl_height / 2);
- SDL_UnlockSurface( xyuv.screen );
- if( xyuv.overlay == NULL ) {
- fprintf( stderr, "recon: SDL_CreateYUVOverlay failedn" );
- return -1;
- }
- for( ;; ) {
- SDL_Event event;
- static int b_fullscreen = 0;
- int64_t i_start = SDL_GetTicks();
- int i_wait;
- if( !xyuv.b_pause ) {
- xyuv_display( &xyuv, xyuv.i_frame );
- }
- for( ;; ) {
- int b_refresh = 0;
- while( SDL_PollEvent( &event ) ) {
- switch( event.type )
- {
- case SDL_QUIT:
- if( b_fullscreen )
- SDL_WM_ToggleFullScreen( xyuv.screen );
- exit( 1 );
- case SDL_KEYDOWN:
- switch( event.key.keysym.sym )
- {
- case SDLK_q:
- case SDLK_ESCAPE:
- if( b_fullscreen )
- SDL_WM_ToggleFullScreen( xyuv.screen );
- exit(1);
- case SDLK_f:
- if( SDL_WM_ToggleFullScreen( xyuv.screen ) )
- b_fullscreen = 1 - b_fullscreen;
- break;
- case SDLK_g:
- if( xyuv.b_grid )
- xyuv.b_grid = 0;
- else
- xyuv.b_grid = 1;
- if( xyuv.b_pause )
- b_refresh = 1;
- break;
- case SDLK_SPACE:
- if( xyuv.b_pause )
- xyuv.b_pause = 0;
- else
- xyuv.b_pause = 1;
- break;
- case SDLK_LEFT:
- if( xyuv.i_frame > 1 ) xyuv.i_frame--;
- b_refresh = 1;
- break;
- case SDLK_RIGHT:
- if( xyuv.i_frame >= xyuv.i_frames )
- xyuv_count_frames( &xyuv );
- if( xyuv.i_frame < xyuv.i_frames ) xyuv.i_frame++;
- b_refresh = 1;
- break;
- case SDLK_HOME:
- xyuv.i_frame = 1;
- if( xyuv.b_pause )
- b_refresh = 1;
- break;
- case SDLK_END:
- xyuv_count_frames( &xyuv );
- xyuv.i_frame = xyuv.i_frames;
- b_refresh = 1;
- break;
- case SDLK_UP:
- xyuv.i_frame += xyuv.i_frames / 20;
- if( xyuv.i_frame >= xyuv.i_frames )
- xyuv_count_frames( &xyuv );
- if( xyuv.i_frame > xyuv.i_frames )
- xyuv.i_frame = xyuv.i_frames;
- b_refresh = 1;
- break;
- case SDLK_DOWN:
- xyuv.i_frame -= xyuv.i_frames / 20;
- if( xyuv.i_frame < 1 )
- xyuv.i_frame = 1;
- b_refresh = 1;
- break;
- case SDLK_PAGEUP:
- xyuv.i_frame += xyuv.i_frames / 10;
- if( xyuv.i_frame >= xyuv.i_frames )
- xyuv_count_frames( &xyuv );
- if( xyuv.i_frame > xyuv.i_frames )
- xyuv.i_frame = xyuv.i_frames;
- b_refresh = 1;
- break;
- case SDLK_PAGEDOWN:
- xyuv.i_frame -= xyuv.i_frames / 10;
- if( xyuv.i_frame < 1 )
- xyuv.i_frame = 1;
- b_refresh = 1;
- break;
- default:
- break;
- }
- break;
- case SDL_VIDEORESIZE:
- xyuv.i_display_width = event.resize.w;
- xyuv.i_display_height = event.resize.h;
- xyuv.screen = SDL_SetVideoMode( xyuv.i_display_width, xyuv.i_display_height, 0,
- SDL_HWSURFACE|SDL_RESIZABLE|
- SDL_ASYNCBLIT|SDL_HWACCEL );
- xyuv_display( &xyuv, xyuv.i_frame );
- break;
- default:
- break;
- }
- }
- if( b_refresh ) {
- xyuv.b_pause = 1;
- xyuv_display( &xyuv, xyuv.i_frame );
- }
- /* wait */
- i_wait = 1000 / xyuv.f_fps - ( SDL_GetTicks() - i_start);
- if( i_wait < 0 )
- break;
- else if( i_wait > 200 )
- SDL_Delay( 200 );
- else {
- SDL_Delay( i_wait );
- break;
- }
- }
- if( !xyuv.b_pause ) {
- /* next frame */
- if( xyuv.i_frame == xyuv.i_frames )
- xyuv.b_pause = 1;
- else if( xyuv.i_frame < xyuv.i_frames )
- xyuv.i_frame++;
- }
- }
- return 0;
- err_missing_arg:
- fprintf( stderr, "missing arg for option=%sn", argv[i] );
- return -1;
- }
- static void xyuv_display( xyuv_t *xyuv, int i_frame )
- {
- SDL_Rect rect;
- int i_picture = 0;
- int i;
- if( i_frame > xyuv->i_frames )
- return;
- xyuv->i_frame = i_frame;
- /* Load and copy pictue data */
- for( i = 0; i < xyuv->i_yuv; i++ ) {
- int i_plane;
- fprintf( stderr, "yuv[%d] %d/%dn", i, i_frame, xyuv->yuv[i].i_frames );
- if( i_frame - 1 >= xyuv->yuv[i].i_frames ) {
- xyuv_count_frames( xyuv );
- if( i_frame - 1 >= xyuv->yuv[i].i_frames )
- continue;
- }
- i_picture++;
- fseek( xyuv->yuv[i].f, (xyuv->i_frame-1) * xyuv->i_frame_size, SEEK_SET );
- fread( xyuv->pic, xyuv->i_frame_size, 1, xyuv->yuv[i].f );
- SDL_LockYUVOverlay( xyuv->overlay );
- if( xyuv->b_diff || xyuv->b_split ) {
- /* Reset UV */
- for( i_plane = 1; i_plane < 3; i_plane++ ) {
- memset( xyuv->overlay->pixels[i_plane], 128, xyuv->overlay->pitches[i_plane] * xyuv->overlay->h / 2 );
- }
- /* Show diff in Y plane of overlay */
- for( i_plane = 0; i_plane < 3; i_plane++ ) {
- int div = i_plane == 0 ? 1 : 2;
- uint8_t *src = xyuv->pic;
- uint8_t *dst = xyuv->overlay->pixels[0] +
- (xyuv->yuv[i].x + xyuv->yuv[i].y * xyuv->overlay->pitches[0] );
- int j;
- if( i_plane == 1 ) {
- src += 5*xyuv->i_width * xyuv->i_height/4;
- dst += xyuv->i_width;
- } else if( i_plane == 2 ) {
- src += xyuv->i_width * xyuv->i_height;
- dst += xyuv->i_width + xyuv->i_height / 2 * xyuv->overlay->pitches[0];
- }
- for( j = 0; j < xyuv->i_height / div; j++ ) {
- if( i_picture == 1 || xyuv->b_split ) {
- memcpy( dst, src, xyuv->i_width / div );
- } else {
- int k;
- for( k = 0; k < xyuv->i_width / div; k++ ) {
- dst[k] = abs( dst[k] - src[k]);
- }
- }
- src += xyuv->i_width / div;
- dst += xyuv->overlay->pitches[0];
- }
- }
- } else {
- for( i_plane = 0; i_plane < 3; i_plane++ ) {
- int div = i_plane == 0 ? 1 : 2;
- uint8_t *src = xyuv->pic;
- uint8_t *dst = xyuv->overlay->pixels[i_plane] +
- ((xyuv->yuv[i].x + xyuv->yuv[i].y * xyuv->overlay->pitches[i_plane] ) / div );
- int w = xyuv->i_width / div;
- int j;
- if( i_plane == 1 ) {
- src += 5*xyuv->i_width * xyuv->i_height/4;
- } else if( i_plane == 2 ) {
- src += xyuv->i_width * xyuv->i_height;
- }
- if( xyuv->i_join > 0 ) {
- if( i_picture > 1 ) {
- src += xyuv->i_join / div;
- dst += xyuv->i_join / div;
- w = (xyuv->i_width - xyuv->i_join) /div;
- } else {
- w = xyuv->i_join / div;
- }
- }
- for( j = 0; j < xyuv->i_height / div; j++ ) {
- memcpy( dst, src, w );
- src += xyuv->i_width / div;
- dst += xyuv->overlay->pitches[i_plane];
- }
- }
- }
- SDL_UnlockYUVOverlay( xyuv->overlay );
- }
- if( xyuv->f_y != 0.0 ) {
- uint8_t *pix = xyuv->overlay->pixels[0];
- int j;
- for( j = 0; j < xyuv->i_sdl_height; j++ ) {
- int k;
- for( k = 0; k < xyuv->i_sdl_width; k++ ) {
- int v= pix[k] * xyuv->f_y;
- if( v > 255 )
- pix[k] = 255;
- else if( v < 0 )
- pix[k] = 0;
- else
- pix[k] = v;
- }
- pix += xyuv->overlay->pitches[0];
- }
- }
- if( xyuv->b_grid ) {
- int x, y;
- for( y = 0; y < xyuv->i_sdl_height; y += 4 ) {
- uint8_t *p = xyuv->overlay->pixels[0] + y * xyuv->overlay->pitches[0];
- for( x = 0; x < xyuv->i_sdl_width; x += 4 ) {
- if( x%16== 0 || y%16 == 0 )
- p[x] = 0;
- }
- }
- }
- /* Update display */
- rect.x = 0;
- rect.y = 0;
- rect.w = xyuv->i_display_width;
- rect.h = xyuv->i_display_height;
- SDL_DisplayYUVOverlay( xyuv->overlay, &rect );
- /* Display title */
- if( xyuv->title )
- free( xyuv->title );
- asprintf( &xyuv->title, SDL_TITLE, xyuv->yuv[0].name, xyuv->i_frame, xyuv->i_frames, xyuv->f_fps );
- SDL_WM_SetCaption( xyuv->title, "" );
- }
- static void xyuv_count_frames( xyuv_t *xyuv )
- {
- int i;
- xyuv->i_frames = 0;
- if( xyuv->i_frame_size <= 0 )
- return;
- for( i = 0; i < xyuv->i_yuv; i++ ) {
- /* Beurk but avoid using fstat */
- fseek( xyuv->yuv[i].f, 0, SEEK_END );
- xyuv->yuv[i].i_frames = ftell( xyuv->yuv[i].f ) / xyuv->i_frame_size;
- fprintf( stderr, "count (%d) -> %dn", i, xyuv->yuv[i].i_frames );
- fseek( xyuv->yuv[i].f, 0, SEEK_SET );
- if( xyuv->i_frames < xyuv->yuv[i].i_frames )
- xyuv->i_frames = xyuv->yuv[i].i_frames;
- }
- }
- static inline int ssd( int a ) { return a*a; }
- static void xyuv_detect( int *pi_width, int *pi_height )
- {
- static const int pi_size[][2] = {
- {128, 96},
- {160,120},
- {320,244},
- {320,288},
- /* PAL */
- {176,144}, // QCIF
- {352,288}, // CIF
- {352,576}, // 1/2 D1
- {480,576}, // 2/3 D1
- {544,576},
- {640,576}, // VGA
- {704,576}, // D1
- {720,576}, // D1
- /* NTSC */
- {176,112}, // QCIF
- {320,240}, // MPEG I
- {352,240}, // CIF
- {352,480}, // 1/2 D1
- {480,480}, // 2/3 D1
- {544,480},
- {640,480}, // VGA
- {704,480}, // D1
- {720,480}, // D1
- /* */
- {0,0},
- };
- int i_max;
- int i_size_max;
- uint8_t *pic;
- int i;
- *pi_width = 0;
- *pi_height = 0;
- /* Compute size max */
- for( i_max = 0, i_size_max = 0;
- pi_size[i_max][0] != 0 && pi_size[i_max][1] != 0; i_max++ ) {
- int s = pi_size[i_max][0] * pi_size[i_max][1] * 3 / 2;
- if( i_size_max < s )
- i_size_max = s;
- }
- /* Temporary buffer */
- i_size_max *= 3;
- pic = malloc( i_size_max );
- fprintf( stderr, "guessing size for:n" );
- for( i = 0; i < xyuv.i_yuv; i++ ) {
- int j;
- int i_read;
- double dbest = 255*255;
- int i_best = i_max;
- int64_t t;
- fprintf( stderr, " - %sn", xyuv.yuv[i].name );
- i_read = fread( pic, 1, i_size_max, xyuv.yuv[i].f );
- if( i_read < 0 )
- continue;
- /* Check if file size is at least compatible with one format
- * (if not, ignore file size)*/
- fseek( xyuv.yuv[i].f, 0, SEEK_END );
- t = ftell( xyuv.yuv[i].f );
- fseek( xyuv.yuv[i].f, 0, SEEK_SET );
- for( j = 0; j < i_max; j++ ) {
- const int w = pi_size[j][0];
- const int h = pi_size[j][1];
- const int s = w * h * 3 / 2;
- if( t % s == 0 )
- break;
- }
- if( j == i_max )
- t = 0;
- /* Try all size */
- for( j = 0; j < i_max; j++ ) {
- const int w = pi_size[j][0];
- const int h = pi_size[j][1];
- const int s = w * h * 3 / 2;
- double dd;
- int x, y, n;
- int64_t d;
- /* To small */
- if( i_read < 3*s )
- continue;
- /* Check file size */
- if( ( t > 0 && (t % s) != 0 ) ) {
- fprintf( stderr, " * %dx%d ignored (incompatible file size)n", w, h );
- continue;
- }
- /* We do a simple ssd between 2 consecutives lines */
- d = 0;
- for( n = 0; n < 3; n++ ) {
- uint8_t *p;
- /* Y */
- p = &pic[n*s];
- for( y = 0; y < h-1; y++ ) {
- for( x = 0; x < w; x++ )
- d += ssd( p[x] - p[w+x] );
- p += w;
- }
- /* U */
- p = &pic[n*s+w*h];
- for( y = 0; y < h/2-1; y++ ) {
- for( x = 0; x < w/2; x++ )
- d += ssd( p[x] - p[(w/2)+x] );
- p += w/2;
- }
- /* V */
- p = &pic[n*s+5*w*h/4];
- for( y = 0; y < h/2-1; y++ ) {
- for( x = 0; x < w/2; x++ )
- d += ssd( p[x] - p[(w/2)+x] );
- p += w/2;
- }
- }
- dd = (double)d / (3*w*h*3/2);
- fprintf( stderr, " * %dx%d d=%fn", w, h, dd );
- if( dd < dbest ) {
- i_best = j;
- dbest = dd;
- }
- }
- fseek( xyuv.yuv[i].f, 0, SEEK_SET );
- if( i_best < i_max ) {
- fprintf( stderr, " -> %dx%dn", pi_size[i_best][0], pi_size[i_best][1] );
- *pi_width = pi_size[i_best][0];
- *pi_height = pi_size[i_best][1];
- }
- }
- free( pic );
- }