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

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 "image.h"
  16. #include "input.h"
  17. void write_out_picture(StorablePicture *p, int p_out);
  18. FrameStore* out_buffer;
  19. /*!
  20.  ************************************************************************
  21.  * brief
  22.  *    Convert image plane to temporary buffer for file writing
  23.  * param imgX
  24.  *    Pointer to image plane
  25.  * param buf
  26.  *    Buffer for file output
  27.  * param size_x
  28.  *    horizontal size
  29.  * param size_y
  30.  *    vertical size
  31.  * param symbol_size_in_bytes
  32.  *    number of bytes used per pel
  33.  * param crop_left
  34.  *    pixels to crop from left
  35.  * param crop_right
  36.  *    pixels to crop from right
  37.  * param crop_top
  38.  *    pixels to crop from top
  39.  * param crop_bottom
  40.  *    pixels to crop from bottom
  41.  ************************************************************************
  42.  */
  43. 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)
  44. {
  45.   int i,j;
  46.   int twidth  = size_x - crop_left - crop_right;
  47.   int theight = size_y - crop_top - crop_bottom;
  48.   int size = 0;
  49.   unsigned char  ui8;
  50.   unsigned short tmp16, ui16;
  51.   unsigned long  tmp32, ui32;
  52.   if (( sizeof(char) == sizeof (imgpel)) && ( sizeof(char) == symbol_size_in_bytes))
  53.   {
  54.     // imgpel == pixel_in_file == 1 byte -> simple copy
  55.     if (crop_left == 0 && crop_top == 0 && crop_right == 0 && crop_bottom == 0)
  56.       memcpy(buf,&(imgX[0][0]), twidth * theight);
  57.     else
  58.     {
  59.       for(i=0;i<theight;i++)
  60.         memcpy(buf + crop_left + (i * twidth),&(imgX[i + crop_top][crop_left]), twidth);
  61.     }
  62.   }
  63.   else
  64.   {
  65.     // sizeof (imgpel) > sizeof(char)
  66.     if (testEndian())
  67.     {
  68.       // big endian
  69.       switch (symbol_size_in_bytes)
  70.       {
  71.       case 1:
  72.         {
  73.           for(i=crop_top;i<size_y-crop_bottom;i++)
  74.             for(j=crop_left;j<size_x-crop_right;j++)
  75.             {
  76.               ui8 = (unsigned char) (imgX[i][j]);
  77.               buf[(j-crop_left+((i-crop_top)*(twidth)))] = ui8;
  78.             }
  79.           break;
  80.         }
  81.       case 2:
  82.         {
  83.           for(i=crop_top;i<size_y-crop_bottom;i++)
  84.             for(j=crop_left;j<size_x-crop_right;j++)
  85.             {
  86.               tmp16 = (unsigned short) (imgX[i][j]);
  87.               ui16  = (tmp16 >> 8) | ((tmp16&0xFF)<<8);
  88.               memcpy(buf+((j-crop_left+((i-crop_top)*(twidth)))*2),&(ui16), 2);
  89.             }
  90.           break;
  91.         }
  92.       case 4:
  93.         {
  94.           for(i=crop_top;i<size_y-crop_bottom;i++)
  95.             for(j=crop_left;j<size_x-crop_right;j++)
  96.             {
  97.               tmp32 = (unsigned long) (imgX[i][j]);
  98.               ui32  = ((tmp32&0xFF00)<<8) | ((tmp32&0xFF)<<24) | ((tmp32&0xFF0000)>>8) | ((tmp32&0xFF000000)>>24);
  99.               memcpy(buf+((j-crop_left+((i-crop_top)*(twidth)))*4),&(ui32), 4);
  100.             }
  101.           break;
  102.         }
  103.       default:
  104.         {
  105.            error ("writing only to formats of 8, 16 or 32 bit allowed on big endian architecture", 500);
  106.            break;
  107.         }
  108.       }
  109.     }
  110.     else
  111.     {
  112.       // little endian
  113.       if (sizeof (imgpel) < symbol_size_in_bytes)
  114.       {
  115.         // this should not happen. we should not have smaller imgpel than our source material.
  116.         size = sizeof (imgpel);
  117.         // clear buffer
  118.         memset (buf, 0, (twidth*theight*symbol_size_in_bytes));
  119.       }
  120.       else
  121.       {
  122.         size = symbol_size_in_bytes;
  123.       }
  124.       for(i=crop_top;i<size_y-crop_bottom;i++)
  125.       {
  126.         int i_pos = (i-crop_top)*(twidth) - crop_left;
  127.         for(j=crop_left;j<size_x-crop_right;j++)
  128.         {
  129.           memcpy(buf+((j + i_pos)*symbol_size_in_bytes),&(imgX[i][j]), size);
  130.         }
  131.       }
  132.     }
  133.   }
  134. }
  135. /*!
  136.  ************************************************************************
  137.  * brief
  138.  *    Writes out a storable picture without doing any output modifications
  139.  * param p
  140.  *    Picture to be written
  141.  * param p_out
  142.  *    Output file
  143.  * param real_structure
  144.  *    real picture structure
  145.  ************************************************************************
  146.  */
  147. void write_picture(StorablePicture *p, int p_out, int real_structure)
  148. {
  149.   write_out_picture(p, p_out);
  150. }
  151. /*!
  152.  ************************************************************************
  153.  * brief
  154.  *    Writes out a storable picture
  155.  * param p
  156.  *    Picture to be written
  157.  * param p_out
  158.  *    Output file
  159.  ************************************************************************
  160.  */
  161. void write_out_picture(StorablePicture *p, int p_out)
  162. {
  163.   int SubWidthC  [4]= { 1, 2, 2, 1};
  164.   int SubHeightC [4]= { 1, 2, 1, 1};
  165.   int crop_left, crop_right, crop_top, crop_bottom;
  166.   int symbol_size_in_bytes = img->out_unit_size_on_disk/8;
  167.   Boolean rgb_output = (Boolean) (params->rgb_input_flag != 0 && params->yuv_format==3);
  168.   unsigned char *buf;
  169.   if (p->non_existing)
  170.     return;
  171.   if (p_out == -1)
  172.     return;
  173.   if (p->frame_cropping_flag)
  174.   {
  175.     crop_left   = SubWidthC[p->chroma_format_idc] * p->frame_cropping_rect_left_offset;
  176.     crop_right  = SubWidthC[p->chroma_format_idc] * p->frame_cropping_rect_right_offset;
  177.     crop_top    = SubHeightC[p->chroma_format_idc]*( 2 - p->frame_mbs_only_flag ) * p->frame_cropping_rect_top_offset;
  178.     crop_bottom = SubHeightC[p->chroma_format_idc]*( 2 - p->frame_mbs_only_flag ) * p->frame_cropping_rect_bottom_offset;
  179.   }
  180.   else
  181.   {
  182.     crop_left = crop_right = crop_top = crop_bottom = 0;
  183.   }
  184.   //printf ("write frame size: %dx%dn", p->size_x-crop_left-crop_right,p->size_y-crop_top-crop_bottom );
  185.   // KS: this buffer should actually be allocated only once, but this is still much faster than the previous version
  186.   buf = malloc (p->size_x * p->size_y * symbol_size_in_bytes);
  187.   if (NULL==buf)
  188.   {
  189.     no_mem_exit("write_out_picture: buf");
  190.   }
  191.   if(rgb_output)
  192.   {
  193.     crop_left   = p->frame_cropping_rect_left_offset;
  194.     crop_right  = p->frame_cropping_rect_right_offset;
  195.     crop_top    = ( 2 - p->frame_mbs_only_flag ) * p->frame_cropping_rect_top_offset;
  196.     crop_bottom = ( 2 - p->frame_mbs_only_flag ) * p->frame_cropping_rect_bottom_offset;
  197.     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);
  198.     write(p_out, buf, (p->size_y_cr-crop_bottom-crop_top)*(p->size_x_cr-crop_right-crop_left)*symbol_size_in_bytes);
  199.     if (p->frame_cropping_flag)
  200.     {
  201.       crop_left   = SubWidthC[p->chroma_format_idc] * p->frame_cropping_rect_left_offset;
  202.       crop_right  = SubWidthC[p->chroma_format_idc] * p->frame_cropping_rect_right_offset;
  203.       crop_top    = SubHeightC[p->chroma_format_idc]*( 2 - p->frame_mbs_only_flag ) * p->frame_cropping_rect_top_offset;
  204.       crop_bottom = SubHeightC[p->chroma_format_idc]*( 2 - p->frame_mbs_only_flag ) * p->frame_cropping_rect_bottom_offset;
  205.     }
  206.     else
  207.     {
  208.       crop_left = crop_right = crop_top = crop_bottom = 0;
  209.     }
  210.   }
  211.   img2buf (p->imgY, buf, p->size_x, p->size_y, symbol_size_in_bytes, crop_left, crop_right, crop_top, crop_bottom);
  212.   write(p_out, buf, (p->size_y-crop_bottom-crop_top)*(p->size_x-crop_right-crop_left)*symbol_size_in_bytes);
  213.   if (p->chroma_format_idc!=YUV400)
  214.   {
  215.     crop_left   = p->frame_cropping_rect_left_offset;
  216.     crop_right  = p->frame_cropping_rect_right_offset;
  217.     crop_top    = ( 2 - p->frame_mbs_only_flag ) * p->frame_cropping_rect_top_offset;
  218.     crop_bottom = ( 2 - p->frame_mbs_only_flag ) * p->frame_cropping_rect_bottom_offset;
  219.     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);
  220.     write(p_out, buf, (p->size_y_cr-crop_bottom-crop_top)*(p->size_x_cr-crop_right-crop_left)* symbol_size_in_bytes);
  221.     if (!rgb_output)
  222.     {
  223.       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);
  224.       write(p_out, buf, (p->size_y_cr-crop_bottom-crop_top)*(p->size_x_cr-crop_right-crop_left)*symbol_size_in_bytes);
  225.     }
  226.   }
  227.   free(buf);
  228. //  fsync(p_out);
  229. }
  230. /*!
  231.  ************************************************************************
  232.  * brief
  233.  *    Initialize output buffer for direct output
  234.  ************************************************************************
  235.  */
  236. void init_out_buffer()
  237. {
  238.   out_buffer = alloc_frame_store();
  239. }
  240. /*!
  241.  ************************************************************************
  242.  * brief
  243.  *    Uninitialize output buffer for direct output
  244.  ************************************************************************
  245.  */
  246. void uninit_out_buffer()
  247. {
  248.   free_frame_store(out_buffer);
  249.   out_buffer=NULL;
  250. }
  251. /*!
  252.  ************************************************************************
  253.  * brief
  254.  *    Initialize picture memory with (Y:0,U:128,V:128)
  255.  ************************************************************************
  256.  */
  257. void clear_picture(StorablePicture *p)
  258. {
  259.   int i;
  260.   if (img->bitdepth_luma == 8)
  261.   {
  262.     // this does not seem to be right since it seems to work only for imgpel == byte
  263.     // should be fixed
  264.     for(i=0;i<p->size_y;i++)
  265.       memset(p->imgY[i], img->dc_pred_value_comp[0], p->size_x*sizeof(imgpel));
  266.   }
  267.   else
  268.   {
  269.     int j;
  270.     for(i=0;i < p->size_y; i++)
  271.     for(j=0;j < p->size_x; j++)
  272.       p->imgY[i][j] = img->dc_pred_value_comp[0];
  273.   }
  274.   if (img->bitdepth_chroma == 8)
  275.   {
  276.     for(i=0;i<p->size_y_cr;i++)
  277.       memset(p->imgUV[0][i], img->dc_pred_value_comp[1], p->size_x_cr*sizeof(imgpel));
  278.     for(i=0;i<p->size_y_cr;i++)
  279.       memset(p->imgUV[1][i], img->dc_pred_value_comp[2], p->size_x_cr*sizeof(imgpel));
  280.   }
  281.   else
  282.   {  
  283.    int k, j;
  284.    for (k = 0; k < 2; k++)
  285.    {
  286.       for(i=0;i<p->size_y_cr;i++)
  287.       for(j=0;j < p->size_x_cr; j++)
  288.         p->imgUV[k][i][j] = img->dc_pred_value_comp[1];
  289.    }
  290.   }
  291. }
  292. /*!
  293.  ************************************************************************
  294.  * brief
  295.  *    Write out not paired direct output fields. A second empty field is generated
  296.  *    and combined into the frame buffer.
  297.  * param fs
  298.  *    FrameStore that contains a single field
  299.  * param p_out
  300.  *    Output file
  301.  ************************************************************************
  302.  */
  303. void write_unpaired_field(FrameStore* fs, int p_out)
  304. {
  305.   StorablePicture *p;
  306.   assert (fs->is_used<3);
  307.   if(fs->is_used &1)
  308.   {
  309.     // we have a top field
  310.     // construct an empty bottom field
  311.     p = fs->top_field;
  312.     fs->bottom_field = alloc_storable_picture(BOTTOM_FIELD, p->size_x, p->size_y, p->size_x_cr, p->size_y_cr);
  313.     fs->bottom_field->chroma_format_idc = p->chroma_format_idc;
  314.     clear_picture(fs->bottom_field);
  315.     dpb_combine_field_yuv(fs);
  316.     write_picture (fs->frame, p_out, TOP_FIELD);
  317.   }
  318.   if(fs->is_used &2)
  319.   {
  320.     // we have a bottom field
  321.     // construct an empty top field
  322.     p = fs->bottom_field;
  323.     fs->top_field = alloc_storable_picture(TOP_FIELD, p->size_x, p->size_y, p->size_x_cr, p->size_y_cr);
  324.     clear_picture(fs->top_field);
  325.     fs->top_field->chroma_format_idc = p->chroma_format_idc;
  326.     clear_picture(fs->top_field);
  327.     fs ->top_field->frame_cropping_flag = fs->bottom_field->frame_cropping_flag;
  328.     if(fs ->top_field->frame_cropping_flag)
  329.     {
  330.       fs ->top_field->frame_cropping_rect_top_offset = fs->bottom_field->frame_cropping_rect_top_offset;
  331.       fs ->top_field->frame_cropping_rect_bottom_offset = fs->bottom_field->frame_cropping_rect_bottom_offset;
  332.       fs ->top_field->frame_cropping_rect_left_offset = fs->bottom_field->frame_cropping_rect_left_offset;
  333.       fs ->top_field->frame_cropping_rect_right_offset = fs->bottom_field->frame_cropping_rect_right_offset;
  334.     }
  335.     dpb_combine_field_yuv(fs);
  336.     write_picture (fs->frame, p_out, BOTTOM_FIELD);
  337.   }
  338.   fs->is_used=3;
  339. }
  340. /*!
  341.  ************************************************************************
  342.  * brief
  343.  *    Write out unpaired fields from output buffer.
  344.  * param p_out
  345.  *    Output file
  346.  ************************************************************************
  347.  */
  348. void flush_direct_output(int p_out)
  349. {
  350.   write_unpaired_field(out_buffer, p_out);
  351.   free_storable_picture(out_buffer->frame);
  352.   out_buffer->frame = NULL;
  353.   free_storable_picture(out_buffer->top_field);
  354.   out_buffer->top_field = NULL;
  355.   free_storable_picture(out_buffer->bottom_field);
  356.   out_buffer->bottom_field = NULL;
  357.   out_buffer->is_used = 0;
  358. }
  359. /*!
  360.  ************************************************************************
  361.  * brief
  362.  *    Write a frame (from FrameStore)
  363.  * param fs
  364.  *    FrameStore containing the frame
  365.  * param p_out
  366.  *    Output file
  367.  ************************************************************************
  368.  */
  369. void write_stored_frame( FrameStore *fs,int p_out)
  370. {
  371.   // make sure no direct output field is pending
  372.   flush_direct_output(p_out);
  373.   if (fs->is_used<3)
  374.   {
  375.     write_unpaired_field(fs, p_out);
  376.   }
  377.   else
  378.   {
  379.     write_picture(fs->frame, p_out, FRAME);
  380.   }
  381.   fs->is_output = 1;
  382. }
  383. /*!
  384.  ************************************************************************
  385.  * brief
  386.  *    Directly output a picture without storing it in the DPB. Fields
  387.  *    are buffered before they are written to the file.
  388.  * param p
  389.  *    Picture for output
  390.  * param p_out
  391.  *    Output file
  392.  ************************************************************************
  393.  */
  394. void direct_output(StorablePicture *p, int p_out)
  395. {
  396.   switch ( p->structure )
  397.   {
  398.   case FRAME:
  399.     // we have a frame (or complementary field pair)
  400.     // so output it directly
  401.     flush_direct_output(p_out);
  402.     write_picture (p, p_out, FRAME);
  403.     free_storable_picture(p);
  404.     return;
  405.     break;
  406.   case TOP_FIELD:
  407.     if (out_buffer->is_used &1)
  408.       flush_direct_output(p_out);
  409.     out_buffer->top_field = p;
  410.     out_buffer->is_used |= 1;
  411.     break;
  412.   case BOTTOM_FIELD:
  413.     if (out_buffer->is_used &2)
  414.       flush_direct_output(p_out);
  415.     out_buffer->bottom_field = p;
  416.     out_buffer->is_used |= 2;
  417.     break;
  418.   default:
  419.     printf("invalid picture typen");
  420.     break;
  421.   }
  422.   if (out_buffer->is_used == 3)
  423.   {
  424.     // we have both fields, so output them
  425.     dpb_combine_field_yuv(out_buffer);
  426.     write_picture (out_buffer->frame, p_out, FRAME);
  427.     free_storable_picture(out_buffer->frame);
  428.     out_buffer->frame = NULL;
  429.     free_storable_picture(out_buffer->top_field);
  430.     out_buffer->top_field = NULL;
  431.     free_storable_picture(out_buffer->bottom_field);
  432.     out_buffer->bottom_field = NULL;
  433.     out_buffer->is_used = 0;
  434.   }
  435. }
  436. /*!
  437. ************************************************************************
  438. * brief
  439. *    For adaptive frame/field coding remove dangling top field from direct
  440. *    output frame version instead.
  441. * param p
  442. *    Picture for output
  443. * param p_out
  444. *    Output file
  445. ************************************************************************
  446. */
  447. void direct_output_paff(StorablePicture *p, int p_out)
  448. {
  449.   printf("Warning!!! Frame can't fit in DPB. Displayed out of sequence.n");
  450.   free_storable_picture(out_buffer->frame);
  451.   out_buffer->frame = NULL;
  452.   free_storable_picture(out_buffer->top_field);
  453.   out_buffer->top_field = NULL;
  454.   free_storable_picture(out_buffer->bottom_field);
  455.   out_buffer->bottom_field = NULL;
  456.   out_buffer->is_used = 0;
  457.   direct_output(p, p_out);
  458. }