コード例 #1
0
ファイル: nalu.c プロジェクト: Foredoomed/JM
int Write_Filler_Data_NALU( VideoParameters *p_Vid, int num_bytes )
{  
  int     RBSPlen = num_bytes - 1;
  int     len, bytes_written = 0;
  byte    rbsp[MAXRBSPSIZE];
  byte    filler_byte = (byte)0xFF;
  byte    trailing_byte = (byte)0x80;
  NALU_t *nalu = AllocNALU( MAXNALUSIZE );

  num_bytes = iClip3( 1, (MAXRBSPSIZE - 2), num_bytes );
  assert( num_bytes > 0 && num_bytes < (MAXRBSPSIZE - 1) );

  num_bytes = imax( 2, num_bytes ); // one byte for the NAL header and one for the rbsp trailing byte

  if ( RBSPlen > 1 )
  {
    while ( bytes_written < (RBSPlen - 1) )
    {
      rbsp[ bytes_written++ ] = filler_byte;
    }
  }
  rbsp[ bytes_written++ ] = trailing_byte; // rbsp_trailing_bits    
  assert( num_bytes == (bytes_written + 1) );  

  // write RBSP into NALU
  RBSPtoNALU( rbsp, nalu, RBSPlen, NALU_TYPE_FILL, NALU_PRIORITY_DISPOSABLE, 1 );
  // write NALU into bitstream
  len = p_Vid->WriteNALU( p_Vid, nalu, p_Vid->f_out );
  p_Vid->bytes_in_picture += (nalu->len + 1);

  FreeNALU( nalu );

  return len;
}
コード例 #2
0
ファイル: explicit_gop.c プロジェクト: 5432935/crossbridge
/*!
************************************************************************
* \brief
*    Interpret GOP struct from input parameters
************************************************************************
*/
void interpret_gop_structure()
{

  int nLength = strlen(input->ExplicitHierarchyFormat);
  int i =0, k, dqp, display_no;
  int slice_read =0, order_read = 0, stored_read = 0, qp_read =0;
  int coded_frame = 0;

  if (nLength > 0)
  {

    for (i = 0; i < nLength ; i++)
    {
      //! First lets read slice type
      if (slice_read == 0)
      {
        switch (input->ExplicitHierarchyFormat[i])
        {
        case 'P':
        case 'p':
          gop_structure[coded_frame].slice_type=P_SLICE;
          break;
        case 'B':
        case 'b':
          gop_structure[coded_frame].slice_type=B_SLICE;
          break;
        case 'I':
        case 'i':
          gop_structure[coded_frame].slice_type=I_SLICE;
          break;
        default:
          snprintf(errortext, ET_SIZE, "Slice Type invalid in ExplicitHierarchyFormat param. Please check configuration file.");
          error (errortext, 400);
          break;
        }
        slice_read = 1;
      }
      else
      {
        //! Next is Display Order
        if (order_read == 0)
        {
          if (isdigit((int)(*(input->ExplicitHierarchyFormat+i))))
          {
            sscanf(input->ExplicitHierarchyFormat+i,"%d",&display_no);
            gop_structure[coded_frame].display_no = display_no;
            order_read = 1;
            if (display_no<0 || display_no>=input->jumpd)
            {
              snprintf(errortext, ET_SIZE, "Invalid Frame Order value. Frame position needs to be in [0,%d] range.",input->jumpd-1);
              error (errortext, 400);
            }
            for (k=0;k<coded_frame;k++)
            {
              if (gop_structure[k].display_no == display_no)
              {
                snprintf(errortext, ET_SIZE, "Frame Order value %d in frame %d already used for enhancement frame %d.",display_no,coded_frame,k);
                error (errortext, 400);
              }
            }
          }
          else
          {
            snprintf(errortext, ET_SIZE, "Slice Type needs to be followed by Display Order. Please check configuration file.");
            error (errortext, 400);
          }
        }
        else if (order_read == 1)
        {
          if (stored_read == 0 && !(isdigit((int)(*(input->ExplicitHierarchyFormat+i)))))
          {
            switch (input->ExplicitHierarchyFormat[i])
            {
            case 'E':
            case 'e':
              gop_structure[coded_frame].reference_idc = NALU_PRIORITY_DISPOSABLE;
              gop_structure[coded_frame].hierarchy_layer = 0;
              break;
            case 'R':
            case 'r':
              gop_structure[coded_frame].reference_idc= NALU_PRIORITY_HIGH;
              gop_structure[coded_frame].hierarchy_layer = 1;
              img->GopLevels = 2;
              break;
            default:
              snprintf(errortext, ET_SIZE, "Reference_IDC invalid in ExplicitHierarchyFormat param. Please check configuration file.");
              error (errortext, 400);
              break;
            }
            stored_read = 1;
          }
          else if (stored_read == 1 && qp_read == 0)
          {
            if (isdigit((int)(*(input->ExplicitHierarchyFormat+i))))
            {
              sscanf(input->ExplicitHierarchyFormat+i,"%d",&dqp);

              if (gop_structure[coded_frame].slice_type == I_SLICE)
                gop_structure[coded_frame].slice_qp = input->qp0;
              else if (gop_structure[coded_frame].slice_type == P_SLICE)
                gop_structure[coded_frame].slice_qp = input->qpN;
              else
                gop_structure[coded_frame].slice_qp = input->qpB;

              gop_structure[coded_frame].slice_qp = iClip3(-img->bitdepth_luma_qp_scale, 51,gop_structure[coded_frame].slice_qp + dqp);
                qp_read = 1;
            }
            else
            {
              snprintf(errortext, ET_SIZE, "Reference_IDC needs to be followed by QP. Please check configuration file.");
              error (errortext, 400);
            }
          }
          else if (stored_read == 1 && qp_read == 1 && !(isdigit((int)(*(input->ExplicitHierarchyFormat+i)))) && (i < nLength - 2))
          {
            stored_read =0;
            qp_read=0;
            order_read=0;
            slice_read=0;
            i--;
            coded_frame ++;
            if (coded_frame >= input->jumpd )
            {
              snprintf(errortext, ET_SIZE, "Total number of frames in Enhancement GOP need to be fewer or equal to FrameSkip parameter.");
              error (errortext, 400);
            }
          }
        }
      }
    }
  }
  else
  {
    snprintf(errortext, ET_SIZE, "ExplicitHierarchyFormat is empty. Please check configuration file.");
    error (errortext, 400);
  }

  input->successive_Bframe = coded_frame + 1;
}
コード例 #3
0
ファイル: image_mp.c プロジェクト: Foredoomed/JM
void frame_picture_mp_b_slice(VideoParameters *p_Vid, InputParameters *p_Inp)
{
  int   rd_pass = 0;
  int   rd_qp = p_Vid->p_curr_frm_struct->qp;
  float rateRatio = 1.0F;
  int   wp_pass = 0;
  CodingInfo coding_info;
  FrameCodingMethod best_method = REGULAR;
  int apply_wp = 0;
  int selection;
  Slice *dummy_slice = NULL;

#if (DBG_IMAGE_MP)
  printf("pass0_wp = %d\n", p_Vid->pass0_wp);
#endif  

  frame_picture (p_Vid, p_Vid->frame_pic[rd_pass], &p_Vid->imgData, rd_pass);
  store_coding_and_rc_info(p_Vid, &coding_info);
  
  if(p_Inp->WPIterMC)
    p_Vid->frameOffsetAvail = 1; 

  rd_pass++;
  if(rd_pass >= p_Inp->RDPictureMaxPassBSlice)
  {
    frame_picture_mp_exit(p_Vid, &coding_info);
    return;
  }

  init_slice_lite(p_Vid, &dummy_slice, 0);

#if (DBG_IMAGE_MP)
    printf("rd_pass = %d: %d (%.0f, %.0f, %.0f)\n", rd_pass, 
      p_Vid->frame_pic[0]->bits_per_picture, 
      p_Vid->frame_pic[0]->distortion.value[0], p_Vid->frame_pic[0]->distortion.value[1], p_Vid->frame_pic[0]->distortion.value[2]);
#endif

  // for B_Slice, consider implicit WP 
  wp_pass = 0;
  {    
    if (p_Inp->GenerateMultiplePPS)
    {
      InitWP(p_Vid, p_Inp, 0);
      if ( p_Inp->WPMCPrecision )
        p_Vid->pWPX->curr_wp_rd_pass = p_Vid->pWPX->wp_rd_passes + 1;

      if (p_Vid->TestWPBSlice(dummy_slice, 1) == 1)
      {
        // regular WP pass
        p_Vid->active_pps = p_Vid->PicParSet[2];
        if(p_Inp->WPMCPrecision)
          p_Vid->pWPX->curr_wp_rd_pass->algorithm = WP_REGULAR;
        wp_pass = 1;
      }
    }

    if(wp_pass)
    {
      p_Vid->write_macroblock = FALSE;
      p_Vid->p_curr_frm_struct->qp = p_Vid->qp;
      frame_picture (p_Vid, p_Vid->frame_pic[rd_pass], &p_Vid->imgData, rd_pass);
      selection = picture_coding_decision(p_Vid, p_Vid->frame_pic[0], p_Vid->frame_pic[rd_pass], rd_qp);
#if (DBG_IMAGE_MP)
      printf("IMP WP, rd_pass = %d, selection = %d\n", rd_pass, selection);
      printf("rd_pass = %d: %d (%.0f, %.0f, %.0f)\n", rd_pass, 
        p_Vid->frame_pic[rd_pass]->bits_per_picture, 
        p_Vid->frame_pic[rd_pass]->distortion.value[0], p_Vid->frame_pic[rd_pass]->distortion.value[1], p_Vid->frame_pic[rd_pass]->distortion.value[2]);
#endif

      if (selection)
      {
        swap_frame_buffer(p_Vid, 0, rd_pass); 
        store_coding_and_rc_info(p_Vid, &coding_info);
        best_method = IMP_WP; 
        apply_wp = IMP_WP;
      }

      rd_pass++;
      if(rd_pass >= p_Inp->RDPictureMaxPassBSlice)
      {
        frame_picture_mp_exit(p_Vid, &coding_info);
        free_slice(dummy_slice);
        return;
      }
    }

    // for B_Slice, consider explicit WP 
    wp_pass = 0;
    if (p_Inp->GenerateMultiplePPS)
    {
      InitWP(p_Vid, p_Inp, 0);
      if( p_Inp->WPMCPrecision )
        p_Vid->pWPX->curr_wp_rd_pass = p_Vid->pWPX->wp_rd_passes + 1;

      if (p_Vid->TestWPBSlice(dummy_slice, 0) == 1)
      {
        // regular WP pass
        p_Vid->active_pps = p_Vid->PicParSet[1];
        if( p_Inp->WPMCPrecision )
          p_Vid->pWPX->curr_wp_rd_pass->algorithm = WP_REGULAR;
        wp_pass = 1;
      }
      else if ( p_Inp->WPMCPrecision == 2 && (p_Inp->WPMCPrecBSlice == 2 || (p_Inp->WPMCPrecBSlice == 1 && p_Vid->nal_reference_idc) ) )
      {
        p_Vid->active_pps = p_Vid->PicParSet[1];
        wp_pass = 1;
      }
    }

    if(wp_pass)
    {
      p_Vid->write_macroblock = FALSE;
      p_Vid->p_curr_frm_struct->qp = p_Vid->qp;
      frame_picture (p_Vid, p_Vid->frame_pic[rd_pass], &p_Vid->imgData, rd_pass);
      selection = picture_coding_decision(p_Vid, p_Vid->frame_pic[0], p_Vid->frame_pic[rd_pass], rd_qp);
#if (DBG_IMAGE_MP)
      printf("EXP WP, rd_pass = %d, selection = %d\n", rd_pass, selection);
      printf("rd_pass = %d: %d (%.0f, %.0f, %.0f)\n", rd_pass, 
        p_Vid->frame_pic[rd_pass]->bits_per_picture, 
        p_Vid->frame_pic[rd_pass]->distortion.value[0], p_Vid->frame_pic[rd_pass]->distortion.value[1], p_Vid->frame_pic[rd_pass]->distortion.value[2]);
#endif

      if (selection)
      {
        swap_frame_buffer(p_Vid, 0, rd_pass); 
        store_coding_and_rc_info(p_Vid, &coding_info);
        best_method = EXP_WP;
        apply_wp = EXP_WP;
      }

      rd_pass++;
      if(rd_pass >= p_Inp->RDPictureMaxPassBSlice)
      {
        frame_picture_mp_exit(p_Vid, &coding_info);
        free_slice(dummy_slice);
        return;
      }
    }
  }

  if(p_Inp->RDPictureFrameQPBSlice)
  {
    // frame QP pass
    p_Vid->active_pps = best_method == EXP_WP ? p_Vid->PicParSet[1]:best_method==IMP_WP?p_Vid->PicParSet[2]:p_Vid->PicParSet[0];
    //p_Vid->qp = (p_Vid->nal_reference_idc==0 ? rd_qp + 1 : rd_qp - 1);
    p_Vid->qp = (p_Vid->nal_reference_idc==0 ? rd_qp + 1 : rd_qp );
    p_Vid->qp = iClip3( p_Vid->RCMinQP, p_Vid->RCMaxQP, p_Vid->qp );
    if ( p_Inp->RCEnable )
    {
      rateRatio = p_Vid->nal_reference_idc ? 1.15F : 0.85F;
      rc_init_frame_rdpic( p_Vid, p_Inp, rateRatio );
    }

    p_Vid->write_macroblock = FALSE;
    p_Vid->p_curr_frm_struct->qp = p_Vid->qp;
    frame_picture (p_Vid, p_Vid->frame_pic[rd_pass], &p_Vid->imgData, rd_pass);
    selection = picture_coding_decision(p_Vid, p_Vid->frame_pic[0], p_Vid->frame_pic[rd_pass], rd_qp);
#if (DBG_IMAGE_MP)
    printf("frame QP, rd_pass = %d, selection = %d \n", rd_pass, selection);
    printf("rd_pass = %d: %d (%.0f, %.0f, %.0f)\n", rd_pass, 
      p_Vid->frame_pic[rd_pass]->bits_per_picture, 
      p_Vid->frame_pic[rd_pass]->distortion.value[0], p_Vid->frame_pic[rd_pass]->distortion.value[1], p_Vid->frame_pic[rd_pass]->distortion.value[2]);
#endif

    if (selection)
    {
      swap_frame_buffer(p_Vid, 0, rd_pass); 
      store_coding_and_rc_info(p_Vid, &coding_info);
      best_method = FRAME_QP; 
    }

    rd_pass++;
    if(rd_pass >= p_Inp->RDPictureMaxPassBSlice)
    {
      frame_picture_mp_exit(p_Vid, &coding_info);
      free_slice(dummy_slice);
      return;
    }
  }

  // alternative direct mode pass
  if(p_Inp->RDPictureDirectMode)
  {
    // consider using the best coding "method" found so far
    p_Vid->active_pps = apply_wp == IMP_WP ? p_Vid->PicParSet[1]:apply_wp==EXP_WP?p_Vid->PicParSet[2]:p_Vid->PicParSet[0];
    if(best_method == FRAME_QP)
      p_Vid->qp = (p_Vid->nal_reference_idc==0 ? rd_qp+1:rd_qp-1);
    else 
      p_Vid->qp = rd_qp; 
    p_Vid->qp = iClip3( p_Vid->RCMinQP, p_Vid->RCMaxQP, p_Vid->qp );
    // flip direct mode type
    p_Vid->direct_spatial_mv_pred_flag = 1-p_Vid->direct_spatial_mv_pred_flag;
    p_Vid->write_macroblock = FALSE;
    p_Vid->p_curr_frm_struct->qp = p_Vid->qp;
    frame_picture (p_Vid, p_Vid->frame_pic[rd_pass], &p_Vid->imgData, rd_pass);
    selection = picture_coding_decision(p_Vid, p_Vid->frame_pic[0], p_Vid->frame_pic[rd_pass], rd_qp);
#if (DBG_IMAGE_MP)
    printf("alternate direct mode, rd_pass = %d, selection = %d\n", rd_pass, selection);
#endif

    if (selection)
    {
      swap_frame_buffer(p_Vid, 0, rd_pass); 
      store_coding_and_rc_info(p_Vid, &coding_info);
      best_method = ALT_DIRECT;
    }

    rd_pass++;
    if(rd_pass >= p_Inp->RDPictureMaxPassBSlice)
    {
      frame_picture_mp_exit(p_Vid, &coding_info);
      free_slice(dummy_slice);
      return;
    }
  }
  frame_picture_mp_exit(p_Vid, &coding_info);
  free_slice(dummy_slice);
  return;
}
コード例 #4
0
ファイル: image_mp.c プロジェクト: Foredoomed/JM
void frame_picture_mp_i_slice(VideoParameters *p_Vid, InputParameters *p_Inp)
{
  int rd_pass = 0;
  int   qp = p_Vid->qp;
  float rateRatio = 1.0F;
  CodingInfo coding_info; 
  int selection;

  // initial pass encoding
  frame_picture (p_Vid, p_Vid->frame_pic[rd_pass], &p_Vid->imgData, rd_pass);
  store_coding_and_rc_info(p_Vid, &coding_info);

  rd_pass++;
  if(rd_pass >= p_Inp->RDPictureMaxPassISlice)
  {
    frame_picture_mp_exit(p_Vid, &coding_info);
    return;
  }

  {
    // try QP-1
    qp = p_Vid->qp;
    p_Vid->qp = qp - 1;
    p_Vid->qp = iClip3( p_Vid->RCMinQP, p_Vid->RCMaxQP, p_Vid->qp );
    if ( p_Inp->RCEnable )
    {
      rateRatio = 1.15F;
      rc_init_frame_rdpic( p_Vid, p_Inp, rateRatio );
    }

    p_Vid->write_macroblock = FALSE;
    p_Vid->p_curr_frm_struct->qp = p_Vid->qp;
    frame_picture (p_Vid, p_Vid->frame_pic[rd_pass], &p_Vid->imgData, rd_pass);
    selection = picture_coding_decision(p_Vid, p_Vid->frame_pic[0], p_Vid->frame_pic[rd_pass], qp);

    if (selection)
    {
      swap_frame_buffer(p_Vid, 0, rd_pass); 
      store_coding_and_rc_info(p_Vid, &coding_info);
    }

    rd_pass++;
    if(rd_pass >= p_Inp->RDPictureMaxPassISlice)
    {
      frame_picture_mp_exit(p_Vid, &coding_info);
      return;
    }

    // try QP+1
    p_Vid->qp    = (qp + 1);
    p_Vid->qp = iClip3( p_Vid->RCMinQP, p_Vid->RCMaxQP, p_Vid->qp );
    p_Vid->write_macroblock = FALSE;

    if ( p_Inp->RCEnable )
    {
      rateRatio = 1.0F;
      rc_init_frame_rdpic( p_Vid, p_Inp, rateRatio );
    }

    p_Vid->qp = iClip3( p_Vid->RCMinQP, p_Vid->RCMaxQP, p_Vid->qp );
    p_Vid->p_curr_frm_struct->qp = p_Vid->qp;
    frame_picture (p_Vid, p_Vid->frame_pic[rd_pass], &p_Vid->imgData, rd_pass);
    selection  = picture_coding_decision(p_Vid, p_Vid->frame_pic[0], p_Vid->frame_pic[rd_pass], qp);

    if ( selection )
    {
      swap_frame_buffer(p_Vid, 0, rd_pass);
      store_coding_and_rc_info(p_Vid, &coding_info);
    }

    rd_pass++;
    if(rd_pass >= p_Inp->RDPictureMaxPassISlice)
    {
      frame_picture_mp_exit(p_Vid, &coding_info);
      return;
    }
  }

  frame_picture_mp_exit(p_Vid, &coding_info);
}
コード例 #5
0
ファイル: image_mp.c プロジェクト: Foredoomed/JM
void frame_picture_mp_p_slice(VideoParameters *p_Vid, InputParameters *p_Inp)
{
  int   rd_pass = 0;
  int   rd_qp = p_Vid->p_curr_frm_struct->qp;
  float rateRatio = 1.0F;
  int   wp_pass=0;
  int   frame_type_pass = 0;
  CodingInfo coding_info;
  FrameCodingMethod best_method = REGULAR; 
  int frame_type = P_SLICE; 
  int apply_wp = 0;
  int selection;

  frame_picture (p_Vid, p_Vid->frame_pic[rd_pass], &p_Vid->imgData, rd_pass);
  store_coding_and_rc_info(p_Vid, &coding_info);

  if(p_Inp->WPIterMC)
    p_Vid->frameOffsetAvail = 1; 

#if (DBG_IMAGE_MP)
    printf("rd_pass = %d: %d (%.0f, %.0f, %.0f)\n", rd_pass, 
      p_Vid->frame_pic[0]->bits_per_picture, 
      p_Vid->frame_pic[0]->distortion.value[0], p_Vid->frame_pic[0]->distortion.value[1], p_Vid->frame_pic[0]->distortion.value[2]);
#endif

  rd_pass++;
  if(rd_pass >= p_Inp->RDPictureMaxPassPSlice)
  {
    frame_picture_mp_exit(p_Vid, &coding_info);
    return;
  }

  // for P_Slice, consider WP  
  wp_pass = 0;
  if (p_Inp->GenerateMultiplePPS)
  {
    Slice *dummy_slice = NULL;

    InitWP(p_Vid, p_Inp, 0);
    if ( p_Inp->WPMCPrecision )
      p_Vid->pWPX->curr_wp_rd_pass = p_Vid->pWPX->wp_rd_passes + 1;
    init_slice_lite(p_Vid, &dummy_slice, 0);

    if (p_Vid->TestWPPSlice(dummy_slice, 0) == 1)
    {
      // regular WP pass
      p_Vid->active_pps = p_Vid->PicParSet[1];
      if ( p_Inp->WPMCPrecision )
        p_Vid->pWPX->curr_wp_rd_pass->algorithm = WP_REGULAR;
      wp_pass = 1;
    }
    else if ( p_Inp->WPMCPrecision )
    {
      // WPMC pass
      p_Vid->active_pps = p_Vid->PicParSet[1];
      wp_pass = 1;
    }  

    // The way it is, the code would only reach here if prior conditional using 
    // generatemultiplepps is satisfied
    if(wp_pass)
    {
      p_Vid->write_macroblock = FALSE;
      p_Vid->p_curr_frm_struct->qp = p_Vid->qp;
      frame_picture (p_Vid, p_Vid->frame_pic[rd_pass], &p_Vid->imgData, rd_pass);
      selection = picture_coding_decision(p_Vid, p_Vid->frame_pic[0], p_Vid->frame_pic[rd_pass], rd_qp);
#if (DBG_IMAGE_MP)
      printf("rd_pass = %d, selection = %d\n", rd_pass, selection);
#endif
#if (DBG_IMAGE_MP)
      printf("rd_pass = %d: %d (%.0f, %.0f, %.0f)\n", rd_pass, 
        p_Vid->frame_pic[rd_pass]->bits_per_picture, 
        p_Vid->frame_pic[rd_pass]->distortion.value[0], p_Vid->frame_pic[rd_pass]->distortion.value[1], p_Vid->frame_pic[rd_pass]->distortion.value[2]);
#endif

      if (selection)
      {
        swap_frame_buffer(p_Vid, 0, rd_pass); 
        store_coding_and_rc_info(p_Vid, &coding_info);
        best_method = EXP_WP;
        apply_wp = 1;
      }

      if(p_Inp->WPMethod == 0 || p_Inp->WPMCPrecision) 
      {
        wp_pass = 0;
        if ( p_Inp->WPMCPrecision )
          p_Vid->pWPX->curr_wp_rd_pass = p_Vid->pWPX->wp_rd_passes + 2;
        if (p_Inp->WPMethod == 0 && p_Vid->TestWPPSlice(dummy_slice, 1) == 1)
        {
          // regular WP pass
          p_Vid->active_pps = p_Vid->PicParSet[1];
          if ( p_Inp->WPMCPrecision )
            p_Vid->pWPX->curr_wp_rd_pass->algorithm = WP_REGULAR;
          wp_pass = 1;
        }
        else if ( p_Inp->WPMCPrecision )
        {
          // WPMC pass
          p_Vid->active_pps = p_Vid->PicParSet[1];
          wp_pass = 1;
        }

        if(wp_pass)
        {
          p_Vid->write_macroblock = FALSE;
          p_Vid->p_curr_frm_struct->qp = p_Vid->qp;
          free_slice_list(p_Vid->frame_pic[rd_pass]);
          free_storable_picture(p_Vid, p_Vid->enc_frame_picture[rd_pass]);
          frame_picture (p_Vid, p_Vid->frame_pic[rd_pass], &p_Vid->imgData, rd_pass);
          selection = picture_coding_decision(p_Vid, p_Vid->frame_pic[0], p_Vid->frame_pic[rd_pass], rd_qp);
#if (DBG_IMAGE_MP)
          printf("rd_pass = %d, selection = %d\n", rd_pass, selection);
#endif
#if (DBG_IMAGE_MP)
          printf("rd_pass = %d: %d (%.0f, %.0f, %.0f)\n", rd_pass, 
            p_Vid->frame_pic[rd_pass]->bits_per_picture, 
            p_Vid->frame_pic[rd_pass]->distortion.value[0], p_Vid->frame_pic[rd_pass]->distortion.value[1], p_Vid->frame_pic[rd_pass]->distortion.value[2]);
#endif

          if (selection)
          {
            swap_frame_buffer(p_Vid, 0, rd_pass); 
            store_coding_and_rc_info(p_Vid, &coding_info);
            best_method = EXP_WP;
            apply_wp = 1;
          }
        }
      }

      rd_pass++;
      //free_slice(dummy_slice);

      if(rd_pass >= p_Inp->RDPictureMaxPassPSlice)
      {
        frame_picture_mp_exit(p_Vid, &coding_info);
        free_slice(dummy_slice);
        return;
      }
    }
    free_slice(dummy_slice);
  }


  // code as I? or maybe as B?
  frame_type_pass = 0;
  if(p_Inp->RDPSliceITest && (coding_info.intras * 100/p_Vid->FrameSizeInMbs) >= 75)
  {
    frame_type = I_SLICE; 
    set_slice_type(p_Vid, p_Inp, I_SLICE);
    populate_frame_slice_type( p_Inp, p_Vid->p_curr_frm_struct, I_SLICE, p_Vid->p_pred->max_num_slices );
    p_Vid->active_pps = p_Vid->PicParSet[0];
    frame_type_pass = 1;
  }
  else if (p_Inp->RDPSliceBTest && p_Vid->active_sps->profile_idc != BASELINE)
  // later need to add some automatic criterion to see if this (coding P as B) may be beneficial 
  {
    frame_type = B_SLICE; 
    set_slice_type(p_Vid, p_Inp, B_SLICE );
    populate_frame_slice_type( p_Inp, p_Vid->p_curr_frm_struct, B_SLICE, p_Vid->p_pred->max_num_slices );
    p_Vid->active_pps = p_Vid->PicParSet[0];
    frame_type_pass = 1;
  }

  if(frame_type_pass)
  {
    p_Vid->write_macroblock = FALSE;
    p_Vid->p_curr_frm_struct->qp = p_Vid->qp;
    frame_picture (p_Vid, p_Vid->frame_pic[rd_pass], &p_Vid->imgData, rd_pass);
    selection = picture_coding_decision(p_Vid, p_Vid->frame_pic[0], p_Vid->frame_pic[rd_pass], rd_qp);
#if (DBG_IMAGE_MP)
  printf("rd_pass = %d, selection = %d\n", rd_pass, selection);
#endif

    if (selection)
    {
      swap_frame_buffer(p_Vid, 0, rd_pass); 
      store_coding_and_rc_info(p_Vid, &coding_info);
      best_method = FRAME_TYPE; 
    }
    // reset frame_type
    else 
      frame_type = P_SLICE;

    rd_pass++;
    if(rd_pass >= p_Inp->RDPictureMaxPassPSlice)
    {
      frame_picture_mp_exit(p_Vid, &coding_info);
      return;
    }
  }

  if(p_Vid->EvaluateDBOff)
  {
    // Perform DB off coding pass
    p_Vid->active_pps = (best_method == EXP_WP?p_Vid->PicParSet[1]:p_Vid->PicParSet[0]);
    if(frame_type != P_SLICE)
    {
      set_slice_type(p_Vid, p_Inp, frame_type);
      populate_frame_slice_type( p_Inp, p_Vid->p_curr_frm_struct, frame_type, p_Vid->p_pred->max_num_slices );
    }
    p_Vid->TurnDBOff = 1; 
    p_Vid->write_macroblock = FALSE;
    p_Vid->p_curr_frm_struct->qp = p_Vid->qp;
    frame_picture (p_Vid, p_Vid->frame_pic[rd_pass], &p_Vid->imgData, rd_pass);
    selection = picture_coding_decision(p_Vid, p_Vid->frame_pic[0], p_Vid->frame_pic[rd_pass], rd_qp);
#if (DBG_IMAGE_MP)
  printf("DB OFF, rd_pass = %d, selection = %d\n", rd_pass, selection);
#endif

    if (selection)
    {
      swap_frame_buffer(p_Vid, 0, rd_pass); 
      store_coding_and_rc_info(p_Vid, &coding_info);
      best_method = DB_OFF; 
    }

    rd_pass++;
    if(rd_pass >= p_Inp->RDPictureMaxPassPSlice)
    {
      frame_picture_mp_exit(p_Vid, &coding_info);
      return;
    }
  }

  if(p_Inp->RDPictureFrameQPPSlice)
  {
    // frame QP pass
    p_Vid->active_pps = (apply_wp?p_Vid->PicParSet[1]:p_Vid->PicParSet[0]);
    if(frame_type != P_SLICE)
    {
      set_slice_type(p_Vid, p_Inp, frame_type);
      populate_frame_slice_type( p_Inp, p_Vid->p_curr_frm_struct, I_SLICE, p_Vid->p_pred->max_num_slices );
    }
    p_Vid->qp = (p_Vid->nal_reference_idc==0 ? rd_qp+1:rd_qp-1);
    p_Vid->qp = iClip3( p_Vid->RCMinQP, p_Vid->RCMaxQP, p_Vid->qp );
    if ( p_Inp->RCEnable )
    {
      rateRatio = p_Vid->nal_reference_idc ? 1.15F : 0.85F;
      rc_init_frame_rdpic( p_Vid, p_Inp, rateRatio );
    }
    p_Vid->TurnDBOff = 0;
    p_Vid->write_macroblock = FALSE;
    p_Vid->p_curr_frm_struct->qp = p_Vid->qp;
    frame_picture (p_Vid, p_Vid->frame_pic[rd_pass], &p_Vid->imgData, rd_pass);
    selection = picture_coding_decision(p_Vid, p_Vid->frame_pic[0], p_Vid->frame_pic[rd_pass], rd_qp);
#if (DBG_IMAGE_MP)
    printf("rd_pass = %d, selection = %d\n", rd_pass, selection);
#endif

    if (selection)
    {
      swap_frame_buffer(p_Vid, 0, rd_pass); 
      store_coding_and_rc_info(p_Vid, &coding_info);
      best_method = FRAME_QP;
    }

    rd_pass++;
    if(rd_pass >= p_Inp->RDPictureMaxPassPSlice)
    {
      frame_picture_mp_exit(p_Vid, &coding_info);
      return;
    }
  }

  frame_picture_mp_exit(p_Vid, &coding_info);
}
コード例 #6
0
/*!
************************************************************************
* \brief
*    Interpret GOP struct from input parameters
************************************************************************
*/
void interpret_gop_structure(VideoParameters *p_Vid, InputParameters *p_Inp)
{
  int nLength = (int) strlen(p_Inp->ExplicitHierarchyFormat);
  int i =0, k, dqp, display_no;
  int slice_read =0, order_read = 0, stored_read = 0, qp_read =0;
  int coded_frame = 0;
  int tlyr, temporal_layer_read = 0; 

  if (nLength > 0)
  {

    for (i = 0; i < nLength ; i++)
    {
      //! First lets read slice type
      if (slice_read == 0)
      {
        switch (p_Inp->ExplicitHierarchyFormat[i])
        {
        case 'P':
        case 'p':
          p_Vid->gop_structure[coded_frame].slice_type = P_SLICE;
          break;
        case 'B':
        case 'b':
          p_Vid->gop_structure[coded_frame].slice_type = B_SLICE;
          break;
        case 'I':
        case 'i':
          p_Vid->gop_structure[coded_frame].slice_type = I_SLICE;
          break;
        default:
          snprintf(errortext, ET_SIZE, "Slice Type invalid in ExplicitHierarchyFormat param. Please check configuration file.");
          error (errortext, 400);
          break;
        }
        slice_read = 1;
      }
      else
      {
        //! Next is Display Order
        if (order_read == 0)
        {
          if (isdigit((int)(*(p_Inp->ExplicitHierarchyFormat+i))))
          {
            sscanf(p_Inp->ExplicitHierarchyFormat+i,"%d",&display_no);
            p_Vid->gop_structure[coded_frame].display_no = display_no;
            order_read = 1;
            if (display_no < 0 || display_no >= p_Inp->NumberBFrames)
            {
              snprintf(errortext, ET_SIZE, "Invalid Frame Order value. Frame position needs to be in [0,%d] range.",p_Inp->NumberBFrames - 1);
              error (errortext, 400);
            }
            for (k=0;k<coded_frame;k++)
            {
              if (p_Vid->gop_structure[k].display_no == display_no)
              {
                snprintf(errortext, ET_SIZE, "Frame Order value %d in frame %d already used for enhancement frame %d.",display_no,coded_frame,k);
                error (errortext, 400);
              }
            }
          }
          else
          {
            snprintf(errortext, ET_SIZE, "Slice Type needs to be followed by Display Order. Please check configuration file.");
            error (errortext, 400);
          }
        }
        else if (order_read == 1)
        {
          if (stored_read == 0 && !(isdigit((int)(*(p_Inp->ExplicitHierarchyFormat+i)))))
          {
            switch (p_Inp->ExplicitHierarchyFormat[i])
            {
            case 'E':
            case 'e':
              p_Vid->gop_structure[coded_frame].reference_idc = NALU_PRIORITY_DISPOSABLE;
              p_Vid->gop_structure[coded_frame].hierarchy_layer = 0;
              break;
            case 'R':
            case 'r':
              p_Vid->gop_structure[coded_frame].reference_idc= NALU_PRIORITY_LOW;
              p_Vid->gop_structure[coded_frame].hierarchy_layer = 1;
              break;
            default:
              snprintf(errortext, ET_SIZE, "Reference_IDC invalid in ExplicitHierarchyFormat param. Please check configuration file.");
              error (errortext, 400);
              break;
            }
            stored_read = 1;
          }
          else if (stored_read == 1 && qp_read == 0)
          {
            if (isdigit((int)(*(p_Inp->ExplicitHierarchyFormat+i))))
            {
              sscanf(p_Inp->ExplicitHierarchyFormat+i,"%d",&dqp);

              p_Vid->gop_structure[coded_frame].slice_qp = 0; //p_Inp->qp[ p_Vid->gop_structure[coded_frame].slice_type ];
              p_Vid->gop_structure[coded_frame].slice_qp = iClip3(-p_Vid->bitdepth_luma_qp_scale, 51,p_Vid->gop_structure[coded_frame].slice_qp + dqp);
              qp_read = 1;
            }
            else
            {
              snprintf(errortext, ET_SIZE, "Reference_IDC needs to be followed by QP. Please check configuration file.");
              error (errortext, 400);
            }
          }
          else if (stored_read == 1 && qp_read == 1 && temporal_layer_read == 0)
          {
            if (!(isdigit((int)(*(p_Inp->ExplicitHierarchyFormat+i)))))
            {
              if (p_Inp->ExplicitHierarchyFormat[i] == 't' || p_Inp->ExplicitHierarchyFormat[i] == 'T')
              {
                p_Vid->gop_structure[coded_frame].temporal_layer = 0; 
                if (isdigit((int)(*(p_Inp->ExplicitHierarchyFormat+i+1))))
                {
                  sscanf(p_Inp->ExplicitHierarchyFormat+i+1,"%d",&tlyr);

                  p_Vid->gop_structure[coded_frame].temporal_layer = tlyr; 
                  i++; // temporal layer number is specified
                }
              }
              else
              {
                i--; // temporal layer is optional and it is not specified
              }
            }
            temporal_layer_read = 1;
          }
          else if (stored_read == 1 && qp_read == 1 && temporal_layer_read == 1 && !(isdigit((int)(*(p_Inp->ExplicitHierarchyFormat+i)))) && (i < nLength - 3))

          {
            stored_read =0;
            qp_read=0;
            order_read=0;
            slice_read=0;
            temporal_layer_read=0;
            i--;
            coded_frame ++;
            if (coded_frame >= p_Inp->NumberBFrames )
            {
              snprintf(errortext, ET_SIZE, "Total number of frames in Enhancement GOP need to be fewer or equal to NumberBFrames parameter.");
              error (errortext, 400);
            }
          }
        }
      }
    }
  }
  else
  {
    snprintf(errortext, ET_SIZE, "ExplicitHierarchyFormat is empty. Please check configuration file.");
    error (errortext, 400);
  }

  p_Inp->NumberBFrames = coded_frame + 1;
}
コード例 #7
0
ファイル: transform8x8.c プロジェクト: Foredoomed/JM
int residual_transform_quant_luma_8x8_ls(Macroblock *currMB, ColorPlane pl, int b8, int *coeff_cost, int intra)
{
  VideoParameters *p_Vid = currMB->p_Vid;
  int i,j,coeff_ctr;
  int scan_pos = 0,run = -1;
  int nonzero = FALSE;  

  int block_x = 8*(b8 & 0x01);
  int block_y = 8*(b8 >> 1);
  int pl_off = b8 + (pl<<2);
  Slice *currSlice = currMB->p_Slice;
  int*  ACLevel = currSlice->cofAC[pl_off][0][0];
  int*  ACRun   = currSlice->cofAC[pl_off][0][1];  
  imgpel **img_enc = p_Vid->enc_picture->p_curr_img;
  imgpel **mb_pred = currSlice->mb_pred[pl];
  int    **mb_ores = currSlice->mb_ores[pl];
  int    **mb_rres = currSlice->mb_rres[pl];

  int scan_poss[4] = { 0 }, runs[4] = { -1, -1, -1, -1 };
  int MCcoeff = 0;
  int *m7;
  int is_cavlc = (currSlice->symbol_mode == CAVLC);

  const byte (*pos_scan)[2] = currMB->is_field_mode ? FIELD_SCAN8x8 : SNGL_SCAN8x8;

  int **fadjust8x8 = p_Vid->AdaptiveRounding ? (&p_Vid->ARCofAdj8x8[pl][currMB->ar_mode][block_y]) :NULL;
  
  runs[0]=runs[1]=runs[2]=runs[3]=-1;
  scan_poss[0] = scan_poss[1] = scan_poss[2] = scan_poss[3] = 0;

  if( (currMB->ipmode_DPCM < 2)&&(intra))
  {
    Residual_DPCM_8x8(currMB->ipmode_DPCM, mb_ores, mb_rres, block_y, block_x);
  }
  else
  { 
    for (j = block_y ; j < block_y + BLOCK_SIZE_8x8 ; j ++)
      for (i = block_x ; i < block_x + BLOCK_SIZE_8x8 ; i ++)
        mb_rres[j][i] = mb_ores[j][i] ;
  }

  for (coeff_ctr=0; coeff_ctr < 64; coeff_ctr++)
  {
    i=pos_scan[coeff_ctr][0];
    j=pos_scan[coeff_ctr][1];

    run++;

    if (currMB->luma_transform_size_8x8_flag && is_cavlc)
    {
      MCcoeff = (coeff_ctr & 3);
      runs[MCcoeff]++;
    }

    m7 = &mb_rres[block_y + j][block_x + i];

    if (p_Vid->AdaptiveRounding)
    {
      fadjust8x8[j][block_x+i] = 0;
    }

    if (*m7 != 0)
    {
      nonzero = TRUE;

      if (currMB->luma_transform_size_8x8_flag && is_cavlc)
      {
        *m7 = iClip3(-CAVLC_LEVEL_LIMIT, CAVLC_LEVEL_LIMIT, *m7);
        *coeff_cost += MAX_VALUE;

        currSlice->cofAC[pl_off][MCcoeff][0][scan_poss[MCcoeff]  ] = *m7;
        currSlice->cofAC[pl_off][MCcoeff][1][scan_poss[MCcoeff]++] = runs[MCcoeff];
        ++scan_pos;
        runs[MCcoeff]=-1;
      }
      else
      {
        *coeff_cost += MAX_VALUE;
        ACLevel[scan_pos  ] = *m7;
        ACRun  [scan_pos++] = run;
        run=-1;                     // reset zero level counter
      }
    }
  }

  if (!currMB->luma_transform_size_8x8_flag || !is_cavlc)
    ACLevel[scan_pos] = 0;
  else
  {
    for(i=0; i<4; i++)
      currSlice->cofAC[pl_off][i][0][scan_poss[i]] = 0;
  }

  if( (currMB->ipmode_DPCM < 2) && (intra))
  {
    Inv_Residual_DPCM_8x8(currMB, mb_rres, block_y, block_x);
  }

  for( j=block_y; j<block_y + BLOCK_SIZE_8x8; j++)
  {            
    for( i=block_x; i< block_x + BLOCK_SIZE_8x8; i++)
    {
      mb_rres[j][i] += (int) mb_pred[j][i];
      img_enc[currMB->pix_y + j][currMB->pix_x + i]= (imgpel) mb_rres[j][i];
    }
  }  

  //  Decoded block moved to frame memory
  return nonzero;
}