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

📄 rwmh.c

📁 QccPack-0.54-1 released (2007-04-30) is being developed and tested on Fedora Core Linux. QccPack pro
💻 C
📖 第 1 页 / 共 4 页
字号:
  switch (subpixel_accuracy)
    {
    case QCCVID_ME_FULLPIXEL:
      final_search_step = 1.0;
      break;
    case QCCVID_ME_HALFPIXEL:
      final_search_step = 0.5;
      break;
    case QCCVID_ME_QUARTERPIXEL:
      final_search_step = 0.25;
      break;
    case QCCVID_ME_EIGHTHPIXEL:
      final_search_step = 0.125;
      break;
    default:
      QccErrorAddMessage("(QccVIDRWMHMotionEstimation): Unrecognized subpixel accuracy");
      goto Error;
    }

  for (row = 0; row < num_rows; row += blocksize)
    for (col = 0; col < num_cols; col += blocksize)
      {
        if (QccVIDRWMHBlockExtract(&current_block,
                                   current_frame_rdwt,
                                   num_rows,
                                   num_cols,
                                   num_levels,
                                   (double)row,
                                   (double)col,
                                   QCCVID_ME_FULLPIXEL))
          {
            QccErrorAddMessage("(QccVIDRWMHMotionEstimation): Error calling QccVIDRWMHBlockExtract()");
            goto Error;
          }

        mv_row = row / blocksize;
        mv_col = col / blocksize;

        horizontal_motion->image[mv_row][mv_col] = 0.0;
        vertical_motion->image[mv_row][mv_col] = 0.0;

        for (current_search_step = 1.0;
             current_search_step >= final_search_step;
             current_search_step /= 2)
          {
            search_row = row + 
              vertical_motion->image[mv_row][mv_col];
            search_col = col + 
              horizontal_motion->image[mv_row][mv_col];

            current_window_size =
              (current_search_step == 1.0) ?
              (double)QCCVIDRWMH_WINDOWSIZE : current_search_step;
            
            if (QccVIDRWMHMotionEstimationSearch(reference_frame_rdwt,
                                                 reference_num_rows,
                                                 reference_num_cols,
                                                 num_levels,
                                                 &current_block,
                                                 &reference_block,
                                                 search_row,
                                                 search_col,
                                                 current_window_size,
                                                 current_search_step,
                                                 subpixel_accuracy,
                                                 &u,
                                                 &v))
              {
                QccErrorAddMessage("(QccVIDRWMHMotionEstimation): Error calling QccVIRWMHMotionEstimationSearch()");
                goto Error;
              }
            horizontal_motion->image[mv_row][mv_col] += u;
            vertical_motion->image[mv_row][mv_col] += v;
          }
      }
  
  return_value = 0;
  goto Return;
 Error:
  return_value = 1;
 Return:
  QccVIDRWMHBlockFree(&current_block);
  QccVIDRWMHBlockFree(&reference_block);
  return(return_value);
}


static
int QccVIDRWMHMotionCompensation(QccMatrix *reference_frame_rdwt,
                                 QccMatrix *compensated_frame_rdwt,
                                 int num_rows,
                                 int num_cols,
                                 int reference_num_rows,
                                 int reference_num_cols,
                                 int num_levels,
                                 int blocksize,
                                 int subpixel_accuracy,
                                 QccIMGImageComponent *horizontal_motion,
                                 QccIMGImageComponent *vertical_motion)
{
  int return_value;
  int row, col;
  int mv_row, mv_col;
  double reference_row, reference_col;
  QccVIDRWMHBlock reference_block;

  QccVIDRWMHBlockInitialize(&reference_block);

  reference_block.blocksize = blocksize;
  reference_block.num_levels = num_levels;
  if (QccVIDRWMHBlockAlloc(&reference_block))
    {
      QccErrorAddMessage("(QccVIDRWMHMotionCompensation): Error calling QccVIDRWMHBlockAlloc()");
      goto Error;
    }

  for (row = 0; row < num_rows; row += blocksize)
    for (col = 0; col < num_cols; col += blocksize)
      {
        mv_row = row / blocksize;
        mv_col = col / blocksize;

        reference_row = row + vertical_motion->image[mv_row][mv_col];
        reference_col = col + horizontal_motion->image[mv_row][mv_col];

        if (QccVIDRWMHBlockExtract(&reference_block,
                                   reference_frame_rdwt,
                                   reference_num_rows,
                                   reference_num_cols,
                                   num_levels,
                                   reference_row,
                                   reference_col,
                                   subpixel_accuracy))
          {
            QccErrorAddMessage("(QccVIDRWMHMotionCompensation): Error calling QccVIDRWMHBlockExtract()");
            goto Error;
          }

        if (QccVIDRWMHBlockInsert(&reference_block,
                                  compensated_frame_rdwt,
                                  num_rows,
                                  num_cols,
                                  num_levels,
                                  row,
                                  col))
          {
            QccErrorAddMessage("(QccVIDRWMHMotionCompensation): Error calling QccVIDRWMHBlockInsert()");
            goto Error;
          }
      }

  return_value = 0;
  goto Return;
 Error:
  return_value = 1;
 Return:
  QccVIDRWMHBlockFree(&reference_block);
  return(return_value);
}


