Exemplo n.º 1
0
/*!
 ************************************************************************
 * \brief
 *    Write out unpaired fields from output buffer.
 * \param p_out
 *    Output file
 ************************************************************************
 */
void flush_direct_output(FILE *p_out)
{
  write_unpaired_field(out_buffer, p_out);

  free_storable_picture(out_buffer->frame);
  out_buffer->frame = NULL;
  free_storable_picture(out_buffer->top_field);
  out_buffer->top_field = NULL;
  free_storable_picture(out_buffer->bottom_field);
  out_buffer->bottom_field = NULL;
  out_buffer->is_used = 0;
}
Exemplo n.º 2
0
Arquivo: output.c Projeto: VVer/JM86
/*!
 ************************************************************************
 * \brief
 *    Directly output a picture without storing it in the DPB. Fields 
 *    are buffered before they are written to the file.
 * \param p
 *    Picture for output
 * \param p_out
 *    Output file
 ************************************************************************
 */
void direct_output(StorablePicture *p, FILE *p_out)
{
  if (p->structure==FRAME)
  {
    // we have a frame (or complementary field pair)
    // so output it directly
    flush_direct_output(p_out);
    write_picture (p, p_out, FRAME);
    if (p_ref)
      find_snr(snr, p, p_ref);
    free_storable_picture(p);
    return;
  }

  if (p->structure == TOP_FIELD)
  {
    if (out_buffer->is_used &1)
      flush_direct_output(p_out);
    out_buffer->top_field = p;
    out_buffer->is_used |= 1;
  }

  if (p->structure == BOTTOM_FIELD)
  {
    if (out_buffer->is_used &2)
      flush_direct_output(p_out);
    out_buffer->bottom_field = p;
    out_buffer->is_used |= 2;
  }

  if (out_buffer->is_used == 3)
  {
    // we have both fields, so output them
    dpb_combine_field(out_buffer);
    write_picture (out_buffer->frame, p_out, FRAME);
    if (p_ref)
      find_snr(snr, out_buffer->frame, p_ref);
    free_storable_picture(out_buffer->frame);
    out_buffer->frame = NULL;
    free_storable_picture(out_buffer->top_field);
    out_buffer->top_field = NULL;
    free_storable_picture(out_buffer->bottom_field);
    out_buffer->bottom_field = NULL;
    out_buffer->is_used = 0;
  }
}
Exemplo n.º 3
0
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);
}