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

Audio

开发平台:

Visual C++

  1. /*!
  2.  ************************************************************************
  3.  *  file
  4.  *     sei.c
  5.  *  brief
  6.  *     implementation of SEI related functions
  7.  *  author(s)
  8.  *      - Dong Tian                             <tian@cs.tut.fi>
  9.  *
  10.  ************************************************************************
  11.  */
  12. #include "global.h"
  13. #include "memalloc.h"
  14. #include "rtp.h"
  15. #include "mbuffer.h"
  16. #include "sei.h"
  17. #include "vlc.h"
  18. Boolean seiHasTemporal_reference=FALSE;
  19. Boolean seiHasClock_timestamp=FALSE;
  20. Boolean seiHasPanscan_rect=FALSE;
  21. Boolean seiHasHrd_picture=FALSE;
  22. Boolean seiHasFiller_payload=FALSE;
  23. Boolean seiHasUser_data_registered_itu_t_t35=FALSE;
  24. Boolean seiHasUser_data_unregistered=FALSE;
  25. Boolean seiHasRecoveryPoint_info=FALSE;
  26. Boolean seiHasRef_pic_buffer_management_repetition=FALSE;
  27. Boolean seiHasSpare_picture=FALSE;
  28. Boolean seiHasBuffering_period=FALSE;
  29. Boolean seiHasPicTiming_info=FALSE;
  30. Boolean seiHasSceneInformation=FALSE;
  31. Boolean seiHasSubseq_information=FALSE;
  32. Boolean seiHasSubseq_layer_characteristics=FALSE;
  33. Boolean seiHasSubseq_characteristics=FALSE;
  34. Boolean seiHasTone_mapping=FALSE;
  35. Boolean seiHasPostFilterHints_info=FALSE;
  36. //#define PRINT_TONE_MAPPING
  37. /*
  38.  ************************************************************************
  39.  *  basic functions on supplemental enhancement information
  40.  *  brief
  41.  *     The implementations are based on FCD
  42.  ************************************************************************
  43.  */
  44. //! sei_message[0]: this struct is to store the sei message packetized independently
  45. //! sei_message[1]: this struct is to store the sei message packetized together with slice data
  46. sei_struct sei_message[2];
  47. void InitSEIMessages()
  48. {
  49.   int i;
  50.   for (i=0; i<2; i++)
  51.   {
  52.     sei_message[i].data = malloc(MAXRTPPAYLOADLEN);
  53.     if( sei_message[i].data == NULL ) no_mem_exit("InitSEIMessages: sei_message[i].data");
  54.     sei_message[i].subPacketType = SEI_PACKET_TYPE;
  55.     clear_sei_message(i);
  56.   }
  57.   // init sei messages
  58.   seiSparePicturePayload.data = NULL;
  59.   InitSparePicture();
  60.   InitSubseqChar();
  61.   if (params->NumFramesInELSubSeq != 0)
  62.     InitSubseqLayerInfo();
  63.   InitSceneInformation();
  64.   // init panscanrect sei message
  65.   InitPanScanRectInfo();
  66.   // init user_data_unregistered
  67.   InitUser_data_unregistered();
  68.   // init user_data_unregistered
  69.   InitUser_data_registered_itu_t_t35();
  70.   // init user_RandomAccess
  71.   InitRandomAccess();
  72.   // Init tone_mapping
  73.   InitToneMapping();
  74.   // init post_filter_hints
  75.   InitPostFilterHints();
  76.   // init BufferingPeriod
  77.   InitBufferingPeriod();
  78.   // init PicTiming
  79.   InitPicTiming();
  80. }
  81. void CloseSEIMessages()
  82. {
  83.   int i;
  84.   if (params->NumFramesInELSubSeq != 0)
  85.     CloseSubseqLayerInfo();
  86.   CloseSubseqChar();
  87.   CloseSparePicture();
  88.   CloseSceneInformation();
  89.   ClosePanScanRectInfo();
  90.   CloseUser_data_unregistered();
  91.   CloseUser_data_registered_itu_t_t35();
  92.   CloseRandomAccess();
  93.   CloseToneMapping();
  94.   ClosePostFilterHints();
  95.   CloseBufferingPeriod();
  96.   ClosePicTiming();
  97.   for (i=0; i<MAX_LAYER_NUMBER; i++)
  98.   {
  99.     if ( sei_message[i].data ) free( sei_message[i].data );
  100.     sei_message[i].data = NULL;
  101.   }
  102. }
  103. Boolean HaveAggregationSEI()
  104. {
  105.   if (sei_message[AGGREGATION_SEI].available && img->type != B_SLICE)
  106.     return TRUE;
  107.   if (seiHasSubseqInfo)
  108.     return TRUE;
  109.   if (seiHasSubseqLayerInfo && img->number == 0)
  110.     return TRUE;
  111.   if (seiHasSubseqChar)
  112.     return TRUE;
  113.   if (seiHasSceneInformation)
  114.     return TRUE;
  115.   if (seiHasPanScanRectInfo)
  116.     return TRUE;
  117.   if (seiHasUser_data_unregistered_info)
  118.     return TRUE;
  119.   if (seiHasUser_data_registered_itu_t_t35_info)
  120.     return TRUE;
  121.   if (seiHasRecoveryPoint_info)
  122.     return TRUE;
  123.   if (seiHasTone_mapping)
  124.     return TRUE;
  125.   if (seiHasPostFilterHints_info)
  126.     return TRUE;
  127.   if (seiHasBuffering_period)
  128.     return TRUE;
  129.   if (seiHasPicTiming_info)
  130.     return TRUE;
  131.   return FALSE;
  132. //  return params->SparePictureOption && ( seiHasSpare_picture || seiHasSubseq_information ||
  133. //    seiHasSubseq_layer_characteristics || seiHasSubseq_characteristics );
  134. }
  135. /*!
  136.  ************************************************************************
  137.  *  brief
  138.  *     write one sei payload to the sei message
  139.  *  param id
  140.  *    0, if this is the normal packetn
  141.  *    1, if this is a aggregation packet
  142.  *  param payload
  143.  *    a pointer that point to the sei payload. Note that the bitstream
  144.  *    should have be byte aligned already.
  145.  *  param payload_size
  146.  *    the size of the sei payload
  147.  *  param payload_type
  148.  *    the type of the sei payload
  149.  *  par Output
  150.  *    the content of the sei message (sei_message[id]) is updated.
  151.  ************************************************************************
  152.  */
  153. void write_sei_message(int id, byte* payload, int payload_size, int payload_type)
  154. {
  155.   int offset, type, size;
  156.   assert(payload_type >= 0 && payload_type < SEI_MAX_ELEMENTS);
  157.   type = payload_type;
  158.   size = payload_size;
  159.   offset = sei_message[id].payloadSize;
  160.   while ( type > 254 )
  161.   {
  162.     sei_message[id].data[offset++] = 0xFF;
  163.     type = type - 255;
  164.   }
  165.   sei_message[id].data[offset++] = (byte) type;
  166.   while ( size > 254 )
  167.   {
  168.     sei_message[id].data[offset++] = 0xFF;
  169.     size = size - 255;
  170.   }
  171.   sei_message[id].data[offset++] = (byte) size;
  172.   memcpy(sei_message[id].data + offset, payload, payload_size);
  173.   offset += payload_size;
  174.   sei_message[id].payloadSize = offset;
  175. }
  176. /*!
  177.  ************************************************************************
  178.  *  brief
  179.  *     write rbsp_trailing_bits to the sei message
  180.  *  param id
  181.  *    0, if this is the normal packet n
  182.  *    1, if this is a aggregation packet
  183.  *  par Output
  184.  *    the content of the sei message is updated and ready for packetisation
  185.  ************************************************************************
  186.  */
  187. void finalize_sei_message(int id)
  188. {
  189.   int offset = sei_message[id].payloadSize;
  190.   sei_message[id].data[offset] = 0x80;
  191.   sei_message[id].payloadSize++;
  192.   sei_message[id].available = TRUE;
  193. }
  194. /*!
  195.  ************************************************************************
  196.  *  brief
  197.  *     empty the sei message buffer
  198.  *  param id
  199.  *    0, if this is the normal packet n
  200.  *    1, if this is a aggregation packet
  201.  *  par Output
  202.  *    the content of the sei message is cleared and ready for storing new
  203.  *      messages
  204.  ************************************************************************
  205.  */
  206. void clear_sei_message(int id)
  207. {
  208.   memset( sei_message[id].data, 0, MAXRTPPAYLOADLEN);
  209.   sei_message[id].payloadSize       = 0;
  210.   sei_message[id].available         = FALSE;
  211. }
  212. /*!
  213.  ************************************************************************
  214.  *  brief
  215.  *     copy the bits from one bitstream buffer to another one
  216.  *  param dest
  217.  *    pointer to the dest bitstream buffer
  218.  *  param source
  219.  *    pointer to the source bitstream buffer
  220.  *  par Output
  221.  *    the content of the dest bitstream is changed.
  222.  ************************************************************************
  223.  */
  224. void AppendTmpbits2Buf( Bitstream* dest, Bitstream* source )
  225. {
  226.   int i, j;
  227.   byte mask;
  228.   int bits_in_last_byte;
  229.   // copy the first bytes in source buffer
  230.   for (i=0; i<source->byte_pos; i++)
  231.   {
  232.     mask = 0x80;
  233.     for (j=0; j<8; j++)
  234.     {
  235.       dest->byte_buf <<= 1;
  236.       if (source->streamBuffer[i] & mask)
  237.         dest->byte_buf |= 1;
  238.       dest->bits_to_go--;
  239.       mask >>= 1;
  240.       if (dest->bits_to_go==0)
  241.       {
  242.         dest->bits_to_go = 8;
  243.         dest->streamBuffer[dest->byte_pos++]=dest->byte_buf;
  244.         dest->byte_buf = 0;
  245.       }
  246.     }
  247.   }
  248.   // copy the last byte, there are still (8-source->bits_to_go) bits in the source buffer
  249.   bits_in_last_byte = 8-source->bits_to_go;
  250.   if ( bits_in_last_byte > 0 )
  251.   {
  252.     mask = (byte) (1 << (bits_in_last_byte-1));
  253.     for (j=0; j<bits_in_last_byte; j++)
  254.     {
  255.       dest->byte_buf <<= 1;
  256.       if (source->byte_buf & mask)
  257.         dest->byte_buf |= 1;
  258.       dest->bits_to_go--;
  259.       mask >>= 1;
  260.       if (dest->bits_to_go==0)
  261.       {
  262.         dest->bits_to_go = 8;
  263.         dest->streamBuffer[dest->byte_pos++]=dest->byte_buf;
  264.         dest->byte_buf = 0;
  265.       }
  266.     }
  267.   }
  268. }
  269. /*
  270.  **++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  271.  *  functions on spare pictures
  272.  *  brief
  273.  *     implementation of Spare Pictures related functions based on
  274.  *      JVT-D100
  275.  *  author
  276.  *      Dong Tian                 <tian@cs.tut.fi>
  277.  **++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  278.  */
  279. // global variables for spare pictures
  280. // In current implementation, Sept 2002, the spare picture info is
  281. // paketized together with the immediately following frame. Thus we
  282. // define one set of global variables to save the info.
  283. Boolean seiHasSparePicture = FALSE;
  284. spare_picture_struct seiSparePicturePayload;
  285. /*!
  286.  ************************************************************************
  287.  *  brief
  288.  *      Init the global variables for spare picture information
  289.  ************************************************************************
  290.  */
  291. void InitSparePicture()
  292. {
  293.   if ( seiSparePicturePayload.data != NULL ) CloseSparePicture();
  294.   seiSparePicturePayload.data = malloc( sizeof(Bitstream) );
  295.   if ( seiSparePicturePayload.data == NULL ) no_mem_exit("InitSparePicture: seiSparePicturePayload.data");
  296.   seiSparePicturePayload.data->streamBuffer = malloc(MAXRTPPAYLOADLEN);
  297.   if ( seiSparePicturePayload.data->streamBuffer == NULL ) no_mem_exit("InitSparePicture: seiSparePicturePayload.data->streamBuffer");
  298.   memset( seiSparePicturePayload.data->streamBuffer, 0, MAXRTPPAYLOADLEN);
  299.   seiSparePicturePayload.num_spare_pics = 0;
  300.   seiSparePicturePayload.target_frame_num = 0;
  301.   seiSparePicturePayload.data->bits_to_go  = 8;
  302.   seiSparePicturePayload.data->byte_pos    = 0;
  303.   seiSparePicturePayload.data->byte_buf    = 0;
  304. }
  305. /*!
  306.  ************************************************************************
  307.  *  brief
  308.  *      Close the global variables for spare picture information
  309.  ************************************************************************
  310.  */
  311. void CloseSparePicture()
  312. {
  313.   if (seiSparePicturePayload.data->streamBuffer)
  314.     free(seiSparePicturePayload.data->streamBuffer);
  315.   seiSparePicturePayload.data->streamBuffer = NULL;
  316.   if (seiSparePicturePayload.data)
  317.     free(seiSparePicturePayload.data);
  318.   seiSparePicturePayload.data = NULL;
  319.   seiSparePicturePayload.num_spare_pics = 0;
  320.   seiSparePicturePayload.target_frame_num = 0;
  321. }
  322. /*!
  323.  ************************************************************************
  324.  *  brief
  325.  *     Calculate the spare picture info, save the result in map_sp
  326.  *      then compose the spare picture information.
  327.  *  par Output
  328.  *      the spare picture payload is available in *seiSparePicturePayload*
  329.  *      the syntax elements in the loop (see FCD), excluding the two elements
  330.  *      at the beginning.
  331.  ************************************************************************
  332.  */
  333. void CalculateSparePicture()
  334. {
  335.   /*
  336.   int i, j, tmp, i0, j0, m;
  337.   byte **map_sp;
  338.   int delta_spare_frame_num;
  339.   Bitstream *tmpBitstream;
  340.   int num_of_mb=(img->height/16) * (img->width/16);
  341.   int threshold1 = 16*16*params->SPDetectionThreshold;
  342.   int threshold2 = num_of_mb * params->SPPercentageThreshold / 100;
  343.   int ref_area_indicator;
  344.   int CandidateSpareFrameNum, SpareFrameNum;
  345.   int possible_spare_pic_num;
  346.   // define it for debug purpose
  347.   #define WRITE_MAP_IMAGE
  348. #ifdef WRITE_MAP_IMAGE
  349.   byte **y;
  350.   int k;
  351.   FILE* fp;
  352.   static int first = 1;
  353.   char map_file_name[255]="map.yuv";
  354. #endif
  355.   // basic check
  356.   if (fb->picbuf_short[0]->used==0 || fb->picbuf_short[1]->used==0)
  357.   {
  358. #ifdef WRITE_MAP_IMAGE
  359.     fp = fopen( map_file_name, "wb" );
  360.     assert( fp != NULL );
  361.     // write the map image
  362.     for (i=0; i < img->height; i++)
  363.       for (j=0; j < img->width; j++)
  364.         fputc(0, fp);
  365.     for (k=0; k < 2; k++)
  366.       for (i=0; i < img->height/2; i++)
  367.         for (j=0; j < img->width/2; j++)
  368.           fputc(128, fp);
  369.     fclose( fp );
  370. #endif
  371.     seiHasSparePicture = FALSE;
  372.     return;
  373.   }
  374.   seiHasSparePicture = TRUE;
  375.   // set the global bitstream memory.
  376.   InitSparePicture();
  377.   seiSparePicturePayload.target_frame_num = img->number % MAX_FN;
  378.   // init the local bitstream memory.
  379.   tmpBitstream = malloc(sizeof(Bitstream));
  380.   if ( tmpBitstream == NULL ) no_mem_exit("CalculateSparePicture: tmpBitstream");
  381.   tmpBitstream->streamBuffer = malloc(MAXRTPPAYLOADLEN);
  382.   if ( tmpBitstream->streamBuffer == NULL ) no_mem_exit("CalculateSparePicture: tmpBitstream->streamBuffer");
  383.   memset( tmpBitstream->streamBuffer, 0, MAXRTPPAYLOADLEN);
  384. #ifdef WRITE_MAP_IMAGE
  385.   if ( first )
  386.   {
  387.     fp = fopen( map_file_name, "wb" );
  388.     first = 0;
  389.   }
  390.   else
  391.     fp = fopen( map_file_name, "ab" );
  392.   get_mem2D(&y, img->height, img->width);
  393. #endif
  394.   get_mem2D(&map_sp, img->height/16, img->width/16);
  395.   if (fb->picbuf_short[2]->used!=0) possible_spare_pic_num = 2;
  396.   else possible_spare_pic_num = 1;
  397.   // loop over the spare pictures
  398.   for (m=0; m<possible_spare_pic_num; m++)
  399.   {
  400.     // clear the temporal bitstream buffer
  401.     tmpBitstream->bits_to_go  = 8;
  402.     tmpBitstream->byte_pos    = 0;
  403.     tmpBitstream->byte_buf    = 0;
  404.     memset( tmpBitstream->streamBuffer, 0, MAXRTPPAYLOADLEN);
  405.     // set delta_spare_frame_num
  406.     // the order of the following lines cannot be changed.
  407.     if (m==0)
  408.       CandidateSpareFrameNum = seiSparePicturePayload.target_frame_num - 1; // TargetFrameNum - 1;
  409.     else
  410.       CandidateSpareFrameNum = SpareFrameNum - 1;
  411.     if ( CandidateSpareFrameNum < 0 ) CandidateSpareFrameNum = MAX_FN - 1;
  412.     SpareFrameNum = fb->picbuf_short[m+1]->frame_num_256;
  413.     delta_spare_frame_num = CandidateSpareFrameNum - SpareFrameNum;
  414.     assert( delta_spare_frame_num == 0 );
  415.     // calculate the spare macroblock map of one spare picture
  416.     // the results are stored into map_sp[][]
  417.     for (i=0; i < img->height/16; i++)
  418.       for (j=0; j < img->width/16; j++)
  419.       {
  420.         tmp = 0;
  421.         for (i0=0; i0<16; i0++)
  422.           for (j0=0; j0<16; j0++)
  423.             tmp+=iabs(fb->picbuf_short[m+1]->Refbuf11[(i*16+i0)*img->width+j*16+j0]-
  424.                        fb->picbuf_short[0]->Refbuf11[(i*16+i0)*img->width+j*16+j0]);
  425.         tmp = (tmp<=threshold1? 255 : 0);
  426.         map_sp[i][j] = (tmp==0? 1 : 0);
  427. #ifdef WRITE_MAP_IMAGE
  428. //        if (m==0)
  429.         {
  430.         for (i0=0; i0<16; i0++)
  431.           for (j0=0; j0<16; j0++)
  432.             y[i*16+i0][j*16+j0]=tmp;
  433.         }
  434. #endif
  435.       }
  436.     // based on map_sp[][], compose the spare picture information
  437.     // and write the spare picture information to a temp bitstream
  438.     tmp = 0;
  439.     for (i=0; i < img->height/16; i++)
  440.       for (j=0; j < img->width/16; j++)
  441.         if (map_sp[i][j]==0) tmp++;
  442.     if ( tmp > threshold2 )
  443.       ref_area_indicator = 0;
  444.     else if ( !CompressSpareMBMap(map_sp, tmpBitstream) )
  445.       ref_area_indicator = 1;
  446.     else
  447.       ref_area_indicator = 2;
  448. //    printf( "ref_area_indicator = %dn", ref_area_indicator );
  449. #ifdef WRITE_MAP_IMAGE
  450.     // write the map to a file
  451. //    if (m==0)
  452.     {
  453.       // write the map image
  454.       for (i=0; i < img->height; i++)
  455.         for (j=0; j < img->width; j++)
  456.         {
  457.           if ( ref_area_indicator == 0 ) fputc(255, fp);
  458.           else fputc(y[i][j], fp);
  459.         }
  460.       for (k=0; k < 2; k++)
  461.         for (i=0; i < img->height/2; i++)
  462.           for (j=0; j < img->width/2; j++)
  463.             fputc(128, fp);
  464.     }
  465. #endif
  466.     // Finnally, write the current spare picture information to
  467.     // the global variable: seiSparePicturePayload
  468.     ComposeSparePictureMessage(delta_spare_frame_num, ref_area_indicator, tmpBitstream);
  469.     seiSparePicturePayload.num_spare_pics++;
  470.   }  // END for (m=0; m<2; m++)
  471.   free_mem2D( map_sp );
  472.   free( tmpBitstream->streamBuffer );
  473.   free( tmpBitstream );
  474. #ifdef WRITE_MAP_IMAGE
  475.   free_mem2D( y );
  476.   fclose( fp );
  477. #undef WRITE_MAP_IMAGE
  478. #endif
  479.   */
  480. }
  481. /*!
  482.  ************************************************************************
  483.  *  brief
  484.  *      compose the spare picture information.
  485.  *  param delta_spare_frame_num
  486.  *      see FCD
  487.  *  param ref_area_indicator
  488.  *      Indicate how to represent the spare mb map
  489.  *  param tmpBitstream
  490.  *      pointer to a buffer to save the payload
  491.  *  par Output
  492.  *      bitstream: the composed spare picture payload are
  493.  *        ready to put into the sei_message.
  494.  ************************************************************************
  495.  */
  496. void ComposeSparePictureMessage(int delta_spare_frame_num, int ref_area_indicator, Bitstream *tmpBitstream)
  497. {
  498.   Bitstream *bitstream = seiSparePicturePayload.data;
  499.   SyntaxElement sym;
  500.   sym.type = SE_HEADER;
  501.   sym.mapping = ue_linfo;
  502.   sym.value1 = delta_spare_frame_num;
  503.   writeSyntaxElement2Buf_UVLC(&sym, bitstream);
  504.   sym.value1 = ref_area_indicator;
  505.   writeSyntaxElement2Buf_UVLC(&sym, bitstream);
  506.   AppendTmpbits2Buf( bitstream, tmpBitstream );
  507. }
  508. /*!
  509.  ************************************************************************
  510.  *  brief
  511.  *      test if the compressed spare mb map will occupy less mem and
  512.  *      fill the payload buffer.
  513.  *  param map_sp
  514.  *      in which the spare picture information are stored.
  515.  *  param bitstream
  516.  *      pointer to a buffer to save the payload
  517.  *  return
  518.  *      TRUE: If it is compressed version, n
  519.  *             FALSE: If it is not compressed.
  520.  ************************************************************************
  521.  */
  522. Boolean CompressSpareMBMap(unsigned char **map_sp, Bitstream *bitstream)
  523. {
  524.   int j, k;
  525.   int noc, bit0, bit1, bitc;
  526.   SyntaxElement sym;
  527.   int x, y, left, right, bottom, top, directx, directy;
  528.   // this is the size of the uncompressed mb map:
  529.   int size_uncompressed = (img->height/16) * (img->width/16);
  530.   int size_compressed   = 0;
  531.   Boolean ret;
  532.   // initialization
  533.   sym.type = SE_HEADER;
  534.   sym.mapping = ue_linfo;
  535.   noc = 0;
  536.   bit0 = 0;
  537.   bit1 = 1;
  538.   bitc = bit0;
  539.   // compress the map, the result goes to the temporal bitstream buffer
  540.   x = ( img->width/16 - 1 ) / 2;
  541.   y = ( img->height/16 - 1 ) / 2;
  542.   left = right = x;
  543.   top = bottom = y;
  544.   directx = 0;
  545.   directy = 1;
  546.   for (j=0; j<img->height/16; j++)
  547.     for (k=0; k<img->width/16; k++)
  548.     {
  549.       // check current mb
  550.       if ( map_sp[y][x] == bitc ) noc++;
  551.       else
  552.       {
  553.         sym.value1 = noc;
  554.         size_compressed += writeSyntaxElement2Buf_UVLC(&sym, bitstream);    // the return value indicate the num of bits written
  555.         noc=0;
  556.       }
  557.       // go to the next mb:
  558.       if ( directx == -1 && directy == 0 )
  559.       {
  560.         if (x > left) x--;
  561.         else if (x == 0)
  562.         {
  563.           y = bottom + 1;
  564.           bottom++;
  565.           directx = 1;
  566.           directy = 0;
  567.         }
  568.         else if (x == left)
  569.         {
  570.           x--;
  571.           left--;
  572.           directx = 0;
  573.           directy = 1;
  574.         }
  575.       }
  576.       else if ( directx == 1 && directy == 0 )
  577.       {
  578.         if (x < right) x++;
  579.         else if (x == img->width/16 - 1)
  580.         {
  581.           y = top - 1;
  582.           top--;
  583.           directx = -1;
  584.           directy = 0;
  585.         }
  586.         else if (x == right)
  587.         {
  588.           x++;
  589.           right++;
  590.           directx = 0;
  591.           directy = -1;
  592.         }
  593.       }
  594.       else if ( directx == 0 && directy == -1 )
  595.       {
  596.         if ( y > top) y--;
  597.         else if (y == 0)
  598.         {
  599.           x = left - 1;
  600.           left--;
  601.           directx = 0;
  602.           directy = 1;
  603.         }
  604.         else if (y == top)
  605.         {
  606.           y--;
  607.           top--;
  608.           directx = -1;
  609.           directy = 0;
  610.         }
  611.       }
  612.       else if ( directx == 0 && directy == 1 )
  613.       {
  614.         if (y < bottom) y++;
  615.         else if (y == img->height/16 - 1)
  616.         {
  617.           x = right+1;
  618.           right++;
  619.           directx = 0;
  620.           directy = -1;
  621.         }
  622.         else if (y == bottom)
  623.         {
  624.           y++;
  625.           bottom++;
  626.           directx = 1;
  627.           directy = 0;
  628.         }
  629.       }
  630.     }
  631.   if (noc!=0)
  632.   {
  633.     sym.value1 = noc;
  634.     size_compressed += writeSyntaxElement2Buf_UVLC(&sym, bitstream);
  635.   }
  636.   ret = (size_compressed<size_uncompressed? TRUE : FALSE);
  637.   if ( !ret ) // overwrite the streambuffer with the original mb map
  638.   {
  639.     // write the mb map to payload bit by bit
  640.     bitstream->byte_buf = 0;
  641.     bitstream->bits_to_go = 8;
  642.     bitstream->byte_pos = 0;
  643.     for (j=0; j<img->height/16; j++)
  644.     {
  645.       for (k=0; k<img->width/16; k++)
  646.       {
  647.         bitstream->byte_buf <<= 1;
  648.         if (map_sp[j][k]) bitstream->byte_buf |= 1;
  649.         bitstream->bits_to_go--;
  650.         if (bitstream->bits_to_go==0)
  651.         {
  652.           bitstream->bits_to_go = 8;
  653.           bitstream->streamBuffer[bitstream->byte_pos++]=bitstream->byte_buf;
  654.           bitstream->byte_buf = 0;
  655.         }
  656.       }
  657.     }
  658.   }
  659.   return ret;
  660. }
  661. /*!
  662.  ************************************************************************
  663.  *  brief
  664.  *      Finalize the spare picture SEI payload.
  665.  *        The spare picture paylaod will be ready for encapsulation, and it
  666.  *        should be called before current picture packetized.
  667.  *  par Input
  668.  *      seiSparePicturePayload.data: points to the payload starting from
  669.  *        delta_spare_frame_num. (See FCD)
  670.  *  par Output
  671.  *      seiSparePicturePayload.data is updated, pointing to the whole spare
  672.  *        picture information: spare_picture( PayloadSize ) (See FCD)
  673.  *        Make sure it is byte aligned.
  674.  ************************************************************************
  675.  */
  676. void FinalizeSpareMBMap()
  677. {
  678.   int CurrFrameNum = img->number % MAX_FN;
  679.   int delta_frame_num;
  680.   SyntaxElement sym;
  681.   Bitstream *dest, *source;
  682.   sym.type = SE_HEADER;
  683.   sym.mapping = ue_linfo;
  684.   source = seiSparePicturePayload.data;
  685.   dest = malloc(sizeof(Bitstream));
  686.   if ( dest == NULL ) no_mem_exit("FinalizeSpareMBMap: dest");
  687.   dest->streamBuffer = malloc(MAXRTPPAYLOADLEN);
  688.   if ( dest->streamBuffer == NULL ) no_mem_exit("FinalizeSpareMBMap: dest->streamBuffer");
  689.   dest->bits_to_go  = 8;
  690.   dest->byte_pos    = 0;
  691.   dest->byte_buf    = 0;
  692.   memset( dest->streamBuffer, 0, MAXRTPPAYLOADLEN);
  693.   //    delta_frame_num
  694.   delta_frame_num = CurrFrameNum - seiSparePicturePayload.target_frame_num;
  695.   if ( delta_frame_num < 0 ) delta_frame_num += MAX_FN;
  696.   sym.value1 = delta_frame_num;
  697.   writeSyntaxElement2Buf_UVLC(&sym, dest);
  698.   // num_spare_pics_minus1
  699.   sym.value1 = seiSparePicturePayload.num_spare_pics - 1;
  700.   writeSyntaxElement2Buf_UVLC(&sym, dest);
  701.   // copy the other bits
  702.   AppendTmpbits2Buf( dest, source);
  703.   // make sure the payload is byte aligned, stuff bits are 10..0
  704.   if ( dest->bits_to_go != 8 )
  705.   {
  706.     (dest->byte_buf) <<= 1;
  707.     dest->byte_buf |= 1;
  708.     dest->bits_to_go--;
  709.     if ( dest->bits_to_go != 0 ) (dest->byte_buf) <<= (dest->bits_to_go);
  710.     dest->bits_to_go = 8;
  711.     dest->streamBuffer[dest->byte_pos++]=dest->byte_buf;
  712.     dest->byte_buf = 0;
  713.   }
  714.   seiSparePicturePayload.payloadSize = dest->byte_pos;
  715.   // the payload is ready now
  716.   seiSparePicturePayload.data = dest;
  717.   free( source->streamBuffer );
  718.   free( source );
  719. }
  720. /*
  721.  **++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  722.  *  functions on subseq information sei messages
  723.  *  brief
  724.  *      JVT-D098
  725.  *  author
  726.  *      Dong Tian                 <tian@cs.tut.fi>
  727.  **++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  728.  */
  729. Boolean seiHasSubseqInfo = FALSE;
  730. subseq_information_struct seiSubseqInfo[MAX_LAYER_NUMBER];
  731. /*!
  732.  ************************************************************************
  733.  *  brief
  734.  *      init subseqence info
  735.  ************************************************************************
  736.  */
  737. void InitSubseqInfo(int currLayer)
  738. {
  739.   static unsigned short id = 0;
  740.   seiHasSubseqInfo = TRUE;
  741.   seiSubseqInfo[currLayer].subseq_layer_num = currLayer;
  742.   seiSubseqInfo[currLayer].subseq_id = id++;
  743.   seiSubseqInfo[currLayer].last_picture_flag = 0;
  744.   seiSubseqInfo[currLayer].stored_frame_cnt = -1;
  745.   seiSubseqInfo[currLayer].payloadSize = 0;
  746.   seiSubseqInfo[currLayer].data = malloc( sizeof(Bitstream) );
  747.   if ( seiSubseqInfo[currLayer].data == NULL ) no_mem_exit("InitSubseqInfo: seiSubseqInfo[currLayer].data");
  748.   seiSubseqInfo[currLayer].data->streamBuffer = malloc( MAXRTPPAYLOADLEN );
  749.   if ( seiSubseqInfo[currLayer].data->streamBuffer == NULL ) no_mem_exit("InitSubseqInfo: seiSubseqInfo[currLayer].data->streamBuffer");
  750.   seiSubseqInfo[currLayer].data->bits_to_go  = 8;
  751.   seiSubseqInfo[currLayer].data->byte_pos    = 0;
  752.   seiSubseqInfo[currLayer].data->byte_buf    = 0;
  753.   memset( seiSubseqInfo[currLayer].data->streamBuffer, 0, MAXRTPPAYLOADLEN );
  754. }
  755. /*!
  756.  ************************************************************************
  757.  *  brief
  758.  *      update subsequence info
  759.  ************************************************************************
  760.  */
  761. void UpdateSubseqInfo(int currLayer)
  762. {
  763.   if (img->type != B_SLICE)
  764.   {
  765.     seiSubseqInfo[currLayer].stored_frame_cnt ++;
  766.     seiSubseqInfo[currLayer].stored_frame_cnt = seiSubseqInfo[currLayer].stored_frame_cnt % MAX_FN;
  767.   }
  768.   if ( currLayer == 0 )
  769.   {
  770.     if ( img->number == params->no_frames - 1 )
  771.       seiSubseqInfo[currLayer].last_picture_flag = 1;
  772.     else
  773.       seiSubseqInfo[currLayer].last_picture_flag = 0;
  774.   }
  775.   if ( currLayer == 1 )
  776.   {
  777.     if ( ((IMG_NUMBER%(params->NumFramesInELSubSeq + 1) == 0) && (params->successive_Bframe != 0) && (IMG_NUMBER>0)) || // there are B frames
  778.       ((IMG_NUMBER%(params->NumFramesInELSubSeq + 1) == params->NumFramesInELSubSeq) && (params->successive_Bframe==0))  // there are no B frames
  779.       )
  780.       seiSubseqInfo[currLayer].last_picture_flag = 1;
  781.     else
  782.       seiSubseqInfo[currLayer].last_picture_flag = 0;
  783.   }
  784. }
  785. /*!
  786.  ************************************************************************
  787.  *  brief
  788.  *      Finalize subseqence info
  789.  ************************************************************************
  790.  */
  791. void FinalizeSubseqInfo(int currLayer)
  792. {
  793.   SyntaxElement sym;
  794.   Bitstream *dest = seiSubseqInfo[currLayer].data;
  795.   sym.type = SE_HEADER;
  796.   sym.mapping = ue_linfo;
  797.   sym.value1 = seiSubseqInfo[currLayer].subseq_layer_num;
  798.   writeSyntaxElement2Buf_UVLC(&sym, dest);
  799.   sym.value1 = seiSubseqInfo[currLayer].subseq_id;
  800.   writeSyntaxElement2Buf_UVLC(&sym, dest);
  801.   sym.bitpattern = seiSubseqInfo[currLayer].last_picture_flag;
  802.   sym.len = 1;
  803.   writeSyntaxElement2Buf_Fixed(&sym, dest);
  804.   sym.value1 = seiSubseqInfo[currLayer].stored_frame_cnt;
  805.   writeSyntaxElement2Buf_UVLC(&sym, dest);
  806.   // make sure the payload is byte aligned, stuff bits are 10..0
  807.   if ( dest->bits_to_go != 8 )
  808.   {
  809.     (dest->byte_buf) <<= 1;
  810.     dest->byte_buf |= 1;
  811.     dest->bits_to_go--;
  812.     if ( dest->bits_to_go != 0 ) (dest->byte_buf) <<= (dest->bits_to_go);
  813.     dest->bits_to_go = 8;
  814.     dest->streamBuffer[dest->byte_pos++]=dest->byte_buf;
  815.     dest->byte_buf = 0;
  816.   }
  817.   seiSubseqInfo[currLayer].payloadSize = dest->byte_pos;
  818. //  printf("layer %d, last picture %d, stored_cnt %dn", currLayer, seiSubseqInfo[currLayer].last_picture_flag, seiSubseqInfo[currLayer].stored_frame_cnt );
  819. }
  820. /*!
  821.  ************************************************************************
  822.  *  brief
  823.  *      Clear the payload buffer
  824.  ************************************************************************
  825.  */
  826. void ClearSubseqInfoPayload(int currLayer)
  827. {
  828.   seiSubseqInfo[currLayer].data->bits_to_go  = 8;
  829.   seiSubseqInfo[currLayer].data->byte_pos    = 0;
  830.   seiSubseqInfo[currLayer].data->byte_buf    = 0;
  831.   memset( seiSubseqInfo[currLayer].data->streamBuffer, 0, MAXRTPPAYLOADLEN );
  832.   seiSubseqInfo[currLayer].payloadSize = 0;
  833. }
  834. /*!
  835.  ************************************************************************
  836.  *  brief
  837.  *      Close the global variables for spare picture information
  838.  ************************************************************************
  839.  */
  840. void CloseSubseqInfo(int currLayer)
  841. {
  842.   seiSubseqInfo[currLayer].stored_frame_cnt = -1;
  843.   seiSubseqInfo[currLayer].payloadSize = 0;
  844.   free( seiSubseqInfo[currLayer].data->streamBuffer );
  845.   free( seiSubseqInfo[currLayer].data );
  846. }
  847. /*
  848.  **++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  849.  *  functions on subseq layer characteristic sei messages
  850.  *  brief
  851.  *      JVT-D098
  852.  *  author
  853.  *      Dong Tian                 <tian@cs.tut.fi>
  854.  **++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  855.  */
  856. Boolean seiHasSubseqLayerInfo = FALSE;
  857. subseq_layer_information_struct seiSubseqLayerInfo;
  858. /*!
  859.  ************************************************************************
  860.  *  brief
  861.  *      Init the global variables for spare picture information
  862.  ************************************************************************
  863.  */
  864. void InitSubseqLayerInfo()
  865. {
  866.   int i;
  867.   seiHasSubseqLayerInfo = TRUE;
  868.   seiSubseqLayerInfo.layer_number = 0;
  869.   for (i=0; i<MAX_LAYER_NUMBER; i++)
  870.   {
  871.     seiSubseqLayerInfo.bit_rate[i] = 0;
  872.     seiSubseqLayerInfo.frame_rate[i] = 0;
  873.     seiSubseqLayerInfo.layer_number++;
  874.   }
  875. }
  876. /*!
  877.  ************************************************************************
  878.  *  brief
  879.  *
  880.  ************************************************************************
  881.  */
  882. void CloseSubseqLayerInfo()
  883. {
  884. }
  885. /*!
  886.  ************************************************************************
  887.  *  brief
  888.  *      Write the data to buffer, which is byte aligned
  889.  ************************************************************************
  890.  */
  891. void FinalizeSubseqLayerInfo()
  892. {
  893.   int i, pos;
  894.   pos = 0;
  895.   seiSubseqLayerInfo.payloadSize = 0;
  896.   for (i=0; i<seiSubseqLayerInfo.layer_number; i++)
  897.   {
  898.     *((unsigned short*)&(seiSubseqLayerInfo.data[pos])) = seiSubseqLayerInfo.bit_rate[i];
  899.     pos += 2;
  900.     *((unsigned short*)&(seiSubseqLayerInfo.data[pos])) = seiSubseqLayerInfo.frame_rate[i];
  901.     pos += 2;
  902.     seiSubseqLayerInfo.payloadSize += 4;
  903.   }
  904. }
  905. /*
  906.  **++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  907.  *  functions on subseq characteristic sei messages
  908.  *  brief
  909.  *      JVT-D098
  910.  *  author
  911.  *      Dong Tian                 <tian@cs.tut.fi>
  912.  **++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  913.  */
  914. Boolean seiHasSubseqChar = FALSE;
  915. subseq_char_information_struct seiSubseqChar;
  916. void InitSubseqChar()
  917. {
  918.   seiSubseqChar.data = malloc( sizeof(Bitstream) );
  919.   if( seiSubseqChar.data == NULL ) no_mem_exit("InitSubseqChar: seiSubseqChar.data");
  920.   seiSubseqChar.data->streamBuffer = malloc(MAXRTPPAYLOADLEN);
  921.   if( seiSubseqChar.data->streamBuffer == NULL ) no_mem_exit("InitSubseqChar: seiSubseqChar.data->streamBuffer");
  922.   ClearSubseqCharPayload();
  923.   seiSubseqChar.subseq_layer_num = img->layer;
  924.   seiSubseqChar.subseq_id = seiSubseqInfo[img->layer].subseq_id;
  925.   seiSubseqChar.duration_flag = 0;
  926.   seiSubseqChar.average_rate_flag = 0;
  927.   seiSubseqChar.num_referenced_subseqs = 0;
  928. }
  929. void ClearSubseqCharPayload()
  930. {
  931.   memset( seiSubseqChar.data->streamBuffer, 0, MAXRTPPAYLOADLEN);
  932.   seiSubseqChar.data->bits_to_go  = 8;
  933.   seiSubseqChar.data->byte_pos    = 0;
  934.   seiSubseqChar.data->byte_buf    = 0;
  935.   seiSubseqChar.payloadSize       = 0;
  936.   seiHasSubseqChar = FALSE;
  937. }
  938. void UpdateSubseqChar()
  939. {
  940.   seiSubseqChar.subseq_layer_num = img->layer;
  941.   seiSubseqChar.subseq_id = seiSubseqInfo[img->layer].subseq_id;
  942.   seiSubseqChar.duration_flag = 0;
  943.   seiSubseqChar.average_rate_flag = 0;
  944.   seiSubseqChar.average_bit_rate = 100;
  945.   seiSubseqChar.average_frame_rate = 30;
  946.   seiSubseqChar.num_referenced_subseqs = 0;
  947.   seiSubseqChar.ref_subseq_layer_num[0] = 1;
  948.   seiSubseqChar.ref_subseq_id[0] = 2;
  949.   seiSubseqChar.ref_subseq_layer_num[1] = 3;
  950.   seiSubseqChar.ref_subseq_id[1] = 4;
  951.   seiHasSubseqChar = TRUE;
  952. }
  953. void FinalizeSubseqChar()
  954. {
  955.   int i;
  956.   SyntaxElement sym;
  957.   Bitstream *dest = seiSubseqChar.data;
  958.   sym.type = SE_HEADER;
  959.   sym.mapping = ue_linfo;
  960.   sym.value1 = seiSubseqChar.subseq_layer_num;
  961.   writeSyntaxElement2Buf_UVLC(&sym, dest);
  962.   sym.value1 = seiSubseqChar.subseq_id;
  963.   writeSyntaxElement2Buf_UVLC(&sym, dest);
  964.   sym.bitpattern = seiSubseqChar.duration_flag;
  965.   sym.len = 1;
  966.   writeSyntaxElement2Buf_Fixed(&sym, dest);
  967.   if ( seiSubseqChar.duration_flag )
  968.   {
  969.     sym.bitpattern = seiSubseqChar.subseq_duration;
  970.     sym.len = 32;
  971.     writeSyntaxElement2Buf_Fixed(&sym, dest);
  972.   }
  973.   sym.bitpattern = seiSubseqChar.average_rate_flag;
  974.   sym.len = 1;
  975.   writeSyntaxElement2Buf_Fixed(&sym, dest);
  976.   if ( seiSubseqChar.average_rate_flag )
  977.   {
  978.     sym.bitpattern = seiSubseqChar.average_bit_rate;
  979.     sym.len = 16;
  980.     writeSyntaxElement2Buf_Fixed(&sym, dest);
  981.     sym.bitpattern = seiSubseqChar.average_frame_rate;
  982.     sym.len = 16;
  983.     writeSyntaxElement2Buf_Fixed(&sym, dest);
  984.   }
  985.   sym.value1 = seiSubseqChar.num_referenced_subseqs;
  986.   writeSyntaxElement2Buf_UVLC(&sym, dest);
  987.   for (i=0; i<seiSubseqChar.num_referenced_subseqs; i++)
  988.   {
  989.     sym.value1 = seiSubseqChar.ref_subseq_layer_num[i];
  990.     writeSyntaxElement2Buf_UVLC(&sym, dest);
  991.     sym.value1 = seiSubseqChar.ref_subseq_id[i];
  992.     writeSyntaxElement2Buf_UVLC(&sym, dest);
  993.   }
  994.   // make sure the payload is byte aligned, stuff bits are 10..0
  995.   if ( dest->bits_to_go != 8 )
  996.   {
  997.     (dest->byte_buf) <<= 1;
  998.     dest->byte_buf |= 1;
  999.     dest->bits_to_go--;
  1000.     if ( dest->bits_to_go != 0 ) (dest->byte_buf) <<= (dest->bits_to_go);
  1001.     dest->bits_to_go = 8;
  1002.     dest->streamBuffer[dest->byte_pos++]=dest->byte_buf;
  1003.     dest->byte_buf = 0;
  1004.   }
  1005.   seiSubseqChar.payloadSize = dest->byte_pos;
  1006. }
  1007. void CloseSubseqChar()
  1008. {
  1009.   if (seiSubseqChar.data)
  1010.   {
  1011.     free(seiSubseqChar.data->streamBuffer);
  1012.     free(seiSubseqChar.data);
  1013.   }
  1014.   seiSubseqChar.data = NULL;
  1015. }
  1016. // JVT-D099
  1017. /*
  1018.  **++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  1019.  *  functions on scene information SEI message
  1020.  *  brief
  1021.  *      JVT-D099
  1022.  *  author
  1023.  *      Ye-Kui Wang                 <wyk@ieee.org>
  1024.  **++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  1025.  */
  1026. scene_information_struct seiSceneInformation;
  1027. void InitSceneInformation()
  1028. {
  1029.   seiHasSceneInformation = TRUE;
  1030.   seiSceneInformation.scene_id = 0;
  1031.   seiSceneInformation.scene_transition_type = 0;
  1032.   seiSceneInformation.second_scene_id = -1;
  1033.   seiSceneInformation.data = malloc( sizeof(Bitstream) );
  1034.   if( seiSceneInformation.data == NULL ) no_mem_exit("InitSceneInformation: seiSceneInformation.data");
  1035.   seiSceneInformation.data->streamBuffer = malloc( MAXRTPPAYLOADLEN );
  1036.   if( seiSceneInformation.data->streamBuffer == NULL ) no_mem_exit("InitSceneInformation: seiSceneInformation.data->streamBuffer");
  1037.   seiSceneInformation.data->bits_to_go  = 8;
  1038.   seiSceneInformation.data->byte_pos    = 0;
  1039.   seiSceneInformation.data->byte_buf    = 0;
  1040.   memset( seiSceneInformation.data->streamBuffer, 0, MAXRTPPAYLOADLEN );
  1041. }
  1042. void CloseSceneInformation()
  1043. {
  1044.   if (seiSceneInformation.data)
  1045.   {
  1046.     free(seiSceneInformation.data->streamBuffer);
  1047.     free(seiSceneInformation.data);
  1048.   }
  1049.   seiSceneInformation.data = NULL;
  1050. }
  1051. void FinalizeSceneInformation()
  1052. {
  1053.   SyntaxElement sym;
  1054.   Bitstream *dest = seiSceneInformation.data;
  1055.   sym.type = SE_HEADER;
  1056.   sym.mapping = ue_linfo;
  1057.   sym.bitpattern = seiSceneInformation.scene_id;
  1058.   sym.len = 8;
  1059.   writeSyntaxElement2Buf_Fixed(&sym, dest);
  1060.   sym.value1 = seiSceneInformation.scene_transition_type;
  1061.   writeSyntaxElement2Buf_UVLC(&sym, dest);
  1062.   if(seiSceneInformation.scene_transition_type > 3)
  1063.   {
  1064.     sym.bitpattern = seiSceneInformation.second_scene_id;
  1065.     sym.len = 8;
  1066.     writeSyntaxElement2Buf_Fixed(&sym, dest);
  1067.   }
  1068.   // make sure the payload is byte aligned, stuff bits are 10..0
  1069.   if ( dest->bits_to_go != 8 )
  1070.   {
  1071.     (dest->byte_buf) <<= 1;
  1072.     dest->byte_buf |= 1;
  1073.     dest->bits_to_go--;
  1074.     if ( dest->bits_to_go != 0 ) (dest->byte_buf) <<= (dest->bits_to_go);
  1075.     dest->bits_to_go = 8;
  1076.     dest->streamBuffer[dest->byte_pos++]=dest->byte_buf;
  1077.     dest->byte_buf = 0;
  1078.   }
  1079.   seiSceneInformation.payloadSize = dest->byte_pos;
  1080. }
  1081. // HasSceneInformation: To include a scene information SEI into the next slice/DP,
  1082. //      set HasSceneInformation to be TRUE when calling this function. Otherwise,
  1083. //      set HasSceneInformation to be FALSE.
  1084. void UpdateSceneInformation(Boolean HasSceneInformation, int sceneID, int sceneTransType, int secondSceneID)
  1085. {
  1086.   seiHasSceneInformation = HasSceneInformation;
  1087.   assert (sceneID < 256);
  1088.   seiSceneInformation.scene_id = sceneID;
  1089.   assert (sceneTransType <= 6 );
  1090.   seiSceneInformation.scene_transition_type = sceneTransType;
  1091.   if(sceneTransType > 3)
  1092.   {
  1093.     assert (secondSceneID < 256);
  1094.     seiSceneInformation.second_scene_id = secondSceneID;
  1095.   }
  1096. }
  1097. // End JVT-D099
  1098. /*
  1099.  **++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  1100.  *  functions on Pan Scan messages
  1101.  *  brief
  1102.  *      Based on FCD
  1103.  *  author
  1104.  *      Shankar Regunathan                 <tian@cs.tut.fi>
  1105.  **++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  1106.  */
  1107. Boolean seiHasPanScanRectInfo = FALSE;
  1108. panscanrect_information_struct seiPanScanRectInfo;
  1109. void InitPanScanRectInfo()
  1110. {
  1111.   seiPanScanRectInfo.data = malloc( sizeof(Bitstream) );
  1112.   if( seiPanScanRectInfo.data == NULL ) no_mem_exit("InitPanScanRectInfo: seiPanScanRectInfo.data");
  1113.   seiPanScanRectInfo.data->streamBuffer = malloc(MAXRTPPAYLOADLEN);
  1114.   if( seiPanScanRectInfo.data->streamBuffer == NULL ) no_mem_exit("InitPanScanRectInfo: seiPanScanRectInfo.data->streamBuffer");
  1115.   ClearPanScanRectInfoPayload();
  1116.   seiPanScanRectInfo.pan_scan_rect_left_offset = 0;
  1117.   seiPanScanRectInfo.pan_scan_rect_right_offset = 0;
  1118.   seiPanScanRectInfo.pan_scan_rect_top_offset = 0;
  1119.   seiPanScanRectInfo.pan_scan_rect_bottom_offset = 0;
  1120. }
  1121. void ClearPanScanRectInfoPayload()
  1122. {
  1123.   memset( seiPanScanRectInfo.data->streamBuffer, 0, MAXRTPPAYLOADLEN);
  1124.   seiPanScanRectInfo.data->bits_to_go  = 8;
  1125.   seiPanScanRectInfo.data->byte_pos    = 0;
  1126.   seiPanScanRectInfo.data->byte_buf    = 0;
  1127.   seiPanScanRectInfo.payloadSize       = 0;
  1128.   seiHasPanScanRectInfo = FALSE;
  1129. }
  1130. void UpdatePanScanRectInfo()
  1131. {
  1132.   seiPanScanRectInfo.pan_scan_rect_id = 3;
  1133.   seiPanScanRectInfo.pan_scan_rect_left_offset = 10;
  1134.   seiPanScanRectInfo.pan_scan_rect_right_offset = 40;
  1135.   seiPanScanRectInfo.pan_scan_rect_top_offset = 20;
  1136.   seiPanScanRectInfo.pan_scan_rect_bottom_offset =32;
  1137.   seiHasPanScanRectInfo = TRUE;
  1138. }
  1139. void FinalizePanScanRectInfo()
  1140. {
  1141.   SyntaxElement sym;
  1142.   Bitstream *dest = seiPanScanRectInfo.data;
  1143.   sym.type = SE_HEADER;
  1144.   sym.mapping = ue_linfo;
  1145.   sym.value1 = seiPanScanRectInfo.pan_scan_rect_id;
  1146.   writeSyntaxElement2Buf_UVLC(&sym, dest);
  1147.   sym.value1 = seiPanScanRectInfo.pan_scan_rect_left_offset;
  1148.   writeSyntaxElement2Buf_UVLC(&sym, dest);
  1149.   sym.value1 = seiPanScanRectInfo.pan_scan_rect_right_offset;
  1150.   writeSyntaxElement2Buf_UVLC(&sym, dest);
  1151.   sym.value1 = seiPanScanRectInfo.pan_scan_rect_top_offset;
  1152.   writeSyntaxElement2Buf_UVLC(&sym, dest);
  1153.   sym.value1 = seiPanScanRectInfo.pan_scan_rect_bottom_offset;
  1154.   writeSyntaxElement2Buf_UVLC(&sym, dest);
  1155. // #define PRINT_PAN_SCAN_RECT
  1156. #ifdef PRINT_PAN_SCAN_RECT
  1157.   printf("Pan Scan Id %d Left %d Right %d Top %d Bottom %d n", seiPanScanRectInfo.pan_scan_rect_id, seiPanScanRectInfo.pan_scan_rect_left_offset, seiPanScanRectInfo.pan_scan_rect_right_offset, seiPanScanRectInfo.pan_scan_rect_top_offset, seiPanScanRectInfo.pan_scan_rect_bottom_offset);
  1158. #endif
  1159. #ifdef PRINT_PAN_SCAN_RECT
  1160. #undef PRINT_PAN_SCAN_RECT
  1161. #endif
  1162.   // make sure the payload is byte aligned, stuff bits are 10..0
  1163.   if ( dest->bits_to_go != 8 )
  1164.   {
  1165.     (dest->byte_buf) <<= 1;
  1166.     dest->byte_buf |= 1;
  1167.     dest->bits_to_go--;
  1168.     if ( dest->bits_to_go != 0 ) (dest->byte_buf) <<= (dest->bits_to_go);
  1169.     dest->bits_to_go = 8;
  1170.     dest->streamBuffer[dest->byte_pos++]=dest->byte_buf;
  1171.     dest->byte_buf = 0;
  1172.   }
  1173.   seiPanScanRectInfo.payloadSize = dest->byte_pos;
  1174. }
  1175. void ClosePanScanRectInfo()
  1176. {
  1177.   if (seiPanScanRectInfo.data)
  1178.   {
  1179.     free(seiPanScanRectInfo.data->streamBuffer);
  1180.     free(seiPanScanRectInfo.data);
  1181.   }
  1182.   seiPanScanRectInfo.data = NULL;
  1183. }
  1184. /*
  1185.  **++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  1186.  *  functions on arbitrary (unregistered) data
  1187.  *  brief
  1188.  *      Based on FCD
  1189.  *  author
  1190.  *      Shankar Regunathan                 <tian@cs.tut.fi>
  1191.  **++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  1192.  */
  1193. Boolean seiHasUser_data_unregistered_info;
  1194. user_data_unregistered_information_struct seiUser_data_unregistered;
  1195. void InitUser_data_unregistered()
  1196. {
  1197.   seiUser_data_unregistered.data = malloc( sizeof(Bitstream) );
  1198.   if( seiUser_data_unregistered.data == NULL ) no_mem_exit("InitUser_data_unregistered: seiUser_data_unregistered.data");
  1199.   seiUser_data_unregistered.data->streamBuffer = malloc(MAXRTPPAYLOADLEN);
  1200.   if( seiUser_data_unregistered.data->streamBuffer == NULL ) no_mem_exit("InitUser_data_unregistered: seiUser_data_unregistered.data->streamBuffer");
  1201.   seiUser_data_unregistered.byte = malloc(MAXRTPPAYLOADLEN);
  1202.   if( seiUser_data_unregistered.byte == NULL ) no_mem_exit("InitUser_data_unregistered: seiUser_data_unregistered.byte");
  1203.   ClearUser_data_unregistered();
  1204. }
  1205. void ClearUser_data_unregistered()
  1206. {
  1207.   memset( seiUser_data_unregistered.data->streamBuffer, 0, MAXRTPPAYLOADLEN);
  1208.   seiUser_data_unregistered.data->bits_to_go  = 8;
  1209.   seiUser_data_unregistered.data->byte_pos    = 0;
  1210.   seiUser_data_unregistered.data->byte_buf    = 0;
  1211.   seiUser_data_unregistered.payloadSize       = 0;
  1212.   memset( seiUser_data_unregistered.byte, 0, MAXRTPPAYLOADLEN);
  1213.   seiUser_data_unregistered.total_byte = 0;
  1214.   seiHasUser_data_unregistered_info = FALSE;
  1215. }
  1216. void UpdateUser_data_unregistered()
  1217. {
  1218.   int i, temp_data;
  1219.   int total_byte;
  1220.   total_byte = 7;
  1221.   for(i = 0; i < total_byte; i++)
  1222.   {
  1223.     temp_data = i * 4;
  1224.     seiUser_data_unregistered.byte[i] = (char) iClip3(0, 255, temp_data);
  1225.   }
  1226.   seiUser_data_unregistered.total_byte = total_byte;
  1227. }
  1228. void FinalizeUser_data_unregistered()
  1229. {
  1230.   int i;
  1231.   SyntaxElement sym;
  1232.   Bitstream *dest = seiUser_data_unregistered.data;
  1233.   sym.type = SE_HEADER;
  1234.   sym.mapping = ue_linfo;
  1235. // #define PRINT_USER_DATA_UNREGISTERED_INFO
  1236.   for( i = 0; i < seiUser_data_unregistered.total_byte; i++)
  1237.   {
  1238.     sym.bitpattern = seiUser_data_unregistered.byte[i];
  1239.     sym.len = 8; // b (8)
  1240.     writeSyntaxElement2Buf_Fixed(&sym, dest);
  1241. #ifdef PRINT_USER_DATA_UNREGISTERED_INFO
  1242.     printf("Unreg data payload_byte = %dn", seiUser_data_unregistered.byte[i]);
  1243. #endif
  1244.   }
  1245. #ifdef PRINT_USER_DATA_UNREGISTERED_INFO
  1246. #undef PRINT_USER_DATA_UNREGISTERED_INFO
  1247. #endif
  1248.   // make sure the payload is byte aligned, stuff bits are 10..0
  1249.   if ( dest->bits_to_go != 8 )
  1250.   {
  1251.     (dest->byte_buf) <<= 1;
  1252.     dest->byte_buf |= 1;
  1253.     dest->bits_to_go--;
  1254.     if ( dest->bits_to_go != 0 ) (dest->byte_buf) <<= (dest->bits_to_go);
  1255.     dest->bits_to_go = 8;
  1256.     dest->streamBuffer[dest->byte_pos++]=dest->byte_buf;
  1257.     dest->byte_buf = 0;
  1258.   }
  1259.   seiUser_data_unregistered.payloadSize = dest->byte_pos;
  1260. }
  1261. void CloseUser_data_unregistered()
  1262. {
  1263.   if (seiUser_data_unregistered.data)
  1264.   {
  1265.     free(seiUser_data_unregistered.data->streamBuffer);
  1266.     free(seiUser_data_unregistered.data);
  1267.   }
  1268.   seiUser_data_unregistered.data = NULL;
  1269.   if(seiUser_data_unregistered.byte)
  1270.   {
  1271.     free(seiUser_data_unregistered.byte);
  1272.   }
  1273. }
  1274. /*
  1275.  **++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  1276.  *  functions on registered ITU_T_T35 user data
  1277.  *  brief
  1278.  *      Based on FCD
  1279.  *  author
  1280.  *      Shankar Regunathan                 <tian@cs.tut.fi>
  1281.  **++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  1282.  */
  1283. Boolean seiHasUser_data_registered_itu_t_t35_info;
  1284. user_data_registered_itu_t_t35_information_struct seiUser_data_registered_itu_t_t35;
  1285. void InitUser_data_registered_itu_t_t35()
  1286. {
  1287.   seiUser_data_registered_itu_t_t35.data = malloc( sizeof(Bitstream) );
  1288.   if( seiUser_data_registered_itu_t_t35.data == NULL ) no_mem_exit("InitUser_data_unregistered: seiUser_data_registered_itu_t_t35.data");
  1289.   seiUser_data_registered_itu_t_t35.data->streamBuffer = malloc(MAXRTPPAYLOADLEN);
  1290.   if( seiUser_data_registered_itu_t_t35.data->streamBuffer == NULL ) no_mem_exit("InitUser_data_unregistered: seiUser_data_registered_itu_t_t35.data->streamBuffer");
  1291.   seiUser_data_registered_itu_t_t35.byte = malloc(MAXRTPPAYLOADLEN);
  1292.   if( seiUser_data_registered_itu_t_t35.data == NULL ) no_mem_exit("InitUser_data_unregistered: seiUser_data_registered_itu_t_t35.byte");
  1293.   ClearUser_data_registered_itu_t_t35();
  1294. }
  1295. void ClearUser_data_registered_itu_t_t35()
  1296. {
  1297.   memset( seiUser_data_registered_itu_t_t35.data->streamBuffer, 0, MAXRTPPAYLOADLEN);
  1298.   seiUser_data_registered_itu_t_t35.data->bits_to_go  = 8;
  1299.   seiUser_data_registered_itu_t_t35.data->byte_pos    = 0;
  1300.   seiUser_data_registered_itu_t_t35.data->byte_buf    = 0;
  1301.   seiUser_data_registered_itu_t_t35.payloadSize       = 0;
  1302.   memset( seiUser_data_registered_itu_t_t35.byte, 0, MAXRTPPAYLOADLEN);
  1303.   seiUser_data_registered_itu_t_t35.total_byte = 0;
  1304.   seiUser_data_registered_itu_t_t35.itu_t_t35_country_code = 0;
  1305.   seiUser_data_registered_itu_t_t35.itu_t_t35_country_code_extension_byte = 0;
  1306.   seiHasUser_data_registered_itu_t_t35_info = FALSE;
  1307. }
  1308. void UpdateUser_data_registered_itu_t_t35()
  1309. {
  1310.   int i, temp_data;
  1311.   int total_byte;
  1312.   int country_code;
  1313.   country_code = 82; // Country_code for India
  1314.   if(country_code < 0xFF)
  1315.   {
  1316.     seiUser_data_registered_itu_t_t35.itu_t_t35_country_code = country_code;
  1317.   }
  1318.   else
  1319.   {
  1320.     seiUser_data_registered_itu_t_t35.itu_t_t35_country_code = 0xFF;
  1321.     seiUser_data_registered_itu_t_t35.itu_t_t35_country_code_extension_byte = country_code - 0xFF;
  1322.   }
  1323.   total_byte = 7;
  1324.   for(i = 0; i < total_byte; i++)
  1325.   {
  1326.     temp_data = i * 3;
  1327.     seiUser_data_registered_itu_t_t35.byte[i] = (char) iClip3(0, 255, temp_data);
  1328.   }
  1329.   seiUser_data_registered_itu_t_t35.total_byte = total_byte;
  1330. }
  1331. void FinalizeUser_data_registered_itu_t_t35()
  1332. {
  1333.   int i;
  1334.   SyntaxElement sym;
  1335.   Bitstream *dest = seiUser_data_registered_itu_t_t35.data;
  1336.   sym.type = SE_HEADER;
  1337.   sym.mapping = ue_linfo;
  1338.   sym.bitpattern = seiUser_data_registered_itu_t_t35.itu_t_t35_country_code;
  1339.   sym.len = 8;
  1340.   writeSyntaxElement2Buf_Fixed(&sym, dest);
  1341. // #define PRINT_USER_DATA_REGISTERED_ITU_T_T35_INFO
  1342. #ifdef PRINT_USER_DATA_REGISTERED_ITU_T_T35_INFO
  1343.   printf(" ITU_T_T35_COUNTRTY_CODE %d n", seiUser_data_registered_itu_t_t35.itu_t_t35_country_code);
  1344. #endif
  1345.   if(seiUser_data_registered_itu_t_t35.itu_t_t35_country_code == 0xFF)
  1346.   {
  1347.     sym.bitpattern = seiUser_data_registered_itu_t_t35.itu_t_t35_country_code_extension_byte;
  1348.     sym.len = 8;
  1349.     writeSyntaxElement2Buf_Fixed(&sym, dest);
  1350. #ifdef PRINT_USER_DATA_REGISTERED_ITU_T_T35_INFO
  1351.     printf(" ITU_T_T35_COUNTRTY_CODE_EXTENSION_BYTE %d n", seiUser_data_registered_itu_t_t35.itu_t_t35_country_code_extension_byte);
  1352. #endif
  1353.   }
  1354.   for( i = 0; i < seiUser_data_registered_itu_t_t35.total_byte; i++)
  1355.   {
  1356.     sym.bitpattern = seiUser_data_registered_itu_t_t35.byte[i];
  1357.     sym.len = 8; // b (8)
  1358.     writeSyntaxElement2Buf_Fixed(&sym, dest);
  1359. #ifdef PRINT_USER_DATA_REGISTERED_ITU_T_T35_INFO
  1360.     printf("itu_t_t35 payload_byte = %dn", seiUser_data_registered_itu_t_t35.byte[i]);
  1361. #endif
  1362.   }
  1363. #ifdef PRINT_USER_DATA_REGISTERED_ITU_T_T35_INFO
  1364. #undef PRINT_USER_DATA_REGISTERED_ITU_T_T35_INFO
  1365. #endif
  1366.   // make sure the payload is byte aligned, stuff bits are 10..0
  1367.   if ( dest->bits_to_go != 8 )
  1368.   {
  1369.     (dest->byte_buf) <<= 1;
  1370.     dest->byte_buf |= 1;
  1371.     dest->bits_to_go--;
  1372.     if ( dest->bits_to_go != 0 ) (dest->byte_buf) <<= (dest->bits_to_go);
  1373.     dest->bits_to_go = 8;
  1374.     dest->streamBuffer[dest->byte_pos++]=dest->byte_buf;
  1375.     dest->byte_buf = 0;
  1376.   }
  1377.   seiUser_data_registered_itu_t_t35.payloadSize = dest->byte_pos;
  1378. }
  1379. void CloseUser_data_registered_itu_t_t35()
  1380. {
  1381.   if (seiUser_data_registered_itu_t_t35.data)
  1382.   {
  1383.     free(seiUser_data_registered_itu_t_t35.data->streamBuffer);
  1384.     free(seiUser_data_registered_itu_t_t35.data);
  1385.   }
  1386.   seiUser_data_registered_itu_t_t35.data = NULL;
  1387.   if(seiUser_data_registered_itu_t_t35.byte)
  1388.   {
  1389.     free(seiUser_data_registered_itu_t_t35.byte);
  1390.   }
  1391. }
  1392. /*
  1393.  **++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  1394.  *  functions on random access message
  1395.  *  brief
  1396.  *      Based on FCD
  1397.  *  author
  1398.  *      Shankar Regunathan                 <tian@cs.tut.fi>
  1399.  **++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  1400.  */
  1401. recovery_point_information_struct seiRecoveryPoint;
  1402. void InitRandomAccess()
  1403. {
  1404.   seiRecoveryPoint.data = malloc( sizeof(Bitstream) );
  1405.   if( seiRecoveryPoint.data == NULL ) no_mem_exit("InitRandomAccess: seiRandomAccess.data");
  1406.   seiRecoveryPoint.data->streamBuffer = malloc(MAXRTPPAYLOADLEN);
  1407.   if( seiRecoveryPoint.data->streamBuffer == NULL ) no_mem_exit("InitRandomAccess: seiRandomAccess.data->streamBuffer");
  1408.   ClearRandomAccess();
  1409. }
  1410. void ClearRandomAccess()
  1411. {
  1412.   memset( seiRecoveryPoint.data->streamBuffer, 0, MAXRTPPAYLOADLEN);
  1413.   seiRecoveryPoint.data->bits_to_go  = 8;
  1414.   seiRecoveryPoint.data->byte_pos    = 0;
  1415.   seiRecoveryPoint.data->byte_buf    = 0;
  1416.   seiRecoveryPoint.payloadSize       = 0;
  1417.   seiRecoveryPoint.recovery_frame_cnt = 0;
  1418.   seiRecoveryPoint.broken_link_flag = 0;
  1419.   seiRecoveryPoint.exact_match_flag = 0;
  1420.   seiHasRecoveryPoint_info = FALSE;
  1421. }
  1422. void UpdateRandomAccess()
  1423. {
  1424.   if(img->type == I_SLICE)
  1425.   {
  1426.     seiRecoveryPoint.recovery_frame_cnt = 0;
  1427.     seiRecoveryPoint.exact_match_flag = 1;
  1428.     seiRecoveryPoint.broken_link_flag = 0;
  1429.     seiHasRecoveryPoint_info = TRUE;
  1430.   }
  1431.   else
  1432.   {
  1433.     seiHasRecoveryPoint_info = FALSE;
  1434.   }
  1435. }
  1436. void FinalizeRandomAccess()
  1437. {
  1438.   Bitstream *bitstream = seiRecoveryPoint.data;
  1439.   ue_v(   "SEI: recovery_frame_cnt",       seiRecoveryPoint.recovery_frame_cnt,       bitstream);
  1440.   u_1 (   "SEI: exact_match_flag",         seiRecoveryPoint.exact_match_flag,         bitstream);
  1441.   u_1 (   "SEI: broken_link_flag",         seiRecoveryPoint.broken_link_flag,         bitstream);
  1442.   u_v (2, "SEI: changing_slice_group_idc", seiRecoveryPoint.changing_slice_group_idc, bitstream);
  1443. // #define PRINT_RECOVERY_POINT
  1444. #ifdef PRINT_RECOVERY_POINT
  1445.   printf(" recovery_frame_cnt %d n",       seiRecoveryPoint.recovery_frame_cnt);
  1446.   printf(" exact_match_flag %d n",         seiRecoveryPoint.exact_match_flag);
  1447.   printf(" broken_link_flag %d n",         seiRecoveryPoint.broken_link_flag);
  1448.   printf(" changing_slice_group_idc %d n", seiRecoveryPoint.changing_slice_group_idc);
  1449.   printf(" %d %d n", bitstream->byte_pos, bitstream->bits_to_go);
  1450. #undef PRINT_RECOVERY_POINT
  1451. #endif
  1452.   // make sure the payload is byte aligned, stuff bits are 10..0
  1453.   if ( bitstream->bits_to_go != 8 )
  1454.   {
  1455.     (bitstream->byte_buf) <<= 1;
  1456.     bitstream->byte_buf |= 1;
  1457.     bitstream->bits_to_go--;
  1458.     if ( bitstream->bits_to_go != 0 )
  1459.       (bitstream->byte_buf) <<= (bitstream->bits_to_go);
  1460.     bitstream->bits_to_go = 8;
  1461.     bitstream->streamBuffer[bitstream->byte_pos++]=bitstream->byte_buf;
  1462.     bitstream->byte_buf = 0;
  1463.   }
  1464.   seiRecoveryPoint.payloadSize = bitstream->byte_pos;
  1465. }
  1466. void CloseRandomAccess()
  1467. {
  1468.   if (seiRecoveryPoint.data)
  1469.   {
  1470.     free(seiRecoveryPoint.data->streamBuffer);
  1471.     free(seiRecoveryPoint.data);
  1472.   }
  1473.   seiRecoveryPoint.data = NULL;
  1474. }
  1475. /*
  1476.  **++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  1477.  *  functions on HDR tone-mapping messages
  1478.  *  brief
  1479.  *      Based on JVT-T060
  1480.  *  author
  1481.  *      Jane Zhao, sharp labs of america
  1482.  **++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  1483.  */
  1484. tone_mapping_struct seiToneMapping;
  1485. int ParseToneMappingConfigFile(tone_mapping_struct* pSeiToneMapping)
  1486. {
  1487.   int i;
  1488.   FILE* fp;
  1489.   char buf[1024];
  1490.   unsigned int tmp;
  1491.   printf ("Parsing Tone mapping cfg file %s ..........nn", params->ToneMappingFile);
  1492.   if ((fp = fopen(params->ToneMappingFile, "r")) == NULL) 
  1493.   {
  1494.     fprintf(stderr, "Tone mapping config file %s is not found, disable tone mapping SEIn", params->ToneMappingFile);
  1495.     seiHasTone_mapping=FALSE;
  1496.     return 1;
  1497.   }
  1498.   //read the tone mapping config file
  1499.   while (fscanf(fp, "%s", buf)!=EOF) 
  1500.   {
  1501.     if (strcmp(buf, "tone_map_id")==0) 
  1502.     {
  1503.       fscanf(fp, " = %udn", &(pSeiToneMapping->tone_map_id));
  1504.     }
  1505.     else if (strcmp(buf, "tone_map_cancel_flag")==0) 
  1506.     {
  1507.       fscanf(fp, " = %udn", &tmp);
  1508.       pSeiToneMapping->tone_map_cancel_flag = tmp ? 1 : 0;
  1509.     }
  1510.     else if (strcmp(buf, "tone_map_repetition_period")==0) 
  1511.     {
  1512.       fscanf(fp, " = %udn", &(pSeiToneMapping->tone_map_repetition_period));
  1513.     }
  1514.     else if (strcmp(buf, "coded_data_bit_depth")==0) 
  1515.     {
  1516.       fscanf(fp, " = %udn", &tmp);
  1517.       pSeiToneMapping->coded_data_bit_depth = (unsigned char) tmp;
  1518.     }
  1519.     else if (strcmp(buf, "sei_bit_depth")==0) 
  1520.     {
  1521.       fscanf(fp, " = %udn", &tmp);
  1522.       pSeiToneMapping->sei_bit_depth =  (unsigned char) tmp;
  1523.     }
  1524.     else if (strcmp(buf, "model_id")==0) 
  1525.     {
  1526.       fscanf(fp, " = %udn", &(pSeiToneMapping->model_id));
  1527.     }
  1528.     //else if (model_id ==0) 
  1529.     else if (strcmp(buf, "min_value")==0) 
  1530.     {
  1531.       fscanf(fp, " = %dn", &(pSeiToneMapping->min_value));
  1532.     }
  1533.     else if (strcmp(buf, "max_value")==0) 
  1534.     {
  1535.       fscanf(fp, " = %dn", &(pSeiToneMapping->max_value));
  1536.     }
  1537.     //(model_id == 1)
  1538.     else if (strcmp(buf, "sigmoid_midpoint")==0) 
  1539.     {
  1540.       fscanf(fp, " = %dn", &(pSeiToneMapping->sigmoid_midpoint));
  1541.     }
  1542.     else if (strcmp(buf, "sigmoid_width")==0) 
  1543.     {
  1544.       fscanf(fp, " = %dn", &(pSeiToneMapping->sigmoid_width));
  1545.     }
  1546.     // (model_id == 2) 
  1547.     else if (strcmp(buf, "start_of_coded_interval")==0) 
  1548.     {
  1549.       int max_output_num = 1<<(pSeiToneMapping->sei_bit_depth);
  1550.       fscanf(fp, " = ");
  1551.       for (i=0; i < max_output_num; i++)
  1552.         fscanf(fp, "%dn", &(pSeiToneMapping->start_of_coded_interval[i]));
  1553.     }
  1554.     //(model_id == 3)
  1555.     else if (strcmp(buf, "num_pivots")==0) 
  1556.     {
  1557.       fscanf(fp, " = %dn", &(pSeiToneMapping->num_pivots));
  1558.     }
  1559.     else if (strcmp(buf, "coded_pivot_value")==0) 
  1560.     {
  1561.       fscanf(fp, " = ");
  1562.       for (i=0; i < pSeiToneMapping->num_pivots; i++)
  1563.         fscanf(fp, "%dn", &(pSeiToneMapping->coded_pivot_value[i]));
  1564.     }
  1565.     else if (strcmp(buf, "sei_pivot_value")==0) 
  1566.     {
  1567.       fscanf(fp, " = ");
  1568.       for (i=0; i < pSeiToneMapping->num_pivots; i++)
  1569.         fscanf(fp, "%dn", &(pSeiToneMapping->sei_pivot_value[i]));
  1570.     }
  1571.     else
  1572.     {
  1573.       // read till the line end 
  1574.       fgets(buf, sizeof(buf), fp);
  1575.     }
  1576.   }
  1577.   fclose(fp);
  1578.   return 0;
  1579. }
  1580. void InitToneMapping() 
  1581. {
  1582.   if (params->ToneMappingSEIPresentFlag == 0)
  1583.   {
  1584.     seiHasTone_mapping = FALSE;
  1585.     return;
  1586.   }
  1587.   else
  1588.     seiHasTone_mapping = TRUE;
  1589.   seiToneMapping.data = malloc( sizeof(Bitstream) );
  1590.   if( seiToneMapping.data == NULL ) no_mem_exit("InitToneMapping: seiToneMapping.data");
  1591.   seiToneMapping.data->streamBuffer = malloc(MAXRTPPAYLOADLEN);
  1592.   if( seiToneMapping.data->streamBuffer == NULL ) no_mem_exit("InitToneMapping: seiToneMapping.data->streamBuffer");
  1593.   memset( seiToneMapping.data->streamBuffer, 0, MAXRTPPAYLOADLEN);
  1594.   seiToneMapping.data->bits_to_go  = 8;
  1595.   seiToneMapping.data->byte_pos    = 0;
  1596.   seiToneMapping.data->byte_buf    = 0;
  1597.   seiToneMapping.payloadSize       = 0;
  1598.   // read tone mapping config from file
  1599.   ParseToneMappingConfigFile(&seiToneMapping);
  1600. }
  1601. void FinalizeToneMapping()
  1602. {
  1603.   Bitstream *bitstream = seiToneMapping.data;  
  1604.   int i;
  1605.   ue_v("SEI: tone_map_id"               , seiToneMapping.tone_map_id,             bitstream);
  1606.   u_1("SEI: tone_map_cancel_flag"       , seiToneMapping.tone_map_cancel_flag,    bitstream);
  1607. #ifdef PRINT_TONE_MAPPING
  1608.   printf("frame %d: Tone-mapping SEI messagen", img->frame_num);
  1609.   printf("tone_map_id = %dn", seiToneMapping.tone_map_id);
  1610.   printf("tone_map_cancel_flag = %dn", seiToneMapping.tone_map_cancel_flag);
  1611. #endif
  1612.   if (!seiToneMapping.tone_map_cancel_flag) 
  1613.   {
  1614.     ue_v(  "SEI: tone_map_repetition_period", seiToneMapping.tone_map_repetition_period, bitstream);
  1615.     u_v (8,"SEI: coded_data_bit_depth"      , seiToneMapping.coded_data_bit_depth,       bitstream);
  1616.     u_v (8,"SEI: sei_bit_depth"             , seiToneMapping.sei_bit_depth,              bitstream);
  1617.     ue_v(  "SEI: model_id"                  , seiToneMapping.model_id,                   bitstream);
  1618. #ifdef PRINT_TONE_MAPPING
  1619.     printf("tone_map_repetition_period = %dn", seiToneMapping.tone_map_repetition_period);
  1620.     printf("coded_data_bit_depth = %dn", seiToneMapping.coded_data_bit_depth);
  1621.     printf("sei_bit_depth = %dn", seiToneMapping.sei_bit_depth);
  1622.     printf("model_id = %dn", seiToneMapping.model_id);
  1623. #endif
  1624.     if (seiToneMapping.model_id == 0) 
  1625.     { // linear mapping
  1626.       u_v (32,"SEI: min_value", seiToneMapping.min_value, bitstream);
  1627.       u_v (32,"SEI: min_value", seiToneMapping.max_value, bitstream);
  1628. #ifdef PRINT_TONE_MAPPING
  1629.       printf("min_value = %d, max_value = %dn", seiToneMapping.min_value, seiToneMapping.max_value);
  1630. #endif
  1631.     }
  1632.     else if (seiToneMapping.model_id == 1) 
  1633.     { // sigmoidal mapping
  1634.       u_v (32,"SEI: sigmoid_midpoint", seiToneMapping.sigmoid_midpoint,   bitstream);
  1635.       u_v (32,"SEI: sigmoid_width", seiToneMapping.sigmoid_width,         bitstream);
  1636. #ifdef PRINT_TONE_MAPPING
  1637.       printf("sigmoid_midpoint = %d, sigmoid_width = %dn", seiToneMapping.sigmoid_midpoint, seiToneMapping.sigmoid_width);
  1638. #endif
  1639.     }
  1640.     else if (seiToneMapping.model_id == 2) 
  1641.     { // user defined table mapping
  1642.       int bit_depth_val = 1<<seiToneMapping.sei_bit_depth;
  1643.       for (i=0; i<bit_depth_val; i++) 
  1644.       {
  1645.         u_v((((seiToneMapping.coded_data_bit_depth+7)>>3)<<3), "SEI: start_of_coded_interval", seiToneMapping.start_of_coded_interval[i], bitstream);
  1646. #ifdef PRINT_TONE_MAPPING
  1647.         //printf("start_of_coded_interval[%d] = %dn", i, seiToneMapping.start_of_coded_interval[i]);
  1648. #endif
  1649.       }
  1650.     }
  1651.     else if (seiToneMapping.model_id == 3) 
  1652.     {  // piece-wise linear mapping
  1653.       u_v (16,"SEI: num_pivots", seiToneMapping.num_pivots, bitstream);
  1654. #ifdef PRINT_TONE_MAPPING
  1655.       printf("num_pivots = %dn", seiToneMapping.num_pivots);
  1656. #endif
  1657.       for (i=0; i < seiToneMapping.num_pivots; i++) 
  1658.       {
  1659.         u_v( (((seiToneMapping.coded_data_bit_depth+7)>>3)<<3), "SEI: coded_pivot_value",  seiToneMapping.coded_pivot_value[i], bitstream);
  1660.         u_v( (((seiToneMapping.sei_bit_depth+7)>>3)<<3), "SEI: sei_pivot_value",           seiToneMapping.sei_pivot_value[i],   bitstream);
  1661. #ifdef PRINT_TONE_MAPPING
  1662.         printf("coded_pivot_value[%d] = %d, sei_pivot_value[%d] = %dn", i, seiToneMapping.coded_pivot_value[i], i, seiToneMapping.sei_pivot_value[i]);
  1663. #endif
  1664.       }
  1665.     }
  1666.   } // end !tone_map_cancel_flag
  1667.   // make sure the payload is byte aligned, stuff bits are 10..0
  1668.   if ( bitstream->bits_to_go != 8 )
  1669.   {
  1670.     (bitstream->byte_buf) <<= 1;
  1671.     bitstream->byte_buf |= 1;
  1672.     bitstream->bits_to_go--;
  1673.     if ( bitstream->bits_to_go != 0 ) 
  1674.       (bitstream->byte_buf) <<= (bitstream->bits_to_go);
  1675.     bitstream->bits_to_go = 8;
  1676.     bitstream->streamBuffer[bitstream->byte_pos++]=bitstream->byte_buf;
  1677.     bitstream->byte_buf = 0;
  1678.   }
  1679.   seiToneMapping.payloadSize = bitstream->byte_pos;
  1680. }
  1681. void UpdateToneMapping() 
  1682. {
  1683.   // return;
  1684.   // you may manually generate some test case here
  1685. }
  1686. void ClearToneMapping() 
  1687. {
  1688.   memset( seiToneMapping.data->streamBuffer, 0, MAXRTPPAYLOADLEN);
  1689.   seiToneMapping.data->bits_to_go  = 8;
  1690.   seiToneMapping.data->byte_pos    = 0;
  1691.   seiToneMapping.data->byte_buf    = 0;
  1692.   seiToneMapping.payloadSize       = 0;
  1693.   seiHasTone_mapping=FALSE;
  1694. }
  1695. void CloseToneMapping() 
  1696. {
  1697.   if (seiToneMapping.data)
  1698.   {
  1699.     free(seiToneMapping.data->streamBuffer);
  1700.     free(seiToneMapping.data);
  1701.   }
  1702.   seiToneMapping.data = NULL;
  1703.   seiHasTone_mapping = FALSE;
  1704. }
  1705. /*
  1706.  ************************************************************************
  1707.  *  functions on post-filter message
  1708.  *  brief
  1709.  *      Based on JVT-U035
  1710.  *  author
  1711.  *      Steffen Wittmann <steffen.wittmann@eu.panasonic.com>
  1712.  ************************************************************************
  1713.  */
  1714. post_filter_information_struct seiPostFilterHints;
  1715. void InitPostFilterHints()
  1716. {
  1717.   seiPostFilterHints.data = malloc( sizeof(Bitstream) );
  1718.   if( seiPostFilterHints.data == NULL ) no_mem_exit("InitPostFilterHints: seiPostFilterHints.data");
  1719.   seiPostFilterHints.data->streamBuffer = malloc(MAXRTPPAYLOADLEN);
  1720.   if( seiPostFilterHints.data->streamBuffer == NULL ) no_mem_exit("InitPostFilterHints: seiPostFilterHints.data->streamBuffer");
  1721.   ClearPostFilterHints();
  1722. }
  1723. void ClearPostFilterHints()
  1724. {
  1725.   memset( seiPostFilterHints.data->streamBuffer, 0, MAXRTPPAYLOADLEN);
  1726.   seiPostFilterHints.data->bits_to_go  = 8;
  1727.   seiPostFilterHints.data->byte_pos    = 0;
  1728.   seiPostFilterHints.data->byte_buf    = 0;
  1729.   seiPostFilterHints.payloadSize       = 0;
  1730.   seiPostFilterHints.filter_hint_size_y        = 0;
  1731.   seiPostFilterHints.filter_hint_size_x        = 0;
  1732.   seiPostFilterHints.filter_hint_type          = 0;
  1733.   seiPostFilterHints.additional_extension_flag = 0;
  1734. }
  1735. void UpdatePostFilterHints()
  1736. {
  1737.   unsigned int color_component, cx, cy;
  1738.   seiPostFilterHints.filter_hint_type = 0; //define filter_hint_type here
  1739.   seiPostFilterHints.filter_hint_size_y = seiPostFilterHints.filter_hint_size_x = 5; //define filter_hint_size here
  1740.   get_mem3Dint(&seiPostFilterHints.filter_hint, 3, seiPostFilterHints.filter_hint_size_y, seiPostFilterHints.filter_hint_size_x);
  1741.   for (color_component = 0; color_component < 3; color_component ++)
  1742.     for (cy = 0; cy < seiPostFilterHints.filter_hint_size_y; cy ++)
  1743.       for (cx = 0; cx < seiPostFilterHints.filter_hint_size_x; cx ++)
  1744.         seiPostFilterHints.filter_hint[color_component][cy][cx] = 1; //define filter_hint here
  1745.   seiPostFilterHints.additional_extension_flag = 0;
  1746. }
  1747. void FinalizePostFilterHints()
  1748. {
  1749.   Bitstream *bitstream = seiPostFilterHints.data;
  1750.   unsigned int color_component, cx, cy;
  1751.   ue_v(  "SEI: post_filter_hint_size_y", seiPostFilterHints.filter_hint_size_y, bitstream);
  1752.   ue_v(  "SEI: post_filter_hint_size_x", seiPostFilterHints.filter_hint_size_x, bitstream);
  1753.   u_v (2,"SEI: post_filter_hint_type",   seiPostFilterHints.filter_hint_type,   bitstream);
  1754.   for (color_component = 0; color_component < 3; color_component ++)
  1755.     for (cy = 0; cy < seiPostFilterHints.filter_hint_size_y; cy ++)
  1756.       for (cx = 0; cx < seiPostFilterHints.filter_hint_size_x; cx ++)
  1757.         se_v("SEI: post_filter_hints", seiPostFilterHints.filter_hint[color_component][cy][cx], bitstream);
  1758.   u_1 ("SEI: post_filter_additional_extension_flag", seiPostFilterHints.additional_extension_flag, bitstream);
  1759. // #define PRINT_POST_FILTER_HINTS
  1760. #ifdef PRINT_POST_FILTER_HINTS
  1761.   printf(" post_filter_hint_size_y %d n", seiPostFilterHints.filter_hint_size_y);
  1762.   printf(" post_filter_hint_size_x %d n", seiPostFilterHints.filter_hint_size_x);
  1763.   printf(" post_filter_hint_type %d n",   seiPostFilterHints.filter_hint_type);
  1764.   for (color_component = 0; color_component < 3; color_component ++)
  1765.     for (cy = 0; cy < seiPostFilterHints.filter_hint_size_y; cy ++)
  1766.       for (cx = 0; cx < seiPostFilterHints.filter_hint_size_x; cx ++)
  1767.         printf(" post_filter_hint[%d][%d][%d] %d n", color_component, cy, cx, filter_hint[color_component][cy][cx]);
  1768.   printf(" additional_extension_flag %d n", seiPostFilterHints.additional_extension_flag);
  1769. #undef PRINT_POST_FILTER_HINTS
  1770. #endif
  1771.   // make sure the payload is byte aligned, stuff bits are 10..0
  1772.   if ( bitstream->bits_to_go != 8 )
  1773.   {
  1774.     (bitstream->byte_buf) <<= 1;
  1775.     bitstream->byte_buf |= 1;
  1776.     bitstream->bits_to_go--;
  1777.     if ( bitstream->bits_to_go != 0 ) 
  1778.       (bitstream->byte_buf) <<= (bitstream->bits_to_go);
  1779.     bitstream->bits_to_go = 8;
  1780.     bitstream->streamBuffer[bitstream->byte_pos++]=bitstream->byte_buf;
  1781.     bitstream->byte_buf = 0;
  1782.   }
  1783.   seiPostFilterHints.payloadSize = bitstream->byte_pos;
  1784. }
  1785. void ClosePostFilterHints()
  1786. {
  1787.   if (seiPostFilterHints.data)
  1788.   {
  1789.     free(seiPostFilterHints.data->streamBuffer);
  1790.     free(seiPostFilterHints.data);  
  1791.     if (seiPostFilterHints.filter_hint)
  1792.       free_mem3Dint(seiPostFilterHints.filter_hint);
  1793.   }
  1794.   seiPostFilterHints.data = NULL;
  1795. }
  1796. /*
  1797. **++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  1798. *  functions to write SEI message into NAL
  1799. *  brief     
  1800. **++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  1801. */
  1802. int Write_SEI_NALU(int len)
  1803. {  
  1804.   NALU_t *nalu = NULL;
  1805.   int RBSPlen = 0;
  1806.   int NALUlen;
  1807.   byte *rbsp;
  1808.   if (HaveAggregationSEI())
  1809.   {
  1810.     nalu = AllocNALU(64000);
  1811.     rbsp = sei_message[AGGREGATION_SEI].data;
  1812.     RBSPlen = sei_message[AGGREGATION_SEI].payloadSize;
  1813.     NALUlen = RBSPtoNALU (rbsp, nalu, RBSPlen, NALU_TYPE_SEI, NALU_PRIORITY_LOW, 0, 1);
  1814.     nalu->startcodeprefix_len = 4;
  1815.     len += WriteNALU (nalu);
  1816.     FreeNALU (nalu);
  1817.   }  
  1818.   return len;
  1819. }
  1820. /*
  1821.  **++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  1822.  *  functions on buffering period SEI message
  1823.  *  brief
  1824.  *      Based on final Recommendation
  1825.  *  author
  1826.  *      Athanasios Leontaris                 <aleon@dolby.com>
  1827.  **++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  1828.  */
  1829. void InitBufferingPeriod()
  1830. {
  1831.   seiBufferingPeriod.data = malloc( sizeof(Bitstream) );
  1832.   if( seiBufferingPeriod.data == NULL ) 
  1833.     no_mem_exit("InitBufferingPeriod: seiBufferingPeriod.data");
  1834.   seiBufferingPeriod.data->streamBuffer = malloc(MAXRTPPAYLOADLEN);
  1835.   if( seiBufferingPeriod.data->streamBuffer == NULL ) 
  1836.     no_mem_exit("InitBufferingPeriod: seiBufferingPeriod.data->streamBuffer");
  1837.   ClearBufferingPeriod();
  1838. }
  1839. void ClearBufferingPeriod()
  1840. {
  1841.   unsigned int SchedSelIdx;
  1842.   memset( seiBufferingPeriod.data->streamBuffer, 0, MAXRTPPAYLOADLEN);
  1843.   seiBufferingPeriod.data->bits_to_go  = 8;
  1844.   seiBufferingPeriod.data->byte_pos    = 0;
  1845.   seiBufferingPeriod.data->byte_buf    = 0;
  1846.   seiBufferingPeriod.payloadSize       = 0;
  1847.   seiBufferingPeriod.seq_parameter_set_id = active_sps->seq_parameter_set_id;
  1848.   if ( active_sps->vui_seq_parameters.nal_hrd_parameters_present_flag )
  1849.   {
  1850.     for ( SchedSelIdx = 0; SchedSelIdx <= active_sps->vui_seq_parameters.nal_hrd_parameters.cpb_cnt_minus1; SchedSelIdx++ )
  1851.     {
  1852.       seiBufferingPeriod.nal_initial_cpb_removal_delay[SchedSelIdx] = 0;
  1853.       seiBufferingPeriod.nal_initial_cpb_removal_delay_offset[SchedSelIdx] = 0;
  1854.     }
  1855.   }
  1856.   if ( active_sps->vui_seq_parameters.vcl_hrd_parameters_present_flag )
  1857.   {
  1858.     for ( SchedSelIdx = 0; SchedSelIdx <= active_sps->vui_seq_parameters.vcl_hrd_parameters.cpb_cnt_minus1; SchedSelIdx++ )
  1859.     {
  1860.       seiBufferingPeriod.vcl_initial_cpb_removal_delay[SchedSelIdx] = 0;
  1861.       seiBufferingPeriod.vcl_initial_cpb_removal_delay_offset[SchedSelIdx] = 0;
  1862.     }
  1863.   }
  1864.   seiHasBuffering_period = FALSE;
  1865. }
  1866. void UpdateBufferingPeriod()
  1867. {
  1868.   seiHasBuffering_period = FALSE;
  1869. }
  1870. void FinalizeBufferingPeriod()
  1871. {
  1872.   unsigned int SchedSelIdx;
  1873.   Bitstream *bitstream = seiBufferingPeriod.data;
  1874.   ue_v(   "SEI: seq_parameter_set_id",     seiBufferingPeriod.seq_parameter_set_id,   bitstream);
  1875.   if ( active_sps->vui_seq_parameters.nal_hrd_parameters_present_flag )
  1876.   {
  1877.     for ( SchedSelIdx = 0; SchedSelIdx <= active_sps->vui_seq_parameters.nal_hrd_parameters.cpb_cnt_minus1; SchedSelIdx++ )
  1878.     {
  1879.       u_v( active_sps->vui_seq_parameters.nal_hrd_parameters.initial_cpb_removal_delay_length_minus1 + 1,
  1880.         "SEI: initial_cpb_removal_delay",     seiBufferingPeriod.nal_initial_cpb_removal_delay[SchedSelIdx],   bitstream);
  1881.       u_v( active_sps->vui_seq_parameters.nal_hrd_parameters.initial_cpb_removal_delay_length_minus1 + 1,
  1882.         "SEI: initial_cpb_removal_delay_offset",     seiBufferingPeriod.nal_initial_cpb_removal_delay_offset[SchedSelIdx],   bitstream);
  1883.     }
  1884.   }
  1885.   if ( active_sps->vui_seq_parameters.vcl_hrd_parameters_present_flag )
  1886.   {
  1887.     for ( SchedSelIdx = 0; SchedSelIdx <= active_sps->vui_seq_parameters.vcl_hrd_parameters.cpb_cnt_minus1; SchedSelIdx++ )
  1888.     {
  1889.       u_v( active_sps->vui_seq_parameters.vcl_hrd_parameters.initial_cpb_removal_delay_length_minus1 + 1,
  1890.         "SEI: initial_cpb_removal_delay",     seiBufferingPeriod.vcl_initial_cpb_removal_delay[SchedSelIdx],   bitstream);
  1891.       u_v( active_sps->vui_seq_parameters.vcl_hrd_parameters.initial_cpb_removal_delay_length_minus1 + 1,
  1892.         "SEI: initial_cpb_removal_delay_offset",     seiBufferingPeriod.vcl_initial_cpb_removal_delay_offset[SchedSelIdx],   bitstream);
  1893.     }
  1894.   }
  1895.   // make sure the payload is byte aligned, stuff bits are 10..0
  1896.   if ( bitstream->bits_to_go != 8 )
  1897.   {
  1898.     (bitstream->byte_buf) <<= 1;
  1899.     bitstream->byte_buf |= 1;
  1900.     bitstream->bits_to_go--;
  1901.     if ( bitstream->bits_to_go != 0 )
  1902.       (bitstream->byte_buf) <<= (bitstream->bits_to_go);
  1903.     bitstream->bits_to_go = 8;
  1904.     bitstream->streamBuffer[bitstream->byte_pos++]=bitstream->byte_buf;
  1905.     bitstream->byte_buf = 0;
  1906.   }
  1907.   seiBufferingPeriod.payloadSize = bitstream->byte_pos;
  1908. }
  1909. void CloseBufferingPeriod()
  1910. {
  1911.   if (seiBufferingPeriod.data)
  1912.   {
  1913.     free(seiBufferingPeriod.data->streamBuffer);
  1914.     free(seiBufferingPeriod.data);
  1915.   }
  1916.   seiBufferingPeriod.data = NULL;
  1917. }
  1918. /*
  1919.  **++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  1920.  *  functions on picture timing SEI message
  1921.  *  brief
  1922.  *      Based on final Recommendation
  1923.  *  author
  1924.  *      Athanasios Leontaris                 <aleon@dolby.com>
  1925.  **++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  1926.  */
  1927. void InitPicTiming()
  1928. {
  1929.   seiPicTiming.data = malloc( sizeof(Bitstream) );
  1930.   if( seiPicTiming.data == NULL ) 
  1931.     no_mem_exit("InitPicTiming: seiPicTiming.data");
  1932.   seiPicTiming.data->streamBuffer = malloc(MAXRTPPAYLOADLEN);
  1933.   if( seiPicTiming.data->streamBuffer == NULL ) 
  1934.     no_mem_exit("InitPicTiming: seiPicTiming.data->streamBuffer");
  1935.   ClearPicTiming();
  1936. }
  1937. void ClearPicTiming()
  1938. {
  1939.   memset( seiPicTiming.data->streamBuffer, 0, MAXRTPPAYLOADLEN);
  1940.   seiPicTiming.data->bits_to_go  = 8;
  1941.   seiPicTiming.data->byte_pos    = 0;
  1942.   seiPicTiming.data->byte_buf    = 0;
  1943.   seiPicTiming.payloadSize       = 0;
  1944.   // initialization
  1945.   seiPicTiming.cpb_removal_delay = 0;
  1946.   seiPicTiming.dpb_output_delay = 0;
  1947.   seiPicTiming.pic_struct = 0;
  1948.   memset(seiPicTiming.clock_timestamp_flag, 0, MAX_PIC_STRUCT_VALUE * sizeof(Boolean) ); // 0 == FALSE
  1949.   seiPicTiming.ct_type = 0;
  1950.   seiPicTiming.nuit_field_based_flag = FALSE;
  1951.   seiPicTiming.counting_type = 0;
  1952.   seiPicTiming.full_timestamp_flag = FALSE;
  1953.   seiPicTiming.discontinuity_flag = FALSE;
  1954.   seiPicTiming.cnt_dropped_flag = FALSE;
  1955.   seiPicTiming.n_frames = 0;
  1956.   seiPicTiming.seconds_value = 0;
  1957.   seiPicTiming.minutes_value = 0;
  1958.   seiPicTiming.hours_value = 0;
  1959.   seiPicTiming.seconds_flag = FALSE;
  1960.   seiPicTiming.minutes_flag = FALSE;
  1961.   seiPicTiming.hours_flag = FALSE;
  1962.   seiPicTiming.time_offset = 0;  
  1963.   seiHasPicTiming_info = FALSE;
  1964. }
  1965. void UpdatePicTiming()
  1966. {
  1967.   seiHasPicTiming_info = FALSE;
  1968. }
  1969. void FinalizePicTiming()
  1970. {
  1971.   Bitstream *bitstream = seiPicTiming.data;
  1972.   // CpbDpbDelaysPresentFlag can also be set "by some means not specified in this Recommendation | International Standard"
  1973.   Boolean CpbDpbDelaysPresentFlag =  (Boolean) (active_sps->vui_parameters_present_flag
  1974.                               && (   (active_sps->vui_seq_parameters.nal_hrd_parameters_present_flag != 0)
  1975.                                    ||(active_sps->vui_seq_parameters.vcl_hrd_parameters_present_flag != 0)));
  1976.   hrd_parameters_t *hrd = NULL;
  1977.   assert( active_sps->vui_seq_parameters.vcl_hrd_parameters_present_flag || active_sps->vui_seq_parameters.nal_hrd_parameters_present_flag );
  1978.   if (active_sps->vui_seq_parameters.vcl_hrd_parameters_present_flag)
  1979.     hrd = &(active_sps->vui_seq_parameters.vcl_hrd_parameters);
  1980.   else if (active_sps->vui_seq_parameters.nal_hrd_parameters_present_flag)
  1981.     hrd = &(active_sps->vui_seq_parameters.nal_hrd_parameters);
  1982.   else // this should never happen
  1983.     error ("HRD structures not properly created.",-1);
  1984.   if ( CpbDpbDelaysPresentFlag )
  1985.   {
  1986.     u_v( hrd->cpb_removal_delay_length_minus1 + 1, "SEI: cpb_removal_delay", seiPicTiming.cpb_removal_delay, bitstream);
  1987.     u_v( hrd->dpb_output_delay_length_minus1  + 1, "SEI: dpb_output_delay",  seiPicTiming.dpb_output_delay,  bitstream);
  1988.   }
  1989.   if ( active_sps->vui_seq_parameters.pic_struct_present_flag )
  1990.   {
  1991.     int NumClockTS = 0, i;
  1992.     int bottom_field_flag = (img->structure == BOTTOM_FIELD);
  1993.     u_v( 4, "SEI: pic_struct", seiPicTiming.pic_struct, bitstream);
  1994.     // interpret pic_struct
  1995.     switch( seiPicTiming.pic_struct )
  1996.     {
  1997.     case 0:
  1998.     default:
  1999.       // frame
  2000.       assert( img->fld_flag == FALSE );
  2001.       NumClockTS = 1;
  2002.       break;
  2003.     case 1:
  2004.       // top field
  2005.       assert( (img->fld_flag == TRUE) && (bottom_field_flag == FALSE) );
  2006.       NumClockTS = 1;
  2007.       break;
  2008.     case 2:
  2009.       // bottom field
  2010.       assert( (img->fld_flag == TRUE) && (bottom_field_flag == TRUE) );
  2011.       NumClockTS = 1;
  2012.       break;
  2013.     case 3:
  2014.       // top field, bottom field, in that order
  2015.     case 4:
  2016.       // bottom field, top field, in that order
  2017.       assert( img->fld_flag == FALSE );
  2018.       NumClockTS = 2;
  2019.       break;
  2020.     case 5:
  2021.       // top field, bottom field, top field repeated, in that order
  2022.     case 6:
  2023.       // bottom field, top field, bottom field repeated, in that order
  2024.       assert( img->fld_flag == FALSE );
  2025.       NumClockTS = 3;
  2026.     case 7:
  2027.       // frame doubling
  2028.       assert( (img->fld_flag == FALSE) && active_sps->vui_seq_parameters.fixed_frame_rate_flag == 1 );
  2029.       NumClockTS = 2;
  2030.       break;
  2031.     case 8:
  2032.       // frame tripling
  2033.       assert( (img->fld_flag == FALSE) && active_sps->vui_seq_parameters.fixed_frame_rate_flag == 1 );
  2034.       NumClockTS = 3;
  2035.       break;
  2036.     }
  2037.     for ( i = 0; i < NumClockTS; i++ )
  2038.     {
  2039.       u_1( "SEI: clock_timestamp_flag", seiPicTiming.clock_timestamp_flag[i], bitstream);
  2040.       if ( seiPicTiming.clock_timestamp_flag[i] )
  2041.       {
  2042.         u_v( 2, "SEI: ct_type", seiPicTiming.ct_type, bitstream);
  2043.         u_1( "SEI: nuit_field_based_flag", seiPicTiming.nuit_field_based_flag, bitstream);
  2044.         u_v( 5, "SEI: counting_type", seiPicTiming.counting_type, bitstream);
  2045.         u_1( "SEI: full_timestamp_flag", seiPicTiming.full_timestamp_flag, bitstream);
  2046.         u_1( "SEI: discontinuity_flag", seiPicTiming.discontinuity_flag, bitstream);
  2047.         u_1( "SEI: cnt_dropped_flag", seiPicTiming.cnt_dropped_flag, bitstream);
  2048.         u_v( 8, "SEI: n_frames", seiPicTiming.n_frames, bitstream);
  2049.         if ( seiPicTiming.full_timestamp_flag )
  2050.         {      
  2051.           u_v( 6, "SEI: seconds_value", seiPicTiming.seconds_value, bitstream);
  2052.           u_v( 6, "SEI: minutes_value", seiPicTiming.minutes_value, bitstream);
  2053.           u_v( 5, "SEI: hours_value",   seiPicTiming.hours_value, bitstream);
  2054.         }
  2055.         else
  2056.         {            
  2057.           u_1( "SEI: seconds_flag", seiPicTiming.seconds_flag, bitstream);
  2058.           if (seiPicTiming.seconds_flag)
  2059.           {
  2060.             u_v( 6, "SEI: seconds_value", seiPicTiming.seconds_value, bitstream);
  2061.             u_1( "SEI: minutes_flag", seiPicTiming.minutes_flag, bitstream);
  2062.             if (seiPicTiming.minutes_flag)
  2063.             {
  2064.               u_v( 6, "SEI: minutes_value", seiPicTiming.minutes_value, bitstream);
  2065.               u_1( "SEI: hours_flag", seiPicTiming.hours_flag, bitstream);
  2066.               if (seiPicTiming.hours_flag)
  2067.               {
  2068.                 u_v( 5, "SEI: hours_value",   seiPicTiming.hours_value, bitstream);
  2069.               }
  2070.             }
  2071.           }
  2072.         }
  2073.         if ( hrd->time_offset_length )
  2074.         {
  2075.           u_v( hrd->time_offset_length, "SEI: time_offset", seiPicTiming.time_offset, bitstream);
  2076.         }
  2077.       }
  2078.     }
  2079.   }
  2080.   // make sure the payload is byte aligned, stuff bits are 10..0
  2081.   if ( bitstream->bits_to_go != 8 )
  2082.   {
  2083.     (bitstream->byte_buf) <<= 1;
  2084.     bitstream->byte_buf |= 1;
  2085.     bitstream->bits_to_go--;
  2086.     if ( bitstream->bits_to_go != 0 )
  2087.       (bitstream->byte_buf) <<= (bitstream->bits_to_go);
  2088.     bitstream->bits_to_go = 8;
  2089.     bitstream->streamBuffer[bitstream->byte_pos++]=bitstream->byte_buf;
  2090.     bitstream->byte_buf = 0;
  2091.   }
  2092.   seiPicTiming.payloadSize = bitstream->byte_pos;
  2093. }
  2094. void ClosePicTiming()
  2095. {
  2096.   if (seiPicTiming.data)
  2097.   {
  2098.     free(seiPicTiming.data->streamBuffer);
  2099.     free(seiPicTiming.data);
  2100.   }
  2101.   seiPicTiming.data = NULL;
  2102. }