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

📄 image.c

📁 H.264 codec source code
💻 C
📖 第 1 页 / 共 5 页
字号:
  int redundant_pic_cnt_b, redundant_pic_cnt_c;
  long ftell_position;
  
  while (1)
  {
    ftell_position = ftell(bits);

    if (input->FileFormat == PAR_OF_ANNEXB)
      ret=GetAnnexbNALU (nalu);
    else
      ret=GetRTPNALU (nalu);

    //In some cases, zero_byte shall be present. If current NALU is a VCL NALU, we can't tell
    //whether it is the first VCL NALU at this point, so only non-VCL NAL unit is checked here.
    CheckZeroByteNonVCL(nalu, &ret);

    NALUtoRBSP(nalu);
    
    if (ret < 0)
      printf ("Error while getting the NALU in file format %s, exit\n", input->FileFormat==PAR_OF_ANNEXB?"Annex B":"RTP");
    if (ret == 0)
    {
        return EOS;
    }

    // Got a NALU
    if (nalu->forbidden_bit)
    {
      printf ("Found NALU w/ forbidden_bit set, bit error?  Let's try...\n");
    }

    switch (nalu->nal_unit_type)
    {
      case NALU_TYPE_SLICE:
      case NALU_TYPE_IDR:

        if (img->recovery_point || nalu->nal_unit_type == NALU_TYPE_IDR)
        {
          if (img->recovery_point_found == 0)
          {
            if (nalu->nal_unit_type != NALU_TYPE_IDR)
            {
              printf("Warning: Decoding does not start with an IDR picture.\n");
              non_conforming_stream = 1;
            }
            else
              non_conforming_stream = 0;
          }
          img->recovery_point_found = 1;
        }

        if (img->recovery_point_found == 0)
            break;

        img->idr_flag = (nalu->nal_unit_type == NALU_TYPE_IDR);
        img->nal_reference_idc = nalu->nal_reference_idc;
        currSlice->dp_mode = PAR_DP_1;
        currSlice->max_part_nr = 1;
        currSlice->ei_flag = 0;
        currStream = currSlice->partArr[0].bitstream;
        currStream->ei_flag = 0;
        currStream->frame_bitoffset = currStream->read_len = 0;
        memcpy (currStream->streamBuffer, &nalu->buf[1], nalu->len-1);
        currStream->code_len = currStream->bitstream_length = RBSPtoSODB(currStream->streamBuffer, nalu->len-1);

        // Some syntax of the Slice Header depends on the parameter set, which depends on
        // the parameter set ID of the SLice header.  Hence, read the pic_parameter_set_id
        // of the slice header first, then setup the active parameter sets, and then read
        // the rest of the slice header
        BitsUsedByHeader = FirstPartOfSliceHeader();
        UseParameterSet (currSlice->pic_parameter_set_id);
        BitsUsedByHeader+= RestOfSliceHeader ();

        FmoInit (active_pps, active_sps);

        AssignQuantParam (active_pps, active_sps);

        // if primary slice is replaced with redundant slice, set the correct image type
        if(img->redundant_pic_cnt && Is_primary_correct==0 && Is_redundant_correct)
        {
          dec_picture->slice_type=img->type; 
        }

        if(is_new_picture())
        {
          init_picture(img, input);
          
          current_header = SOP;
          //check zero_byte if it is also the first NAL unit in the access unit
          CheckZeroByteVCL(nalu, &ret);
        }
        else
          current_header = SOS;
  
        init_lists(img->type, img->currentSlice->structure);
        reorder_lists (img->type, img->currentSlice);

        if (img->structure==FRAME)
        {
          init_mbaff_lists();
        }

/*        if (img->frame_num==1) // write a reference list
        {
          count ++;
          if (count==1)
            for (i=0; i<listXsize[0]; i++)
              write_picture(listX[0][i], p_out2);
        }
*/

        // From here on, active_sps, active_pps and the slice header are valid
        if (img->MbaffFrameFlag)
          img->current_mb_nr = currSlice->start_mb_nr << 1;
        else
          img->current_mb_nr = currSlice->start_mb_nr;

        if (active_pps->entropy_coding_mode_flag)
        {
          int ByteStartPosition = currStream->frame_bitoffset/8;
          if (currStream->frame_bitoffset%8 != 0) 
          {
            ByteStartPosition++;
          }
          arideco_start_decoding (&currSlice->partArr[0].de_cabac, currStream->streamBuffer, ByteStartPosition, &currStream->read_len, img->type);
        }
// printf ("read_new_slice: returning %s\n", current_header == SOP?"SOP":"SOS");
        FreeNALU(nalu);
        img->recovery_point = 0;
        return current_header;
        break;
      case NALU_TYPE_DPA:
        // read DP_A
        img->idr_flag          = (nalu->nal_unit_type == NALU_TYPE_IDR);
        if (img->idr_flag)
        {
          printf ("Data partiton A cannot have idr_flag set, trying anyway \n");
        }
        img->nal_reference_idc = nalu->nal_reference_idc;
        currSlice->dp_mode     = PAR_DP_3;
        currSlice->max_part_nr = 3;
        currSlice->ei_flag     = 0;
        currStream             = currSlice->partArr[0].bitstream;
        currStream->ei_flag    = 0;
        currStream->frame_bitoffset = currStream->read_len = 0;
        memcpy (currStream->streamBuffer, &nalu->buf[1], nalu->len-1);
        currStream->code_len = currStream->bitstream_length = RBSPtoSODB(currStream->streamBuffer, nalu->len-1);
        
        BitsUsedByHeader     = FirstPartOfSliceHeader();
        UseParameterSet (currSlice->pic_parameter_set_id);
        BitsUsedByHeader    += RestOfSliceHeader ();
        
        FmoInit (active_pps, active_sps);
        
        if(is_new_picture())
        {
          init_picture(img, input);
          current_header = SOP;
          CheckZeroByteVCL(nalu, &ret);
        }
        else
          current_header = SOS;
        
        init_lists(img->type, img->currentSlice->structure);
        reorder_lists (img->type, img->currentSlice);
        
        if (img->structure==FRAME)
        {
          init_mbaff_lists();
        }

        // From here on, active_sps, active_pps and the slice header are valid
        if (img->MbaffFrameFlag)
          img->current_mb_nr = currSlice->start_mb_nr << 1;
        else
          img->current_mb_nr = currSlice->start_mb_nr;

        // Now I need to read the slice ID, which depends on the value of 
        // redundant_pic_cnt_present_flag
        
        slice_id_a  = ue_v("NALU: DP_A slice_id", currStream);

        if (active_pps->entropy_coding_mode_flag)
          error ("received data partition with CABAC, this is not allowed", 500);

        // continue with reading next DP
        ftell_position = ftell(bits);
        if (input->FileFormat == PAR_OF_ANNEXB)
          ret=GetAnnexbNALU (nalu);
        else
          ret=GetRTPNALU (nalu);

        CheckZeroByteNonVCL(nalu, &ret);
        NALUtoRBSP(nalu);

        if (ret < 0)
          printf ("Error while getting the NALU in file format %s, exit\n", input->FileFormat==PAR_OF_ANNEXB?"Annex B":"RTP");
        if (ret == 0)
          return current_header;

        if ( NALU_TYPE_DPB == nalu->nal_unit_type)
        {
          // we got a DPB
          currStream             = currSlice->partArr[1].bitstream;
          currStream->ei_flag    = 0;
          currStream->frame_bitoffset = currStream->read_len = 0;

          memcpy (currStream->streamBuffer, &nalu->buf[1], nalu->len-1);
          currStream->code_len = currStream->bitstream_length = RBSPtoSODB(currStream->streamBuffer, nalu->len-1);

          slice_id_b  = ue_v("NALU: DP_B slice_id", currStream);

          if (slice_id_b != slice_id_a)
          {
            printf ("got a data partition B which does not match DP_A\n");
            // KS: needs error handling !!!
          }

          if (active_pps->redundant_pic_cnt_present_flag)
            redundant_pic_cnt_b = ue_v("NALU: DP_B redudant_pic_cnt", currStream);
          else
            redundant_pic_cnt_b = 0;

          // we're finished with DP_B, so let's continue with next DP
          ftell_position = ftell(bits);
          if (input->FileFormat == PAR_OF_ANNEXB)
            ret=GetAnnexbNALU (nalu);
          else
            ret=GetRTPNALU (nalu);

          CheckZeroByteNonVCL(nalu, &ret);
          NALUtoRBSP(nalu);

          if (ret < 0)
            printf ("Error while getting the NALU in file format %s, exit\n", input->FileFormat==PAR_OF_ANNEXB?"Annex B":"RTP");
          if (ret == 0)
            return current_header;
        }

        // check if we got DP_C
        if ( NALU_TYPE_DPC == nalu->nal_unit_type)
        {
          currStream             = currSlice->partArr[2].bitstream;
          currStream->ei_flag    = 0;
          currStream->frame_bitoffset = currStream->read_len = 0;

          memcpy (currStream->streamBuffer, &nalu->buf[1], nalu->len-1);
          currStream->code_len = currStream->bitstream_length = RBSPtoSODB(currStream->streamBuffer, nalu->len-1);

          slice_id_c  = ue_v("NALU: DP_C slice_id", currStream);
          if (slice_id_c != slice_id_a)
          {
            printf ("got a data partition C which does not match DP_A\n");
            // KS: needs error handling !!!
          }

          if (active_pps->redundant_pic_cnt_present_flag)
            redundant_pic_cnt_c = ue_v("NALU:SLICE_C redudand_pic_cnt", currStream);
          else
            redundant_pic_cnt_c = 0;
        }

        // check if we read anything else than the expected partitions
        if ((nalu->nal_unit_type != NALU_TYPE_DPB) && (nalu->nal_unit_type != NALU_TYPE_DPC))
        {
          // reset bitstream position and read again in next call
          fseek(bits, ftell_position, SEEK_SET);
        }

        FreeNALU(nalu);
        return current_header;

        break;
      case NALU_TYPE_DPB:
        printf ("found data partition B without matching DP A, discarding\n");
        break;
      case NALU_TYPE_DPC:
        printf ("found data partition C without matching DP A, discarding\n");
        break;
      case NALU_TYPE_SEI:
        printf ("read_new_slice: Found NALU_TYPE_SEI, len %d\n", nalu->len);
        InterpretSEIMessage(nalu->buf,nalu->len,img);
        break;
      case NALU_TYPE_PPS:
        ProcessPPS(nalu);
        break;
      case NALU_TYPE_SPS:
        ProcessSPS(nalu);
        break;
      case NALU_TYPE_AUD:
//        printf ("read_new_slice: Found 'Access Unit Delimiter' NAL unit, len %d, ignored\n", nalu->len);
        break;
      case NALU_TYPE_EOSEQ:
//        printf ("read_new_slice: Found 'End of Sequence' NAL unit, len %d, ignored\n", nalu->len);
        break;
      case NALU_TYPE_EOSTREAM:
//        printf ("read_new_slice: Found 'End of Stream' NAL unit, len %d, ignored\n", nalu->len);
        break;
      case NALU_TYPE_FILL:
        printf ("read_new_slice: Found NALU_TYPE_FILL, len %d\n", nalu->len);
        printf ("Skipping these filling bits, proceeding w/ next NALU\n");
        break;
      default:
        printf ("Found NALU type %d, len %d undefined, ignore NALU, moving on\n", nalu->nal_unit_type, nalu->len);
    }
  }
  FreeNALU(nalu);

  return  current_header;
}


