📄 xyuv.c
字号:
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=%s\n", 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/%d\n", 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) -> %d\n", 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, " - %s\n", 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=%f\n", 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%d\n", 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 );}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -