Changeset 517 in SHVCSoftware
- Timestamp:
- 17 Dec 2013, 20:25:51 (11 years ago)
- Location:
- branches/SHM-4.1-dev
- Files:
-
- 2 added
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/SHM-4.1-dev/build/linux/app/TAppDownConvert/makefile
r341 r517 27 27 OBJS = \ 28 28 $(OBJ_DIR)/TAppDownConvert.o \ 29 $(OBJ_DIR)/DownConvert.o \ 30 29 31 30 32 # set libs to link with -
branches/SHM-4.1-dev/build/vc10/TAppDownConvert/TAppDownConvert.vcxproj
r344 r517 123 123 </ItemDefinitionGroup> 124 124 <ItemGroup> 125 <ClCompile Include="..\..\..\source\App\TAppDownConvert\DownConvert.cpp" /> 125 126 <ClCompile Include="..\..\..\source\App\TAppDownConvert\TAppDownConvert.cpp" /> 127 </ItemGroup> 128 <ItemGroup> 129 <ClInclude Include="..\..\..\source\App\TAppDownConvert\DownConvert.h" /> 126 130 </ItemGroup> 127 131 <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> -
branches/SHM-4.1-dev/source/App/TAppDownConvert/TAppDownConvert.cpp
r442 r517 35 35 \brief Down convert application main 36 36 */ 37 #include <stdio.h> 38 #include <stdlib.h> 39 #include <string.h> 40 #include <math.h> 41 42 //! \ingroup TAppDecoder 43 //! \{ 44 45 #define pi 3.1415926 46 47 int get_mem2DPelWithPad(unsigned char ***array2D, int dim0, int dim1, int iPadY, int iPadX) 48 { 49 int i; 50 unsigned char *curr = NULL; 51 int iHeight, iWidth; 52 53 iHeight = dim0+2*iPadY; 54 iWidth = dim1+2*iPadX; 55 (*array2D) = (unsigned char**)malloc(iHeight*sizeof(unsigned char*)); 56 *(*array2D) = (unsigned char* )calloc(iHeight * iWidth, sizeof(unsigned char )); 57 58 (*array2D)[0] += iPadX; 59 curr = (*array2D)[0]; 60 for(i = 1 ; i < iHeight; i++) 61 { 62 curr += iWidth; 63 (*array2D)[i] = curr; 64 } 65 (*array2D) = &((*array2D)[iPadY]); 66 37 38 #include <cmath> 39 #include <cstdio> 40 #include <cstdlib> 41 #include <cstring> 42 #include <ctime> 43 44 #include "DownConvert.h" 45 46 typedef struct 47 { 48 int stride; 49 int lines; 50 unsigned char* data; 51 unsigned char* data2; 52 } ColorComponent; 53 54 typedef struct 55 { 56 ColorComponent y; 57 ColorComponent u; 58 ColorComponent v; 59 } YuvFrame; 60 61 62 void 63 createColorComponent( ColorComponent& c, int maxwidth, int maxheight ) 64 { 65 maxwidth = ( ( maxwidth + 15 ) >> 4 ) << 4; 66 maxheight = ( ( maxheight + 15 ) >> 4 ) << 4; 67 int size = maxwidth * maxheight; 68 c.stride = maxwidth; 69 c.lines = maxheight; 70 c.data = new unsigned char [ size ]; 71 c.data2 = new unsigned char [ size ]; 72 73 if( ! c.data || ! c.data2 ) 74 { 75 fprintf(stderr, "\nERROR: memory allocation failed!\n\n"); 76 exit(1); 77 } 78 } 79 80 void 81 deleteColorComponent( ColorComponent& c ) 82 { 83 delete[] c.data; 84 delete[] c.data2; 85 c.stride = 0; 86 c.lines = 0; 87 c.data = 0; 88 c.data2 = 0; 89 } 90 91 int 92 readColorComponent( ColorComponent& c, FILE* file, int width, int height, bool second ) 93 { 94 assert( width <= c.stride ); 95 assert( height <= c.lines ); 96 97 int iMaxPadWidth = gMin( c.stride, ( ( width + 15 ) >> 4 ) << 4 ); 98 int iMaxPadHeight = gMin( c.lines, ( ( height + 31 ) >> 5 ) << 5 ); 99 100 for( int i = 0; i < height; i++ ) 101 { 102 unsigned char* buffer = ( second ? c.data2 : c.data ) + i * c.stride; 103 int rsize = (int)fread( buffer, sizeof(unsigned char), width, file ); 104 if( rsize != width ) 105 { 106 return 1; 107 } 108 for( int xp = width; xp < iMaxPadWidth; xp++ ) 109 { 110 buffer[xp] = buffer[xp-1]; 111 } 112 } 113 for( int yp = height; yp < iMaxPadHeight; yp++ ) 114 { 115 unsigned char* buffer = ( second ? c.data2 : c.data ) + yp * c.stride; 116 unsigned char* bufferX = buffer - c.stride; 117 for( int xp = 0; xp < c.stride; xp++ ) 118 { 119 buffer[xp] = bufferX[xp]; 120 } 121 } 67 122 return 0; 68 123 } 69 124 70 int get_mem2DintWithPad(int ***array2D, int dim0, int dim1, int iPadY, int iPadX) 71 { 72 int i; 73 int *curr = NULL; 74 int iHeight, iWidth; 75 76 iHeight = dim0+2*iPadY; 77 iWidth = dim1+2*iPadX; 78 (*array2D) = (int**)malloc(iHeight*sizeof(int*)); 79 *(*array2D) = (int* )calloc(iHeight * iWidth, sizeof(int )); 80 81 (*array2D)[0] += iPadX; 82 curr = (*array2D)[0]; 83 for(i = 1 ; i < iHeight; i++) 84 { 85 curr += iWidth; 86 (*array2D)[i] = curr; 87 } 88 (*array2D) = &((*array2D)[iPadY]); 89 125 void 126 duplicateColorComponent( ColorComponent& c ) 127 { 128 memcpy( c.data2, c.data, c.stride * c.lines * sizeof(unsigned char) ); 129 } 130 131 void 132 combineTopAndBottomInColorComponent( ColorComponent& c, Bool bBotField ) 133 { 134 int offs = ( bBotField ? c.stride : 0 ); 135 unsigned char* pDes = c.data + offs; 136 unsigned char* pSrc = c.data2 + offs; 137 for( int i = 0; i < c.lines / 2; i++, pDes += 2*c.stride, pSrc += 2*c.stride ) 138 { 139 memcpy( pDes, pSrc, c.stride * sizeof(unsigned char) ); 140 } 141 } 142 143 void 144 writeColorComponent( ColorComponent& c, FILE* file, int width, int height, bool second ) 145 { 146 assert( width <= c.stride ); 147 assert( height <= c.lines ); 148 149 for( int i = 0; i < height; i++ ) 150 { 151 unsigned char* buffer = ( second ? c.data2 : c.data ) + i * c.stride; 152 int wsize = (int)fwrite( buffer, sizeof(unsigned char), width, file ); 153 154 if( wsize != width ) 155 { 156 fprintf(stderr, "\nERROR: while writing to output file!\n\n"); 157 exit(1); 158 } 159 } 160 } 161 162 163 void 164 createFrame( YuvFrame& f, int width, int height ) 165 { 166 createColorComponent( f.y, width, height ); 167 createColorComponent( f.u, width >> 1, height >> 1 ); 168 createColorComponent( f.v, width >> 1, height >> 1 ); 169 } 170 171 void 172 deleteFrame( YuvFrame& f ) 173 { 174 deleteColorComponent( f.y ); 175 deleteColorComponent( f.u ); 176 deleteColorComponent( f.v ); 177 } 178 179 int 180 readFrame( YuvFrame& f, FILE* file, int width, int height, bool second = false ) 181 { 182 ROTRS( readColorComponent( f.y, file, width, height, second ), 1 ); 183 ROTRS( readColorComponent( f.u, file, width >> 1, height >> 1, second ), 1 ); 184 ROTRS( readColorComponent( f.v, file, width >> 1, height >> 1, second ), 1 ); 90 185 return 0; 91 186 } 92 187 93 void free_mem2DPelWithPad(unsigned char **array2D, int iPadY, int iPadX) 94 { 95 if (array2D) 96 { 97 if (*array2D) 98 { 99 free (array2D[-iPadY]-iPadX); 100 } 101 else 102 { 103 printf("free_mem2DintWithPad: trying to free unused memory\r\nPress Any Key\r\n"); 104 } 105 106 free (&array2D[-iPadY]); 107 } 108 else 109 { 110 printf("free_mem2DintWithPad: trying to free unused memory\r\nPress Any Key\r\n"); 111 } 112 } 113 114 void free_mem2DintWithPad(int **array2D, int iPadY, int iPadX) 115 { 116 if (array2D) 117 { 118 if (*array2D) 119 { 120 free (array2D[-iPadY]-iPadX); 121 } 122 else 123 { 124 printf("free_mem2DintWithPad: trying to free unused memory\r\nPress Any Key\r\n"); 125 } 126 127 free (&array2D[-iPadY]); 128 } 129 else 130 { 131 printf("free_mem2DintWithPad: trying to free unused memory\r\nPress Any Key\r\n"); 132 } 133 } 134 135 void PadImgHorizontal(unsigned char **src, unsigned char **dst, int height, int width, int pad_h) 136 { 137 int i, j; 138 unsigned char *BufSrc, *BufDst; 139 140 for (j=0;j<height;j++) 141 { 142 BufDst = &(dst[j][-pad_h] ); 143 BufSrc = src[j]; 144 for (i=0;i<pad_h;i++) 145 { 146 *(BufDst++) = BufSrc[0]; 147 } 148 memcpy(BufDst, BufSrc, width*sizeof(unsigned char)); 149 BufDst += width; 150 for (i=0;i<pad_h;i++) 151 { 152 *(BufDst++) = BufSrc[width-1]; 153 } 154 } 155 } 156 157 void FilterImg( unsigned char **src, 158 int **temp, 159 unsigned char **dst, 160 int height1, 161 int width1, 162 int M, 163 int N, 164 int **phase_filter, 165 int length, 166 int shift, 167 int plane) 168 { 169 int height2,width2; 170 int k,iSum; 171 int i0, div_i0, i1; 172 int j0, div_j0, j1; 173 int *p_filter; 174 unsigned char *p_src, *p_dst; 175 int **p_temp, *p_tmp; 176 int shift2 = (2*shift); 177 int shift_round = (1 << (2 * shift - 1)); 178 179 height2 = (height1 * M) / N; 180 width2 = (width1 * M) / N; 181 182 // horizontal filtering 183 for(j1 = 0; j1 < height1; j1++) 184 { 185 i0=-N; 186 p_tmp = temp[j1]; 187 for(i1 = 0; i1 < width2; i1++) 188 { 189 i0 += N; 190 div_i0 = (i0 / M); 191 p_src = &src[j1][ div_i0 - (length >> 1)]; 192 p_filter = phase_filter[i0 - div_i0 * M]; 193 iSum = 0; 194 for(k = 0; k < length; k++) 195 { 196 iSum += (*p_src++) * (*p_filter++); 197 } 198 *p_tmp++ = iSum; 199 } 200 } 201 202 // pad temp (vertical) 203 for (k=-(length>>1);k<0;k++) 204 memcpy(temp[k], temp[0], width2*sizeof(int)); 205 for (k=height1;k<(height1+(length>>1));k++) 206 memcpy(temp[k], temp[k-1], (width2)* sizeof(int)); 207 208 // vertical filtering 209 j0 = (plane == 0) ? -N : -(N-1); 210 211 for(j1 = 0; j1 < height2; j1++) 212 { 213 j0 += N; 214 div_j0 = (j0 / M); 215 p_dst = dst[j1]; 216 p_temp = &temp[div_j0 - (length>>1)]; 217 p_filter = phase_filter[j0 - div_j0 * M]; 218 for(i1 = 0; i1 < width2;i1++) 219 { 220 iSum=0; 221 for(k = 0; k < length; k++) 222 { 223 iSum += p_temp[k][i1] * p_filter[k]; 224 } 225 iSum=((iSum + shift_round) >> shift2); 226 *p_dst++ = (unsigned char)(iSum > 255 ? 255 : iSum < 0 ? 0 : iSum); 227 } 228 } 229 } 230 231 // ==================================================================================================================== 232 // Main function 233 // ==================================================================================================================== 234 235 int main(int argc, char *argv[]) 236 { 237 const int phase_filter_0[4][13]={ 238 {0, 2, -3, -9, 6, 39, 58, 39, 6, -9, -3, 2, 0}, 239 {0, 1, -1, -8, -1, 31, 57, 47, 13, -7, -5, 1, 0}, 240 {0, 1, 0, -7, -5, 22, 53, 53, 22, -5, -7, 0, 1}, 241 {0, 0, 1, -5, -7, 13, 47, 57, 31, -1, -8,-1, 1} 242 }; 243 244 const int phase_filter_1[8][13]={ 245 {0, 0, 5, -6, -10, 37, 76, 37,-10, -6, 5, 0, 0}, 246 {0, -1, 5, -3, -12, 29, 75, 45, -7, -8, 5, 0, 0}, 247 {0, -1, 4, -1, -13, 22, 73, 52, -3, -10, 4, 1, 0}, 248 {0, -1, 4, 1, -13, 14, 70, 59, 2, -12, 3, 2, -1}, 249 {0, -1, 3, 2, -13, 8, 65, 65, 8, -13, 2, 3, -1}, 250 {0, -1, 2, 3, -12, 2, 59, 70, 14, -13, 1, 4, -1}, 251 {0, 0, 1, 4, -10, -3, 52, 73, 22, -13,-1, 4, -1}, 252 {0, 0, 0, 5, -8, -7, 45, 75, 29, -12,-3, 5, -1} 253 }; 254 255 int i,j; 256 257 int width_org, width_org_c, width_sampled, width_sampled_c; 258 int height_org, height_org_c, height_sampled, height_sampled_c; 259 int size_org, size_org_c, size_sampled, size_sampled_c; 260 261 unsigned char **Y1, **U1, **V1; 262 unsigned char **Y2, **U2, **V2; 263 unsigned char **temp_luma, **temp_chroma; 264 int **tempY, **tempU, **tempV; 265 266 int **phase_filter; 267 int log2_scaling_factor=7; 268 269 FILE * infile; 270 FILE * outfile; 271 272 int M = -1 ,N = -1; 273 int ratio = -1; 274 int Frames=0; 275 int totalFrames=0; 276 int StartFrame=0; 277 int Tap=13; 278 279 if (argc < 6) 280 { 281 printf("\nIncorrect number of arguments!!!\n\n"); 282 printf("Syntax: \n"); 283 printf("%s <input width> <input height> <input file> <output file> <downsampling method> [frames_to_process] [start_frame]\n\n", argv[0]); 284 printf("<downsampling method> 0: 2x downsampling, 1: 1.5x downsampling. \n"); 285 printf("Examples: \n"); 286 printf("%s 1920 1080 input_1920x1080_24p.yuv output_960x540_24p.yuv 0 \n", argv[0]); 287 printf("%s 1920 1080 input_1920x1080_24p.yuv output_1280x720_24p.yuv 1 \n", argv[0]); 288 return -1; 289 } 290 291 width_org = atoi (argv[1]); 292 height_org = atoi (argv[2]); 293 infile = fopen (argv[3], "rb"); 294 outfile = fopen (argv[4], "wb"); 295 ratio = atoi (argv[5]); 296 297 for(i=7; i<= argc; i++) 298 { 299 switch(i) 300 { 301 case 7: 302 Frames = atoi(argv[6]); 303 break; 304 case 8: 305 StartFrame = atoi(argv[7]); 306 break; 307 default: 308 printf("Too many input arguments"); 309 break; 310 } 311 } 312 313 if( width_org < 4 || height_org < 4 ) 314 { 315 printf("\ninput resolution is too small, exit\n"); 316 return -1; 317 } 318 if ( infile == NULL || outfile == NULL ) 319 { 320 printf("\ninput or output file is invalid, exit\n"); 321 return -1; 322 } 323 if ((argc > 6) && (Frames < 1 || StartFrame < 0)) 324 { 325 printf("input frame parameter error\n"); 326 return -1; 327 } 328 329 switch( ratio ) 330 { 331 default: 332 printf("\ndown sampling parameter %d is not supported (0: 2x downsampling, 1: 1.5x downsampling)\n", ratio); 333 return -1; 334 case 0: 335 M=4; 336 N=8; 337 break; 338 case 1: 339 M=8; 340 N=12; 341 break; 342 } 343 344 width_org_c = width_org >> 1; 345 height_org_c = height_org >> 1; 346 width_sampled = (width_org * M) / N; 347 height_sampled = (height_org * M) / N; 348 width_sampled_c = width_sampled >> 1; 349 height_sampled_c = height_sampled >> 1; 350 size_org = height_org * width_org; 351 size_org_c = height_org_c * width_org_c; 352 size_sampled = height_sampled * width_sampled; 353 size_sampled_c = height_sampled_c * width_sampled_c; 354 355 printf("\n=============================================================\n"); 356 printf("\n Input = %s", argv[3]); 357 printf("\n Output = %s", argv[4]); 358 printf("\n Rescaling input from (%d,%d) to (%d,%d) resolution\n", width_org, height_org, width_sampled, height_sampled); 359 printf("\n=============================================================\n\n"); 360 361 // construct phase filters 362 get_mem2DintWithPad (&phase_filter, M, Tap, 0, 0); 363 364 for (j=0;j<M;j++) 365 for (i=0;i<Tap;i++) 366 phase_filter[j][i]= ratio==0 ? phase_filter_0[j][i] : phase_filter_1[j][i]; 367 368 get_mem2DPelWithPad (&Y1, height_org, width_org, 0, Tap>>1); 369 get_mem2DPelWithPad (&U1, height_org_c, width_org_c, 0, Tap>>1); 370 get_mem2DPelWithPad (&V1, height_org_c, width_org_c, 0, Tap>>1); 371 372 get_mem2DintWithPad (&tempY, height_org, width_sampled, Tap>>1, 0); 373 get_mem2DintWithPad (&tempU, height_org_c, width_sampled_c, Tap>>1, 0); 374 get_mem2DintWithPad (&tempV, height_org_c, width_sampled_c, Tap>>1, 0); 375 376 get_mem2DPelWithPad (&Y2, height_sampled, width_sampled, 0,0); 377 get_mem2DPelWithPad (&U2, height_sampled_c, width_sampled_c,0,0); 378 get_mem2DPelWithPad (&V2, height_sampled_c, width_sampled_c,0,0); 379 380 get_mem2DPelWithPad (&temp_luma, height_org, width_org, 0,0); 381 get_mem2DPelWithPad (&temp_chroma, height_org_c, width_org_c,0,0); 382 383 if(StartFrame!=0) 384 { 385 for (i = 0; i < StartFrame; i ++) 386 { 387 fread(temp_luma[0], sizeof(unsigned char), size_org, infile); 388 fread(temp_chroma[0], sizeof(unsigned char), size_org_c, infile); 389 fread(temp_chroma[0], sizeof(unsigned char), size_org_c, infile); 390 if (feof(infile)) 391 { 392 printf("\nThe start frame number exceeds the file size\n"); 393 return -1; 394 } 395 } 396 //fseek64(infile, (size_org * StartFrame * 3) >> 1,SEEK_SET); 397 } 398 399 if (Frames) 400 { 401 totalFrames = Frames; 402 } 403 else 404 { 405 totalFrames = 0x7FFF; 406 } 407 408 i = 0; 409 while(totalFrames) 410 { 411 412 // read and pad Y 413 fread(temp_luma[0], sizeof(unsigned char), size_org, infile); 414 PadImgHorizontal(temp_luma, Y1, height_org, width_org, Tap>>1); 415 416 // read and pad U 417 fread(temp_chroma[0], sizeof(unsigned char), size_org_c, infile); 418 PadImgHorizontal(temp_chroma, U1, height_org_c, width_org_c, Tap>>1); 419 420 // read and pad V 421 fread(temp_chroma[0], sizeof(unsigned char), size_org_c, infile); 422 PadImgHorizontal(temp_chroma, V1, height_org_c, width_org_c, Tap>>1); 423 424 if (feof(infile)) 425 { 426 break; 427 } 428 429 fprintf(stdout,"Rescaling %dth frame\r", i); 430 fflush(stdout); 431 432 i ++; 433 totalFrames --; 434 435 FilterImg(Y1,tempY,Y2,height_org, width_org, M, N, phase_filter,Tap,log2_scaling_factor,0); 436 FilterImg(U1,tempU,U2,height_org_c,width_org_c,M, N, phase_filter,Tap,log2_scaling_factor,1); 437 FilterImg(V1,tempV,V2,height_org_c,width_org_c,M, N, phase_filter,Tap,log2_scaling_factor,2); 438 439 // write a sampled frame 440 fwrite(Y2[0], sizeof(unsigned char), size_sampled, outfile); 441 fwrite(U2[0], sizeof(unsigned char), size_sampled_c, outfile); 442 fwrite(V2[0], sizeof(unsigned char), size_sampled_c, outfile); 443 444 } 445 446 printf("\nEnd of rescaling process.\n"); 447 448 free_mem2DintWithPad (phase_filter, 0, 0); 449 450 free_mem2DPelWithPad (Y1, 0, Tap>>1); 451 free_mem2DPelWithPad (U1, 0, Tap>>1); 452 free_mem2DPelWithPad (V1, 0, Tap>>1); 453 454 free_mem2DintWithPad (tempY, Tap>>1, 0); 455 free_mem2DintWithPad (tempU, Tap>>1, 0); 456 free_mem2DintWithPad (tempV, Tap>>1, 0); 457 458 free_mem2DPelWithPad (Y2,0,0); 459 free_mem2DPelWithPad (U2,0,0); 460 free_mem2DPelWithPad (V2,0,0); 461 462 free_mem2DPelWithPad (temp_luma, 0,0); 463 free_mem2DPelWithPad (temp_chroma,0,0); 464 465 fclose(infile); 466 fclose(outfile); 467 188 void 189 duplicateFrame( YuvFrame& f ) 190 { 191 duplicateColorComponent( f.y ); 192 duplicateColorComponent( f.u ); 193 duplicateColorComponent( f.v ); 194 } 195 196 void 197 combineTopAndBottomInFrame( YuvFrame& f, Bool botField ) 198 { 199 combineTopAndBottomInColorComponent( f.y, botField ); 200 combineTopAndBottomInColorComponent( f.u, botField ); 201 combineTopAndBottomInColorComponent( f.v, botField ); 202 } 203 204 void 205 writeFrame( YuvFrame& f, FILE* file, int width, int height, bool both = false ) 206 { 207 writeColorComponent( f.y, file, width, height, false ); 208 writeColorComponent( f.u, file, width >> 1, height >> 1, false ); 209 writeColorComponent( f.v, file, width >> 1, height >> 1, false ); 210 211 if( both ) 212 { 213 writeColorComponent( f.y, file, width, height, true ); 214 writeColorComponent( f.u, file, width >> 1, height >> 1, true ); 215 writeColorComponent( f.v, file, width >> 1, height >> 1, true ); 216 } 217 } 218 219 220 void 221 print_usage_and_exit( int test, const char* name, const char* message = 0 ) 222 { 223 if( test ) 224 { 225 if( message ) 226 { 227 fprintf ( stderr, "\nERROR: %s\n", message ); 228 } 229 fprintf ( stderr, "\nUsage: %s <win> <hin> <in> <wout> <hout> <out> [<t> [<skip> [<frms>]]] [[-phase <args>] ]\n\n", name ); 230 fprintf ( stderr, " win : input width (luma samples)\n" ); 231 fprintf ( stderr, " hin : input height (luma samples)\n" ); 232 fprintf ( stderr, " in : input file\n" ); 233 fprintf ( stderr, " wout : output width (luma samples)\n" ); 234 fprintf ( stderr, " hout : output height (luma samples)\n" ); 235 fprintf ( stderr, " out : output file\n" ); 236 fprintf ( stderr, "\n--------------------------- OPTIONAL ---------------------------\n\n" ); 237 fprintf ( stderr, " t : number of temporal downsampling stages (default: 0)\n" ); 238 fprintf ( stderr, " skip : number of frames to skip at start (default: 0)\n" ); 239 fprintf ( stderr, " frms : number of frames wanted in output file (default: max)\n" ); 240 fprintf ( stderr, "\n-------------------------- OVERLOADED --------------------------\n\n" ); 241 fprintf ( stderr, " -phase <in_uv_ph_x> <in_uv_ph_y> <out_uv_ph_x> <out_uv_ph_y>\n"); 242 fprintf ( stderr, " in_uv_ph_x : input chroma phase shift in horizontal direction (default:-1)\n" ); 243 fprintf ( stderr, " in_uv_ph_y : input chroma phase shift in vertical direction (default: 0)\n" ); 244 fprintf ( stderr, " out_uv_ph_x: output chroma phase shift in horizontal direction (default:-1)\n" ); 245 fprintf ( stderr, " out_uv_ph_y: output chroma phase shift in vertical direction (default: 0)\n" ); 246 fprintf ( stderr, "\n\n"); 247 exit ( 1 ); 248 } 249 } 250 251 252 void 253 updateCropParametersFromFile( ResizeParameters& cRP, FILE* cropFile, int resamplingMethod, char* name ) 254 { 255 int crop_x0 = 0; 256 int crop_y0 = 0; 257 int crop_w = 0; 258 int crop_h = 0; 259 if( fscanf( cropFile, "%d,%d,%d,%d\n", &crop_x0, &crop_y0, &crop_w, &crop_h ) == 4 ) 260 { 261 cRP.m_iLeftFrmOffset = crop_x0; 262 cRP.m_iTopFrmOffset = crop_y0; 263 cRP.m_iScaledRefFrmWidth = crop_w; 264 cRP.m_iScaledRefFrmHeight = crop_h; 265 } 266 print_usage_and_exit( cRP.m_iLeftFrmOffset & 1 || cRP.m_iTopFrmOffset & 1, name, "cropping parameters must be even values" ); 267 print_usage_and_exit( cRP.m_iScaledRefFrmWidth & 1 || cRP.m_iScaledRefFrmHeight & 1, name, "cropping parameters must be even values" ); 268 print_usage_and_exit( resamplingMethod == 2 && cRP.m_iScaledRefFrmWidth != gMin( cRP.m_iRefLayerFrmWidth, cRP.m_iFrameWidth ), name, "crop dimensions must be the same as the minimal dimensions" ); 269 print_usage_and_exit( resamplingMethod == 2 && cRP.m_iScaledRefFrmHeight != gMin( cRP.m_iRefLayerFrmHeight, cRP.m_iFrameHeight ), name, "crop dimensions must be the same as the minimal dimensions" ); 270 print_usage_and_exit( cRP.m_iScaledRefFrmWidth > gMax( cRP.m_iRefLayerFrmWidth, cRP.m_iFrameWidth ), name, "wrong crop window size" ); 271 print_usage_and_exit( cRP.m_iScaledRefFrmHeight > gMax( cRP.m_iRefLayerFrmHeight, cRP.m_iFrameHeight ), name, "wrong crop window size" ); 272 print_usage_and_exit( cRP.m_iScaledRefFrmWidth < gMin( cRP.m_iRefLayerFrmWidth, cRP.m_iFrameWidth ), name, "wrong crop window size" ); 273 print_usage_and_exit( cRP.m_iScaledRefFrmHeight < gMin( cRP.m_iRefLayerFrmHeight, cRP.m_iFrameHeight ), name, "wrong crop window size" ); 274 print_usage_and_exit( cRP.m_iLeftFrmOffset + cRP.m_iScaledRefFrmWidth > gMax( cRP.m_iRefLayerFrmWidth, cRP.m_iFrameWidth ), name, "wrong crop window size and origin" ); 275 print_usage_and_exit( cRP.m_iTopFrmOffset + cRP.m_iScaledRefFrmHeight > gMax( cRP.m_iRefLayerFrmHeight, cRP.m_iFrameHeight ), name, "wrong crop window size and origin" ); 276 } 277 278 279 void 280 resampleFrame( YuvFrame& rcFrame, 281 DownConvert& rcDownConvert, 282 ResizeParameters& rcRP, 283 int resamplingMethod, 284 int resamplingMode, 285 bool resampling, 286 bool upsampling, 287 bool bSecondInputFrame ) 288 { 289 assert( upsampling == 0 ); 290 291 //===== downsampling ===== 292 ResizeParameters cRP = rcRP; 293 { 294 Int iRefVerMbShift = ( cRP.m_bRefLayerFrameMbsOnlyFlag ? 4 : 5 ); 295 Int iScaledVerShift = ( cRP.m_bFrameMbsOnlyFlag ? 1 : 2 ); 296 Int iHorDiv = ( cRP.m_iFrameWidth << 1 ); 297 Int iVerDiv = ( cRP.m_iFrameHeight << iScaledVerShift ); 298 Int iRefFrmW = ( ( cRP.m_iFrameWidth + ( 1 << 4 ) - 1 ) >> 4 ) << 4; // round to next multiple of 16 299 Int iRefFrmH = ( ( cRP.m_iFrameHeight + ( 1 << iRefVerMbShift ) - 1 ) >> iRefVerMbShift ) << iRefVerMbShift; // round to next multiple of 16 or 32 (for interlaced) 300 Int iScaledRefFrmW = ( ( cRP.m_iScaledRefFrmWidth * iRefFrmW + ( iHorDiv >> 1 ) ) / iHorDiv ) << 1; // scale and round to next multiple of 2 301 Int iScaledRefFrmH = ( ( cRP.m_iScaledRefFrmHeight * iRefFrmH + ( iVerDiv >> 1 ) ) / iVerDiv ) << iScaledVerShift; // scale and round to next multiple of 2 or 4 (for interlaced) 302 cRP.m_iFrameWidth = iRefFrmW; 303 cRP.m_iFrameHeight = iRefFrmH; 304 cRP.m_iScaledRefFrmWidth = iScaledRefFrmW; 305 cRP.m_iScaledRefFrmHeight = iScaledRefFrmH; 306 } 307 assert( resamplingMethod == 0 ); 308 if( resamplingMode < 4 ) 309 { 310 rcDownConvert.downsamplingSVC ( rcFrame.y.data, rcFrame.y.stride, rcFrame.u.data, rcFrame.u.stride, rcFrame.v.data, rcFrame.v.stride, &cRP, resamplingMode == 3 ); 311 return; 312 } 313 } 314 315 316 317 int 318 main( int argc, char *argv[] ) 319 { 320 //===== set standard resize parameters ===== 321 ResizeParameters cRP; 322 cRP.m_bRefLayerFrameMbsOnlyFlag = true; 323 cRP.m_bFrameMbsOnlyFlag = true; 324 cRP.m_bRefLayerFieldPicFlag = false; 325 cRP.m_bFieldPicFlag = false; 326 cRP.m_bRefLayerBotFieldFlag = false; 327 cRP.m_bBotFieldFlag = false; 328 cRP.m_bRefLayerIsMbAffFrame = false; 329 cRP.m_bIsMbAffFrame = false; 330 #if ZERO_PHASE 331 cRP.m_iRefLayerChromaPhaseX = 0; 332 cRP.m_iRefLayerChromaPhaseY = 1; 333 cRP.m_iChromaPhaseX = 0; 334 cRP.m_iChromaPhaseY = 1; 335 #else 336 cRP.m_iRefLayerChromaPhaseX = -1; 337 cRP.m_iRefLayerChromaPhaseY = 0; 338 cRP.m_iChromaPhaseX = -1; 339 cRP.m_iChromaPhaseY = 0; 340 #endif 341 cRP.m_iRefLayerFrmWidth = 0; 342 cRP.m_iRefLayerFrmHeight = 0; 343 cRP.m_iScaledRefFrmWidth = 0; 344 cRP.m_iScaledRefFrmHeight = 0; 345 cRP.m_iFrameWidth = 0; 346 cRP.m_iFrameHeight = 0; 347 cRP.m_iLeftFrmOffset = 0; 348 cRP.m_iTopFrmOffset = 0; 349 //cRP.m_iExtendedSpatialScalability = 0; 350 cRP.m_iLevelIdc = 0; 351 352 //===== init parameters ===== 353 FILE* inputFile = 0; 354 FILE* outputFile = 0; 355 FILE* croppingParametersFile = 0; 356 int resamplingMethod = 0; 357 int resamplingMode = 0; 358 bool croppingInitialized = false; 359 bool phaseInitialized = false; 360 bool methodInitialized = false; 361 bool resampling = false; 362 bool upsampling = false; 363 int numSpatialDyadicStages = 0; 364 int skipBetween = 0; 365 int skipAtStart = 0; 366 int maxNumOutputFrames = 0; 367 368 369 //===== read input parameters ===== 370 print_usage_and_exit( ( argc < 7 || argc > 24 ), argv[0], "wrong number of arguments" ); 371 cRP.m_iRefLayerFrmWidth = atoi ( argv[1] ); 372 cRP.m_iRefLayerFrmHeight = atoi ( argv[2] ); 373 inputFile = fopen ( argv[3], "rb" ); 374 cRP.m_iFrameWidth = atoi ( argv[4] ); 375 cRP.m_iFrameHeight = atoi ( argv[5] ); 376 outputFile = fopen ( argv[6], "wb" ); 377 print_usage_and_exit( ! inputFile, argv[0], "failed to open input file" ); 378 print_usage_and_exit( ! outputFile, argv[0], "failed to open input file" ); 379 print_usage_and_exit( cRP.m_iRefLayerFrmWidth > cRP.m_iFrameWidth && cRP.m_iRefLayerFrmHeight < cRP.m_iFrameHeight, argv[0], "mixed upsampling and downsampling not supported" ); 380 print_usage_and_exit( cRP.m_iRefLayerFrmWidth < cRP.m_iFrameWidth && cRP.m_iRefLayerFrmHeight > cRP.m_iFrameHeight, argv[0], "mixed upsampling and downsampling not supported" ); 381 for( int i = 7; i < argc; ) 382 { 383 if( ! strcmp( argv[i], "-phase" ) ) 384 { 385 print_usage_and_exit( resamplingMethod != 0, argv[0], "phases only supported in normative resampling" ); 386 print_usage_and_exit( phaseInitialized || argc < i+5, argv[0], "wrong number of phase parameters" ); 387 phaseInitialized = true; 388 i++; 389 cRP.m_iRefLayerChromaPhaseX = atoi( argv[i++] ); 390 cRP.m_iRefLayerChromaPhaseY = atoi( argv[i++] ); 391 cRP.m_iChromaPhaseX = atoi( argv[i++] ); 392 cRP.m_iChromaPhaseY = atoi( argv[i++] ); 393 print_usage_and_exit( cRP.m_iRefLayerChromaPhaseX > 0 || cRP.m_iRefLayerChromaPhaseX < -1, argv[0], "wrong phase x parameters (range : [-1, 0])"); 394 print_usage_and_exit( cRP.m_iRefLayerChromaPhaseY > 1 || cRP.m_iRefLayerChromaPhaseY < -1, argv[0], "wrong phase x parameters (range : [-1, 1])"); 395 print_usage_and_exit( cRP.m_iChromaPhaseX > 0 || cRP.m_iChromaPhaseX < -1, argv[0], "wrong phase x parameters (range : [-1, 0])"); 396 print_usage_and_exit( cRP.m_iChromaPhaseY > 1 || cRP.m_iChromaPhaseY < -1, argv[0], "wrong phase x parameters (range : [-1, 1])"); 397 } 398 else if (i == 7) 399 { 400 methodInitialized = true; 401 resamplingMethod = atoi( argv[i++] ); 402 print_usage_and_exit( resamplingMethod < 0 || resamplingMethod > 4, argv[0], "unsupported method" ); 403 if( resamplingMethod > 2 ) 404 { 405 print_usage_and_exit( cRP.m_iRefLayerFrmWidth > cRP.m_iFrameWidth, argv[0], "method 3 and 4 are not supported for downsampling" ); 406 print_usage_and_exit( cRP.m_iRefLayerFrmHeight > cRP.m_iFrameHeight, argv[0], "method 3 and 4 are not supported for downsampling" ); 407 } 408 if( resamplingMethod != 2 ) 409 { 410 resampling = true; 411 upsampling = ( cRP.m_iRefLayerFrmWidth < cRP.m_iFrameWidth ) || ( cRP.m_iRefLayerFrmHeight < cRP.m_iFrameHeight ); 412 } 413 if( resamplingMethod == 1 ) 414 { 415 if( upsampling ) 416 { 417 int div = cRP.m_iFrameWidth / cRP.m_iRefLayerFrmWidth; 418 if ( div == 1) numSpatialDyadicStages = 0; 419 else if( div == 2) numSpatialDyadicStages = 1; 420 else if( div == 4) numSpatialDyadicStages = 2; 421 else if( div == 8) numSpatialDyadicStages = 3; 422 else numSpatialDyadicStages = -1; 423 print_usage_and_exit( numSpatialDyadicStages < 0, argv[0], "ratio not supported for dyadic upsampling method" ); 424 print_usage_and_exit( div * cRP.m_iRefLayerFrmWidth != cRP.m_iFrameWidth, argv[0], "ratio is not dyadic in dyadic mode" ); 425 print_usage_and_exit( div * cRP.m_iRefLayerFrmHeight != cRP.m_iFrameHeight, argv[0], "different horizontal and vertical ratio in dyadic mode" ); 426 } 427 else 428 { 429 int div = cRP.m_iRefLayerFrmWidth / cRP.m_iFrameWidth; 430 if ( div == 1) numSpatialDyadicStages = 0; 431 else if( div == 2) numSpatialDyadicStages = 1; 432 else if( div == 4) numSpatialDyadicStages = 2; 433 else if( div == 8) numSpatialDyadicStages = 3; 434 else numSpatialDyadicStages = -1; 435 print_usage_and_exit( numSpatialDyadicStages < 0, argv[0], "ratio not supported for dyadic downsampling method" ); 436 print_usage_and_exit( div * cRP.m_iFrameWidth != cRP.m_iRefLayerFrmWidth, argv[0], "ratio is not dyadic in dyadic mode" ); 437 print_usage_and_exit( div * cRP.m_iFrameHeight != cRP.m_iRefLayerFrmHeight, argv[0], "different horizontal and vertical ratio in dyadic mode" ); 438 } 439 } 440 } 441 else if( i == 8 ) 442 { 443 int TStages = atoi( argv[i++] ); 444 skipBetween = ( 1 << TStages ) - 1; 445 print_usage_and_exit( TStages < 0, argv[0], "negative number of temporal stages" ); 446 } 447 else if( i == 9 ) 448 { 449 skipAtStart = atoi( argv[i++] ); 450 print_usage_and_exit( skipAtStart < 0, argv[0], "negative number of skipped frames at start" ); 451 } 452 else if( i == 10 ) 453 { 454 maxNumOutputFrames = atoi( argv[i++] ); 455 print_usage_and_exit( maxNumOutputFrames < 0 , argv[0], "negative number of output frames" ); 456 } 457 else 458 { 459 print_usage_and_exit( true, argv[0], "error in command line parameters" ); 460 } 461 } 462 if( ! methodInitialized ) 463 { 464 resampling = true; 465 upsampling = ( cRP.m_iRefLayerFrmWidth < cRP.m_iFrameWidth ) || ( cRP.m_iRefLayerFrmHeight < cRP.m_iFrameHeight ); 466 } 467 if( ! croppingInitialized ) 468 { 469 if( resamplingMethod == 2 ) 470 { 471 cRP.m_iScaledRefFrmWidth = gMin( cRP.m_iRefLayerFrmWidth, cRP.m_iFrameWidth ); 472 cRP.m_iScaledRefFrmHeight = gMin( cRP.m_iRefLayerFrmHeight, cRP.m_iFrameHeight ); 473 } 474 else 475 { 476 cRP.m_iScaledRefFrmWidth = gMax( cRP.m_iRefLayerFrmWidth, cRP.m_iFrameWidth ); 477 cRP.m_iScaledRefFrmHeight = gMax( cRP.m_iRefLayerFrmHeight, cRP.m_iFrameHeight ); 478 } 479 } 480 481 //===== set basic parameters for resampling control ===== 482 if( resamplingMethod == 0 ) 483 { 484 if( resamplingMode == 1 ) 485 { 486 cRP.m_bRefLayerFrameMbsOnlyFlag = false; 487 cRP.m_bFrameMbsOnlyFlag = false; 488 } 489 else if( resamplingMode == 2 || resamplingMode == 3 ) 490 { 491 cRP.m_bFrameMbsOnlyFlag = false; 492 if( ! upsampling ) 493 { 494 cRP.m_bFieldPicFlag = true; 495 cRP.m_bBotFieldFlag = ( resamplingMode == 3 ); 496 } 497 } 498 else if( resamplingMode == 4 || resamplingMode == 5 ) 499 { 500 cRP.m_bRefLayerFrameMbsOnlyFlag = false; 501 cRP.m_bRefLayerFieldPicFlag = true; 502 } 503 } 504 505 //===== initialize classes ===== 506 YuvFrame cFrame; 507 DownConvert cDownConvert; 508 { 509 int maxWidth = gMax( cRP.m_iRefLayerFrmWidth, cRP.m_iFrameWidth ); 510 int maxHeight = gMax( cRP.m_iRefLayerFrmHeight, cRP.m_iFrameHeight ); 511 int minWidth = gMin( cRP.m_iRefLayerFrmWidth, cRP.m_iFrameWidth ); 512 int minHeight = gMin( cRP.m_iRefLayerFrmHeight, cRP.m_iFrameHeight ); 513 int minWRnd16 = ( ( minWidth + 15 ) >> 4 ) << 4; 514 int minHRnd32 = ( ( minHeight + 31 ) >> 5 ) << 5; 515 maxWidth = ( ( maxWidth * minWRnd16 + ( minWidth << 4 ) - 1 ) / ( minWidth << 4 ) ) << 4; 516 maxHeight = ( ( maxHeight * minHRnd32 + ( minHeight << 4 ) - 1 ) / ( minHeight << 4 ) ) << 4; 517 createFrame( cFrame, maxWidth, maxHeight ); 518 cDownConvert.init( maxWidth, maxHeight ); 519 } 520 521 printf("Resampler\n\n"); 522 523 //===== loop over frames ===== 524 int skip = skipAtStart; 525 int writtenFrames = 0; 526 int numInputFrames = ( resamplingMode >= 4 && ! upsampling ? 2 : 1 ); 527 int numOutputFrames = ( resamplingMode >= 4 && upsampling ? 2 : 1 ); 528 bool bFinished = false; 529 long startTime = clock(); 530 while( ! bFinished ) 531 { 532 for( int inputFrame = 0; inputFrame < numInputFrames && ! bFinished; inputFrame++ ) 533 { 534 //===== read input frame ===== 535 for( int numToRead = skip + 1; numToRead > 0 && ! bFinished; numToRead-- ) 536 { 537 bFinished = ( readFrame( cFrame, inputFile, cRP.m_iRefLayerFrmWidth, cRP.m_iRefLayerFrmHeight, inputFrame != 0 ) != 0 ); 538 } 539 skip = skipBetween; 540 if( cRP.m_iExtendedSpatialScalability == 2 && ! bFinished ) 541 { 542 updateCropParametersFromFile( cRP, croppingParametersFile, resamplingMethod, argv[0] ); 543 } 544 545 //===== set resampling parameter ===== 546 if( resamplingMethod != 0 && 547 cRP.m_iScaledRefFrmWidth == gMin( cRP.m_iRefLayerFrmWidth, cRP.m_iFrameWidth ) && 548 cRP.m_iScaledRefFrmHeight == gMin( cRP.m_iRefLayerFrmHeight, cRP.m_iFrameHeight ) ) 549 { 550 resampling = false; 551 } 552 else 553 { 554 resampling = true; 555 } 556 557 //===== resample input frame ===== 558 if( ! bFinished ) 559 { 560 resampleFrame( cFrame, cDownConvert, cRP, resamplingMethod, resamplingMode, resampling, upsampling, inputFrame != 0 ); 561 } 562 } 563 564 //===== write output frame ===== 565 if( ! bFinished ) 566 { 567 Bool bWriteTwoFrames = ( numOutputFrames == 2 && ( maxNumOutputFrames == 0 || writtenFrames + 1 < maxNumOutputFrames ) ); 568 writeFrame( cFrame, outputFile, cRP.m_iFrameWidth, cRP.m_iFrameHeight, bWriteTwoFrames ); 569 writtenFrames += ( bWriteTwoFrames ? 2 : 1 ); 570 bFinished = ( maxNumOutputFrames != 0 && writtenFrames == maxNumOutputFrames ); 571 fprintf( stderr, "\r%6d frames converted", writtenFrames ); 572 } 573 } 574 long endTime = clock(); 575 576 deleteFrame( cFrame ); 577 fclose ( inputFile ); 578 fclose ( outputFile ); 579 if( croppingParametersFile ) 580 { 581 fclose ( croppingParametersFile ); 582 } 583 584 fprintf( stderr, "\n" ); 585 double deltaInSecond = (double)( endTime - startTime) / (double)CLOCKS_PER_SEC; 586 fprintf( stderr, "in %.2lf seconds => %.0lf ms/frame\n", deltaInSecond, deltaInSecond / (double)writtenFrames * 1000.0 ); 587 if( writtenFrames < maxNumOutputFrames ) 588 { 589 fprintf( stderr, "\nNOTE: less output frames generated than specified!!!\n\n" ); 590 } 468 591 return 0; 469 592 } 470 471 //! \}
Note: See TracChangeset for help on using the changeset viewer.