00001
00015 #include "contributors.h"
00016
00017 #include "global.h"
00018 #include "mbuffer.h"
00019 #include "image.h"
00020 #include "memalloc.h"
00021 #include "sei.h"
00022 #include "input.h"
00023
00024 static void write_out_picture(ImageParameters *p_Img, StorablePicture *p, int p_out);
00025 static void img2buf_byte (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);
00026 static void img2buf_normal (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);
00027 static void img2buf_endian (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);
00028
00029
00030
00039 static void initOutput(ImageParameters *p_Img, int symbol_size_in_bytes)
00040 {
00041 if (( sizeof(char) == sizeof (imgpel)) && ( sizeof(char) == symbol_size_in_bytes))
00042 {
00043 p_Img->img2buf = img2buf_byte;
00044 }
00045 else
00046 {
00047 if (( sizeof(char) != sizeof (imgpel)) && testEndian())
00048 p_Img->img2buf = img2buf_endian;
00049 else
00050 p_Img->img2buf = img2buf_normal;
00051 }
00052 }
00053
00078 static void img2buf_normal (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)
00079 {
00080 int i,j;
00081
00082 int twidth = size_x - crop_left - crop_right;
00083 int theight = size_y - crop_top - crop_bottom;
00084
00085 int size = 0;
00086
00087
00088
00089 if (sizeof (imgpel) < symbol_size_in_bytes)
00090 {
00091
00092 size = sizeof (imgpel);
00093
00094 memset (buf, 0, (twidth * theight * symbol_size_in_bytes));
00095 }
00096 else
00097 {
00098 size = symbol_size_in_bytes;
00099 }
00100
00101 if ((crop_top || crop_bottom || crop_left || crop_right) || (size != 1))
00102 {
00103 for(i=crop_top;i<size_y-crop_bottom;i++)
00104 {
00105 int ipos = (i - crop_top) * (twidth);
00106 for(j=crop_left;j<size_x-crop_right;j++)
00107 {
00108 memcpy(buf+((j-crop_left+(ipos))*symbol_size_in_bytes),&(imgX[i][j]), size);
00109 }
00110 }
00111 }
00112 else
00113 {
00114 if (sizeof(imgpel) == sizeof(char))
00115 {
00116 memcpy(buf, &(imgX[0][0]), size_y * size_x * sizeof(imgpel));
00117 }
00118 else
00119 {
00120 imgpel *cur_pixel = &(imgX[0][0]);
00121 for(i = 0; i < size_y * size_x; i++)
00122 {
00123 *(buf++)=(char) *(cur_pixel++);
00124 }
00125 }
00126 }
00127 }
00128
00153 static void img2buf_byte (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)
00154 {
00155 int i;
00156
00157 int twidth = size_x - crop_left - crop_right;
00158 int theight = size_y - crop_top - crop_bottom;
00159
00160
00161 buf += crop_left;
00162 for(i = 0; i < theight; i++)
00163 {
00164 memcpy(buf, &(imgX[i + crop_top][crop_left]), twidth);
00165 buf += twidth;
00166 }
00167 }
00168
00193 static void img2buf_endian (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)
00194 {
00195 int i,j;
00196 static unsigned char ui8;
00197 static uint16 tmp16, ui16;
00198 static unsigned long tmp32, ui32;
00199
00200 int twidth = size_x - crop_left - crop_right;
00201
00202
00203 switch (symbol_size_in_bytes)
00204 {
00205 case 1:
00206 {
00207 for(i=crop_top;i<size_y-crop_bottom;i++)
00208 for(j=crop_left;j<size_x-crop_right;j++)
00209 {
00210 ui8 = (unsigned char) (imgX[i][j]);
00211 buf[(j-crop_left+((i-crop_top)*(twidth)))] = ui8;
00212 }
00213 break;
00214 }
00215 case 2:
00216 {
00217 for(i=crop_top;i<size_y-crop_bottom;i++)
00218 for(j=crop_left;j<size_x-crop_right;j++)
00219 {
00220 tmp16 = (uint16) (imgX[i][j]);
00221 ui16 = (uint16) ((tmp16 >> 8) | ((tmp16&0xFF)<<8));
00222 memcpy(buf+((j-crop_left+((i-crop_top)*(twidth)))*2),&(ui16), 2);
00223 }
00224 break;
00225 }
00226 case 4:
00227 {
00228 for(i=crop_top;i<size_y-crop_bottom;i++)
00229 for(j=crop_left;j<size_x-crop_right;j++)
00230 {
00231 tmp32 = (unsigned long) (imgX[i][j]);
00232 ui32 = (unsigned long) (((tmp32&0xFF00)<<8) | ((tmp32&0xFF)<<24) | ((tmp32&0xFF0000)>>8) | ((tmp32&0xFF000000)>>24));
00233 memcpy(buf+((j-crop_left+((i-crop_top)*(twidth)))*4),&(ui32), 4);
00234 }
00235 break;
00236 }
00237 default:
00238 {
00239 error ("writing only to formats of 8, 16 or 32 bit allowed on big endian architecture", 500);
00240 break;
00241 }
00242 }
00243 }
00244
00245
00246 #if (PAIR_FIELDS_IN_OUTPUT)
00247
00248 void clear_picture(ImageParameters *p_Img, StorablePicture *p);
00249
00258 void flush_pending_output(ImageParameters *p_Img, int p_out)
00259 {
00260 if (p_Img->pending_output_state != FRAME)
00261 {
00262 write_out_picture(p_Img, p_Img->pending_output, p_out);
00263 }
00264
00265 if (p_Img->pending_output->imgY)
00266 {
00267 free_mem2Dpel (p_Img->pending_output->imgY);
00268 p_Img->pending_output->imgY=NULL;
00269 }
00270 if (p_Img->pending_output->imgUV)
00271 {
00272 free_mem3Dpel (p_Img->pending_output->imgUV);
00273 p_Img->pending_output->imgUV=NULL;
00274 }
00275
00276 p_Img->pending_output_state = FRAME;
00277 }
00278
00279
00292 void write_picture(ImageParameters *p_Img, StorablePicture *p, int p_out, int real_structure)
00293 {
00294 int i, add;
00295
00296 if (real_structure==FRAME)
00297 {
00298 flush_pending_output(p_Img, p_out);
00299 write_out_picture(p_Img, p, p_out);
00300 return;
00301 }
00302 if (real_structure == p_Img->pending_output_state)
00303 {
00304 flush_pending_output(p_Img, p_out);
00305 write_picture(p_Img, p, p_out, real_structure);
00306 return;
00307 }
00308
00309 if (p_Img->pending_output_state == FRAME)
00310 {
00311 p_Img->pending_output->size_x = p->size_x;
00312 p_Img->pending_output->size_y = p->size_y;
00313 p_Img->pending_output->size_x_cr = p->size_x_cr;
00314 p_Img->pending_output->size_y_cr = p->size_y_cr;
00315 p_Img->pending_output->chroma_format_idc = p->chroma_format_idc;
00316
00317 p_Img->pending_output->frame_mbs_only_flag = p->frame_mbs_only_flag;
00318 p_Img->pending_output->frame_cropping_flag = p->frame_cropping_flag;
00319 if (p_Img->pending_output->frame_cropping_flag)
00320 {
00321 p_Img->pending_output->frame_cropping_rect_left_offset = p->frame_cropping_rect_left_offset;
00322 p_Img->pending_output->frame_cropping_rect_right_offset = p->frame_cropping_rect_right_offset;
00323 p_Img->pending_output->frame_cropping_rect_top_offset = p->frame_cropping_rect_top_offset;
00324 p_Img->pending_output->frame_cropping_rect_bottom_offset = p->frame_cropping_rect_bottom_offset;
00325 }
00326
00327 get_mem2Dpel (&(p_Img->pending_output->imgY), p_Img->pending_output->size_y, p_Img->pending_output->size_x);
00328 get_mem3Dpel (&(p_Img->pending_output->imgUV), 2, p_Img->pending_output->size_y_cr, p_Img->pending_output->size_x_cr);
00329
00330 clear_picture(p_Img, p_Img->pending_output);
00331
00332
00333 if (real_structure == TOP_FIELD)
00334 {
00335 add = 0;
00336 }
00337 else
00338 {
00339 add = 1;
00340 }
00341
00342 for (i=0; i<p_Img->pending_output->size_y; i+=2)
00343 {
00344 memcpy(p_Img->pending_output->imgY[(i+add)], p->imgY[(i+add)], p->size_x * sizeof(imgpel));
00345 }
00346 for (i=0; i<p_Img->pending_output->size_y_cr; i+=2)
00347 {
00348 memcpy(p_Img->pending_output->imgUV[0][(i+add)], p->imgUV[0][(i+add)], p->size_x_cr * sizeof(imgpel));
00349 memcpy(p_Img->pending_output->imgUV[1][(i+add)], p->imgUV[1][(i+add)], p->size_x_cr * sizeof(imgpel));
00350 }
00351 p_Img->pending_output_state = real_structure;
00352 }
00353 else
00354 {
00355 if ( (p_Img->pending_output->size_x!=p->size_x) || (p_Img->pending_output->size_y!= p->size_y)
00356 || (p_Img->pending_output->frame_mbs_only_flag != p->frame_mbs_only_flag)
00357 || (p_Img->pending_output->frame_cropping_flag != p->frame_cropping_flag)
00358 || ( p_Img->pending_output->frame_cropping_flag &&
00359 ( (p_Img->pending_output->frame_cropping_rect_left_offset != p->frame_cropping_rect_left_offset)
00360 ||(p_Img->pending_output->frame_cropping_rect_right_offset != p->frame_cropping_rect_right_offset)
00361 ||(p_Img->pending_output->frame_cropping_rect_top_offset != p->frame_cropping_rect_top_offset)
00362 ||(p_Img->pending_output->frame_cropping_rect_bottom_offset != p->frame_cropping_rect_bottom_offset)
00363 )
00364 )
00365 )
00366 {
00367 flush_pending_output(p_Img, p_out);
00368 write_picture (p_Img, p, p_out, real_structure);
00369 return;
00370 }
00371
00372 if (real_structure == TOP_FIELD)
00373 {
00374 add = 0;
00375 }
00376 else
00377 {
00378 add = 1;
00379 }
00380
00381 for (i=0; i<p_Img->pending_output->size_y; i+=2)
00382 {
00383 memcpy(p_Img->pending_output->imgY[(i+add)], p->imgY[(i+add)], p->size_x * sizeof(imgpel));
00384 }
00385 for (i=0; i<p_Img->pending_output->size_y_cr; i+=2)
00386 {
00387 memcpy(p_Img->pending_output->imgUV[0][(i+add)], p->imgUV[0][(i+add)], p->size_x_cr * sizeof(imgpel));
00388 memcpy(p_Img->pending_output->imgUV[1][(i+add)], p->imgUV[1][(i+add)], p->size_x_cr * sizeof(imgpel));
00389 }
00390
00391 flush_pending_output(p_Img, p_out);
00392 }
00393 }
00394
00395 #else
00396
00412 void write_picture(ImageParameters *p_Img, StorablePicture *p, int p_out, int real_structure)
00413 {
00414 write_out_picture(p_Img, p, p_out);
00415 }
00416
00417
00418 #endif
00419
00433 static void write_out_picture(ImageParameters *p_Img, StorablePicture *p, int p_out)
00434 {
00435 InputParameters *p_Inp = p_Img->p_Inp;
00436
00437 static const int SubWidthC [4]= { 1, 2, 2, 1};
00438 static const int SubHeightC [4]= { 1, 2, 1, 1};
00439
00440 int crop_left, crop_right, crop_top, crop_bottom;
00441 int symbol_size_in_bytes = (p_Img->pic_unit_bitsize_on_disk >> 3);
00442 Boolean rgb_output = (Boolean) (p_Img->active_sps->vui_seq_parameters.matrix_coefficients==0);
00443 unsigned char *buf;
00444
00445 int ret;
00446
00447 if (p->non_existing)
00448 return;
00449
00450 #if (ENABLE_OUTPUT_TONEMAPPING)
00451
00452 if (p->seiHasTone_mapping && rgb_output)
00453 {
00454
00455 symbol_size_in_bytes = (p->tonemapped_bit_depth>8)? 2 : 1;
00456 tone_map(p->imgY, p->tone_mapping_lut, p->size_x, p->size_y);
00457 tone_map(p->imgUV[0], p->tone_mapping_lut, p->size_x_cr, p->size_y_cr);
00458 tone_map(p->imgUV[1], p->tone_mapping_lut, p->size_x_cr, p->size_y_cr);
00459 }
00460 #endif
00461
00462 if (p->frame_cropping_flag)
00463 {
00464 crop_left = SubWidthC[p->chroma_format_idc] * p->frame_cropping_rect_left_offset;
00465 crop_right = SubWidthC[p->chroma_format_idc] * p->frame_cropping_rect_right_offset;
00466 crop_top = SubHeightC[p->chroma_format_idc]*( 2 - p->frame_mbs_only_flag ) * p->frame_cropping_rect_top_offset;
00467 crop_bottom = SubHeightC[p->chroma_format_idc]*( 2 - p->frame_mbs_only_flag ) * p->frame_cropping_rect_bottom_offset;
00468 }
00469 else
00470 {
00471 crop_left = crop_right = crop_top = crop_bottom = 0;
00472 }
00473
00474
00475 initOutput(p_Img, symbol_size_in_bytes);
00476
00477
00478 buf = malloc (p->size_x*p->size_y*symbol_size_in_bytes);
00479 if (NULL==buf)
00480 {
00481 no_mem_exit("write_out_picture: buf");
00482 }
00483
00484 if(rgb_output)
00485 {
00486 crop_left = p->frame_cropping_rect_left_offset;
00487 crop_right = p->frame_cropping_rect_right_offset;
00488 crop_top = ( 2 - p->frame_mbs_only_flag ) * p->frame_cropping_rect_top_offset;
00489 crop_bottom = ( 2 - p->frame_mbs_only_flag ) * p->frame_cropping_rect_bottom_offset;
00490
00491 p_Img->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);
00492 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);
00493 if (ret != ((p->size_y_cr-crop_bottom-crop_top)*(p->size_x_cr-crop_right-crop_left)*symbol_size_in_bytes))
00494 {
00495 error ("write_out_picture: error writing to RGB file", 500);
00496 }
00497
00498 if (p->frame_cropping_flag)
00499 {
00500 crop_left = SubWidthC[p->chroma_format_idc] * p->frame_cropping_rect_left_offset;
00501 crop_right = SubWidthC[p->chroma_format_idc] * p->frame_cropping_rect_right_offset;
00502 crop_top = SubHeightC[p->chroma_format_idc]*( 2 - p->frame_mbs_only_flag ) * p->frame_cropping_rect_top_offset;
00503 crop_bottom = SubHeightC[p->chroma_format_idc]*( 2 - p->frame_mbs_only_flag ) * p->frame_cropping_rect_bottom_offset;
00504 }
00505 else
00506 {
00507 crop_left = crop_right = crop_top = crop_bottom = 0;
00508 }
00509 }
00510
00511 p_Img->img2buf (p->imgY, buf, p->size_x, p->size_y, symbol_size_in_bytes, crop_left, crop_right, crop_top, crop_bottom);
00512 ret = write(p_out, buf, (p->size_y-crop_bottom-crop_top)*(p->size_x-crop_right-crop_left)*symbol_size_in_bytes);
00513 if (ret != ((p->size_y-crop_bottom-crop_top)*(p->size_x-crop_right-crop_left)*symbol_size_in_bytes))
00514 {
00515 error ("write_out_picture: error writing to YUV file", 500);
00516 }
00517
00518 if (p->chroma_format_idc!=YUV400)
00519 {
00520 crop_left = p->frame_cropping_rect_left_offset;
00521 crop_right = p->frame_cropping_rect_right_offset;
00522 crop_top = ( 2 - p->frame_mbs_only_flag ) * p->frame_cropping_rect_top_offset;
00523 crop_bottom = ( 2 - p->frame_mbs_only_flag ) * p->frame_cropping_rect_bottom_offset;
00524
00525 p_Img->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);
00526 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);
00527 if (ret != ((p->size_y_cr-crop_bottom-crop_top)*(p->size_x_cr-crop_right-crop_left)* symbol_size_in_bytes))
00528 {
00529 error ("write_out_picture: error writing to YUV file", 500);
00530 }
00531 if (!rgb_output)
00532 {
00533 p_Img->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);
00534 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);
00535 if (ret != ((p->size_y_cr-crop_bottom-crop_top)*(p->size_x_cr-crop_right-crop_left)*symbol_size_in_bytes))
00536 {
00537 error ("write_out_picture: error writing to YUV file", 500);
00538 }
00539 }
00540 }
00541 else
00542 {
00543 if (p_Inp->write_uv)
00544 {
00545 int i,j;
00546 imgpel cr_val = (imgpel) (1<<(p_Img->bitdepth_luma - 1));
00547
00548 get_mem3Dpel (&(p->imgUV), 1, p->size_y/2, p->size_x/2);
00549 for (j=0; j<p->size_y/2; j++)
00550 for (i=0; i<p->size_x/2; i++)
00551 p->imgUV[0][j][i]=cr_val;
00552
00553
00554 p_Img->img2buf (p->imgUV[0], buf, p->size_x/2, p->size_y/2, symbol_size_in_bytes, crop_left/2, crop_right/2, crop_top/2, crop_bottom/2);
00555
00556 ret = write(p_out, buf, symbol_size_in_bytes * (p->size_y-crop_bottom-crop_top)/2 * (p->size_x-crop_right-crop_left)/2 );
00557 if (ret != (symbol_size_in_bytes * (p->size_y-crop_bottom-crop_top)/2 * (p->size_x-crop_right-crop_left)/2))
00558 {
00559 error ("write_out_picture: error writing to YUV file", 500);
00560 }
00561 ret = write(p_out, buf, symbol_size_in_bytes * (p->size_y-crop_bottom-crop_top)/2 * (p->size_x-crop_right-crop_left)/2 );
00562 if (ret != (symbol_size_in_bytes * (p->size_y-crop_bottom-crop_top)/2 * (p->size_x-crop_right-crop_left)/2))
00563 {
00564 error ("write_out_picture: error writing to YUV file", 500);
00565 }
00566
00567 free_mem3Dpel(p->imgUV);
00568 p->imgUV=NULL;
00569 }
00570 }
00571
00572 free(buf);
00573
00574
00575 }
00576
00583 void init_out_buffer(ImageParameters *p_Img)
00584 {
00585 p_Img->out_buffer = alloc_frame_store();
00586
00587 #if (PAIR_FIELDS_IN_OUTPUT)
00588 p_Img->pending_output = calloc (sizeof(StorablePicture), 1);
00589 if (NULL==p_Img->pending_output) no_mem_exit("init_out_buffer");
00590 p_Img->pending_output->imgUV = NULL;
00591 p_Img->pending_output->imgY = NULL;
00592 #endif
00593 }
00594
00601 void uninit_out_buffer(ImageParameters *p_Img)
00602 {
00603 free_frame_store(p_Img, p_Img->out_buffer);
00604 p_Img->out_buffer=NULL;
00605 #if (PAIR_FIELDS_IN_OUTPUT)
00606 flush_pending_output(p_Img, p_Img->p_out);
00607 free (p_Img->pending_output);
00608 #endif
00609 }
00610
00617 void clear_picture(ImageParameters *p_Img, StorablePicture *p)
00618 {
00619 int i,j;
00620
00621 for(i=0;i<p->size_y;i++)
00622 {
00623 for (j=0; j<p->size_x; j++)
00624 p->imgY[i][j] = (imgpel) p_Img->dc_pred_value_comp[0];
00625 }
00626 for(i=0;i<p->size_y_cr;i++)
00627 {
00628 for (j=0; j<p->size_x_cr; j++)
00629 p->imgUV[0][i][j] = (imgpel) p_Img->dc_pred_value_comp[1];
00630 }
00631 for(i=0;i<p->size_y_cr;i++)
00632 {
00633 for (j=0; j<p->size_x_cr; j++)
00634 p->imgUV[1][i][j] = (imgpel) p_Img->dc_pred_value_comp[2];
00635 }
00636 }
00637
00652 void write_unpaired_field(ImageParameters *p_Img, FrameStore* fs, int p_out)
00653 {
00654 StorablePicture *p;
00655 assert (fs->is_used<3);
00656
00657 if(fs->is_used & 0x01)
00658 {
00659
00660
00661 p = fs->top_field;
00662 fs->bottom_field = alloc_storable_picture(p_Img, BOTTOM_FIELD, p->size_x, 2*p->size_y, p->size_x_cr, 2*p->size_y_cr);
00663 fs->bottom_field->chroma_format_idc = p->chroma_format_idc;
00664 clear_picture(p_Img, fs->bottom_field);
00665 dpb_combine_field_yuv(p_Img, fs);
00666 write_picture (p_Img, fs->frame, p_out, TOP_FIELD);
00667 }
00668
00669 if(fs->is_used & 0x02)
00670 {
00671
00672
00673 p = fs->bottom_field;
00674 fs->top_field = alloc_storable_picture(p_Img, TOP_FIELD, p->size_x, 2*p->size_y, p->size_x_cr, 2*p->size_y_cr);
00675 fs->top_field->chroma_format_idc = p->chroma_format_idc;
00676 clear_picture(p_Img, fs->top_field);
00677 fs ->top_field->frame_cropping_flag = fs->bottom_field->frame_cropping_flag;
00678 if(fs ->top_field->frame_cropping_flag)
00679 {
00680 fs ->top_field->frame_cropping_rect_top_offset = fs->bottom_field->frame_cropping_rect_top_offset;
00681 fs ->top_field->frame_cropping_rect_bottom_offset = fs->bottom_field->frame_cropping_rect_bottom_offset;
00682 fs ->top_field->frame_cropping_rect_left_offset = fs->bottom_field->frame_cropping_rect_left_offset;
00683 fs ->top_field->frame_cropping_rect_right_offset = fs->bottom_field->frame_cropping_rect_right_offset;
00684 }
00685 dpb_combine_field_yuv(p_Img, fs);
00686 write_picture (p_Img, fs->frame, p_out, BOTTOM_FIELD);
00687 }
00688
00689 fs->is_used = 3;
00690 }
00691
00703 void flush_direct_output(ImageParameters *p_Img, int p_out)
00704 {
00705 write_unpaired_field(p_Img, p_Img->out_buffer, p_out);
00706
00707 free_storable_picture(p_Img, p_Img->out_buffer->frame);
00708 p_Img->out_buffer->frame = NULL;
00709 free_storable_picture(p_Img, p_Img->out_buffer->top_field);
00710 p_Img->out_buffer->top_field = NULL;
00711 free_storable_picture(p_Img, p_Img->out_buffer->bottom_field);
00712 p_Img->out_buffer->bottom_field = NULL;
00713 p_Img->out_buffer->is_used = 0;
00714 }
00715
00716
00730 void write_stored_frame( ImageParameters *p_Img, FrameStore *fs,int p_out)
00731 {
00732
00733 flush_direct_output(p_Img, p_out);
00734
00735 if (fs->is_used<3)
00736 {
00737 write_unpaired_field(p_Img, fs, p_out);
00738 }
00739 else
00740 {
00741 if (fs->recovery_frame)
00742 p_Img->recovery_flag = 1;
00743 if ((!p_Img->non_conforming_stream) || p_Img->recovery_flag)
00744 write_picture(p_Img, fs->frame, p_out, FRAME);
00745 }
00746
00747 fs->is_output = 1;
00748 }
00749
00764 void direct_output(ImageParameters *p_Img, StorablePicture *p, int p_out)
00765 {
00766 InputParameters *p_Inp = p_Img->p_Inp;
00767 if (p->structure==FRAME)
00768 {
00769
00770
00771 flush_direct_output(p_Img, p_out);
00772 write_picture (p_Img, p, p_out, FRAME);
00773 calculate_frame_no(p_Img, p);
00774 if (-1 != p_Img->p_ref && !p_Inp->silent)
00775 find_snr(p_Img, p, &p_Img->p_ref);
00776 free_storable_picture(p_Img, p);
00777 return;
00778 }
00779
00780 if (p->structure == TOP_FIELD)
00781 {
00782 if (p_Img->out_buffer->is_used &1)
00783 flush_direct_output(p_Img, p_Img->p_out);
00784 p_Img->out_buffer->top_field = p;
00785 p_Img->out_buffer->is_used |= 1;
00786 }
00787
00788 if (p->structure == BOTTOM_FIELD)
00789 {
00790 if (p_Img->out_buffer->is_used &2)
00791 flush_direct_output(p_Img, p_Img->p_out);
00792 p_Img->out_buffer->bottom_field = p;
00793 p_Img->out_buffer->is_used |= 2;
00794 }
00795
00796 if (p_Img->out_buffer->is_used == 3)
00797 {
00798
00799 dpb_combine_field_yuv(p_Img, p_Img->out_buffer);
00800 write_picture (p_Img, p_Img->out_buffer->frame, p_Img->p_out, FRAME);
00801
00802 calculate_frame_no(p_Img, p);
00803 if (-1 != p_Img->p_ref && !p_Inp->silent)
00804 find_snr(p_Img, p_Img->out_buffer->frame, &p_Img->p_ref);
00805 free_storable_picture(p_Img, p_Img->out_buffer->frame);
00806 p_Img->out_buffer->frame = NULL;
00807 free_storable_picture(p_Img, p_Img->out_buffer->top_field);
00808 p_Img->out_buffer->top_field = NULL;
00809 free_storable_picture(p_Img, p_Img->out_buffer->bottom_field);
00810 p_Img->out_buffer->bottom_field = NULL;
00811 p_Img->out_buffer->is_used = 0;
00812 }
00813 }
00814