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

流媒体/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 header.c
  35.  *
  36.  * brief
  37.  *    H.26L Slice, Picture, and Sequence headers
  38.  *
  39.  * author
  40.  *    Main contributors (see contributors.h for copyright, address and affiliation details)
  41.  *      - Stephan Wenger                  <stewe@cs.tu-berlin.de>
  42.  *************************************************************************************
  43.  */
  44. #include <math.h>
  45. #include <assert.h>
  46. #include <string.h>
  47. #include <stdlib.h>
  48. #include "elements.h"
  49. #include "header.h"
  50. #include "rtp.h"
  51. // A little trick to avoid those horrible #if TRACE all over the source code
  52. #if TRACE
  53. #define SYMTRACESTRING(s) strncpy(sym.tracestring,s,TRACESTRING_SIZE)
  54. #else
  55. #define SYMTRACESTRING(s) // to nothing
  56. #endif
  57. // Local Functions
  58. static int PutSliceStartCode(Bitstream *s);
  59. static int PutPictureStartCode (Bitstream *s);
  60. static int PutStartCode (int Type, Bitstream *s, char *ts);
  61. // End local Functions
  62. int PictureHeader()
  63. {
  64. // StW: PictureTypeSymbol is the Symbol used to encode the picture type.
  65. // This is one of the dirtiest hacks if have seen so far from people who
  66. // usually know what they are doing :-)
  67. // img->type has one of three possible values (I, P, B), the picture type as coded
  68. // distiguishes further by indicating whether one or more reference frames are
  69. // used for P and B frames (hence 5 values).  See decoder/defines.h
  70. // The mapping is performed in image.c select_picture_type()
  71.   int dP_nr = assignSE2partition[input->partition_mode][SE_HEADER];
  72.   Bitstream *currStream = ((img->currentSlice)->partArr[dP_nr]).bitstream;
  73.   DataPartition *partition = &((img->currentSlice)->partArr[dP_nr]);
  74.   SyntaxElement sym;
  75.   int len = 0;
  76.   sym.type = SE_HEADER;       // This will be true for all symbols generated here
  77.   sym.mapping = n_linfo2;       // Mapping rule: Simple code number to len/info
  78.   // Ok.  We are sure we want to code a Picture Header.  So, first: Put PSC
  79.   len+=PutPictureStartCode (currStream);
  80.   // Now, take care of te UVLC coded data structure described in VCEG-M79
  81.   sym.value1 = 0;               // TRType = 0
  82.   SYMTRACESTRING("PH TemporalReferenceType");
  83.   len += writeSyntaxElement_UVLC (&sym, partition);
  84.   sym.value1 = img->tr%256;         // TR, variable length
  85.   SYMTRACESTRING("PH TemporalReference");
  86.   len += writeSyntaxElement_UVLC (&sym, partition);
  87.   // Size information.  If the picture is Intra, then transmit the size in MBs,
  88.   // For all other picture type just indicate that it didn't change.
  89.   // Note: this is currently the prudent way to do things, because we do not
  90.   // have anything similar to Annex P of H.263.  However, we should anticipate
  91.   // taht one day we may want to have an Annex P type functionality.  Hence, it is
  92.   // unwise to assume that P pictures will never have a size indiciation.  So the
  93.   // one bit for an "unchanged" inidication is well spent.
  94.   if (img->type == INTRA_IMG)
  95.   {
  96.     // Double check that width and height are divisible by 16
  97.     assert (img->width  % 16 == 0);
  98.     assert (img->height % 16 == 0);
  99.     sym.value1 = 1;             // SizeType = Width/Height in MBs
  100.     SYMTRACESTRING("PH FullSizeInformation");
  101.     len += writeSyntaxElement_UVLC (&sym, partition);
  102.     sym.value1 = img->width / 16;
  103.     SYMTRACESTRING("PH FullSize-X");
  104.     len += writeSyntaxElement_UVLC (&sym, partition);
  105.     sym.value1 = img->height / 16;
  106.     SYMTRACESTRING("PH FullSize-Y");
  107.     len += writeSyntaxElement_UVLC (&sym, partition);
  108.   } else
  109.   {    // Not an intra frame -> write "unchanged"
  110.     sym.value1 = 0;             // SizeType = Unchanged
  111.     SYMTRACESTRING("PHSizeUnchanged");
  112.     len += writeSyntaxElement_UVLC (&sym, partition);
  113.   }
  114.   select_picture_type (&sym);
  115.   SYMTRACESTRING("Hacked Picture Type Symbol");
  116.   len+= writeSyntaxElement_UVLC (&sym, partition);
  117.   // Finally, write Reference Picture ID 
  118.   // WYK: Oct. 16, 2001. Now I use this for the reference frame ID (non-B frame ID). 
  119.   // If current frame is a B-frame, it will not change; otherwise it is increased by 1 based
  120.   // on refPicID of the previous frame. Thus, the decoder can know how many  non-B 
  121.   // frames are lost, and then can adjust the reference frame buffers correctly.
  122.   if (1)
  123.   {
  124.     sym.value1 = img->refPicID%16;         // refPicID, variable length
  125.     SYMTRACESTRING("PHRefPicID");
  126.     len += writeSyntaxElement_UVLC (&sym, partition);
  127.   }
  128.   return len;
  129. }
  130. int SliceHeader(int UseStartCode)
  131. {
  132.   int dP_nr = assignSE2partition[input->partition_mode][SE_HEADER];
  133.   Bitstream *currStream = ((img->currentSlice)->partArr[dP_nr]).bitstream;
  134.   DataPartition *partition = &((img->currentSlice)->partArr[dP_nr]);
  135.   SyntaxElement sym;
  136.   int len = 0;
  137.   int Quant = img->qp;          // Hack.  This should be a parameter as soon as Gisle is done
  138.   int MBPosition = img->current_mb_nr;  // Hack.  This should be a paremeter as well.
  139.   sym.type = SE_HEADER;       // This will be true for all symbols generated here
  140.   sym.mapping = n_linfo2;       // Mapping rule: Simple code number to len/info
  141.   // Note 1.  Current implementation: Slice start code is similar to pictrure start code
  142.   // (info is 1 for slice and 0 for picture start code).  Slice Start code is not
  143.   // present except when generating an UVLC file.  Start codes are typical NAL
  144.   // functionality, and hence NALs will take care the issue in the future.
  145.   // Note 2:  Traditionally, the QP is a bit mask.  However, at numerically large QPs
  146.   // we usually have high compression and don't want to waste bits, whereas
  147.   // at low QPs this is not as much an issue.  Hence, the QUANT parameter
  148.   // is coded as a UVLC calculated as 31 - QUANT.  That is, the UVLC representation
  149.   // of 31-QUANT is coded, instead of QUANT.
  150.   // Note 3:  In addition to the fields in VCEG-M79 there is one additional header field
  151.   // with the MV resolution.  Currently defined values:
  152.   // 0 == 1/4th pel resolution (old default)
  153.   // 1 == 1/8th pel resolution
  154.   // ... could be enhanced straightforward, it may make sense to define
  155.   // 2 == 1/2 pel resolution
  156.   // 3 == full pel resolution
  157.   if (UseStartCode)
  158.   {
  159.     // Input mode 0, File Format, and not Picture Start (first slice in picture)
  160.     // This is the only case where a slice start code makes sense
  161.     //
  162.     // Putting a Slice Start Code is the same like the picture start code.  It's
  163.     // n ot as straightforward as one thinks,  See remarks above.
  164.     len += PutSliceStartCode(currStream);
  165.   };
  166.   // Now we have coded the Pciture header when appropriate, and the slice header when
  167.   // appropriate.  Follow with the content of the slice header: GOB address of the slice
  168.   // start and (initial) QP.  For the QP see remarks above.  For the GOB address, use
  169.   // straigtforward procedure.  Note that this allows slices to start at MB addresses
  170.   // up to 2^15 MBs due ot start code emulation problems.  This should be enough for
  171.   // most practical applications,. but probably not for cinema.  Has to be discussed.
  172.   // For the MPEG tests this is irrelevant, because there the rule will be one silce--
  173.   // one picture.
  174.   // Put MB-Adresse
  175.   assert (MBPosition < (1<<15));
  176.   SYMTRACESTRING("SH FirstMBInSlice");
  177.   sym.value1 = MBPosition;
  178.   len += writeSyntaxElement_UVLC (&sym, partition);
  179.   // Put Quant.  It's a bit irrationale that we still put the same quant here, but it's
  180.   // a good provision for the future.  In real-world applications slices typically
  181.   // start with Intra information, and Intra MBs will likely use a different quant
  182.   // than Inter
  183.   SYMTRACESTRING("SH SliceQuant");
  184.   sym.value1 = 31 - Quant;
  185.   len += writeSyntaxElement_UVLC (&sym, partition);
  186.   if (img->types==SP_IMG)
  187.   {
  188.     SYMTRACESTRING("SH SP SliceQuant");
  189.     sym.value1 = 31 - img->qpsp;
  190.     len += writeSyntaxElement_UVLC (&sym, partition);
  191.   }
  192.   // Put the Motion Vector resolution as per reflector consensus
  193.   SYMTRACESTRING("SH MVResolution");
  194.   sym.value1 = input->mv_res;
  195.   len += writeSyntaxElement_UVLC (&sym, partition);
  196.   return len;
  197. }
  198. int SequenceHeader (FILE *outf)
  199. {
  200.   int LenInBytes = 0;
  201.   int HeaderInfo;         // Binary coded Headerinfo to be written in file
  202.   int ProfileLevelVersionHash;
  203.   // Handle the RTP case
  204.   if (input->of_mode == PAR_OF_RTP)
  205.   {
  206.     if ((LenInBytes = RTPSequenceHeader (outf)) < 0)
  207.     {
  208.       snprintf (errortext, ET_SIZE, "SequenceHeaqder(): Problems writing the RTP Parameter Packet");
  209.       error (errortext, 600);
  210.       return -1;
  211.     }
  212.     else
  213.       return LenInBytes*8;
  214.   }
  215.   // Non RTP-type file formats follow
  216.   switch (input->SequenceHeaderType)
  217.   {
  218.   case 0:
  219.     // No SequenceHeader, do nothing
  220.     return 0;
  221.   case 1:
  222.     // A binary mini Sequence header.  Fixed length 32 bits.  Defined as follows
  223.     // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  224.     // |        0          |        1          |        2          | 3 |
  225.     // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  226.     // |0|1|2|3|4|5|6|7|8|9|0|1|2|3|4|5|6|7|8|9|0|1|2|3|4|5|6|7|8|9|0|1|
  227.     // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  228.     // |     TR Modulus        |     PicIDModulus      |OfMode |part |S|
  229.     // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  230.     //
  231.     // S is symbol_mode (UVLC = 0, CABAC = 1), the other are as in the input file
  232.     assert (input->TRModulus < 4096);
  233.     assert (sizeof (int) == 4);
  234.     assert (input->PicIdModulus <4096);
  235.     assert (input->of_mode <16);
  236.     assert (input->partition_mode <8);
  237.     assert (input->symbol_mode < 2);
  238.     ProfileLevelVersionHash = input->of_mode<<0 | input->partition_mode<<4 | input->symbol_mode<<7;
  239.     HeaderInfo = input->TRModulus | input->PicIdModulus<<12 | ProfileLevelVersionHash<<24;
  240.     if (1 != fwrite (&HeaderInfo, 4, 1, outf))
  241.     {
  242.       snprintf (errortext, ET_SIZE, "Error while writing Mini Sequence Header");
  243.       error(errortext, 500);
  244.     }
  245. #if TRACE
  246.     fprintf(p_trace, "Binary Mini Sequence Header 0x%xnn", HeaderInfo);
  247. #endif
  248.     return 32;
  249.   case 2:
  250.     // An ASCII representation of many input file parameters, useful for debug purposes
  251.     //
  252.     //
  253.     assert ("To be hacked");
  254.     return -1;
  255.   case 3:
  256.     // An UVLC coded representatioj of the Sequence Header.  To be hacked.
  257.     // Note that all UVLC initialization has already taken place, so just use
  258.     // write_synyaxelement() to put the sequence header symbols.  Has to be double
  259.     // checked whether this is true for cabac as well.  Do we need a new context
  260.     // for that?  Anyway:
  261.     //
  262.     assert ("to be hacked");
  263.     return -1;
  264.   default:
  265.     snprintf (errortext, ET_SIZE, "Unspported Sequence Header Type (should not happen since checked in input module, exiting");
  266.     error (errortext, 600);
  267.     return -1;
  268.   }
  269. }
  270. /********************************************************************************************
  271.  ********************************************************************************************
  272.  *
  273.  * Local Support Functions
  274.  *
  275.  ********************************************************************************************
  276.  ********************************************************************************************/
  277. /*!
  278.  ********************************************************************************************
  279.  * brief
  280.  *    Puts a Picture Start Code into the Bitstream
  281.  *
  282.  * return
  283.  *    number of bits used for the PSC.
  284.  *
  285.  * par Side effects:
  286.  *    Adds picture start code to the Bitstream
  287.  *
  288.  * par Remarks:
  289.  *    THIS IS AN INTERIM SOLUTION FOR A PICTURE HEADER, see VCEG-M79
  290.  *                                                                                        par
  291.  *    The PSC is a NAL functionality and, hence, should not be put into the
  292.  *    bitstream by a module like this.  It was added here in response to
  293.  *    the need for a quick hack for the MPEG tests.
  294.  *    The PSC consists of a UVLC codeword of len 31 with info 0.  This results
  295.  *    in 30 consecutove 0 bits in the bit stream, which should be easily
  296.  *    identifyable if a need arises.
  297.  ********************************************************************************************
  298. */
  299. static int PutPictureStartCode (Bitstream *s)
  300. {
  301.   return PutStartCode (0, s, "nPicture Header");
  302. }
  303. /*!
  304.  ********************************************************************************************
  305.  * brief
  306.  *    Puts a Slice Start Code into the Bitstream
  307.  *
  308.  * return
  309.  *    number of bits used for the PSC.
  310.  *
  311.  * note
  312.  *     See PutPictureStartCode()
  313.  ********************************************************************************************
  314. */
  315. static int PutSliceStartCode(Bitstream *s)
  316. {
  317.   return PutStartCode (1, s, "nSlice Header");
  318. }
  319. /*!
  320.  ********************************************************************************************
  321.  * brief Puts a Start Code into the Bitstream
  322.  *    ts is a TraceString
  323.  *
  324.  * return
  325.  *    number of bits used for the PSC.
  326.  *
  327.  * note
  328.  *  See PutPictureStartCode()
  329.  ********************************************************************************************
  330. */
  331. static int PutStartCode (int Type, Bitstream *s, char *ts)
  332. {
  333.   SyntaxElement sym;
  334.   // Putting the Start Codes is a bit tricky, because we cannot use writesyntaxelement()
  335.   // directly.  Problem is that we want a codeword of len == 31 with an info of 0 or 1.
  336.   // There is no simple mapping() rule to express this.  Of course, one could calculate
  337.   // what info would have to be for such a case.  But I guess it's cleaner to use
  338.   // the len/info interface directly.
  339.   sym.len = LEN_STARTCODE;
  340.   sym.inf = Type;
  341.   sym.type = SE_HEADER;
  342. #if TRACE
  343.   strncpy(sym.tracestring, ts, TRACESTRING_SIZE);
  344. #endif
  345.   symbol2uvlc(&sym);      // generates the bit pattern
  346.   writeUVLC2buffer(&sym, s);  // and puts it out to the buffer
  347. #if TRACE
  348.   trace2out(&sym);
  349. #endif
  350.   return LEN_STARTCODE;
  351. }
  352. // StW Note: This function is a hack.  It would be cleaner if the encoder maintains
  353. // the picture type in the given format.  Note further that I have yet to understand
  354. // why the encoder needs to know whether a picture is predicted from one or more
  355. // reference pictures.
  356. /*!
  357.  ************************************************************************
  358.  * brief
  359.  *    Selects picture type and codes it to symbol
  360.  ************************************************************************
  361.  */
  362. void select_picture_type(SyntaxElement *symbol)
  363. {
  364.   int multpred;
  365. #ifdef _ADDITIONAL_REFERENCE_FRAME_
  366.   if (input->no_multpred <= 1 && input->add_ref_frame == 0)
  367. #else
  368.   if (input->no_multpred <= 1)
  369. #endif
  370.     multpred=FALSE;
  371.   else
  372.     multpred=TRUE;               // multiple reference frames in motion search
  373.   if (img->type == INTRA_IMG)
  374.   {
  375.     symbol->len=3;
  376.     symbol->inf=1;
  377.     symbol->value1 = 2;
  378.   }
  379.   else if((img->type == INTER_IMG) && (multpred == FALSE) ) // inter single reference frame
  380.   {
  381.     symbol->len=1;
  382.     symbol->inf=0;
  383.     symbol->value1 = 0;
  384.   }
  385.   else if((img->type == INTER_IMG) && (multpred == TRUE)) // inter multiple reference frames
  386.   {
  387.     symbol->len=3;
  388.     symbol->inf=0;
  389.     symbol->value1 = 1;
  390.   }
  391.   else if((img->type == B_IMG) && (multpred == FALSE))
  392.   {
  393.     symbol->len=5;
  394.     symbol->inf=0;
  395.     symbol->value1 = 3;
  396.   }
  397.   else if((img->type == B_IMG) && (multpred == TRUE))
  398.   {
  399.     symbol->len=5;
  400.     symbol->inf=1;
  401.     symbol->value1 = 4;
  402.   }
  403.   else
  404.   {
  405.     error("Picture Type not supported!",1);
  406.   }
  407.   if((img->types == SP_IMG ) && (multpred == FALSE))
  408.   {
  409.     symbol->len=5;
  410.     symbol->inf=0;
  411.     symbol->value1 = 5;
  412.   }
  413.   else if((img->types == SP_IMG) && (multpred == TRUE))
  414.   {
  415.     symbol->len=5;
  416.     symbol->inf=0;
  417.     symbol->value1 = 6;
  418.   }
  419. #if TRACE
  420.   snprintf(symbol->tracestring, TRACESTRING_SIZE, "Image type = %3d ", img->type);
  421. #endif
  422.   symbol->type = SE_PTYPE;
  423. }
  424. /*!
  425.  ************************************************************************
  426.  * brief
  427.  *    Writes the number of MBs of this slice
  428.  ************************************************************************
  429.  */
  430. void LastMBInSlice()
  431. {
  432.   int dP_nr = assignSE2partition[input->partition_mode][SE_HEADER];
  433.   DataPartition *partition = &((img->currentSlice)->partArr[dP_nr]);
  434.   SyntaxElement sym;
  435.   int d_MB_Nr;
  436.   d_MB_Nr = img->current_mb_nr-img->currentSlice->start_mb_nr;
  437.   if (d_MB_Nr == img->total_number_mb)
  438.     d_MB_Nr = 0;
  439.   sym.type = SE_HEADER;
  440.   sym.mapping = n_linfo2;       // Mapping rule: Simple code number to len/info
  441.   // Put MB-Adresse
  442.   assert (d_MB_Nr < (1<<15));
  443.   SYMTRACESTRING("SH Numbers of MB in Slice");
  444.   sym.value1 = d_MB_Nr;
  445.   writeSyntaxElement_UVLC (&sym, partition);
  446. }