00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include "contributors.h"
00016 #include "global.h"
00017 #include "image.h"
00018 #include "input.h"
00019
00020 void write_out_picture(StorablePicture *p, int p_out);
00021
00022 FrameStore* out_buffer;
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048 void img2buf (imgpel** imgX, unsigned char* buf, int size_x, int size_y, int symbol_size_in_bytes, int crop_left, int crop_right, int crop_top, int crop_bottom)
00049 {
00050 int i,j;
00051
00052 int twidth = size_x - crop_left - crop_right;
00053 int theight = size_y - crop_top - crop_bottom;
00054
00055 int size = 0;
00056
00057 unsigned char ui8;
00058 unsigned short tmp16, ui16;
00059 unsigned long tmp32, ui32;
00060
00061 if (( sizeof(char) == sizeof (imgpel)) && ( sizeof(char) == symbol_size_in_bytes))
00062 {
00063
00064 if (crop_left == 0 && crop_top == 0 && crop_right == 0 && crop_bottom == 0)
00065 memcpy(buf,&(imgX[0][0]), twidth * theight);
00066 else
00067 {
00068 for(i=0;i<theight;i++)
00069 memcpy(buf + crop_left + (i * twidth),&(imgX[i + crop_top][crop_left]), twidth);
00070 }
00071 }
00072 else
00073 {
00074
00075 if (testEndian())
00076 {
00077
00078 switch (symbol_size_in_bytes)
00079 {
00080 case 1:
00081 {
00082 for(i=crop_top;i<size_y-crop_bottom;i++)
00083 for(j=crop_left;j<size_x-crop_right;j++)
00084 {
00085 ui8 = (unsigned char) (imgX[i][j]);
00086 buf[(j-crop_left+((i-crop_top)*(twidth)))] = ui8;
00087 }
00088 break;
00089 }
00090 case 2:
00091 {
00092 for(i=crop_top;i<size_y-crop_bottom;i++)
00093 for(j=crop_left;j<size_x-crop_right;j++)
00094 {
00095 tmp16 = (unsigned short) (imgX[i][j]);
00096 ui16 = (tmp16 >> 8) | ((tmp16&0xFF)<<8);
00097 memcpy(buf+((j-crop_left+((i-crop_top)*(twidth)))*2),&(ui16), 2);
00098 }
00099 break;
00100 }
00101 case 4:
00102 {
00103 for(i=crop_top;i<size_y-crop_bottom;i++)
00104 for(j=crop_left;j<size_x-crop_right;j++)
00105 {
00106 tmp32 = (unsigned long) (imgX[i][j]);
00107 ui32 = ((tmp32&0xFF00)<<8) | ((tmp32&0xFF)<<24) | ((tmp32&0xFF0000)>>8) | ((tmp32&0xFF000000)>>24);
00108 memcpy(buf+((j-crop_left+((i-crop_top)*(twidth)))*4),&(ui32), 4);
00109 }
00110 break;
00111 }
00112 default:
00113 {
00114 error ("writing only to formats of 8, 16 or 32 bit allowed on big endian architecture", 500);
00115 break;
00116 }
00117 }
00118
00119 }
00120 else
00121 {
00122
00123 if (sizeof (imgpel) < symbol_size_in_bytes)
00124 {
00125
00126 size = sizeof (imgpel);
00127
00128 memset (buf, 0, (twidth*theight*symbol_size_in_bytes));
00129 }
00130 else
00131 {
00132 size = symbol_size_in_bytes;
00133 }
00134
00135 for(i=crop_top;i<size_y-crop_bottom;i++)
00136 {
00137 int i_pos = (i-crop_top)*(twidth) - crop_left;
00138 for(j=crop_left;j<size_x-crop_right;j++)
00139 {
00140 memcpy(buf+((j + i_pos)*symbol_size_in_bytes),&(imgX[i][j]), size);
00141 }
00142 }
00143 }
00144 }
00145 }
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159 void write_picture(StorablePicture *p, int p_out, int real_structure)
00160 {
00161 write_out_picture(p, p_out);
00162 }
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174 void write_out_picture(StorablePicture *p, int p_out)
00175 {
00176 int SubWidthC [4]= { 1, 2, 2, 1};
00177 int SubHeightC [4]= { 1, 2, 1, 1};
00178
00179 int ret;
00180
00181 int crop_left, crop_right, crop_top, crop_bottom;
00182 int symbol_size_in_bytes = img->out_unit_size_on_disk/8;
00183 Boolean rgb_output = (Boolean) (params->rgb_input_flag != CM_YUV && params->output.yuv_format == YUV444);
00184 unsigned char *buf;
00185
00186 if (p->non_existing)
00187 return;
00188 if (p_out == -1)
00189 return;
00190
00191 if (p->frame_cropping_flag)
00192 {
00193 crop_left = SubWidthC[p->chroma_format_idc] * p->frame_cropping_rect_left_offset;
00194 crop_right = SubWidthC[p->chroma_format_idc] * p->frame_cropping_rect_right_offset;
00195 crop_top = SubHeightC[p->chroma_format_idc]*( 2 - p->frame_mbs_only_flag ) * p->frame_cropping_rect_top_offset;
00196 crop_bottom = SubHeightC[p->chroma_format_idc]*( 2 - p->frame_mbs_only_flag ) * p->frame_cropping_rect_bottom_offset;
00197 }
00198 else
00199 {
00200 crop_left = crop_right = crop_top = crop_bottom = 0;
00201 }
00202
00203
00204
00205
00206 buf = malloc (p->size_x * p->size_y * symbol_size_in_bytes);
00207 if (NULL==buf)
00208 {
00209 no_mem_exit("write_out_picture: buf");
00210 }
00211
00212 if(rgb_output)
00213 {
00214 crop_left = p->frame_cropping_rect_left_offset;
00215 crop_right = p->frame_cropping_rect_right_offset;
00216 crop_top = ( 2 - p->frame_mbs_only_flag ) * p->frame_cropping_rect_top_offset;
00217 crop_bottom = ( 2 - p->frame_mbs_only_flag ) * p->frame_cropping_rect_bottom_offset;
00218
00219 img2buf (p->imgUV[1], buf, p->size_x_cr, p->size_y_cr, symbol_size_in_bytes, crop_left, crop_right, crop_top, crop_bottom);
00220 ret = write(p_out, buf, (p->size_y_cr-crop_bottom-crop_top)*(p->size_x_cr-crop_right-crop_left)*symbol_size_in_bytes);
00221 if (ret != ((p->size_y_cr-crop_bottom-crop_top)*(p->size_x_cr-crop_right-crop_left)*symbol_size_in_bytes))
00222 {
00223 error ("write_out_picture: error writing to RGB output file.", 500);
00224 }
00225
00226 if (p->frame_cropping_flag)
00227 {
00228 crop_left = SubWidthC[p->chroma_format_idc] * p->frame_cropping_rect_left_offset;
00229 crop_right = SubWidthC[p->chroma_format_idc] * p->frame_cropping_rect_right_offset;
00230 crop_top = SubHeightC[p->chroma_format_idc]*( 2 - p->frame_mbs_only_flag ) * p->frame_cropping_rect_top_offset;
00231 crop_bottom = SubHeightC[p->chroma_format_idc]*( 2 - p->frame_mbs_only_flag ) * p->frame_cropping_rect_bottom_offset;
00232 }
00233 else
00234 {
00235 crop_left = crop_right = crop_top = crop_bottom = 0;
00236 }
00237 }
00238
00239 img2buf (p->imgY, buf, p->size_x, p->size_y, symbol_size_in_bytes, crop_left, crop_right, crop_top, crop_bottom);
00240 ret = write(p_out, buf, (p->size_y-crop_bottom-crop_top)*(p->size_x-crop_right-crop_left)*symbol_size_in_bytes);
00241 if (ret != ((p->size_y-crop_bottom-crop_top)*(p->size_x-crop_right-crop_left)*symbol_size_in_bytes))
00242 {
00243 error ("write_out_picture: error writing to YUV output file.", 500);
00244 }
00245
00246 if (p->chroma_format_idc != YUV400)
00247 {
00248 crop_left = p->frame_cropping_rect_left_offset;
00249 crop_right = p->frame_cropping_rect_right_offset;
00250 crop_top = ( 2 - p->frame_mbs_only_flag ) * p->frame_cropping_rect_top_offset;
00251 crop_bottom = ( 2 - p->frame_mbs_only_flag ) * p->frame_cropping_rect_bottom_offset;
00252
00253 img2buf (p->imgUV[0], buf, p->size_x_cr, p->size_y_cr, symbol_size_in_bytes, crop_left, crop_right, crop_top, crop_bottom);
00254 ret = write(p_out, buf, (p->size_y_cr-crop_bottom-crop_top)*(p->size_x_cr-crop_right-crop_left)* symbol_size_in_bytes);
00255 if (ret != ((p->size_y_cr-crop_bottom-crop_top)*(p->size_x_cr-crop_right-crop_left)* symbol_size_in_bytes))
00256 {
00257 error ("write_out_picture: error writing to YUV output file.", 500);
00258 }
00259
00260 if (!rgb_output)
00261 {
00262 img2buf (p->imgUV[1], buf, p->size_x_cr, p->size_y_cr, symbol_size_in_bytes, crop_left, crop_right, crop_top, crop_bottom);
00263 ret = write(p_out, buf, (p->size_y_cr-crop_bottom-crop_top)*(p->size_x_cr-crop_right-crop_left)*symbol_size_in_bytes);
00264 if (ret != ((p->size_y_cr-crop_bottom-crop_top)*(p->size_x_cr-crop_right-crop_left)*symbol_size_in_bytes))
00265 {
00266 error ("write_out_picture: error writing to YUV output file.", 500);
00267 }
00268 }
00269 }
00270
00271 free(buf);
00272
00273
00274 }
00275
00276
00277
00278
00279
00280
00281
00282 void init_out_buffer()
00283 {
00284 out_buffer = alloc_frame_store();
00285 }
00286
00287
00288
00289
00290
00291
00292
00293 void uninit_out_buffer()
00294 {
00295 free_frame_store(out_buffer);
00296 out_buffer=NULL;
00297 }
00298
00299
00300
00301
00302
00303
00304
00305 void clear_picture(StorablePicture *p)
00306 {
00307 int i;
00308
00309 if (img->bitdepth_luma == 8)
00310 {
00311
00312
00313 for(i=0;i<p->size_y;i++)
00314 memset(p->imgY[i], img->dc_pred_value_comp[0], p->size_x*sizeof(imgpel));
00315 }
00316 else
00317 {
00318 int j;
00319 for(i=0;i < p->size_y; i++)
00320 for(j=0;j < p->size_x; j++)
00321 p->imgY[i][j] = img->dc_pred_value_comp[0];
00322 }
00323
00324 if (img->bitdepth_chroma == 8)
00325 {
00326 for(i=0;i<p->size_y_cr;i++)
00327 memset(p->imgUV[0][i], img->dc_pred_value_comp[1], p->size_x_cr*sizeof(imgpel));
00328 for(i=0;i<p->size_y_cr;i++)
00329 memset(p->imgUV[1][i], img->dc_pred_value_comp[2], p->size_x_cr*sizeof(imgpel));
00330 }
00331 else
00332 {
00333 int k, j;
00334 for (k = 0; k < 2; k++)
00335 {
00336 for(i=0;i<p->size_y_cr;i++)
00337 for(j=0;j < p->size_x_cr; j++)
00338 p->imgUV[k][i][j] = img->dc_pred_value_comp[1];
00339 }
00340 }
00341 }
00342
00343
00344
00345
00346
00347
00348
00349
00350
00351
00352
00353
00354 void write_unpaired_field(FrameStore* fs, int p_out)
00355 {
00356 StorablePicture *p;
00357 assert (fs->is_used<3);
00358 if(fs->is_used &1)
00359 {
00360
00361
00362 p = fs->top_field;
00363 fs->bottom_field = alloc_storable_picture(BOTTOM_FIELD, p->size_x, p->size_y, p->size_x_cr, p->size_y_cr);
00364 fs->bottom_field->chroma_format_idc = p->chroma_format_idc;
00365 clear_picture(fs->bottom_field);
00366 dpb_combine_field_yuv(fs);
00367 write_picture (fs->frame, p_out, TOP_FIELD);
00368 }
00369
00370 if(fs->is_used &2)
00371 {
00372
00373
00374 p = fs->bottom_field;
00375 fs->top_field = alloc_storable_picture(TOP_FIELD, p->size_x, p->size_y, p->size_x_cr, p->size_y_cr);
00376 clear_picture(fs->top_field);
00377 fs->top_field->chroma_format_idc = p->chroma_format_idc;
00378 clear_picture(fs->top_field);
00379 fs ->top_field->frame_cropping_flag = fs->bottom_field->frame_cropping_flag;
00380 if(fs ->top_field->frame_cropping_flag)
00381 {
00382 fs ->top_field->frame_cropping_rect_top_offset = fs->bottom_field->frame_cropping_rect_top_offset;
00383 fs ->top_field->frame_cropping_rect_bottom_offset = fs->bottom_field->frame_cropping_rect_bottom_offset;
00384 fs ->top_field->frame_cropping_rect_left_offset = fs->bottom_field->frame_cropping_rect_left_offset;
00385 fs ->top_field->frame_cropping_rect_right_offset = fs->bottom_field->frame_cropping_rect_right_offset;
00386 }
00387 dpb_combine_field_yuv(fs);
00388 write_picture (fs->frame, p_out, BOTTOM_FIELD);
00389 }
00390
00391 fs->is_used=3;
00392 }
00393
00394
00395
00396
00397
00398
00399
00400
00401
00402 void flush_direct_output(int p_out)
00403 {
00404 write_unpaired_field(out_buffer, p_out);
00405
00406 free_storable_picture(out_buffer->frame);
00407 out_buffer->frame = NULL;
00408 free_storable_picture(out_buffer->top_field);
00409 out_buffer->top_field = NULL;
00410 free_storable_picture(out_buffer->bottom_field);
00411 out_buffer->bottom_field = NULL;
00412 out_buffer->is_used = 0;
00413 }
00414
00415
00416
00417
00418
00419
00420
00421
00422
00423
00424
00425
00426 void write_stored_frame( FrameStore *fs,int p_out)
00427 {
00428
00429 flush_direct_output(p_out);
00430
00431 if (fs->is_used<3)
00432 {
00433 write_unpaired_field(fs, p_out);
00434 }
00435 else
00436 {
00437 write_picture(fs->frame, p_out, FRAME);
00438 }
00439
00440 fs->is_output = 1;
00441 }
00442
00443
00444
00445
00446
00447
00448
00449
00450
00451
00452
00453
00454
00455 void direct_output(StorablePicture *p, int p_out)
00456 {
00457 switch ( p->structure )
00458 {
00459 case FRAME:
00460
00461
00462 flush_direct_output(p_out);
00463 write_picture (p, p_out, FRAME);
00464 free_storable_picture(p);
00465 return;
00466 break;
00467 case TOP_FIELD:
00468 if (out_buffer->is_used &1)
00469 flush_direct_output(p_out);
00470 out_buffer->top_field = p;
00471 out_buffer->is_used |= 1;
00472 break;
00473 case BOTTOM_FIELD:
00474 if (out_buffer->is_used &2)
00475 flush_direct_output(p_out);
00476 out_buffer->bottom_field = p;
00477 out_buffer->is_used |= 2;
00478 break;
00479 default:
00480 printf("invalid picture type\n");
00481 break;
00482 }
00483
00484 if (out_buffer->is_used == 3)
00485 {
00486
00487 dpb_combine_field_yuv(out_buffer);
00488 write_picture (out_buffer->frame, p_out, FRAME);
00489 free_storable_picture(out_buffer->frame);
00490 out_buffer->frame = NULL;
00491 free_storable_picture(out_buffer->top_field);
00492 out_buffer->top_field = NULL;
00493 free_storable_picture(out_buffer->bottom_field);
00494 out_buffer->bottom_field = NULL;
00495 out_buffer->is_used = 0;
00496 }
00497 }
00498
00499
00500
00501
00502
00503
00504
00505
00506
00507
00508
00509
00510
00511 void direct_output_paff(StorablePicture *p, int p_out)
00512 {
00513 printf("Warning!!! Frame can't fit in DPB. Displayed out of sequence.\n");
00514 free_storable_picture(out_buffer->frame);
00515 out_buffer->frame = NULL;
00516 free_storable_picture(out_buffer->top_field);
00517 out_buffer->top_field = NULL;
00518 free_storable_picture(out_buffer->bottom_field);
00519 out_buffer->bottom_field = NULL;
00520 out_buffer->is_used = 0;
00521
00522 direct_output(p, p_out);
00523 }