static int QccVIDRWMHEncodeHeader(QccBitBuffer *output_buffer,
                                  int num_rows,
                                  int num_cols,
                                  int start_frame_num,
                                  int end_frame_num,
                                  int num_levels,
                                  int blocksize,
                                  int target_bit_cnt)
{
  if (QccBitBufferPutInt(output_buffer, num_rows))
    {
      QccErrorAddMessage("(QccVIDRWMHEncodeHeader): Error calling QccBitBufferPutInt()");
      return(1);
    }
  
  if (QccBitBufferPutInt(output_buffer, num_cols))
    {
      QccErrorAddMessage("(QccVIDRWMHEncodeHeader): Error calling QccBitBufferPutInt()");
      return(1);
    }
  
  if (QccBitBufferPutInt(output_buffer, start_frame_num))
    {
      QccErrorAddMessage("(QccVIDRWMHEncodeHeader): Error calling QccBitBufferPutInt()");
      return(1);
    }
  
  if (QccBitBufferPutInt(output_buffer, end_frame_num))
    {
      QccErrorAddMessage("(QccVIDRWMHEncodeHeader): Error calling QccBitBufferPutInt()");
      return(1);
    }
  
  if (QccBitBufferPutInt(output_buffer, num_levels))
    {
      QccErrorAddMessage("(QccVIDRWMHEncodeHeader): Error calling QccBitBufferPutInt()");
      return(1);
    }
  
  if (QccBitBufferPutInt(output_buffer, blocksize))
    {
      QccErrorAddMessage("(QccVIDRWMHEncodeHeader): Error calling QccBitBufferPutInt()");
      return(1);
    }
  
  if (QccBitBufferPutInt(output_buffer, target_bit_cnt))
    {
      QccErrorAddMessage("(QccVIDRWMHEncodeHeader): Error calling QccBitBufferPutInt()");
      return(1);
    }
  
  if (QccBitBufferFlush(output_buffer))
    {
      QccErrorAddMessage("(QccVIDRWMHEncodeHeader): Error calling QccBitBufferFlush()");
      return(1);
    }
  
  return(0);
}


#if 0
static int QccWAVRWMHCorrelation(QccMatrix *current_frame_rdwt,
                                 QccMatrix *compensated_frame_rdwt,
                                 int num_rows,
                                 int num_cols,
                                 int num_levels)
{
  int num_subbands;
  int subband1;
  int subband2;
  int row, col;
  double difference1;
  double difference2;
  double correlation;
  double variance1;
  double variance2;

  num_subbands = QccWAVSubbandPyramidNumLevelsToNumSubbands(num_levels);

  for (subband1 = 0; subband1 < num_subbands; subband1++)
    {
      for (subband2 = 0; subband2 < num_subbands; subband2++)
        {
          correlation = 0;
          variance1 = 0;
          variance2 = 0;

          for (row = 0; row < num_rows; row++)
            for (col = 0; col < num_cols; col++)
              {
                difference1 =
                  current_frame_rdwt[subband1][row][col] -
                  compensated_frame_rdwt[subband1][row][col];
                difference2 =
                  current_frame_rdwt[subband2][row][col] -
                  compensated_frame_rdwt[subband2][row][col];
                correlation +=
                  difference1 * difference2;
                variance1 +=
                  difference1 * difference1;
                variance2 +=
                  difference2 * difference2;
              }
          
          variance1 /= num_rows * num_cols;
          variance2 /= num_rows * num_cols;
          correlation /= num_rows * num_cols;
          
          correlation /= sqrt(variance1 * variance2);
          
          printf("% 0.2f ",
                 correlation);
        }
      printf("\n");
    }

  return(0);
}
#endif


static int QccVIDRWMHDecodeFrame();

