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

📄 slice.c

📁 JM 11.0 KTA 2.1 Source Code
💻 C
📖 第 1 页 / 共 5 页
字号:
      {
        //!Go back to the previous MB to recode it
        img->current_mb_nr = FmoGetPreviousMBNr(img->current_mb_nr);
        if(img->current_mb_nr == -1 )   // The first MB of the slice group  is too big,
          // which means it's impossible to encode picture using current slice bits restriction
        {
          snprintf (errortext, ET_SIZE, "Error encoding first MB with specified parameter, bits of current MB may be too big");
          error (errortext, 300);
        }
      }
    }
    else                      // TBD -- Addition of FMO
    {

      //! This following ugly code breaks slices, at least for a slice mode that accumulates a certain
      //! number of bits into one slice.  
      //! The suggested algorithm is as follows:
      //!
      //! SaveState (Bitstream, stats,  etc. etc.);
      //! BitsForThisMBPairInFrameMode = CodeMB (Upper, FRAME_MODE) + CodeMB (Lower, FRAME_MODE);
      //! DistortionForThisMBPairInFrameMode = CalculateDistortion(Upper) + CalculateDistortion (Lower);
      //! RestoreState();
      //! BitsForThisMBPairInFieldMode = CodeMB (Upper, FIELD_MODE) + CodeMB (Lower, FIELD_MODE);
      //! DistortionForThisMBPairInFrameMode = CalculateDistortion(Upper) + CalculateDistortion (Lower);
      //! FrameFieldMode = Decision (...)
      //! RestoreState()
      //! if (FrameFieldMode == FRAME) {
      //!   CodeMB (Upper, FRAME); CodeMB (Lower, FRAME);
      //! } else {
      //!   CodeMB (Upper FIELD); CodeMB (Lower, FIELD);
      //! }
      //!
      //! Open questions/issues:
      //!   1. CABAC/CA-VLC state:  It seems that the CABAC/CA_VLC states are changed during the
      //!      dummy encoding processes (for the R-D based selection), but that they are never
      //!      reset, once the selection is made.  I believe that this breaks the MB-adaptive
      //!      frame/field coding.  The necessary code for the state saves is readily available
      //!      in macroblock.c, start_macroblock() and terminate_macroblock() (this code needs
      //!      to be double checked that it works with CA-VLC as well
      //!   2. would it be an option to allocate Bitstreams with zero data in them (or copy the
      //!      already generated bitstream) for the "test coding"?  

      if (input->MbInterlace == ADAPTIVE_CODING)
      {
        //================ code MB pair as frame MB ================
        //----------------------------------------------------------
        recode_macroblock = FALSE;


        img->field_mode = 0;  // MB coded as frame
        img->top_field = 0;   // Set top field to 0

        //Rate control
        img->write_macroblock = 0;
        img->bot_MB = 0;   

        start_macroblock (CurrentMbAddr, FALSE);

        rdopt = &rddata_top_frame_mb; // store data in top frame MB
#ifdef ADAPTIVE_FD_SD_CODING
        currMB    = &img->mb_data[CurrentMbAddr];
        if (img->APEC_in_FD_and_SD==0)
        {
          currMB->SD_Coding_on_off=0;//Turn SD Coding off
          encode_one_macroblock ();
        }
        else
        {
          store_coding_state(cs_slice_coding1);
          slice_bits=stats->bit_slice;
          currMB->SD_Coding_on_off=1;//Turn SD Coding on
          encode_one_macroblock ();

          store_rdopt_data_for_FDSD_coding ();
          store_rdopt_data_for_FDSD_coding_interlace ();

          write_one_macroblock (1);     // write the Top MB data to the bitstream
          rate_only_FD=stats->bit_slice-slice_bits;
          SSD_only_FD=0;
          for (i=0;i<16;i++)
          {
            for (j=0;j<16;j++)
            {
#ifdef  INTERNAL_BIT_DEPTH_INCREASE
              SSD_only_FD+=SQR_DEPTH(enc_picture->imgY[img->pix_y+j][img->pix_x+i], imgY_org[img->opix_y+j][img->opix_x+i], input->BitDepthLuma, img->BitDepthIncrease);
#else
              SSD_only_FD+=img->quad[enc_picture->imgY[img->pix_y+j][img->pix_x+i]-imgY_org[img->opix_y+j][img->opix_x+i]];
#endif
            }
          }
          slice_bits=stats->bit_slice;
          reset_coding_state(cs_slice_coding1);
          currMB->SD_Coding_on_off=0;
          encode_one_macroblock ();
          write_one_macroblock (1);     // write the Top MB data to the bitstream
          rate_FD_and_SD=stats->bit_slice-slice_bits;
          reset_coding_state(cs_slice_coding1);
          SSD_FD_and_SD=0;
          for (i=0;i<16;i++)
          {
            for (j=0;j<16;j++)
            {
#ifdef  INTERNAL_BIT_DEPTH_INCREASE
              SSD_FD_and_SD+=SQR_DEPTH(enc_picture->imgY[img->pix_y+j][img->pix_x+i], imgY_org[img->opix_y+j][img->opix_x+i], input->BitDepthLuma, img->BitDepthIncrease);
#else
              SSD_FD_and_SD+=img->quad[enc_picture->imgY[img->pix_y+j][img->pix_x+i]-imgY_org[img->opix_y+j][img->opix_x+i]];
#endif
            }
          }
          rd_cost_only_FD  =(double)SSD_only_FD  +img->lambda_md[img->type][img->qp] * (double)rate_only_FD;
          rd_cost_FD_and_SD=(double)SSD_FD_and_SD+img->lambda_md[img->type][img->qp] * (double)rate_FD_and_SD;
          if (rd_cost_only_FD<rd_cost_FD_and_SD)
          {
            restore_rdopt_data_for_FDSD_coding();
            restore_rdopt_data_for_FDSD_coding_interlace ();
            slice_bits=stats->bit_slice;
            currMB->SD_Coding_on_off=1;
          }
        }
#else
        encode_one_macroblock ();     // code the MB as frame
#endif
        FrameRDCost = rdopt->min_rdcost;

        //***   Top MB coded as frame MB ***//

        //Rate control
        img->bot_MB = 1; //for Rate control

        // go to the bottom MB in the MB pair
        img->field_mode = 0;  // MB coded as frame  //GB

        start_macroblock (CurrentMbAddr+1, FALSE);
        rdopt = &rddata_bot_frame_mb; // store data in top frame MB
#ifdef ADAPTIVE_FD_SD_CODING
        currMB    = &img->mb_data[CurrentMbAddr+1];
        if (img->APEC_in_FD_and_SD==0)
        {
          currMB->SD_Coding_on_off=0;//Turn SD Coding off
          encode_one_macroblock ();
        }
        else
        {
          store_coding_state(cs_slice_coding1);
          slice_bits=stats->bit_slice;
          currMB->SD_Coding_on_off=1;//Turn SD Coding on
          encode_one_macroblock ();
          store_rdopt_data_for_FDSD_coding();
          store_rdopt_data_for_FDSD_coding_interlace ();
          write_one_macroblock (0);     // write the Bottom MB data to the bitstream
          rate_only_FD=stats->bit_slice-slice_bits;
          SSD_only_FD=0;
          for (i=0;i<16;i++)
          {
            for (j=0;j<16;j++)
            {
#ifdef  INTERNAL_BIT_DEPTH_INCREASE
              SSD_only_FD+=SQR_DEPTH(enc_picture->imgY[img->pix_y+j][img->pix_x+i], imgY_org[img->opix_y+j][img->opix_x+i], input->BitDepthLuma, img->BitDepthIncrease);
#else
              SSD_only_FD+=img->quad[enc_picture->imgY[img->pix_y+j][img->pix_x+i]-imgY_org[img->opix_y+j][img->opix_x+i]];
#endif
            }
          }
          slice_bits=stats->bit_slice;
          reset_coding_state(cs_slice_coding1);
          currMB->SD_Coding_on_off=0;
          encode_one_macroblock ();
          write_one_macroblock (0);     // write the Bottom MB data to the bitstream
          reset_coding_state(cs_slice_coding1);
          rate_FD_and_SD=stats->bit_slice-slice_bits;
          SSD_FD_and_SD=0;
          for (i=0;i<16;i++)
          {
            for (j=0;j<16;j++)
            {
#ifdef  INTERNAL_BIT_DEPTH_INCREASE
              SSD_FD_and_SD+=SQR_DEPTH(enc_picture->imgY[img->pix_y+j][img->pix_x+i], imgY_org[img->opix_y+j][img->opix_x+i], input->BitDepthLuma, img->BitDepthIncrease);
#else
              SSD_FD_and_SD+=img->quad[enc_picture->imgY[img->pix_y+j][img->pix_x+i]-imgY_org[img->opix_y+j][img->opix_x+i]];
#endif
            }
          }
          rd_cost_only_FD  =(double)SSD_only_FD  +img->lambda_md[img->type][img->qp] * (double)rate_only_FD;
          rd_cost_FD_and_SD=(double)SSD_FD_and_SD+img->lambda_md[img->type][img->qp] * (double)rate_FD_and_SD;
          if (rd_cost_only_FD<rd_cost_FD_and_SD)
          {
            restore_rdopt_data_for_FDSD_coding();
            restore_rdopt_data_for_FDSD_coding_interlace ();
            slice_bits=stats->bit_slice;
            currMB->SD_Coding_on_off=1;
          }
        }
#else
        encode_one_macroblock ();     // code the MB as frame
#endif
        FrameRDCost += rdopt->min_rdcost;

        //***   Bottom MB coded as frame MB ***//
      }

      if ((input->MbInterlace == ADAPTIVE_CODING) || (input->MbInterlace == FIELD_CODING))
      {
        //Rate control
        img->bot_MB = 0;

        //=========== start coding the MB pair as a field MB pair =============
        //---------------------------------------------------------------------
        img->field_mode = 1;  // MB coded as field
        img->top_field = 1;   // Set top field to 1
        img->buf_cycle <<= 1;
        input->num_ref_frames <<= 1;
        img->num_ref_idx_l0_active <<= 1;
        img->num_ref_idx_l0_active += 1;
        start_macroblock (CurrentMbAddr, TRUE);


        rdopt = &rddata_top_field_mb; // store data in top frame MB
        //        TopFieldIsSkipped = 0;        // set the top field MB skipped flag to 0
#ifdef ADAPTIVE_FD_SD_CODING
        currMB    = &img->mb_data[CurrentMbAddr];
        if (img->APEC_in_FD_and_SD==0)
        {
          currMB->SD_Coding_on_off=0;//Turn SD Coding off
          encode_one_macroblock ();
        }
        else
        {
          store_coding_state(cs_slice_coding1);
          slice_bits=stats->bit_slice;
          currMB->SD_Coding_on_off=1;//Turn SD Coding on
          encode_one_macroblock ();
          store_rdopt_data_for_FDSD_coding();
          store_rdopt_data_for_FDSD_coding_interlace ();

          write_one_macroblock (1);
          rate_only_FD=stats->bit_slice-slice_bits;
          reset_coding_state(cs_slice_coding1);
          SSD_only_FD=0;
          for (i=0;i<16;i++)
          {
            for (j=0;j<16;j++)
            {
#ifdef  INTERNAL_BIT_DEPTH_INCREASE
              SSD_only_FD+=SQR_DEPTH(enc_picture->imgY[img->pix_y+j][img->pix_x+i], imgY_org[img->opix_y+j][img->opix_x+i], input->BitDepthLuma, img->BitDepthIncrease);
#else
              SSD_only_FD+=img->quad[enc_picture->imgY[img->pix_y+j][img->pix_x+i]-imgY_org[img->opix_y+j][img->opix_x+i]];
#endif
            }
          }
          slice_bits=stats->bit_slice;
          currMB->SD_Coding_on_off=0;
          encode_one_macroblock ();
          write_one_macroblock (1);
          rate_FD_and_SD=stats->bit_slice-slice_bits;
          reset_coding_state(cs_slice_coding1);
          SSD_FD_and_SD=0;
          for (i=0;i<16;i++)
          {
            for (j=0;j<16;j++)
            {
#ifdef  INTERNAL_BIT_DEPTH_INCREASE
              SSD_FD_and_SD+=SQR_DEPTH(enc_picture->imgY[img->pix_y+j][img->pix_x+i], imgY_org[img->opix_y+j][img->opix_x+i], input->BitDepthLuma, img->BitDepthIncrease);
#else
              SSD_FD_and_SD+=img->quad[enc_picture->imgY[img->pix_y+j][img->pix_x+i]-imgY_org[img->opix_y+j][img->opix_x+i]];
#endif
            }
          }
          rd_cost_only_FD  =(double)SSD_only_FD  +img->lambda_md[img->type][img->qp] * (double)rate_only_FD;
          rd_cost_FD_and_SD=(double)SSD_FD_and_SD+img->lambda_md[img->type][img->qp] * (double)rate_FD_and_SD;
          if (rd_cost_only_FD<rd_cost_FD_and_SD)
          {
            restore_rdopt_data_for_FDSD_coding ();
            restore_rdopt_data_for_FDSD_coding_interlace ();
            slice_bits=stats->bit_slice;
            currMB->SD_Coding_on_off=1;
          }
        }
#else
        encode_one_macroblock ();     // code the MB as frame
#endif
        FieldRDCost = rdopt->min_rdcost;
        //***   Top MB coded as field MB ***//
        //Rate control
        img->bot_MB = 1;//for Rate control

        img->top_field = 0;   // Set top field to 0
        start_macroblock (CurrentMbAddr+1, TRUE);
        rdopt = &rddata_bot_field_mb; // store data in top frame MB
#ifdef ADAPTIVE_FD_SD_CODING
        currMB    = &img->mb_data[CurrentMbAddr+1];
        if (img->APEC_in_FD_and_SD==0)
        {
          currMB->SD_Coding_on_off=0;//Turn SD Coding off
          encode_one_macroblock ();
        }
        else
        {
          store_coding_state(cs_slice_coding1);
          slice_bits=stats->bit_slice;
          currMB->SD_Coding_on_off=1;//Turn SD Coding on
          encode_one_macroblock ();
          store_rdopt_data_for_FDSD_coding ();
          store_rdopt_data_for_FDSD_coding_interlace ();
          write_one_macroblock (0);
          rate_only_FD=stats->bit_slice-slice_bits;
          reset_coding_state(cs_slice_coding1);
          SSD_only_FD=0;
          for (i=0;i<16;i++)
          {
            for (j=0;j<16;j++)
            {
#ifdef  INTERNAL_BIT_DEPTH_INCREASE
              SSD_only_FD+=SQR_DEPTH(enc_picture->imgY[img->pix_y+j][img->pix_x+i], imgY_org[img->opix_y+j][img->opix_x+i], input->BitDepthLuma, img->BitDepthIncrease);
#else
              SSD_only_FD+=img->quad[enc_picture->imgY[img->pix_y+j][img->pix_x+i]-imgY_org[img->opix_y+j][img->opix_x+i]];
#endif
            }
          }
          slice_bits=stats->bit_slice;
          currMB->SD_Coding_on_off=0;
          write_one_macroblock (0);
          encode_one_macroblock ();
          rate_FD_and_SD=stats->bit_slice-slice_bits;
          reset_coding_state(cs_slice_coding1);
          SSD_FD_and_SD=0;
          for (i=0;i<16;i++)
          {
            for (j=0;j<16;j++)
            {
#ifdef  INTERNAL_BIT_DEPTH_INCREASE
              SSD_FD_and_SD+=SQR_DEPTH(enc_picture->imgY[img->pix_y+j][img->pix_x+i], imgY_org[img->opix_y+j][img->opix_x+i], input->BitDepthLuma, img->BitDepthIncrease);
#else
              SSD_FD_and_SD+=img->quad[enc_picture->imgY[img->pix_y+j][img->pix_x+i]-imgY_org[img->opix_y+j][img->opix_x+i]];
#endif
            }
          }
          rd_cost_only_FD  =(double)SSD_only_FD  +img->lambda_md[img->type][img->qp] * (double)rate_only_FD;
          rd_cost_FD_and_SD=(double)SSD_FD_and_SD+img->lambda_md[img->type][img->qp] * (double)rate_FD_and_SD;
          if (rd_cost_only_FD<rd_cost_FD_and_SD)
          {
            restore_rdopt_data_for_FDSD_coding();
            restore_rdopt_data_for_FDSD_coding_interlace ();
            slice_bits=stats->bit_slice;
            currMB->SD_Coding_on_off=1;
          }
        }
#else
        encode_one_macroblock ();     // code the MB as frame
#endif
        FieldRDCost += rdopt->min_rdcost;
        //***   Bottom MB coded as field MB ***//
      }

      //Rate control
      img->write_macroblock_frame = 0;  //Rate control

      //=========== decide between frame/field MB pair ============
      //-----------------------------------------------------------
      if ((input->MbInterlace == ADAPTIVE_CODING) && (FrameRDCost < FieldRDCost))
      {
        img->field_mode = 0;
        img->buf_cycle >>= 1;
        input->num_ref_frames >>= 1;
        MBPairIsField = 0;
        img->num_ref_idx_l0_active -= 1;
        img->num_ref_idx_l0_active >>= 1;

        //Rate control
        img->write_macroblock_frame = 1;  //for Rate control
      }
      else
      {
        img->field_mode = 1;
        MBPairIsField = 1;
      }

      //Rate control
      img->write_macroblock = 1;//Rate control 

      if (MBPairIsField)
        img->top_field = 1;
      else

⌨️ 快捷键说明

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