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

📄 image.c

📁 h.264 影像壓縮 必須在 .net 的環境 下操作
💻 C
📖 第 1 页 / 共 5 页
字号:
  }

  if ((p->chroma_format_idc==YUV400) && input->write_uv)
  {
    comp_size_x[1] = comp_size_x[2] = (p->size_x >> 1);
    comp_size_y[1] = comp_size_y[2] = (p->size_y >> 1);
  }
  else
  {
    // These could be computed once and attached to the StorablePicture structure
    comp_size_x[1] = comp_size_x[2] = (p->size_x_cr - crop_left - crop_right); 
    comp_size_y[1] = comp_size_y[2] = (p->size_y_cr - crop_top  - crop_bottom);
  }

  framesize_in_bytes = (((int64) comp_size_x[0] * comp_size_y[0]) + ((int64) comp_size_x[1] * comp_size_y[1] ) * 2) * symbol_size_in_bytes;

  // KS: this buffer should actually be allocated only once, but this is still much faster than the previous version
  buf = malloc ( comp_size_x[0] * comp_size_y[0] * symbol_size_in_bytes );

  if (NULL == buf)
  {
    no_mem_exit("find_snr: buf");
  }

  status = lseek (p_ref, framesize_in_bytes * frame_no, SEEK_SET);
  if (status == -1)
  {
    fprintf(stderr, "Error in seeking frame number: %d\n", frame_no);
    free (buf);
    return;
  }

  if(rgb_output)
    lseek (p_ref, framesize_in_bytes/3, SEEK_CUR);

  for (k = 0; k < ((p->chroma_format_idc != YUV400) ? 3 : 1); k++)
  {

    if(rgb_output && k == 2)
      lseek (p_ref, -framesize_in_bytes, SEEK_CUR);

    read(p_ref, buf, comp_size_x[k] * comp_size_y[k] * symbol_size_in_bytes);
    buf2img(cur_ref[k], buf, comp_size_x[k], comp_size_y[k], symbol_size_in_bytes);

    for (j=0; j < comp_size_y[k]; ++j)
    {
      for (i=0; i < comp_size_x[k]; ++i)
      {
        diff_comp[k] += iabs2(cur_comp[k][j][i] - cur_ref[k][j][i]);
      }
    }

#if ZEROSNR
    diff_comp[k] = imax(diff_comp[k], 1);
#endif
    // Collecting SNR statistics
    if (diff_comp[k]  != 0)
      snr->snr[k]=(float)(10*log10(max_pix_value_sqd[k]*(double)((double)(comp_size_x[k])*(comp_size_y[k]) / diff_comp[k])));   
    else
      snr->snr[k]=0.0;

    if (img->number == 0) // first
    {
      snr->snra[k]=snr->snr1[k]=snr->snr[k];                                                        // keep luma snr for first frame
    }
    else
    {
      snr->snra[k]=(float)(snr->snra[k]*(snr->frame_ctr)+snr->snr[k])/(snr->frame_ctr + 1); // average snr chroma for all frames
    }
  }

   if(rgb_output)
     lseek (p_ref, framesize_in_bytes*2/3, SEEK_CUR);

  free (buf);


  // picture error concealment
  if(p->concealed_pic)
  {
      fprintf(stdout,"%04d(P)  %8d %5d %5d %7.4f %7.4f %7.4f  %s %5d\n",
          frame_no, p->frame_poc, p->pic_num, p->qp,
          snr->snr[0], snr->snr[1], snr->snr[2], yuv_types[p->chroma_format_idc], 0);

  }
}


void reorder_lists(int currSliceType, Slice * currSlice)
{

  if ((currSliceType != I_SLICE)&&(currSliceType != SI_SLICE))
  {
    if (currSlice->ref_pic_list_reordering_flag_l0)
    {
      reorder_ref_pic_list(listX[0], &listXsize[0],
                           img->num_ref_idx_l0_active - 1,
                           currSlice->reordering_of_pic_nums_idc_l0,
                           currSlice->abs_diff_pic_num_minus1_l0,
                           currSlice->long_term_pic_idx_l0);
    }
    if (no_reference_picture == listX[0][img->num_ref_idx_l0_active-1])
    {
      if (non_conforming_stream)
        printf("RefPicList0[ num_ref_idx_l0_active_minus1 ] is equal to 'no reference picture'\n");
      else
        error("RefPicList0[ num_ref_idx_l0_active_minus1 ] is equal to 'no reference picture', invalid bitstream",500);
    }
    // that's a definition
    listXsize[0] = img->num_ref_idx_l0_active;
  }
  if (currSliceType == B_SLICE)
  {
    if (currSlice->ref_pic_list_reordering_flag_l1)
    {
      reorder_ref_pic_list(listX[1], &listXsize[1],
                           img->num_ref_idx_l1_active - 1,
                           currSlice->reordering_of_pic_nums_idc_l1,
                           currSlice->abs_diff_pic_num_minus1_l1,
                           currSlice->long_term_pic_idx_l1);
    }
    if (no_reference_picture == listX[1][img->num_ref_idx_l1_active-1])
    {
      if (non_conforming_stream)
        printf("RefPicList1[ num_ref_idx_l1_active_minus1 ] is equal to 'no reference picture'\n");
      else
        error("RefPicList1[ num_ref_idx_l1_active_minus1 ] is equal to 'no reference picture', invalid bitstream",500);
    }
    // that's a definition
    listXsize[1] = img->num_ref_idx_l1_active;
  }

  free_ref_pic_list_reordering_buffer(currSlice);
}