static
int QccVIDRWMHEncodeFrame(QccIMGImageComponent *current_frame,
                          QccIMGImageComponent *reconstructed_frame,
                          QccMatrix *current_frame_rdwt,
                          QccMatrix *reference_frame_rdwt,
                          int num_levels,
                          int blocksize,
                          int subpixel_accuracy,
                          const QccFilter *filter1,
                          const QccFilter *filter2,
                          const QccFilter *filter3,
                          const QccWAVWavelet *wavelet,
                          QccBitBuffer *output_buffer,
                          QccBitBuffer *input_buffer,
                          QccIMGImageComponent *motion_vector_horizontal,
                          QccIMGImageComponent *motion_vector_vertical,
                          int read_motion_vectors,
                          int target_bit_cnt,
                          QccVIDRWMHStatistics *statistics)
{
  int return_value;
  int row, col;
  int num_rows, num_cols;
  int reference_num_rows, reference_num_cols;
  int intraframe;
  double image_mean;
  int start_position;
  QccMatrix compensated_frame = NULL;
  QccMatrix *compensated_frame_rdwt = NULL;

  start_position = output_buffer->bit_cnt;
  
  num_rows = current_frame->num_rows;
  num_cols = current_frame->num_cols;

  if (QccVIDMotionEstimationCalcReferenceFrameSize(num_rows,
                                                   num_cols,
                                                   &reference_num_rows,
                                                   &reference_num_cols,
                                                   subpixel_accuracy))
    {
      QccErrorAddMessage("(QccVIDRWMHEncodeFrame): Error calling QccVIDMotionEstimationCalcReferenceFrameSize()");
      goto Error;
    }
  
  intraframe =
    (motion_vector_horizontal == NULL) || (motion_vector_vertical == NULL);
  
  if (statistics != NULL)
    statistics->intraframe = intraframe;
  
  if ((compensated_frame = QccMatrixAlloc(num_rows, num_cols)) == NULL)
    {
      QccErrorAddMessage("(QccVIDRWMHEncodeFrame): Error allocating memory");
      goto Error;
    }
  
  if ((compensated_frame_rdwt =
       QccWAVWaveletRedundantDWT2DAlloc(num_rows, num_cols, num_levels)) ==
      NULL)
    {
      QccErrorAddMessage("(QccVIDRWMHEncodeFrame): Error calling QccWAVWaveletRedundantDWT2DAlloc()");
      goto Error;
    }

  if (!intraframe)
    {
      if (!read_motion_vectors)
        {
          if (QccWAVWaveletRedundantDWT2D(current_frame->image,
                                          current_frame_rdwt,
                                          num_rows,
                                          num_cols,
                                          num_levels,
                                          wavelet))
            {
              QccErrorAddMessage("(QccVIDRWMHEncodeFrame): Error calling QccWAVWaveletRedundantDWT2D()");
              goto Error;
            }
          
          if (QccVIDRWMHMotionEstimation(current_frame_rdwt,
                                         reference_frame_rdwt,
                                         num_rows,
                                         num_cols,
                                         reference_num_rows,
                                         reference_num_cols,
                                         blocksize,
                                         num_levels,
                                         subpixel_accuracy,
                                         motion_vector_horizontal,
                                         motion_vector_vertical))
            {
              QccErrorAddMessage("(QccVIDRWMHEncodeFrame): Error calling QccVIDRWMHMotionEstimation()");
              goto Error;
            }
        }
      
      if (QccVIDRWMHMotionCompensation(reference_frame_rdwt,
                                       compensated_frame_rdwt,
                                       num_rows,
                                       num_cols,
                                       reference_num_rows,
                                       reference_num_cols,
                                       num_levels,
                                       blocksize,
                                       subpixel_accuracy,
                                       motion_vector_horizontal,
                                       motion_vector_vertical))
        {
          QccErrorAddMessage("(QccVIDRWMHEncodeFrame): Error calling QccVIDRWMHMotionCompensation()");
          goto Error;
        }
      
      if (QccWAVWaveletInverseRedundantDWT2D(compensated_frame_rdwt,
                                             compensated_frame,
                                             num_rows,
                                             num_cols,
                                             num_levels,
                                             wavelet))
        {
          QccErrorAddMessage("(QccVIDRWMHEncodeFrame): Error calling QccWAVWaveletInverseRedundantDWT2D()");
          goto Error;
        }     
      
      for (row = 0; row < num_rows; row++)
        for (col = 0; col < num_cols; col++)
          current_frame->image[row][col] -= compensated_frame[row][col];
      
      if (!read_motion_vectors)
        if (QccVIDMotionVectorsEncode(motion_vector_horizontal,
                                      motion_vector_vertical,
                                      NULL,
                                      subpixel_accuracy,
                                      output_buffer))
          {
            QccErrorAddMessage("(QccVIDRWMHEncodeFrame): Error calling QccVIDMotionVectorsEncode()");
            goto Error;
          }
      
      if (statistics != NULL)
        statistics->motion_vector_bits =
          output_buffer->bit_cnt - start_position;
      
      if (output_buffer->bit_cnt > start_position + target_bit_cnt)
        {
          QccErrorAddMessage("(QccVIDRWMHEncodeFrame): Rate is not sufficient to store all motion vectors for frame");
          goto Error;
        }
      

⌨️ 快捷键说明

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