📄 xyuv.c.svn-base
字号:
/***************************************************************************** * 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 help\n" "\n" " -s, --size <WIDTHxHEIGHT> Set input size\n" " -w, --width <integer> Set width\n" " -h, --height <integer> Set height\n" "\n" " -S, --split Show splited Y/U/V planes\n" " -d, --diff Show difference (only 2 files) in split mode\n" " -j, --joint <integer>\n" "\n" " -y <float> Set Y factor\n" "\n" " -g, --grid Show a grid (macroblock 16x16)\n" " -W <integer> Set wall width (in picture count)\n" " -f, --fps <float> Set fps\n" "\n" );}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 %s\n", 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 display\n" ); 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%d\n", xyuv.i_width, xyuv.i_height ); } if( xyuv.i_width == 0 || xyuv.i_height == 0 ) { fprintf( stderr, "invalid or missing frames size\n" ); return -1; } if( xyuv.b_diff && xyuv.i_yuv != 2 ) { fprintf( stderr, "--diff works only with 2 files\n" ); 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_frames = 0; xyuv.i_frame_size = 3 * xyuv.i_width * xyuv.i_height / 2; 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; fseek( xyuv.yuv[i].f, 0, SEEK_SET ); fprintf( stderr, " - '%s' : %d frames\n", xyuv.yuv[i].name, xyuv.yuv[i].i_frames ); if( xyuv.i_frames < xyuv.yuv[i].i_frames ) xyuv.i_frames = xyuv.yuv[i].i_frames; } if( xyuv.i_frames == 0 ) { fprintf( stderr, "no frames to display\n" ); } 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 SDL\n" ); 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|
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -