⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 filehandle.c

📁 MPEG-4编解码的实现(包括MPEG4视音频编解码)
💻 C
📖 第 1 页 / 共 2 页
字号:
      {                   // RTP: CABAC 
        eep = &((currSlice->partArr[0]).ee_cabac);
        currStream = (currSlice->partArr[0]).bitstream;

        assert (currStream->bits_to_go == 8);
        assert (currStream->byte_buf == 0);


        header_len=RTPSliceHeader();                      // generate the slice header

        // reserve bits for d_MB_Nr
        currStream->header_len = header_len;
        currStream->header_byte_buffer = currStream->byte_buf;

        currStream->byte_pos += ((31-currStream->bits_to_go)/8);
        if ((31-currStream->bits_to_go)%8 != 0)
          currStream->byte_pos++;
        currStream->bits_to_go = 8;
        currStream->byte_pos++;

        arienco_start_encoding(eep, currStream->streamBuffer, &(currStream->byte_pos));
        
        if(input->partition_mode != PAR_DP_1)
        {
          for (i=1; i<currSlice->max_part_nr; i++)
          {
            eep = &((currSlice->partArr[0]).ee_cabac);
            currStream = (currSlice->partArr[0]).bitstream;
  
            assert (currStream->bits_to_go == 8);
            assert (currStream->byte_buf == 0);
            assert (currStream->byte_pos == 0);

            arienco_start_encoding(eep, currStream->streamBuffer, &(currStream->byte_pos));
          }
        }
        // initialize context models
        init_contexts_MotionInfo(currSlice->mot_ctx, 1);
        init_contexts_TextureInfo(currSlice->tex_ctx, 1);

        return header_len;
      }
    default:
      snprintf(errortext, ET_SIZE, "Output File Mode %d not supported", input->of_mode);
      error(errortext,1);
      return 1;
  }
}


/*!
 ************************************************************************
 * \brief
 *    This function terminates a slice
 * \return
 *    0 if OK,                                                         \n
 *    1 in case of error
 ************************************************************************
 */
