filehandle.c
上传用户:sun1608
上传日期:2007-02-02
资源大小:6116k
文件大小:20k
源码类别:

流媒体/Mpeg4/MP4

开发平台:

Visual C++

  1. /*
  2. ***********************************************************************
  3. * COPYRIGHT AND WARRANTY INFORMATION
  4. *
  5. * Copyright 2001, International Telecommunications Union, Geneva
  6. *
  7. * DISCLAIMER OF WARRANTY
  8. *
  9. * These software programs are available to the user without any
  10. * license fee or royalty on an "as is" basis. The ITU disclaims
  11. * any and all warranties, whether express, implied, or
  12. * statutory, including any implied warranties of merchantability
  13. * or of fitness for a particular purpose.  In no event shall the
  14. * contributor or the ITU be liable for any incidental, punitive, or
  15. * consequential damages of any kind whatsoever arising from the
  16. * use of these programs.
  17. *
  18. * This disclaimer of warranty extends to the user of these programs
  19. * and user's customers, employees, agents, transferees, successors,
  20. * and assigns.
  21. *
  22. * The ITU does not represent or warrant that the programs furnished
  23. * hereunder are free of infringement of any third-party patents.
  24. * Commercial implementations of ITU-T Recommendations, including
  25. * shareware, may be subject to royalty fees to patent holders.
  26. * Information regarding the ITU-T patent policy is available from
  27. * the ITU Web site at http://www.itu.int.
  28. *
  29. * THIS IS NOT A GRANT OF PATENT RIGHTS - SEE THE ITU-T PATENT POLICY.
  30. ************************************************************************
  31. */
  32. /*!
  33.  **************************************************************************************
  34.  * file
  35.  *    filehandle.c
  36.  * brief
  37.  *    Handles the operations how to write
  38.  *    the generated symbols on the interim file format or some
  39.  *    other specified output formats
  40.  * author
  41.  *    Main contributors (see contributors.h for copyright, address and affiliation details)
  42.  *      - Thomas Stockhammer            <stockhammer@ei.tum.de>
  43.  *      - Detlev Marpe                  <marpe@hhi.de>
  44.  ***************************************************************************************
  45.  */
  46. #include "contributors.h"
  47. #include <string.h>
  48. #include <math.h>
  49. #include <time.h>
  50. #include <sys/timeb.h>
  51. #include <stdlib.h>
  52. #include <assert.h>
  53. #include <string.h>
  54. #include "global.h"
  55. #include "header.h"
  56. #include "rtp.h"
  57. // Global Varibales
  58. static FILE *out;   //!< output file
  59. /*
  60.    The implemented solution for a unified picture header
  61. */
  62. /*!
  63.  ************************************************************************
  64.  * brief
  65.  *    Error handling procedure. Print error message to stderr and exit
  66.  *    with supplied code.
  67.  * param text
  68.  *    Error message
  69.  * param code
  70.  *    Exit code
  71.  ************************************************************************
  72.  */
  73. void error(char *text, int code)
  74. {
  75.   fprintf(stderr, "%sn", text);
  76.   exit(code);
  77. }
  78. /*!
  79.  ************************************************************************
  80.  * brief
  81.  *    This function opens the output files and generates the
  82.  *    appropriate sequence header
  83.  ************************************************************************
  84.  */
  85. int start_sequence()
  86. {
  87.   int len;
  88.   switch(input->of_mode)
  89.   {
  90.     case PAR_OF_26L:
  91. #ifndef H26L_LIB
  92.       if ((out=fopen(input->outfile,"wb"))==NULL)
  93.       {
  94.           snprintf(errortext, ET_SIZE, "Error open file %s  n",input->outfile);
  95.           error(errortext,1);
  96.       }
  97. #endif
  98.       len = SequenceHeader(out);
  99.       return 0;
  100.     case PAR_OF_RTP:
  101.       if ((out=fopen(input->outfile,"wb"))==NULL)
  102.       {
  103.           snprintf(errortext, ET_SIZE, "Error open file %s  n",input->outfile);
  104.           error(errortext,1);
  105.       }
  106.       len = SequenceHeader(out);
  107.       return len;
  108.       
  109.     default:
  110.       snprintf(errortext, ET_SIZE, "Output File Mode %d not supported", input->of_mode);
  111.       error(errortext,1);
  112.       return 1;
  113.   }
  114. }
  115. /*!
  116.  ************************************************************************
  117.  * brief
  118.  *     This function terminates the sequence and closes the
  119.  *     output files
  120.  ************************************************************************
  121.  */
  122. int terminate_sequence()
  123. {
  124.   Bitstream *currStream;
  125.   // Mainly flushing of everything
  126.   // Add termination symbol, etc.
  127.   switch(input->of_mode)
  128.   {
  129.     case PAR_OF_26L:
  130.       currStream = ((img->currentSlice)->partArr[0]).bitstream;
  131.       if (input->symbol_mode == UVLC)
  132.       {
  133.         // Current TML File Format
  134.         // Get the trailing bits of the last slice
  135.         currStream->bits_to_go  = currStream->stored_bits_to_go;
  136.         currStream->byte_pos    = currStream->stored_byte_pos;
  137.         currStream->byte_buf    = currStream->stored_byte_buf;
  138.         if (currStream->bits_to_go < 8)   // there are bits left in the last byte
  139.           currStream->streamBuffer[currStream->byte_pos++] = currStream->byte_buf;
  140.         // Write all remaining bits to output bitstream file
  141. #ifdef H26L_LIB
  142.         memcpy(&memout[memoutlength], currStream->streamBuffer, 
  143. currStream->byte_pos);
  144. memoutlength += currStream->byte_pos;
  145. #else
  146.         fwrite (currStream->streamBuffer, 1, currStream->byte_pos, out);
  147.         fclose(out);
  148. #endif
  149.       }
  150.       else
  151.       {
  152.         // CABAC File Format
  153.         fclose(out);
  154.       }
  155.       return 0;
  156.     case PAR_OF_RTP:
  157.       fclose (out);
  158.       return 0;
  159.     default:
  160.       snprintf(errortext, ET_SIZE, "Output File Mode %d not supported", input->of_mode);
  161.       error(errortext,1);
  162.       return 1;
  163.   }
  164. }
  165. /*!
  166.  ************************************************************************
  167.  *  brief
  168.  *     This function generates the appropriate slice
  169.  *     header
  170.  *
  171.  *  return number of bits used for the picture header, including the PSC.
  172.  *
  173.  *  par Side effects:
  174.  *      Adds picture header symbols to the symbol buffer
  175.  *
  176.  *  par Remarks:
  177.  *      THIS IS AN INTERIM SOLUTION FOR A PICTURE HEADER, see VCEG-M79
  178.  *                                                                               par
  179.  *      Generates the Picture Header out of the information in img_par and inp-par,
  180.  *      and writes it to the symbol buffer.  The structure of the Picture Header
  181.  *      is discussed in VCEG-M79.  It is implemented as discussed there.  In addition,
  182.  *      it is preceeded by a picture start code, a UVLC-codeword of LEN=31 and INFO = 0.
  183.  *      It would have been possible to put information into this codeword, similar
  184.  *      to designs earlier than TML 5.9.  But it is deemed that the waste of 15
  185.  *      data bits is acceptable considering the advantages of being able to search
  186.  *      for a picture header quickly and easily, by looking for 30 consecutive, byte-
  187.  *      aligned zero bits.
  188.  *                                                                               par
  189.  *      The accounting of the header length (variable len) relies on the side effect
  190.  *      of writeUVLCSymbol() that sets len and info in the symbol variable parameter
  191.  ************************************************************************
  192. */
  193. int start_slice(SyntaxElement *sym)
  194. {
  195.   EncodingEnvironmentPtr eep;
  196.   Slice *currSlice = img->currentSlice;
  197.   Bitstream *currStream;
  198.   int header_len;
  199.   int i;
  200.   switch(input->of_mode)
  201.   {
  202.     case PAR_OF_26L:
  203.       if (input->symbol_mode == UVLC)
  204.       {
  205.         currStream = (currSlice->partArr[0]).bitstream;
  206.         // the information given in the SliceHeader is far not enought if we want to be able
  207.         // to do some errorconcealment.
  208.         // So write PictureHeader and SliceHeader in any case.
  209.        header_len = PictureHeader();   // Picture Header
  210.        header_len += SliceHeader (0);  // Slice Header without Start Code
  211.        
  212.         return header_len;
  213.       }
  214.       else
  215.       {                   // H.26: CABAC File Format
  216.         eep = &((currSlice->partArr[0]).ee_cabac);
  217.         currStream = (currSlice->partArr[0]).bitstream;
  218.         assert (currStream->bits_to_go == 8);
  219.         assert (currStream->byte_buf == 0);
  220.         assert (currStream->byte_pos == 0);
  221.         memset(currStream->streamBuffer, 0, 12);    // fill first 12 bytes with zeros (debug only)
  222.         // the information given in the SliceHeader is far not enought if we want to be able
  223.         // to do some errorconcealment.
  224.         // So write PictureHeader and SliceHeader in any case.
  225.         header_len = PictureHeader();   // Picture Header
  226.         header_len += SliceHeader (0);  // Slice Header without Start Code
  227.         
  228.         // Note that PictureHeader() and SliceHeader() set the buffer pointers as a side effect
  229.         // Hence no need for adjusting it manually (and preserving space to be patched later
  230.         // reserve bits for d_MB_Nr
  231.         currStream->header_len = header_len;
  232.         currStream->header_byte_buffer = currStream->byte_buf;
  233.         currStream->byte_pos += ((31-currStream->bits_to_go)/8);
  234.         if ((31-currStream->bits_to_go)%8 != 0)
  235.           currStream->byte_pos++;
  236.         currStream->bits_to_go = 8;
  237.         currStream->byte_pos++;
  238.         // If there is an absolute need to communicate the partition size, this would be
  239.         // the space to insert it
  240.         arienco_start_encoding(eep, currStream->streamBuffer, &(currStream->byte_pos));
  241.         // initialize context models
  242.         init_contexts_MotionInfo(currSlice->mot_ctx, 1);
  243.         init_contexts_TextureInfo(currSlice->tex_ctx, 1);
  244.         return header_len;
  245.       }
  246.     
  247.     case PAR_OF_RTP:
  248.       if (img->current_mb_nr == 0)                       // new picture
  249.         RTPUpdateTimestamp (img->tr);
  250.       if (input->symbol_mode == UVLC)
  251.       {
  252.         header_len=RTPSliceHeader();                      // generate the slice header
  253.         currStream = currSlice->partArr[0].bitstream;
  254.         
  255.         if (header_len % 8 != 0)
  256.         {
  257.           currStream->byte_buf <<= currStream->bits_to_go;
  258.           currStream->bits_to_go=8;
  259.           currStream->streamBuffer[currStream->byte_pos++]=currStream->byte_buf;
  260.           currStream->byte_buf=0;
  261.         }
  262.         return header_len;
  263.       }
  264.       else
  265.       {                   // RTP: CABAC 
  266.         eep = &((currSlice->partArr[0]).ee_cabac);
  267.         currStream = (currSlice->partArr[0]).bitstream;
  268.         assert (currStream->bits_to_go == 8);
  269.         assert (currStream->byte_buf == 0);
  270.         header_len=RTPSliceHeader();                      // generate the slice header
  271.         // reserve bits for d_MB_Nr
  272.         currStream->header_len = header_len;
  273.         currStream->header_byte_buffer = currStream->byte_buf;
  274.         currStream->byte_pos += ((31-currStream->bits_to_go)/8);
  275.         if ((31-currStream->bits_to_go)%8 != 0)
  276.           currStream->byte_pos++;
  277.         currStream->bits_to_go = 8;
  278.         currStream->byte_pos++;
  279.         arienco_start_encoding(eep, currStream->streamBuffer, &(currStream->byte_pos));
  280.         
  281.         if(input->partition_mode != PAR_DP_1)
  282.         {
  283.           for (i=1; i<currSlice->max_part_nr; i++)
  284.           {
  285.             eep = &((currSlice->partArr[0]).ee_cabac);
  286.             currStream = (currSlice->partArr[0]).bitstream;
  287.   
  288.             assert (currStream->bits_to_go == 8);
  289.             assert (currStream->byte_buf == 0);
  290.             assert (currStream->byte_pos == 0);
  291.             arienco_start_encoding(eep, currStream->streamBuffer, &(currStream->byte_pos));
  292.           }
  293.         }
  294.         // initialize context models
  295.         init_contexts_MotionInfo(currSlice->mot_ctx, 1);
  296.         init_contexts_TextureInfo(currSlice->tex_ctx, 1);
  297.         return header_len;
  298.       }
  299.     default:
  300.       snprintf(errortext, ET_SIZE, "Output File Mode %d not supported", input->of_mode);
  301.       error(errortext,1);
  302.       return 1;
  303.   }
  304. }
  305. /*!
  306.  ************************************************************************
  307.  * brief
  308.  *    This function terminates a slice
  309.  * return
  310.  *    0 if OK,                                                         n
  311.  *    1 in case of error
  312.  ************************************************************************
  313.  */
  314. int terminate_slice()
  315. {
  316.   int bytes_written;
  317.   Bitstream *currStream;
  318.   Slice *currSlice = img->currentSlice;
  319.   EncodingEnvironmentPtr eep;
  320.   int i;
  321.   int byte_pos, bits_to_go, start_data;
  322.   byte buffer;
  323.   int LastPartition;
  324.   int cabac_byte_pos=0, uvlc_byte_pos=0, empty_bytes=0;
  325.   int rtp_bytes_written;
  326.   // Mainly flushing of everything
  327.   // Add termination symbol, etc.
  328.   switch(input->of_mode)
  329.   {
  330.     case PAR_OF_26L:
  331.       if (input->symbol_mode == UVLC)
  332.       {
  333.         // Current TML File Format
  334.         // Enforce byte alignment of next header: zero bit stuffing
  335.         currStream = (currSlice->partArr[0]).bitstream;
  336.         if (currStream->bits_to_go < 8)
  337.         { // trailing bits to process
  338.           currStream->byte_buf <<= currStream->bits_to_go;
  339.           currStream->streamBuffer[currStream->byte_pos++]=currStream->byte_buf;
  340.           currStream->bits_to_go = 8;
  341.         }
  342.         bytes_written = currStream->byte_pos;
  343.         stat->bit_ctr += 8*bytes_written;     // actually written bits
  344. #ifdef H26L_LIB
  345.         memcpy(&memout[memoutlength], currStream->streamBuffer, bytes_written);
  346. memoutlength += bytes_written;
  347. #else
  348.         fwrite (currStream->streamBuffer, 1, bytes_written, out);
  349. #endif
  350.         currStream->stored_bits_to_go = 8; // store bits_to_go
  351.         currStream->stored_byte_buf   = currStream->byte_buf;   // store current byte
  352.         currStream->stored_byte_pos   = 0; // reset byte position
  353.       }
  354.       else
  355.       {
  356.         // CABAC File Format
  357.         eep = &((currSlice->partArr[0]).ee_cabac);
  358.         currStream = (currSlice->partArr[0]).bitstream;
  359.         // terminate the arithmetic code
  360.         arienco_done_encoding(eep);
  361.         // Add Number of MBs of this slice to the header
  362.         // Save current state of Bitstream
  363.         currStream = (currSlice->partArr[0]).bitstream;
  364.         byte_pos = currStream->byte_pos;
  365.         bits_to_go = currStream->bits_to_go;
  366.         buffer = currStream->byte_buf;
  367.         // Go to the reserved bits
  368.         currStream->byte_pos = (currStream->header_len)/8;
  369.         currStream->bits_to_go = 8-(currStream->header_len)%8;
  370.         currStream->byte_buf = currStream->header_byte_buffer;
  371.         // Ad Info about last MB
  372.         LastMBInSlice();
  373.         // And write the header to the output
  374.         bytes_written = currStream->byte_pos;
  375.         if (currStream->bits_to_go < 8) // trailing bits to process
  376.         {
  377.             currStream->byte_buf <<= currStream->bits_to_go;
  378.             currStream->streamBuffer[currStream->byte_pos++]=currStream->byte_buf;
  379.             bytes_written++;
  380.             currStream->bits_to_go = 8;
  381.         }
  382. #ifdef H26L_LIB
  383.         memcpy(&memout[memoutlength], currStream->streamBuffer, bytes_written);
  384. memoutlength += bytes_written;
  385. #else
  386.         fwrite (currStream->streamBuffer, 1, bytes_written, out);
  387. #endif
  388.         stat->bit_ctr += 8*bytes_written;
  389.         // Go back to the end of the stream
  390.         currStream->byte_pos = byte_pos;
  391.         currStream->bits_to_go = bits_to_go;
  392.         currStream->byte_buf = buffer;
  393.         // Find startposition of databitstream
  394.         start_data = (currStream->header_len+31)/8;
  395.         if ((currStream->header_len+31)%8 != 0)
  396.           start_data++;
  397.         bytes_written = currStream->byte_pos - start_data; // number of written bytes
  398.         stat->bit_ctr += 8*bytes_written;     // actually written bits
  399. #ifdef H26L_LIB
  400.         memcpy(&memout[memoutlength], currStream->streamBuffer+start_data, 
  401. bytes_written);
  402. memoutlength += bytes_written;
  403. #else
  404.         fwrite ((currStream->streamBuffer+start_data), 1, bytes_written, out);
  405. #endif
  406.       }
  407.       return 0;
  408.     case PAR_OF_RTP:
  409.       for (i=0; i<currSlice->max_part_nr; i++)
  410.       {
  411.         if (input->symbol_mode == CABAC)
  412.         {
  413.           eep = &((currSlice->partArr[i]).ee_cabac);
  414.           arienco_done_encoding(eep);
  415.         }
  416.         currStream = (currSlice->partArr[i]).bitstream;
  417.         
  418.         if (currStream->bits_to_go < 8) // trailing bits to process
  419.         {
  420.           currStream->byte_buf <<= currStream->bits_to_go;
  421.           currStream->streamBuffer[currStream->byte_pos++]=currStream->byte_buf;
  422.           currStream->bits_to_go = 8;
  423.         }
  424.         bytes_written = currStream->byte_pos; // number of written bytes
  425.         assert (bytes_written != 0);
  426.         if (bytes_written != 0)     // at least one bit in the partition -- something to do
  427.           {
  428.             int Marker;
  429.             int FirstBytePacketType;
  430.             // Determine First Byte of RTP payload
  431.             switch (input->partition_mode)
  432.             {
  433.               case PAR_DP_1:
  434.                 FirstBytePacketType = 0;
  435.                 break;
  436.               case PAR_DP_3:
  437.                 FirstBytePacketType = i+1;      // See VCEG-N72
  438.                 break;
  439.               default:
  440.                 assert (0==1);
  441.             }
  442.             if (input->symbol_mode == CABAC && i == 0)
  443.             {
  444.               //! Add Number of MBs of this slice to the header
  445.               //! Save current state of Bitstream
  446.               byte_pos = currStream->byte_pos; //last byte in the stream
  447.               //! Go to the reserved bits
  448.               currStream->byte_pos = cabac_byte_pos = (currStream->header_len)/8;
  449.               currStream->bits_to_go = 8-(currStream->header_len)%8;
  450.               currStream->byte_buf = currStream->header_byte_buffer;
  451.               cabac_byte_pos += ((31-currStream->bits_to_go)/8);
  452.               if ((31-currStream->bits_to_go)%8 != 0)
  453.                 cabac_byte_pos++;
  454.               cabac_byte_pos++; //! that's the position where we started to write CABAC code
  455.               //! Ad Info about last MB 
  456.               LastMBInSlice();
  457.               if (currStream->bits_to_go < 8) //! trailing bits to process
  458.               {
  459.                 currStream->byte_buf <<= currStream->bits_to_go;
  460.                 currStream->streamBuffer[currStream->byte_pos++]=currStream->byte_buf;
  461.               }
  462.               uvlc_byte_pos = currStream->byte_pos; //! that's the first byte after the UVLC header data
  463.               currStream->byte_pos = byte_pos;  //! where we were before this last_MB thing
  464.               empty_bytes = cabac_byte_pos - uvlc_byte_pos; //! These bytes contain no information
  465.                                                             //! They were reserved for writing the last_MB information but were not used
  466.               for(byte_pos=uvlc_byte_pos; byte_pos<=currStream->byte_pos-empty_bytes; byte_pos++)
  467.                 currStream->streamBuffer[byte_pos]=currStream->streamBuffer[byte_pos+empty_bytes]; //shift the bitstreams
  468.               bytes_written = byte_pos;
  469.               //! TO 02.11.2001 I'm sure this can be done much more elegant, but that's the way it works. 
  470.               //! If anybody understands what happens here please feel free to change this!
  471.           }  
  472.           // Calculate RTP payload's First Byte
  473.           if (input->partition_mode==PAR_DP_1)
  474.             FirstBytePacketType = 0;
  475.           else
  476.             FirstBytePacketType = i+1;
  477.           assert (FirstBytePacketType == 0);    //! This has to go as soon as data partitioning is to be tested
  478.           // Calculate the Marker bit
  479.           LastPartition=0;
  480.           if (input->partition_mode == PAR_DP_3)
  481.           {
  482.             if (currSlice->partArr[1].bitstream->byte_pos > 0)  // something in partition 1
  483.               LastPartition=1;
  484.             if (currSlice->partArr[2].bitstream->byte_pos > 0)  // something in partition 2
  485.               LastPartition=2;
  486.           }
  487.           Marker = 0;
  488.           if (img->current_mb_nr == img->total_number_mb)   // last MB is in this slice
  489.             if ((input->partition_mode==PAR_DP_1) ||          // Single SLice
  490.                 (input->partition_mode==PAR_DP_3 && i == LastPartition ))   // Last partition containing bits
  491.               Marker = 1;
  492.           // and write the RTP packet
  493.           rtp_bytes_written = RTPWriteBits (Marker, FirstBytePacketType, currStream->streamBuffer, bytes_written, out);
  494.         }
  495.         stat->bit_ctr += 8*bytes_written;
  496.         // Provide the next partition with a 'fresh' buffer
  497.         currStream->stored_bits_to_go = 8;
  498.         currStream->stored_byte_buf   = 0;
  499.         currStream->stored_byte_pos   = 0;
  500.         currStream->bits_to_go = 8;
  501.         currStream->byte_buf   = 0;
  502.         currStream->byte_pos   = 0;
  503.       }
  504.     return 0;
  505.     default:
  506.       snprintf(errortext, ET_SIZE, "Output File Mode %d not supported", input->of_mode);
  507.       error(errortext,1);
  508.       return 1;
  509.   }
  510. }