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
00023 FrameStore* out_buffer;
00024
00025 StorablePicture *pending_output = NULL;
00026 int pending_output_state = FRAME;
00027 int recovery_flag = 0;
00028
00029 extern int non_conforming_stream;
00030
00031 static void write_out_picture(StorablePicture *p, int p_out);
00032 static 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);
00033 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);
00034 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);
00035 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);
00036
00046 int testEndian(void)
00047 {
00048 short s;
00049 byte *p;
00050
00051 p=(byte*)&s;
00052
00053 s=1;
00054
00055 return (*p==0);
00056 }
00057
00058
00067 static void initOutput(int symbol_size_in_bytes)
00068 {
00069 if (( sizeof(char) == sizeof (imgpel)) && ( sizeof(char) == symbol_size_in_bytes))
00070 {
00071 img2buf = img2buf_byte;
00072 }
00073 else
00074 {
00075 if (( sizeof(char) != sizeof (imgpel)) && testEndian())
00076 img2buf = img2buf_endian;
00077 else
00078 img2buf = img2buf_normal;
00079 }
00080 }
00081
00106 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)
00107 {
00108 int i,j;
00109
00110 int twidth = size_x - crop_left - crop_right;
00111 int theight = size_y - crop_top - crop_bottom;
00112
00113 int size = 0;
00114
00115
00116
00117 if (sizeof (imgpel) < symbol_size_in_bytes)
00118 {
00119
00120 size = sizeof (imgpel);
00121
00122 memset (buf, 0, (twidth * theight * symbol_size_in_bytes));
00123 }
00124 else
00125 {
00126 size = symbol_size_in_bytes;
00127 }
00128
00129 if ((crop_top || crop_bottom || crop_left || crop_right) || (size != 1))
00130 {
00131 for(i=crop_top;i<size_y-crop_bottom;i++)
00132 {
00133 int ipos = (i - crop_top) * (twidth);
00134 for(j=crop_left;j<size_x-crop_right;j++)
00135 {
00136 memcpy(buf+((j-crop_left+(ipos))*symbol_size_in_bytes),&(imgX[i][j]), size);
00137 }
00138 }
00139 }
00140 else
00141 {
00142 if (sizeof(imgpel) == sizeof(char))
00143 {
00144 memcpy(buf, &(imgX[0][0]), size_y * size_x * sizeof(imgpel));
00145 }
00146 else
00147 {
00148 imgpel *cur_pixel = &(imgX[0][0]);
00149 for(i = 0; i < size_y * size_x; i++)
00150 {
00151 *(buf++)=(char) *(cur_pixel++);
00152 }
00153 }
00154 }
00155 }
00156
00181 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)
00182 {
00183 int i;
00184
00185 int twidth = size_x - crop_left - crop_right;
00186 int theight = size_y - crop_top - crop_bottom;
00187
00188
00189 buf += crop_left;
00190 for(i = 0; i < theight; i++)
00191 {
00192 memcpy(buf, &(imgX[i + crop_top][crop_left]), twidth);
00193 buf += twidth;
00194 }
00195 }
00196
00221 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)
00222 {
00223 int i,j;
00224 static unsigned char ui8;
00225 static unsigned short tmp16, ui16;
00226 static unsigned long tmp32, ui32;
00227
00228 int twidth = size_x - crop_left - crop_right;
00229
00230
00231 switch (symbol_size_in_bytes)
00232 {
00233 case 1:
00234 {
00235 for(i=crop_top;i<size_y-crop_bottom;i++)
00236 for(j=crop_left;j<size_x-crop_right;j++)
00237 {
00238 ui8 = (unsigned char) (imgX[i][j]);
00239 buf[(j-crop_left+((i-crop_top)*(twidth)))] = ui8;
00240 }
00241 break;
00242 }
00243 case 2:
00244 {
00245 for(i=crop_top;i<size_y-crop_bottom;i++)
00246 for(j=crop_left;j<size_x-crop_right;j++)
00247 {
00248 tmp16 = (unsigned short) (imgX[i][j]);
00249 ui16 = (unsigned short) ((tmp16 >> 8) | ((tmp16&0xFF)<<8));
00250 memcpy(buf+((j-crop_left+((i-crop_top)*(twidth)))*2),&(ui16), 2);
00251 }
00252 break;
00253 }
00254 case 4:
00255 {
00256 for(i=crop_top;i<size_y-crop_bottom;i++)
00257 for(j=crop_left;j<size_x-crop_right;j++)
00258 {
00259 tmp32 = (unsigned long) (imgX[i][j]);
00260 ui32 = (unsigned long) (((tmp32&0xFF00)<<8) | ((tmp32&0xFF)<<24) | ((tmp32&0xFF0000)>>8) | ((tmp32&0xFF000000)>>24));
00261 memcpy(buf+((j-crop_left+((i-crop_top)*(twidth)))*4),&(ui32), 4);
00262 }
00263 break;
00264 }
00265 default:
00266 {
00267 error ("writing only to formats of 8, 16 or 32 bit allowed on big endian architecture", 500);
00268 break;
00269 }
00270 }
00271 }
00272
00273
00274 #if (PAIR_FIELDS_IN_OUTPUT)
00275
00276 void clear_picture(StorablePicture *p);
00277
00286 void flush_pending_output(int p_out)
00287 {
00288 if (pending_output_state!=FRAME)
00289 {
00290 write_out_picture(pending_output, p_out);
00291 }
00292
00293 if (pending_output->imgY)
00294 {
00295 free_mem2Dpel (pending_output->imgY);
00296 pending_output->imgY=NULL;
00297 }
00298 if (pending_output->imgUV)
00299 {
00300 free_mem3Dpel (pending_output->imgUV, 2);
00301 pending_output->imgUV=NULL;
00302 }
00303
00304 pending_output_state = FRAME;
00305 }
00306
00307
00320 void write_picture(StorablePicture *p, int p_out, int real_structure)
00321 {
00322 int i, add;
00323
00324 if (real_structure==FRAME)
00325 {
00326 flush_pending_output(p_out);
00327 write_out_picture(p, p_out);
00328 return;
00329 }
00330 if (real_structure==pending_output_state)
00331 {
00332 flush_pending_output(p_out);
00333 write_picture(p, p_out, real_structure);
00334 return;
00335 }
00336
00337 if (pending_output_state == FRAME)
00338 {
00339 pending_output->size_x = p->size_x;
00340 pending_output->size_y = p->size_y;
00341 pending_output->size_x_cr = p->size_x_cr;
00342 pending_output->size_y_cr = p->size_y_cr;
00343 pending_output->chroma_format_idc = p->chroma_format_idc;
00344
00345 pending_output->frame_mbs_only_flag = p->frame_mbs_only_flag;
00346 pending_output->frame_cropping_flag = p->frame_cropping_flag;
00347 if (pending_output->frame_cropping_flag)
00348 {
00349 pending_output->frame_cropping_rect_left_offset = p->frame_cropping_rect_left_offset;
00350 pending_output->frame_cropping_rect_right_offset = p->frame_cropping_rect_right_offset;
00351 pending_output->frame_cropping_rect_top_offset = p->frame_cropping_rect_top_offset;
00352 pending_output->frame_cropping_rect_bottom_offset = p->frame_cropping_rect_bottom_offset;
00353 }
00354
00355 get_mem2Dpel (&(pending_output->imgY), pending_output->size_y, pending_output->size_x);
00356 get_mem3Dpel (&(pending_output->imgUV), 2, pending_output->size_y_cr, pending_output->size_x_cr);
00357
00358 clear_picture(pending_output);
00359
00360
00361 if (real_structure == TOP_FIELD)
00362 {
00363 add = 0;
00364 }
00365 else
00366 {
00367 add = 1;
00368 }
00369
00370 for (i=0; i<pending_output->size_y; i+=2)
00371 {
00372 memcpy(pending_output->imgY[(i+add)], p->imgY[(i+add)], p->size_x * sizeof(imgpel));
00373 }
00374 for (i=0; i<pending_output->size_y_cr; i+=2)
00375 {
00376 memcpy(pending_output->imgUV[0][(i+add)], p->imgUV[0][(i+add)], p->size_x_cr * sizeof(imgpel));
00377 memcpy(pending_output->imgUV[1][(i+add)], p->imgUV[1][(i+add)], p->size_x_cr * sizeof(imgpel));
00378 }
00379 pending_output_state = real_structure;
00380 }
00381 else
00382 {
00383 if ( (pending_output->size_x!=p->size_x) || (pending_output->size_y!= p->size_y)
00384 || (pending_output->frame_mbs_only_flag != p->frame_mbs_only_flag)
00385 || (pending_output->frame_cropping_flag != p->frame_cropping_flag)
00386 || ( pending_output->frame_cropping_flag &&
00387 ( (pending_output->frame_cropping_rect_left_offset != p->frame_cropping_rect_left_offset)
00388 ||(pending_output->frame_cropping_rect_right_offset != p->frame_cropping_rect_right_offset)
00389 ||(pending_output->frame_cropping_rect_top_offset != p->frame_cropping_rect_top_offset)
00390 ||(pending_output->frame_cropping_rect_bottom_offset != p->frame_cropping_rect_bottom_offset)
00391 )
00392 )
00393 )
00394 {
00395 flush_pending_output(p_out);
00396 write_picture (p, p_out, real_structure);
00397 return;
00398 }
00399
00400 if (real_structure == TOP_FIELD)
00401 {
00402 add = 0;
00403 }
00404 else
00405 {
00406 add = 1;
00407 }
00408
00409 for (i=0; i<pending_output->size_y; i+=2)
00410 {
00411 memcpy(pending_output->imgY[(i+add)], p->imgY[(i+add)], p->size_x * sizeof(imgpel));
00412 }
00413 for (i=0; i<pending_output->size_y_cr; i+=2)
00414 {
00415 memcpy(pending_output->imgUV[0][(i+add)], p->imgUV[0][(i+add)], p->size_x_cr * sizeof(imgpel));
00416 memcpy(pending_output->imgUV[1][(i+add)], p->imgUV[1][(i+add)], p->size_x_cr * sizeof(imgpel));
00417 }
00418
00419 flush_pending_output(p_out);
00420 }
00421 }
00422
00423 #else
00424
00437 void write_picture(StorablePicture *p, int p_out, int real_structure)
00438 {
00439 write_out_picture(p, p_out);
00440 }
00441
00442
00443 #endif
00444
00455 static void write_out_picture(StorablePicture *p, int p_out)
00456 {
00457 static int SubWidthC [4]= { 1, 2, 2, 1};
00458 static int SubHeightC [4]= { 1, 2, 1, 1};
00459
00460 int crop_left, crop_right, crop_top, crop_bottom;
00461 int symbol_size_in_bytes = (img->pic_unit_bitsize_on_disk >> 3);
00462 Boolean rgb_output = (Boolean) (active_sps->vui_seq_parameters.matrix_coefficients==0);
00463 unsigned char *buf;
00464
00465 int ret;
00466
00467 if (p->non_existing)
00468 return;
00469
00470 #if (ENABLE_OUTPUT_TONEMAPPING)
00471
00472 if (p->seiHasTone_mapping && rgb_output)
00473 {
00474
00475 symbol_size_in_bytes = (p->tonemapped_bit_depth>8)? 2 : 1;
00476 tone_map(p->imgY, p->tone_mapping_lut, p->size_x, p->size_y);
00477 tone_map(p->imgUV[0], p->tone_mapping_lut, p->size_x_cr, p->size_y_cr);
00478 tone_map(p->imgUV[1], p->tone_mapping_lut, p->size_x_cr, p->size_y_cr);
00479 }
00480 #endif
00481
00482 if (p->frame_cropping_flag)
00483 {
00484 crop_left = SubWidthC[p->chroma_format_idc] * p->frame_cropping_rect_left_offset;
00485 crop_right = SubWidthC[p->chroma_format_idc] * p->frame_cropping_rect_right_offset;
00486 crop_top = SubHeightC[p->chroma_format_idc]*( 2 - p->frame_mbs_only_flag ) * p->frame_cropping_rect_top_offset;
00487 crop_bottom = SubHeightC[p->chroma_format_idc]*( 2 - p->frame_mbs_only_flag ) * p->frame_cropping_rect_bottom_offset;
00488 }
00489 else
00490 {
00491 crop_left = crop_right = crop_top = crop_bottom = 0;
00492 }
00493
00494
00495 initOutput(symbol_size_in_bytes);
00496
00497
00498 buf = malloc (p->size_x*p->size_y*symbol_size_in_bytes);
00499 if (NULL==buf)
00500 {
00501 no_mem_exit("write_out_picture: buf");
00502 }
00503
00504 if(rgb_output)
00505 {
00506 crop_left = p->frame_cropping_rect_left_offset;
00507 crop_right = p->frame_cropping_rect_right_offset;
00508 crop_top = ( 2 - p->frame_mbs_only_flag ) * p->frame_cropping_rect_top_offset;
00509 crop_bottom = ( 2 - p->frame_mbs_only_flag ) * p->frame_cropping_rect_bottom_offset;
00510
00511 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);
00512 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);
00513 if (ret != ((p->size_y_cr-crop_bottom-crop_top)*(p->size_x_cr-crop_right-crop_left)*symbol_size_in_bytes))
00514 {
00515 error ("write_out_picture: error writing to RGB file", 500);
00516 }
00517
00518 if (p->frame_cropping_flag)
00519 {
00520 crop_left = SubWidthC[p->chroma_format_idc] * p->frame_cropping_rect_left_offset;
00521 crop_right = SubWidthC[p->chroma_format_idc] * p->frame_cropping_rect_right_offset;
00522 crop_top = SubHeightC[p->chroma_format_idc]*( 2 - p->frame_mbs_only_flag ) * p->frame_cropping_rect_top_offset;
00523 crop_bottom = SubHeightC[p->chroma_format_idc]*( 2 - p->frame_mbs_only_flag ) * p->frame_cropping_rect_bottom_offset;
00524 }
00525 else
00526 {
00527 crop_left = crop_right = crop_top = crop_bottom = 0;
00528 }
00529 }
00530
00531 img2buf (p->imgY, buf, p->size_x, p->size_y, symbol_size_in_bytes, crop_left, crop_right, crop_top, crop_bottom);
00532 ret = write(p_out, buf, (p->size_y-crop_bottom-crop_top)*(p->size_x-crop_right-crop_left)*symbol_size_in_bytes);
00533 if (ret != ((p->size_y-crop_bottom-crop_top)*(p->size_x-crop_right-crop_left)*symbol_size_in_bytes))
00534 {
00535 error ("write_out_picture: error writing to YUV file", 500);
00536 }
00537
00538 if (p->chroma_format_idc!=YUV400)
00539 {
00540 crop_left = p->frame_cropping_rect_left_offset;
00541 crop_right = p->frame_cropping_rect_right_offset;
00542 crop_top = ( 2 - p->frame_mbs_only_flag ) * p->frame_cropping_rect_top_offset;
00543 crop_bottom = ( 2 - p->frame_mbs_only_flag ) * p->frame_cropping_rect_bottom_offset;
00544
00545 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);
00546 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);
00547 if (ret != ((p->size_y_cr-crop_bottom-crop_top)*(p->size_x_cr-crop_right-crop_left)* symbol_size_in_bytes))
00548 {
00549 error ("write_out_picture: error writing to YUV file", 500);
00550 }
00551 if (!rgb_output)
00552 {
00553 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);
00554 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);
00555 if (ret != ((p->size_y_cr-crop_bottom-crop_top)*(p->size_x_cr-crop_right-crop_left)*symbol_size_in_bytes))
00556 {
00557 error ("write_out_picture: error writing to YUV file", 500);
00558 }
00559 }
00560 }
00561 else
00562 {
00563 if (params->write_uv)
00564 {
00565 int i,j;
00566 imgpel cr_val = (imgpel) (1<<(img->bitdepth_luma - 1));
00567
00568 get_mem3Dpel (&(p->imgUV), 1, p->size_y/2, p->size_x/2);
00569 for (j=0; j<p->size_y/2; j++)
00570 for (i=0; i<p->size_x/2; i++)
00571 p->imgUV[0][j][i]=cr_val;
00572
00573
00574 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);
00575
00576 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 );
00577 if (ret != (symbol_size_in_bytes * (p->size_y-crop_bottom-crop_top)/2 * (p->size_x-crop_right-crop_left)/2))
00578 {
00579 error ("write_out_picture: error writing to YUV file", 500);
00580 }
00581 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 );
00582 if (ret != (symbol_size_in_bytes * (p->size_y-crop_bottom-crop_top)/2 * (p->size_x-crop_right-crop_left)/2))
00583 {
00584 error ("write_out_picture: error writing to YUV file", 500);
00585 }
00586
00587 free_mem3Dpel(p->imgUV);
00588 p->imgUV=NULL;
00589 }
00590 }
00591
00592 free(buf);
00593
00594
00595 }
00596
00603 void init_out_buffer(void)
00604 {
00605 out_buffer = alloc_frame_store();
00606
00607 #if (PAIR_FIELDS_IN_OUTPUT)
00608 pending_output = calloc (sizeof(StorablePicture), 1);
00609 if (NULL==pending_output) no_mem_exit("init_out_buffer");
00610 pending_output->imgUV = NULL;
00611 pending_output->imgY = NULL;
00612 #endif
00613 }
00614
00621 void uninit_out_buffer(void)
00622 {
00623 free_frame_store(out_buffer);
00624 out_buffer=NULL;
00625 #if (PAIR_FIELDS_IN_OUTPUT)
00626 flush_pending_output(p_out);
00627 free (pending_output);
00628 #endif
00629 }
00630
00637 void clear_picture(StorablePicture *p)
00638 {
00639 int i,j;
00640
00641 for(i=0;i<p->size_y;i++)
00642 {
00643 for (j=0; j<p->size_x; j++)
00644 p->imgY[i][j] = (imgpel) img->dc_pred_value_comp[0];
00645 }
00646 for(i=0;i<p->size_y_cr;i++)
00647 {
00648 for (j=0; j<p->size_x_cr; j++)
00649 p->imgUV[0][i][j] = (imgpel) img->dc_pred_value_comp[1];
00650 }
00651 for(i=0;i<p->size_y_cr;i++)
00652 {
00653 for (j=0; j<p->size_x_cr; j++)
00654 p->imgUV[1][i][j] = (imgpel) img->dc_pred_value_comp[2];
00655 }
00656
00657 }
00658
00670 void write_unpaired_field(FrameStore* fs, int p_out)
00671 {
00672 StorablePicture *p;
00673 assert (fs->is_used<3);
00674
00675 if(fs->is_used & 0x01)
00676 {
00677
00678
00679 p = fs->top_field;
00680 fs->bottom_field = alloc_storable_picture(BOTTOM_FIELD, p->size_x, 2*p->size_y, p->size_x_cr, 2*p->size_y_cr);
00681 fs->bottom_field->chroma_format_idc = p->chroma_format_idc;
00682 clear_picture(fs->bottom_field);
00683 dpb_combine_field_yuv(fs);
00684 write_picture (fs->frame, p_out, TOP_FIELD);
00685 }
00686
00687 if(fs->is_used & 0x02)
00688 {
00689
00690
00691 p = fs->bottom_field;
00692 fs->top_field = alloc_storable_picture(TOP_FIELD, p->size_x, 2*p->size_y, p->size_x_cr, 2*p->size_y_cr);
00693 fs->top_field->chroma_format_idc = p->chroma_format_idc;
00694 clear_picture(fs->top_field);
00695 fs ->top_field->frame_cropping_flag = fs->bottom_field->frame_cropping_flag;
00696 if(fs ->top_field->frame_cropping_flag)
00697 {
00698 fs ->top_field->frame_cropping_rect_top_offset = fs->bottom_field->frame_cropping_rect_top_offset;
00699 fs ->top_field->frame_cropping_rect_bottom_offset = fs->bottom_field->frame_cropping_rect_bottom_offset;
00700 fs ->top_field->frame_cropping_rect_left_offset = fs->bottom_field->frame_cropping_rect_left_offset;
00701 fs ->top_field->frame_cropping_rect_right_offset = fs->bottom_field->frame_cropping_rect_right_offset;
00702 }
00703 dpb_combine_field_yuv(fs);
00704 write_picture (fs->frame, p_out, BOTTOM_FIELD);
00705 }
00706
00707 fs->is_used = 3;
00708 }
00709
00718 void flush_direct_output(int p_out)
00719 {
00720 write_unpaired_field(out_buffer, p_out);
00721
00722 free_storable_picture(out_buffer->frame);
00723 out_buffer->frame = NULL;
00724 free_storable_picture(out_buffer->top_field);
00725 out_buffer->top_field = NULL;
00726 free_storable_picture(out_buffer->bottom_field);
00727 out_buffer->bottom_field = NULL;
00728 out_buffer->is_used = 0;
00729 }
00730
00731
00742 void write_stored_frame( FrameStore *fs,int p_out)
00743 {
00744
00745 flush_direct_output(p_out);
00746
00747 if (fs->is_used<3)
00748 {
00749 write_unpaired_field(fs, p_out);
00750 }
00751 else
00752 {
00753 if (fs->recovery_frame)
00754 recovery_flag = 1;
00755 if ((!non_conforming_stream) || recovery_flag)
00756 write_picture(fs->frame, p_out, FRAME);
00757 }
00758
00759 fs->is_output = 1;
00760 }
00761
00773 void direct_output(StorablePicture *p, int p_out)
00774 {
00775 if (p->structure==FRAME)
00776 {
00777
00778
00779 flush_direct_output(p_out);
00780 write_picture (p, p_out, FRAME);
00781 calculate_frame_no(p);
00782 if (-1 != p_ref && !params->silent)
00783 find_snr(snr, p, &p_ref);
00784 free_storable_picture(p);
00785 return;
00786 }
00787
00788 if (p->structure == TOP_FIELD)
00789 {
00790 if (out_buffer->is_used &1)
00791 flush_direct_output(p_out);
00792 out_buffer->top_field = p;
00793 out_buffer->is_used |= 1;
00794 }
00795
00796 if (p->structure == BOTTOM_FIELD)
00797 {
00798 if (out_buffer->is_used &2)
00799 flush_direct_output(p_out);
00800 out_buffer->bottom_field = p;
00801 out_buffer->is_used |= 2;
00802 }
00803
00804 if (out_buffer->is_used == 3)
00805 {
00806
00807 dpb_combine_field_yuv(out_buffer);
00808 write_picture (out_buffer->frame, p_out, FRAME);
00809
00810 calculate_frame_no(p);
00811 if (-1!=p_ref && !params->silent)
00812 find_snr(snr, out_buffer->frame, &p_ref);
00813 free_storable_picture(out_buffer->frame);
00814 out_buffer->frame = NULL;
00815 free_storable_picture(out_buffer->top_field);
00816 out_buffer->top_field = NULL;
00817 free_storable_picture(out_buffer->bottom_field);
00818 out_buffer->bottom_field = NULL;
00819 out_buffer->is_used = 0;
00820 }
00821 }
00822