/*!
 ************************************************************************
 * \brief
 *    initialize ref_pic_num array
 ************************************************************************
 */
void set_ref_pic_num()
{
  int i,j;

  int slice_id=img->current_slice_nr;

  for (i=0;i<listXsize[LIST_0];i++)
  {
    dec_picture->ref_pic_num        [slice_id][LIST_0][i] = listX[LIST_0][i]->poc * 2 + ((listX[LIST_0][i]->structure==BOTTOM_FIELD)?1:0) ;
    dec_picture->frm_ref_pic_num    [slice_id][LIST_0][i] = listX[LIST_0][i]->frame_poc * 2;
    dec_picture->top_ref_pic_num    [slice_id][LIST_0][i] = listX[LIST_0][i]->top_poc * 2;
    dec_picture->bottom_ref_pic_num [slice_id][LIST_0][i] = listX[LIST_0][i]->bottom_poc * 2 + 1;
    //printf("POCS %d %d %d %d ",listX[LIST_0][i]->frame_poc,listX[LIST_0][i]->bottom_poc,listX[LIST_0][i]->top_poc,listX[LIST_0][i]->poc);
    //printf("refid %d %d %d %d\n",(int) dec_picture->frm_ref_pic_num[LIST_0][i],(int) dec_picture->top_ref_pic_num[LIST_0][i],(int) dec_picture->bottom_ref_pic_num[LIST_0][i],(int) dec_picture->ref_pic_num[LIST_0][i]);
  }

  for (i=0;i<listXsize[LIST_1];i++)
  {
    dec_picture->ref_pic_num        [slice_id][LIST_1][i] = listX[LIST_1][i]->poc  *2 + ((listX[LIST_1][i]->structure==BOTTOM_FIELD)?1:0);
    dec_picture->frm_ref_pic_num    [slice_id][LIST_1][i] = listX[LIST_1][i]->frame_poc * 2;
    dec_picture->top_ref_pic_num    [slice_id][LIST_1][i] = listX[LIST_1][i]->top_poc * 2;
    dec_picture->bottom_ref_pic_num [slice_id][LIST_1][i] = listX[LIST_1][i]->bottom_poc * 2 + 1;
  }

  if (!active_sps->frame_mbs_only_flag)
  {
    if (img->structure==FRAME)
    {
      for (j=2;j<6;j++)
      {
        for (i=0;i<listXsize[j];i++)
        {
          dec_picture->ref_pic_num        [slice_id][j][i] = listX[j][i]->poc * 2 + ((listX[j][i]->structure==BOTTOM_FIELD)?1:0);
          dec_picture->frm_ref_pic_num    [slice_id][j][i] = listX[j][i]->frame_poc * 2 ;
          dec_picture->top_ref_pic_num    [slice_id][j][i] = listX[j][i]->top_poc * 2 ;
          dec_picture->bottom_ref_pic_num [slice_id][j][i] = listX[j][i]->bottom_poc * 2 + 1;
        }
      }
    }
  }
}

/*!
************************************************************************
* \brief
*    Read the next NAL unit (with error handling)
************************************************************************
*/
int read_next_nalu(NALU_t *nalu)
{
  int ret;

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

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

  //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)
    error ("Invalid startcode emulation prevention found.", 602);


  // Got a NALU
  if (nalu->forbidden_bit)
  {
    error ("Found NALU with forbidden_bit set, bit error?", 603);
  }

  return nalu->len;
}

/*!
 ************************************************************************
 * \brief
 *    Reads new slice from bit_stream
 ************************************************************************
 */
int read_new_slice()
{
  NALU_t *nalu = AllocNALU(MAX_CODED_FRAME_SIZE);
  int current_header = 0;
  int BitsUsedByHeader;
  Slice *currSlice = img->currentSlice;
  Bitstream *currStream;

  int slice_id_a, slice_id_b, slice_id_c;
  int redundant_pic_cnt_b, redundant_pic_cnt_c;
  long ftell_position;

  while (1)
  {
    ftell_position = ftell(bits);

    if (0 == read_next_nalu(nalu))
      return EOS;

    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);
        }
        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;

        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
        currSlice->dpB_NotPresent =1; 
        currSlice->dpC_NotPresent =1; 

        img->idr_flag          = 0;
        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);
        }
        else
          current_header = SOS;

        init_lists(img->type, img->currentSlice->structure);
        reorder_lists (img->type, img->currentSlice);

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

⌨️ 快捷键说明

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