/*!
 ************************************************************************
 * \brief
 *    Initializes the parameters for a new picture
 ************************************************************************
 */
void init_picture(struct img_par *img, struct inp_par *inp)
{
  int i,k,l;
  Slice *currSlice = img->currentSlice;

  if (dec_picture)
  {
    // this may only happen on slice loss
    exit_picture();
  }
  if (img->recovery_point)
    img->recovery_frame_num = (img->frame_num + img->recovery_frame_cnt) % img->MaxFrameNum;

  if (img->idr_flag)
    img->recovery_frame_num = img->frame_num;

  if (img->recovery_point == 0 && 
      img->frame_num != img->pre_frame_num && 
      img->frame_num != (img->pre_frame_num + 1) % img->MaxFrameNum) 
  {
    if (active_sps->gaps_in_frame_num_value_allowed_flag == 0)
    {
      // picture error concealment
      if(inp->conceal_mode !=0)
      {
        if((img->frame_num) < ((img->pre_frame_num + 1) % img->MaxFrameNum))
        {
          /* Conceal lost IDR frames and any frames immediately 
             following the IDR. Use frame copy for these since 
             lists cannot be formed correctly for motion copy*/
          img->conceal_mode = 1; 
          img->IDR_concealment_flag = 1;
          conceal_lost_frames(img);
          //reset to original concealment mode for future drops
          img->conceal_mode = inp->conceal_mode;
        }
        else
        {
          //reset to original concealment mode for future drops
          img->conceal_mode = inp->conceal_mode;

          img->IDR_concealment_flag = 0;
          conceal_lost_frames(img);
        }
      }
      else
      {   /* Advanced Error Concealment would be called here to combat unintentional loss of pictures. */
        error("An unintentional loss of pictures occurs! Exit\n", 100);
      }
    }
    if(img->conceal_mode == 0)
      fill_frame_num_gap(img);
  }

  if(img->nal_reference_idc)
  {
    img->pre_frame_num = img->frame_num;
  }

  //img->num_dec_mb = 0;
  
  //calculate POC
  decode_poc(img);

  if (img->recovery_frame_num == img->frame_num && 
      img->recovery_poc == 0x7fffffff)
    img->recovery_poc = img->framepoc;

⌨️ 快捷键说明

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