int terminate_slice()
{
  int bytes_written;
  Bitstream *currStream;
  Slice *currSlice = img->currentSlice;
  EncodingEnvironmentPtr eep;
  int i;
  int byte_pos, bits_to_go, start_data;
  byte buffer;
  int LastPartition;
  int cabac_byte_pos=0, uvlc_byte_pos=0, empty_bytes=0;
  int rtp_bytes_written;

  // Mainly flushing of everything
  // Add termination symbol, etc.
  switch(input->of_mode)
  {
    case PAR_OF_26L:


      if (input->symbol_mode == UVLC)
      {
        // Current TML File Format
        // Enforce byte alignment of next header: zero bit stuffing
        currStream = (currSlice->partArr[0]).bitstream;

        if (currStream->bits_to_go < 8)
        { // trailing bits to process
          currStream->byte_buf <<= currStream->bits_to_go;
          currStream->streamBuffer[currStream->byte_pos++]=currStream->byte_buf;
          currStream->bits_to_go = 8;
        }

        bytes_written = currStream->byte_pos;
        stat->bit_ctr += 8*bytes_written;     // actually written bits
#ifdef H26L_LIB
        memcpy(&memout[memoutlength], currStream->streamBuffer, bytes_written);
		memoutlength += bytes_written;
#else
        fwrite (currStream->streamBuffer, 1, bytes_written, out);
#endif

        currStream->stored_bits_to_go = 8; // store bits_to_go
        currStream->stored_byte_buf   = currStream->byte_buf;   // store current byte
        currStream->stored_byte_pos   = 0; // reset byte position

      }
      else
      {

        // CABAC File Format
        eep = &((currSlice->partArr[0]).ee_cabac);
        currStream = (currSlice->partArr[0]).bitstream;

        // terminate the arithmetic code
        arienco_done_encoding(eep);

        // Add Number of MBs of this slice to the header
        // Save current state of Bitstream
        currStream = (currSlice->partArr[0]).bitstream;
        byte_pos = currStream->byte_pos;
        bits_to_go = currStream->bits_to_go;
        buffer = currStream->byte_buf;

        // Go to the reserved bits
        currStream->byte_pos = (currStream->header_len)/8;
        currStream->bits_to_go = 8-(currStream->header_len)%8;
        currStream->byte_buf = currStream->header_byte_buffer;

        // Ad Info about last MB
        LastMBInSlice();

        // And write the header to the output
        bytes_written = currStream->byte_pos;
        if (currStream->bits_to_go < 8) // trailing bits to process
        {
            currStream->byte_buf <<= currStream->bits_to_go;
            currStream->streamBuffer[currStream->byte_pos++]=currStream->byte_buf;
            bytes_written++;
            currStream->bits_to_go = 8;
        }
#ifdef H26L_LIB
        memcpy(&memout[memoutlength], currStream->streamBuffer, bytes_written);
		memoutlength += bytes_written;
#else
        fwrite (currStream->streamBuffer, 1, bytes_written, out);
#endif
        stat->bit_ctr += 8*bytes_written;

        // Go back to the end of the stream
        currStream->byte_pos = byte_pos;
        currStream->bits_to_go = bits_to_go;
        currStream->byte_buf = buffer;


        // Find startposition of databitstream
        start_data = (currStream->header_len+31)/8;
        if ((currStream->header_len+31)%8 != 0)
          start_data++;
        bytes_written = currStream->byte_pos - start_data; // number of written bytes

        stat->bit_ctr += 8*bytes_written;     // actually written bits
#ifdef H26L_LIB
        memcpy(&memout[memoutlength], currStream->streamBuffer+start_data, 
			bytes_written);
		memoutlength += bytes_written;
#else
        fwrite ((currStream->streamBuffer+start_data), 1, bytes_written, out);
#endif
      }
      return 0;

    case PAR_OF_RTP:

      for (i=0; i<currSlice->max_part_nr; i++)
      {
        if (input->symbol_mode == CABAC)
        {
          eep = &((currSlice->partArr[i]).ee_cabac);
          arienco_done_encoding(eep);
        }
        currStream = (currSlice->partArr[i]).bitstream;
        
        if (currStream->bits_to_go < 8) // trailing bits to process
        {
          currStream->byte_buf <<= currStream->bits_to_go;
          currStream->streamBuffer[currStream->byte_pos++]=currStream->byte_buf;
          currStream->bits_to_go = 8;
        }
        bytes_written = currStream->byte_pos; // number of written bytes

        assert (bytes_written != 0);
        if (bytes_written != 0)     // at least one bit in the partition -- something to do
          {
            int Marker;
            int FirstBytePacketType;

            // Determine First Byte of RTP payload
            switch (input->partition_mode)
            {
              case PAR_DP_1:
                FirstBytePacketType = 0;
                break;
              case PAR_DP_3:
                FirstBytePacketType = i+1;      // See VCEG-N72
                break;
              default:
                assert (0==1);
            }

            if (input->symbol_mode == CABAC && i == 0)
            {
              //! Add Number of MBs of this slice to the header
              //! Save current state of Bitstream
              byte_pos = currStream->byte_pos; //last byte in the stream

              //! Go to the reserved bits
              currStream->byte_pos = cabac_byte_pos = (currStream->header_len)/8;
              currStream->bits_to_go = 8-(currStream->header_len)%8;
              currStream->byte_buf = currStream->header_byte_buffer;

              cabac_byte_pos += ((31-currStream->bits_to_go)/8);
              if ((31-currStream->bits_to_go)%8 != 0)
                cabac_byte_pos++;
              cabac_byte_pos++; //! that's the position where we started to write CABAC code

              //! Ad Info about last MB 
              LastMBInSlice();

              if (currStream->bits_to_go < 8) //! trailing bits to process
              {
                currStream->byte_buf <<= currStream->bits_to_go;
                currStream->streamBuffer[currStream->byte_pos++]=currStream->byte_buf;
              }

              uvlc_byte_pos = currStream->byte_pos; //! that's the first byte after the UVLC header data
              currStream->byte_pos = byte_pos;  //! where we were before this last_MB thing
              empty_bytes = cabac_byte_pos - uvlc_byte_pos; //! These bytes contain no information
                                                            //! They were reserved for writing the last_MB information but were not used

              for(byte_pos=uvlc_byte_pos; byte_pos<=currStream->byte_pos-empty_bytes; byte_pos++)
                currStream->streamBuffer[byte_pos]=currStream->streamBuffer[byte_pos+empty_bytes]; //shift the bitstreams
              bytes_written = byte_pos;
              //! TO 02.11.2001 I'm sure this can be done much more elegant, but that's the way it works. 
              //! If anybody understands what happens here please feel free to change this!
          }  

          // Calculate RTP payload's First Byte
          if (input->partition_mode==PAR_DP_1)
            FirstBytePacketType = 0;
          else
            FirstBytePacketType = i+1;

          assert (FirstBytePacketType == 0);    //! This has to go as soon as data partitioning is to be tested

          // Calculate the Marker bit
          LastPartition=0;
          if (input->partition_mode == PAR_DP_3)
          {
            if (currSlice->partArr[1].bitstream->byte_pos > 0)  // something in partition 1
              LastPartition=1;
            if (currSlice->partArr[2].bitstream->byte_pos > 0)  // something in partition 2
              LastPartition=2;
          }
          Marker = 0;
          if (img->current_mb_nr == img->total_number_mb)   // last MB is in this slice
            if ((input->partition_mode==PAR_DP_1) ||          // Single SLice
                (input->partition_mode==PAR_DP_3 && i == LastPartition ))   // Last partition containing bits
              Marker = 1;
          // and write the RTP packet
          rtp_bytes_written = RTPWriteBits (Marker, FirstBytePacketType, currStream->streamBuffer, bytes_written, out);
        }
        stat->bit_ctr += 8*bytes_written;
        // Provide the next partition with a 'fresh' buffer
        currStream->stored_bits_to_go = 8;
        currStream->stored_byte_buf   = 0;
        currStream->stored_byte_pos   = 0;
        currStream->bits_to_go = 8;
        currStream->byte_buf   = 0;
        currStream->byte_pos   = 0;

      }
    return 0;


    default:
      snprintf(errortext, ET_SIZE, "Output File Mode %d not supported", input->of_mode);
      error(errortext,1);
      return 1;
  }
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -