output.c
上传用户:hjq518
上传日期:2021-12-09
资源大小:5084k
文件大小:24k
源码类别:

Audio

开发平台:

Visual C++

  1. /*!
  2.  ************************************************************************
  3.  * file output.c
  4.  *
  5.  * brief
  6.  *    Output an image and Trance support
  7.  *
  8.  * author
  9.  *    Main contributors (see contributors.h for copyright, address and affiliation details)
  10.  *    - Karsten Suehring               <suehring@hhi.de>
  11.  ************************************************************************
  12.  */
  13. #include "contributors.h"
  14. #include "global.h"
  15. #include "mbuffer.h"
  16. #include "image.h"
  17. #include "memalloc.h"
  18. #include "sei.h"
  19. FrameStore* out_buffer;
  20. StorablePicture *pending_output = NULL;
  21. int              pending_output_state = FRAME;
  22. int recovery_flag = 0;
  23. extern int non_conforming_stream;
  24. static void write_out_picture(StorablePicture *p, int p_out);
  25. 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);
  26. 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);
  27. 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);
  28. 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);
  29. /*!
  30.  ************************************************************************
  31.  * brief
  32.  *      checks if the System is big- or little-endian
  33.  * return
  34.  *      0, little-endian (e.g. Intel architectures)
  35.  *      1, big-endian (e.g. SPARC, MIPS, PowerPC)
  36.  ************************************************************************
  37.  */
  38. int testEndian(void)
  39. {
  40.   short s;
  41.   byte *p;
  42.   p=(byte*)&s;
  43.   s=1;
  44.   return (*p==0);
  45. }
  46. /*!
  47.  ************************************************************************
  48.  * brief
  49.  *      selects appropriate output function given system arch. and data
  50.  * return
  51.  *
  52.  ************************************************************************
  53.  */
  54. static void initOutput(int symbol_size_in_bytes)
  55. {
  56.   if (( sizeof(char) == sizeof (imgpel)) && ( sizeof(char) == symbol_size_in_bytes))
  57.   {
  58.     img2buf = img2buf_byte;
  59.   }
  60.   else
  61.   {
  62.     if (( sizeof(char) != sizeof (imgpel)) && testEndian())
  63.       img2buf = img2buf_endian;
  64.     else
  65.       img2buf = img2buf_normal;
  66.   }    
  67. }
  68. /*!
  69.  ************************************************************************
  70.  * brief
  71.  *    Convert image plane to temporary buffer for file writing
  72.  * param imgX
  73.  *    Pointer to image plane
  74.  * param buf
  75.  *    Buffer for file output
  76.  * param size_x
  77.  *    horizontal size
  78.  * param size_y
  79.  *    vertical size
  80.  * param symbol_size_in_bytes
  81.  *    number of bytes used per pel
  82.  * param crop_left
  83.  *    pixels to crop from left
  84.  * param crop_right
  85.  *    pixels to crop from right
  86.  * param crop_top
  87.  *    pixels to crop from top
  88.  * param crop_bottom
  89.  *    pixels to crop from bottom
  90.  ************************************************************************
  91.  */
  92. 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)
  93. {
  94.   int i,j;
  95.   int twidth  = size_x - crop_left - crop_right;
  96.   int theight = size_y - crop_top - crop_bottom;
  97.   int size = 0;
  98.   // sizeof (imgpel) > sizeof(char)
  99.   // little endian
  100.   if (sizeof (imgpel) < symbol_size_in_bytes)
  101.   {
  102.     // this should not happen. we should not have smaller imgpel than our source material.
  103.     size = sizeof (imgpel);
  104.     // clear buffer
  105.     memset (buf, 0, (twidth * theight * symbol_size_in_bytes));
  106.   }
  107.   else
  108.   {
  109.     size = symbol_size_in_bytes;
  110.   }
  111.   if ((crop_top || crop_bottom || crop_left || crop_right) || (size != 1))
  112.   {
  113.     for(i=crop_top;i<size_y-crop_bottom;i++)
  114.     {
  115.       int ipos = (i - crop_top) * (twidth);
  116.       for(j=crop_left;j<size_x-crop_right;j++)
  117.       {
  118.         memcpy(buf+((j-crop_left+(ipos))*symbol_size_in_bytes),&(imgX[i][j]), size);
  119.       }
  120.     }
  121.   }
  122.   else
  123.   {
  124.     imgpel *cur_pixel = &(imgX[0][0]);;
  125.     for(i = 0; i < size_y * size_x; i++)
  126.     {          
  127.       *(buf++)=(char) *(cur_pixel++);
  128.     }
  129.   }
  130. }
  131. /*!
  132.  ************************************************************************
  133.  * brief
  134.  *    Convert image plane to temporary buffer for file writing
  135.  * param imgX
  136.  *    Pointer to image plane
  137.  * param buf
  138.  *    Buffer for file output
  139.  * param size_x
  140.  *    horizontal size
  141.  * param size_y
  142.  *    vertical size
  143.  * param symbol_size_in_bytes
  144.  *    number of bytes used per pel
  145.  * param crop_left
  146.  *    pixels to crop from left
  147.  * param crop_right
  148.  *    pixels to crop from right
  149.  * param crop_top
  150.  *    pixels to crop from top
  151.  * param crop_bottom
  152.  *    pixels to crop from bottom
  153.  ************************************************************************
  154.  */
  155. 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)
  156. {
  157.   int i;
  158.   int twidth  = size_x - crop_left - crop_right;
  159.   int theight = size_y - crop_top - crop_bottom;
  160.   // imgpel == pixel_in_file == 1 byte -> simple copy
  161.   buf += crop_left;
  162.   for(i = 0; i < theight; i++) 
  163.   {
  164.     memcpy(buf, &(imgX[i + crop_top][crop_left]), twidth);
  165.     buf += twidth;
  166.   }
  167. }
  168. /*!
  169.  ************************************************************************
  170.  * brief
  171.  *    Convert image plane to temporary buffer for file writing
  172.  * param imgX
  173.  *    Pointer to image plane
  174.  * param buf
  175.  *    Buffer for file output
  176.  * param size_x
  177.  *    horizontal size
  178.  * param size_y
  179.  *    vertical size
  180.  * param symbol_size_in_bytes
  181.  *    number of bytes used per pel
  182.  * param crop_left
  183.  *    pixels to crop from left
  184.  * param crop_right
  185.  *    pixels to crop from right
  186.  * param crop_top
  187.  *    pixels to crop from top
  188.  * param crop_bottom
  189.  *    pixels to crop from bottom
  190.  ************************************************************************
  191.  */
  192. 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)
  193. {
  194.   int i,j;
  195.   static unsigned char  ui8;
  196.   static unsigned short tmp16, ui16;
  197.   static unsigned long  tmp32, ui32;
  198.   int twidth  = size_x - crop_left - crop_right;
  199.   // big endian
  200.   switch (symbol_size_in_bytes)
  201.   {
  202.   case 1:
  203.     {
  204.       for(i=crop_top;i<size_y-crop_bottom;i++)
  205.         for(j=crop_left;j<size_x-crop_right;j++)
  206.         {
  207.           ui8 = (unsigned char) (imgX[i][j]);
  208.           buf[(j-crop_left+((i-crop_top)*(twidth)))] = ui8;
  209.         }
  210.         break;
  211.     }
  212.   case 2:
  213.     {
  214.       for(i=crop_top;i<size_y-crop_bottom;i++)
  215.         for(j=crop_left;j<size_x-crop_right;j++)
  216.         {
  217.           tmp16 = (unsigned short) (imgX[i][j]);
  218.           ui16  = (unsigned short) ((tmp16 >> 8) | ((tmp16&0xFF)<<8));
  219.           memcpy(buf+((j-crop_left+((i-crop_top)*(twidth)))*2),&(ui16), 2);
  220.         }
  221.         break;
  222.     }
  223.   case 4:
  224.     {
  225.       for(i=crop_top;i<size_y-crop_bottom;i++)
  226.         for(j=crop_left;j<size_x-crop_right;j++)
  227.         {
  228.           tmp32 = (unsigned long) (imgX[i][j]);
  229.           ui32  = (unsigned long) (((tmp32&0xFF00)<<8) | ((tmp32&0xFF)<<24) | ((tmp32&0xFF0000)>>8) | ((tmp32&0xFF000000)>>24));
  230.           memcpy(buf+((j-crop_left+((i-crop_top)*(twidth)))*4),&(ui32), 4);
  231.         }
  232.         break;
  233.     }
  234.   default:
  235.     {
  236.       error ("writing only to formats of 8, 16 or 32 bit allowed on big endian architecture", 500);
  237.       break;
  238.     }
  239.   }  
  240. }
  241. #if (PAIR_FIELDS_IN_OUTPUT)
  242. void clear_picture(StorablePicture *p);
  243. /*!
  244.  ************************************************************************
  245.  * brief
  246.  *    output the pending frame buffer
  247.  * param p_out
  248.  *    Output file
  249.  ************************************************************************
  250.  */
  251. void flush_pending_output(int p_out)
  252. {
  253.   if (pending_output_state!=FRAME)
  254.   {
  255.     write_out_picture(pending_output, p_out);
  256.   }
  257.   if (pending_output->imgY)
  258.   {
  259.     free_mem2Dpel (pending_output->imgY);
  260.     pending_output->imgY=NULL;
  261.   }
  262.   if (pending_output->imgUV)
  263.   {
  264.     free_mem3Dpel (pending_output->imgUV, 2);
  265.     pending_output->imgUV=NULL;
  266.   }
  267.   pending_output_state = FRAME;
  268. }
  269. /*!
  270.  ************************************************************************
  271.  * brief
  272.  *    Writes out a storable picture
  273.  *    If the picture is a field, the output buffers the picture and tries
  274.  *    to pair it with the next field.
  275.  * param p
  276.  *    Picture to be written
  277.  * param p_out
  278.  *    Output file
  279.  ************************************************************************
  280.  */
  281. void write_picture(StorablePicture *p, int p_out, int real_structure)
  282. {
  283.    int i, add;
  284.   if (real_structure==FRAME)
  285.   {
  286.     flush_pending_output(p_out);
  287.     write_out_picture(p, p_out);
  288.     return;
  289.   }
  290.   if (real_structure==pending_output_state)
  291.   {
  292.     flush_pending_output(p_out);
  293.     write_picture(p, p_out, real_structure);
  294.     return;
  295.   }
  296.   if (pending_output_state == FRAME)
  297.   {
  298.     pending_output->size_x = p->size_x;
  299.     pending_output->size_y = p->size_y;
  300.     pending_output->size_x_cr = p->size_x_cr;
  301.     pending_output->size_y_cr = p->size_y_cr;
  302.     pending_output->chroma_format_idc = p->chroma_format_idc;
  303.     pending_output->frame_mbs_only_flag = p->frame_mbs_only_flag;
  304.     pending_output->frame_cropping_flag = p->frame_cropping_flag;
  305.     if (pending_output->frame_cropping_flag)
  306.     {
  307.       pending_output->frame_cropping_rect_left_offset = p->frame_cropping_rect_left_offset;
  308.       pending_output->frame_cropping_rect_right_offset = p->frame_cropping_rect_right_offset;
  309.       pending_output->frame_cropping_rect_top_offset = p->frame_cropping_rect_top_offset;
  310.       pending_output->frame_cropping_rect_bottom_offset = p->frame_cropping_rect_bottom_offset;
  311.     }
  312.     get_mem2Dpel (&(pending_output->imgY), pending_output->size_y, pending_output->size_x);
  313.     get_mem3Dpel (&(pending_output->imgUV), 2, pending_output->size_y_cr, pending_output->size_x_cr);
  314.     clear_picture(pending_output);
  315.     // copy first field
  316.     if (real_structure == TOP_FIELD)
  317.     {
  318.       add = 0;
  319.     }
  320.     else
  321.     {
  322.       add = 1;
  323.     }
  324.     for (i=0; i<pending_output->size_y; i+=2)
  325.     {
  326.       memcpy(pending_output->imgY[(i+add)], p->imgY[(i+add)], p->size_x * sizeof(imgpel));
  327.     }
  328.     for (i=0; i<pending_output->size_y_cr; i+=2)
  329.     {
  330.       memcpy(pending_output->imgUV[0][(i+add)], p->imgUV[0][(i+add)], p->size_x_cr * sizeof(imgpel));
  331.       memcpy(pending_output->imgUV[1][(i+add)], p->imgUV[1][(i+add)], p->size_x_cr * sizeof(imgpel));
  332.     }
  333.     pending_output_state = real_structure;
  334.   }
  335.   else
  336.   {
  337.     if (  (pending_output->size_x!=p->size_x) || (pending_output->size_y!= p->size_y)
  338.        || (pending_output->frame_mbs_only_flag != p->frame_mbs_only_flag)
  339.        || (pending_output->frame_cropping_flag != p->frame_cropping_flag)
  340.        || ( pending_output->frame_cropping_flag &&
  341.             (  (pending_output->frame_cropping_rect_left_offset   != p->frame_cropping_rect_left_offset)
  342.              ||(pending_output->frame_cropping_rect_right_offset  != p->frame_cropping_rect_right_offset)
  343.              ||(pending_output->frame_cropping_rect_top_offset    != p->frame_cropping_rect_top_offset)
  344.              ||(pending_output->frame_cropping_rect_bottom_offset != p->frame_cropping_rect_bottom_offset)
  345.             )
  346.           )
  347.        )
  348.     {
  349.       flush_pending_output(p_out);
  350.       write_picture (p, p_out, real_structure);
  351.       return;
  352.     }
  353.     // copy second field
  354.     if (real_structure == TOP_FIELD)
  355.     {
  356.       add = 0;
  357.     }
  358.     else
  359.     {
  360.       add = 1;
  361.     }
  362.     for (i=0; i<pending_output->size_y; i+=2)
  363.     {
  364.       memcpy(pending_output->imgY[(i+add)], p->imgY[(i+add)], p->size_x * sizeof(imgpel));
  365.     }
  366.     for (i=0; i<pending_output->size_y_cr; i+=2)
  367.     {
  368.       memcpy(pending_output->imgUV[0][(i+add)], p->imgUV[0][(i+add)], p->size_x_cr * sizeof(imgpel));
  369.       memcpy(pending_output->imgUV[1][(i+add)], p->imgUV[1][(i+add)], p->size_x_cr * sizeof(imgpel));
  370.     }
  371.     flush_pending_output(p_out);
  372.   }
  373. }
  374. #else
  375. /*!
  376.  ************************************************************************
  377.  * brief
  378.  *    Writes out a storable picture without doing any output modifications
  379.  * param p
  380.  *    Picture to be written
  381.  * param p_out
  382.  *    Output file
  383.  * param real_structure
  384.  *    real picture structure
  385.  ************************************************************************
  386.  */
  387. void write_picture(StorablePicture *p, int p_out, int real_structure)
  388. {
  389.   write_out_picture(p, p_out);
  390. }
  391. #endif
  392. /*!
  393. ************************************************************************
  394. * brief
  395. *    Writes out a storable picture
  396. * param p
  397. *    Picture to be written
  398. * param p_out
  399. *    Output file
  400. ************************************************************************
  401. */
  402. static void write_out_picture(StorablePicture *p, int p_out)
  403. {
  404.   static int SubWidthC  [4]= { 1, 2, 2, 1};
  405.   static int SubHeightC [4]= { 1, 2, 1, 1};
  406.   int crop_left, crop_right, crop_top, crop_bottom;
  407.   int symbol_size_in_bytes = (img->pic_unit_bitsize_on_disk >> 3);
  408.   Boolean rgb_output = (Boolean) (active_sps->vui_seq_parameters.matrix_coefficients==0);
  409.   unsigned char *buf;
  410.   if (p->non_existing)
  411.     return;
  412. #if (ENABLE_OUTPUT_TONEMAPPING)
  413.   // note: this tone-mapping is working for RGB format only. Sharp
  414.   if (p->seiHasTone_mapping && rgb_output)
  415.   {
  416.     //printf("output frame %d with tone model id %dn",  p->frame_num, p->tone_mapping_model_id);
  417.     symbol_size_in_bytes = (p->tonemapped_bit_depth>8)? 2 : 1;
  418.     tone_map(p->imgY, p->tone_mapping_lut, p->size_x, p->size_y);
  419.     tone_map(p->imgUV[0], p->tone_mapping_lut, p->size_x_cr, p->size_y_cr);
  420.     tone_map(p->imgUV[1], p->tone_mapping_lut, p->size_x_cr, p->size_y_cr);
  421.   }
  422. #endif
  423.   if (p->frame_cropping_flag)
  424.   {
  425.     crop_left   = SubWidthC[p->chroma_format_idc] * p->frame_cropping_rect_left_offset;
  426.     crop_right  = SubWidthC[p->chroma_format_idc] * p->frame_cropping_rect_right_offset;
  427.     crop_top    = SubHeightC[p->chroma_format_idc]*( 2 - p->frame_mbs_only_flag ) * p->frame_cropping_rect_top_offset;
  428.     crop_bottom = SubHeightC[p->chroma_format_idc]*( 2 - p->frame_mbs_only_flag ) * p->frame_cropping_rect_bottom_offset;
  429.   }
  430.   else
  431.   {
  432.     crop_left = crop_right = crop_top = crop_bottom = 0;
  433.   }
  434.   //printf ("write frame size: %dx%dn", p->size_x-crop_left-crop_right,p->size_y-crop_top-crop_bottom );
  435.   initOutput(symbol_size_in_bytes);
  436.   // KS: this buffer should actually be allocated only once, but this is still much faster than the previous version
  437.   buf = malloc (p->size_x*p->size_y*symbol_size_in_bytes);
  438.   if (NULL==buf)
  439.   {
  440.     no_mem_exit("write_out_picture: buf");
  441.   }
  442.   if(rgb_output)
  443.   {
  444.     crop_left   = p->frame_cropping_rect_left_offset;
  445.     crop_right  = p->frame_cropping_rect_right_offset;
  446.     crop_top    = ( 2 - p->frame_mbs_only_flag ) * p->frame_cropping_rect_top_offset;
  447.     crop_bottom = ( 2 - p->frame_mbs_only_flag ) * p->frame_cropping_rect_bottom_offset;
  448.     img2buf_normal (p->imgUV[1], buf, p->size_x_cr, p->size_y_cr, symbol_size_in_bytes, crop_left, crop_right, crop_top, crop_bottom);
  449.     write(p_out, buf, (p->size_y_cr-crop_bottom-crop_top)*(p->size_x_cr-crop_right-crop_left)*symbol_size_in_bytes);
  450.     if (p->frame_cropping_flag)
  451.     {
  452.       crop_left   = SubWidthC[p->chroma_format_idc] * p->frame_cropping_rect_left_offset;
  453.       crop_right  = SubWidthC[p->chroma_format_idc] * p->frame_cropping_rect_right_offset;
  454.       crop_top    = SubHeightC[p->chroma_format_idc]*( 2 - p->frame_mbs_only_flag ) * p->frame_cropping_rect_top_offset;
  455.       crop_bottom = SubHeightC[p->chroma_format_idc]*( 2 - p->frame_mbs_only_flag ) * p->frame_cropping_rect_bottom_offset;
  456.     }
  457.     else
  458.     {
  459.       crop_left = crop_right = crop_top = crop_bottom = 0;
  460.     }
  461.   }
  462.   img2buf_normal (p->imgY, buf, p->size_x, p->size_y, symbol_size_in_bytes, crop_left, crop_right, crop_top, crop_bottom);
  463.   write(p_out, buf, (p->size_y-crop_bottom-crop_top)*(p->size_x-crop_right-crop_left)*symbol_size_in_bytes);
  464.   if (p->chroma_format_idc!=YUV400)
  465.   {
  466.     crop_left   = p->frame_cropping_rect_left_offset;
  467.     crop_right  = p->frame_cropping_rect_right_offset;
  468.     crop_top    = ( 2 - p->frame_mbs_only_flag ) * p->frame_cropping_rect_top_offset;
  469.     crop_bottom = ( 2 - p->frame_mbs_only_flag ) * p->frame_cropping_rect_bottom_offset;
  470.     img2buf_normal (p->imgUV[0], buf, p->size_x_cr, p->size_y_cr, symbol_size_in_bytes, crop_left, crop_right, crop_top, crop_bottom);
  471.     write(p_out, buf, (p->size_y_cr-crop_bottom-crop_top)*(p->size_x_cr-crop_right-crop_left)* symbol_size_in_bytes);
  472.     if (!rgb_output)
  473.     {
  474.       img2buf_normal (p->imgUV[1], buf, p->size_x_cr, p->size_y_cr, symbol_size_in_bytes, crop_left, crop_right, crop_top, crop_bottom);
  475.       write(p_out, buf, (p->size_y_cr-crop_bottom-crop_top)*(p->size_x_cr-crop_right-crop_left)*symbol_size_in_bytes);
  476.     }
  477.   }
  478.   else
  479.   {
  480.     if (params->write_uv)
  481.     {
  482.       int i,j;
  483.       imgpel cr_val = (imgpel) (1<<(img->bitdepth_luma - 1));
  484.       get_mem3Dpel (&(p->imgUV), 1, p->size_y/2, p->size_x/2);
  485.       for (j=0; j<p->size_y/2; j++)
  486.         for (i=0; i<p->size_x/2; i++)
  487.           p->imgUV[0][j][i]=cr_val;
  488.       // fake out U=V=128 to make a YUV 4:2:0 stream
  489.       img2buf_normal (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);
  490.       write(p_out, buf, symbol_size_in_bytes * (p->size_y-crop_bottom-crop_top)/2 * (p->size_x-crop_right-crop_left)/2 );
  491.       write(p_out, buf, symbol_size_in_bytes * (p->size_y-crop_bottom-crop_top)/2 * (p->size_x-crop_right-crop_left)/2 );
  492.       free_mem3Dpel(p->imgUV);
  493.       p->imgUV=NULL;
  494.     }
  495.   }
  496.   free(buf);
  497. //  fsync(p_out);
  498. }
  499. /*!
  500.  ************************************************************************
  501.  * brief
  502.  *    Initialize output buffer for direct output
  503.  ************************************************************************
  504.  */
  505. void init_out_buffer(void)
  506. {
  507.   out_buffer = alloc_frame_store();  
  508. #if (PAIR_FIELDS_IN_OUTPUT)
  509.   pending_output = calloc (sizeof(StorablePicture), 1);
  510.   if (NULL==pending_output) no_mem_exit("init_out_buffer");
  511.   pending_output->imgUV = NULL;
  512.   pending_output->imgY  = NULL;
  513. #endif
  514. }
  515. /*!
  516.  ************************************************************************
  517.  * brief
  518.  *    Uninitialize output buffer for direct output
  519.  ************************************************************************
  520.  */
  521. void uninit_out_buffer(void)
  522. {
  523.   free_frame_store(out_buffer);
  524.   out_buffer=NULL;
  525. #if (PAIR_FIELDS_IN_OUTPUT)
  526.   flush_pending_output(p_out);
  527.   free (pending_output);
  528. #endif
  529. }
  530. /*!
  531.  ************************************************************************
  532.  * brief
  533.  *    Initialize picture memory with (Y:0,U:128,V:128)
  534.  ************************************************************************
  535.  */
  536. void clear_picture(StorablePicture *p)
  537. {
  538.   int i,j;
  539.   for(i=0;i<p->size_y;i++)
  540.   {
  541.     for (j=0; j<p->size_x; j++)
  542.       p->imgY[i][j] = (imgpel) img->dc_pred_value_comp[0];
  543.   }
  544.   for(i=0;i<p->size_y_cr;i++)
  545.   {
  546.     for (j=0; j<p->size_x_cr; j++)
  547.       p->imgUV[0][i][j] = (imgpel) img->dc_pred_value_comp[1];
  548.   }
  549.   for(i=0;i<p->size_y_cr;i++)
  550.   {
  551.     for (j=0; j<p->size_x_cr; j++)
  552.       p->imgUV[1][i][j] = (imgpel) img->dc_pred_value_comp[2];
  553.   }
  554. }
  555. /*!
  556.  ************************************************************************
  557.  * brief
  558.  *    Write out not paired direct output fields. A second empty field is generated
  559.  *    and combined into the frame buffer.
  560.  * param fs
  561.  *    FrameStore that contains a single field
  562.  * param p_out
  563.  *    Output file
  564.  ************************************************************************
  565.  */
  566. void write_unpaired_field(FrameStore* fs, int p_out)
  567. {
  568.   StorablePicture *p;
  569.   assert (fs->is_used<3);
  570.   if(fs->is_used & 0x01)
  571.   {
  572.     // we have a top field
  573.     // construct an empty bottom field
  574.     p = fs->top_field;
  575.     fs->bottom_field = alloc_storable_picture(BOTTOM_FIELD, p->size_x, 2*p->size_y, p->size_x_cr, 2*p->size_y_cr);
  576.     fs->bottom_field->chroma_format_idc = p->chroma_format_idc;
  577.     clear_picture(fs->bottom_field);
  578.     dpb_combine_field_yuv(fs);
  579.     write_picture (fs->frame, p_out, TOP_FIELD);
  580.   }
  581.   if(fs->is_used & 0x02)
  582.   {
  583.     // we have a bottom field
  584.     // construct an empty top field
  585.     p = fs->bottom_field;
  586.     fs->top_field = alloc_storable_picture(TOP_FIELD, p->size_x, 2*p->size_y, p->size_x_cr, 2*p->size_y_cr);
  587.     fs->top_field->chroma_format_idc = p->chroma_format_idc;
  588.     clear_picture(fs->top_field);
  589.     fs ->top_field->frame_cropping_flag = fs->bottom_field->frame_cropping_flag;
  590.     if(fs ->top_field->frame_cropping_flag)
  591.     {
  592.       fs ->top_field->frame_cropping_rect_top_offset = fs->bottom_field->frame_cropping_rect_top_offset;
  593.       fs ->top_field->frame_cropping_rect_bottom_offset = fs->bottom_field->frame_cropping_rect_bottom_offset;
  594.       fs ->top_field->frame_cropping_rect_left_offset = fs->bottom_field->frame_cropping_rect_left_offset;
  595.       fs ->top_field->frame_cropping_rect_right_offset = fs->bottom_field->frame_cropping_rect_right_offset;
  596.     }
  597.     dpb_combine_field_yuv(fs);
  598.     write_picture (fs->frame, p_out, BOTTOM_FIELD);
  599.   }
  600.   fs->is_used = 3;
  601. }
  602. /*!
  603.  ************************************************************************
  604.  * brief
  605.  *    Write out unpaired fields from output buffer.
  606.  * param p_out
  607.  *    Output file
  608.  ************************************************************************
  609.  */
  610. void flush_direct_output(int p_out)
  611. {
  612.   write_unpaired_field(out_buffer, p_out);
  613.   free_storable_picture(out_buffer->frame);
  614.   out_buffer->frame = NULL;
  615.   free_storable_picture(out_buffer->top_field);
  616.   out_buffer->top_field = NULL;
  617.   free_storable_picture(out_buffer->bottom_field);
  618.   out_buffer->bottom_field = NULL;
  619.   out_buffer->is_used = 0;
  620. }
  621. /*!
  622.  ************************************************************************
  623.  * brief
  624.  *    Write a frame (from FrameStore)
  625.  * param fs
  626.  *    FrameStore containing the frame
  627.  * param p_out
  628.  *    Output file
  629.  ************************************************************************
  630.  */
  631. void write_stored_frame( FrameStore *fs,int p_out)
  632. {
  633.   // make sure no direct output field is pending
  634.   flush_direct_output(p_out);
  635.   if (fs->is_used<3)
  636.   {
  637.     write_unpaired_field(fs, p_out);
  638.   }
  639.   else
  640.   {
  641.     if (fs->recovery_frame)
  642.       recovery_flag = 1;
  643.     if ((!non_conforming_stream) || recovery_flag)
  644.       write_picture(fs->frame, p_out, FRAME);
  645.   }
  646.   fs->is_output = 1;
  647. }
  648. /*!
  649.  ************************************************************************
  650.  * brief
  651.  *    Directly output a picture without storing it in the DPB. Fields
  652.  *    are buffered before they are written to the file.
  653.  * param p
  654.  *    Picture for output
  655.  * param p_out
  656.  *    Output file
  657.  ************************************************************************
  658.  */
  659. void direct_output(StorablePicture *p, int p_out)
  660. {
  661.   if (p->structure==FRAME)
  662.   {
  663.     // we have a frame (or complementary field pair)
  664.     // so output it directly
  665.     flush_direct_output(p_out);
  666.     write_picture (p, p_out, FRAME);
  667.     calculate_frame_no(p);
  668.     if (-1!=p_ref && !params->silent)
  669.       find_snr(snr, p, p_ref);
  670.     free_storable_picture(p);
  671.     return;
  672.   }
  673.   if (p->structure == TOP_FIELD)
  674.   {
  675.     if (out_buffer->is_used &1)
  676.       flush_direct_output(p_out);
  677.     out_buffer->top_field = p;
  678.     out_buffer->is_used |= 1;
  679.   }
  680.   if (p->structure == BOTTOM_FIELD)
  681.   {
  682.     if (out_buffer->is_used &2)
  683.       flush_direct_output(p_out);
  684.     out_buffer->bottom_field = p;
  685.     out_buffer->is_used |= 2;
  686.   }
  687.   if (out_buffer->is_used == 3)
  688.   {
  689.     // we have both fields, so output them
  690.     dpb_combine_field_yuv(out_buffer);
  691.     write_picture (out_buffer->frame, p_out, FRAME);
  692.     calculate_frame_no(p);
  693.     if (-1!=p_ref && !params->silent)
  694.       find_snr(snr, out_buffer->frame, p_ref);
  695.     free_storable_picture(out_buffer->frame);
  696.     out_buffer->frame = NULL;
  697.     free_storable_picture(out_buffer->top_field);
  698.     out_buffer->top_field = NULL;
  699.     free_storable_picture(out_buffer->bottom_field);
  700.     out_buffer->bottom_field = NULL;
  701.     out_buffer->is_used = 0;
  702.   }
  703. }