コード例 #1
0
ファイル: maindec.c プロジェクト: volvet/thor
int main(int argc, char** argv)
{
    FILE *infile,*outfile;
    decoder_info_t decoder_info;
    stream_t stream;
    yuv_frame_t rec[MAX_REORDER_BUFFER];
    yuv_frame_t ref[MAX_REF_FRAMES];
    int rec_available[MAX_REORDER_BUFFER]={0};
    int rec_buffer_idx;
    int op_rec_buffer_idx;
    int decode_frame_num = 0;
    int last_frame_output = -1;
    int done = 0;
    int width;
    int height;
    int r;

    init_use_simd();

    parse_arg(argc, argv, &infile, &outfile);
    
	  fseek(infile, 0, SEEK_END);
	  int input_file_size = ftell(infile);
	  fseek(infile, 0, SEEK_SET);
    
    initbits_dec(infile, &stream);

    decoder_info.stream = &stream;

    memset(&decoder_info.bit_count,0,sizeof(bit_count_t));

    int bit_start = stream.bitcnt;
    /* Read sequence header */
    width = getbits(&stream,16);
    height = getbits(&stream,16);

    decoder_info.width = width;
    decoder_info.height = height;
    printf("width=%4d height=%4d\n",width,height);

    decoder_info.pb_split = getbits(&stream,1);
    printf("pb_split_enable=%1d\n",decoder_info.pb_split); //TODO: Rename variable to pb_split_enable

    decoder_info.tb_split_enable = getbits(&stream,1);
    printf("tb_split_enable=%1d\n",decoder_info.tb_split_enable);

    decoder_info.max_num_ref = getbits(&stream,2) + 1;
    fprintf(stderr,"num refs is %d\n",decoder_info.max_num_ref);

    decoder_info.interp_ref = getbits(&stream,1);
    decoder_info.max_delta_qp = getbits(&stream, 1);
    decoder_info.deblocking = getbits(&stream,1);
    decoder_info.clpf = getbits(&stream,1);
    decoder_info.use_block_contexts = getbits(&stream,1);
    decoder_info.bipred = getbits(&stream,1);

    decoder_info.bit_count.sequence_header += (stream.bitcnt - bit_start);

    for (r=0;r<MAX_REORDER_BUFFER;r++){
      create_yuv_frame(&rec[r],width,height,0,0,0,0);
    }
    for (r=0;r<MAX_REF_FRAMES;r++){
      create_yuv_frame(&ref[r],width,height,PADDING_Y,PADDING_Y,PADDING_Y/2,PADDING_Y/2);
      decoder_info.ref[r] = &ref[r];
    }
    if (decoder_info.interp_ref) {
      for (r=0;r<MAX_SKIP_FRAMES;r++){
        decoder_info.interp_frames[r] = malloc(sizeof(yuv_frame_t));
        create_yuv_frame(decoder_info.interp_frames[r],width,height,PADDING_Y,PADDING_Y,PADDING_Y/2,PADDING_Y/2);
      }
    }

    decoder_info.deblock_data = (deblock_data_t *)malloc((height/MIN_PB_SIZE) * (width/MIN_PB_SIZE) * sizeof(deblock_data_t));

    do
    {
      decoder_info.frame_info.decode_order_frame_num = decode_frame_num;
      decode_frame(&decoder_info,rec);
      rec_buffer_idx = decoder_info.frame_info.display_frame_num%MAX_REORDER_BUFFER;
      rec_available[rec_buffer_idx]=1;

      done = initbits_dec(infile, &stream);

      op_rec_buffer_idx = (last_frame_output+1)%MAX_REORDER_BUFFER;
      if (rec_available[op_rec_buffer_idx]) {
        last_frame_output++;
        write_yuv_frame(&rec[op_rec_buffer_idx],width,height,outfile);
        rec_available[op_rec_buffer_idx] = 0;
      }
      printf("decode_frame_num=%4d display_frame_num=%4d input_file_size=%12d bitcnt=%12d\n",
          decode_frame_num,decoder_info.frame_info.display_frame_num,input_file_size,stream.bitcnt);
      decode_frame_num++;
    }
    while (!done);
    // Output the tail
    int i,j;
    for (i=1; i<=MAX_REORDER_BUFFER; ++i) {
      op_rec_buffer_idx=(last_frame_output+i) % MAX_REORDER_BUFFER;
      if (rec_available[op_rec_buffer_idx])
        write_yuv_frame(&rec[op_rec_buffer_idx],width,height,outfile);
      else
        break;
    }

    bit_count_t bit_count = decoder_info.bit_count;
    uint32_t tot_bits[NUM_FRAME_TYPES] = {0};

    for (i=0;i<NUM_FRAME_TYPES;i++){
      tot_bits[i] = bit_count.frame_header[i] +
                    bit_count.super_mode[i] +
                    bit_count.intra_mode[i] +
                    bit_count.mv[i] +
                    bit_count.skip_idx[i] +
                    bit_count.coeff_y[i] +
                    bit_count.coeff_u[i] +
                    bit_count.coeff_v[i] +
                    bit_count.cbp[i] +
                    bit_count.clpf[i];
    }
    tot_bits[0] += bit_count.sequence_header;
    int ni = bit_count.frame_type[0];
    int np = bit_count.frame_type[1];
    int nb = bit_count.frame_type[2];
    if (np==0) np = (1<<30); //Hack to avoid division by zero if there are no P frames
    if (nb==0) nb = (1<<30); //Hack to avoid division by zero if there are no B frames

    printf("\n\nBIT STATISTICS:\n");
    printf("Sequence header: %4d\n",bit_count.sequence_header);
    printf("                           I pictures:           P pictures:           B pictures:\n");
    printf("                           total    average      total    average      total    average\n");
    printf("Frame header:          %9d  %9d  %9d  %9d  %9d  %9d\n",bit_count.frame_header[0],bit_count.frame_header[0]/ni,bit_count.frame_header[1],bit_count.frame_header[1]/np,bit_count.frame_header[2],bit_count.frame_header[2]/nb);
    printf("Super mode:            %9d  %9d  %9d  %9d  %9d  %9d\n",bit_count.super_mode[0],bit_count.super_mode[0]/ni,bit_count.super_mode[1],bit_count.super_mode[1]/np,bit_count.super_mode[2],bit_count.super_mode[2]/nb);
    printf("Intra mode:            %9d  %9d  %9d  %9d  %9d  %9d\n",bit_count.intra_mode[0],bit_count.intra_mode[0]/ni,bit_count.intra_mode[1],bit_count.intra_mode[1]/np, bit_count.intra_mode[2],bit_count.intra_mode[2]/nb);
    printf("MV:                    %9d  %9d  %9d  %9d  %9d  %9d\n",bit_count.mv[0],bit_count.mv[0],bit_count.mv[1],bit_count.mv[1]/np, bit_count.mv[2],bit_count.mv[2]/nb);
    printf("Skip idx:              %9d  %9d  %9d  %9d  %9d  %9d\n",bit_count.skip_idx[0],bit_count.skip_idx[0],bit_count.skip_idx[1],bit_count.skip_idx[1]/np,bit_count.skip_idx[2],bit_count.skip_idx[2]/nb);
    printf("Coeff_y:               %9d  %9d  %9d  %9d  %9d  %9d\n",bit_count.coeff_y[0],bit_count.coeff_y[0]/ni,bit_count.coeff_y[1],bit_count.coeff_y[1]/np,bit_count.coeff_y[2],bit_count.coeff_y[2]/nb);
    printf("Coeff_u:               %9d  %9d  %9d  %9d  %9d  %9d\n",bit_count.coeff_u[0],bit_count.coeff_u[0]/ni,bit_count.coeff_u[1],bit_count.coeff_u[1]/np,bit_count.coeff_u[2],bit_count.coeff_u[2]/nb);
    printf("Coeff_v:               %9d  %9d  %9d  %9d  %9d  %9d\n",bit_count.coeff_v[0],bit_count.coeff_v[0]/ni,bit_count.coeff_v[1],bit_count.coeff_v[1]/np,bit_count.coeff_v[2],bit_count.coeff_v[2]/nb);
    printf("CBP (TU-split):        %9d  %9d  %9d  %9d  %9d  %9d\n",bit_count.cbp[0],bit_count.cbp[0]/ni,bit_count.cbp[1],bit_count.cbp[1]/np,bit_count.cbp[2],bit_count.cbp[2]/nb);
    printf("CLPF:                  %9d  %9d  %9d  %9d  %9d  %9d\n",bit_count.clpf[0],bit_count.clpf[0]/ni,bit_count.clpf[1],bit_count.clpf[1]/np,bit_count.clpf[2],bit_count.clpf[2]/nb);
    printf("Total:                 %9d  %9d  %9d  %9d  %9d  %9d\n",tot_bits[0],tot_bits[0],tot_bits[1],tot_bits[1]/np,tot_bits[2],tot_bits[2]/nb);
    printf("---------------------------------------------------------------------------------------\n\n");

    printf("PARAMETER STATISTICS:\n");
    printf("                           I pictures:           P pictures:           B pictures:\n");
    printf("                           total    average      total    average      total    average\n");
    printf("Skip-blocks (8x8):     %9d  %9d  %9d  %9d  %9d  %9d\n",bit_count.mode[0][0],bit_count.mode[0][0]/ni,bit_count.mode[1][0],bit_count.mode[1][0]/np,bit_count.mode[2][0],bit_count.mode[2][0]/nb);
    printf("Intra-blocks (8x8):    %9d  %9d  %9d  %9d  %9d  %9d\n",bit_count.mode[0][1],bit_count.mode[0][1]/ni,bit_count.mode[1][1],bit_count.mode[1][1]/np,bit_count.mode[2][1],bit_count.mode[2][1]/nb);
    printf("Inter-blocks (8x8):    %9d  %9d  %9d  %9d  %9d  %9d\n",bit_count.mode[0][2],bit_count.mode[0][2]/ni,bit_count.mode[1][2],bit_count.mode[1][2]/np,bit_count.mode[2][2],bit_count.mode[2][2]/nb);
    printf("Bipred-blocks (8x8):   %9d  %9d  %9d  %9d  %9d  %9d\n",bit_count.mode[0][3],bit_count.mode[0][3]/ni,bit_count.mode[1][3],bit_count.mode[1][3]/np,bit_count.mode[2][3],bit_count.mode[2][3]/nb);
    printf("Merge-blocks (8x8):    %9d  %9d  %9d  %9d  %9d  %9d\n",bit_count.mode[0][4],bit_count.mode[0][4]/ni,bit_count.mode[1][4],bit_count.mode[1][4]/np,bit_count.mode[2][4],bit_count.mode[2][4]/nb);

    printf("\n");
    printf("8x8-blocks (8x8):      %9d  %9d  %9d  %9d  %9d  %9d\n",bit_count.size[0][0],bit_count.size[0][0]/ni,bit_count.size[1][0],bit_count.size[1][0]/np,bit_count.size[2][0],bit_count.size[2][0]/nb);
    printf("16x16-blocks (8x8):    %9d  %9d  %9d  %9d  %9d  %9d\n",bit_count.size[0][1],bit_count.size[0][1]/ni,bit_count.size[1][1],bit_count.size[1][1]/np,bit_count.size[2][1],bit_count.size[2][1]/nb);
    printf("32x32-blocks (8x8):    %9d  %9d  %9d  %9d  %9d  %9d\n",bit_count.size[0][2],bit_count.size[0][2]/ni,bit_count.size[1][2],bit_count.size[1][2]/np,bit_count.size[2][2],bit_count.size[2][2]/nb);
    printf("64x64-blocks (8x8):    %9d  %9d  %9d  %9d  %9d  %9d\n",bit_count.size[0][3],bit_count.size[0][3]/ni,bit_count.size[1][3],bit_count.size[1][3]/np,bit_count.size[2][3],bit_count.size[2][3]/nb);

    printf("\n");
    printf("Mode and size distribution for P pictures:\n");
    printf("                            SKIP      INTRA      INTER     BIPRED      MERGE\n");
    printf("8x8-blocks (8x8):      %9d  %9d  %9d  %9d  %9d\n",bit_count.size_and_mode[P_FRAME][0][0],bit_count.size_and_mode[P_FRAME][0][1],bit_count.size_and_mode[P_FRAME][0][2],bit_count.size_and_mode[P_FRAME][0][3],bit_count.size_and_mode[P_FRAME][0][4]);
    printf("16x16-blocks (8x8):    %9d  %9d  %9d  %9d  %9d\n",bit_count.size_and_mode[P_FRAME][1][0],bit_count.size_and_mode[P_FRAME][1][1],bit_count.size_and_mode[P_FRAME][1][2],bit_count.size_and_mode[P_FRAME][1][3],bit_count.size_and_mode[P_FRAME][1][4]);
    printf("32x32-blocks (8x8):    %9d  %9d  %9d  %9d  %9d\n",bit_count.size_and_mode[P_FRAME][2][0],bit_count.size_and_mode[P_FRAME][2][1],bit_count.size_and_mode[P_FRAME][2][2],bit_count.size_and_mode[P_FRAME][2][3],bit_count.size_and_mode[P_FRAME][2][4]);
    printf("64x64-blocks (8x8):    %9d  %9d  %9d  %9d  %9d\n",bit_count.size_and_mode[P_FRAME][3][0],bit_count.size_and_mode[P_FRAME][3][1],bit_count.size_and_mode[P_FRAME][3][2],bit_count.size_and_mode[P_FRAME][3][3],bit_count.size_and_mode[P_FRAME][3][4]);

    printf("\n");
    printf("Mode and size distribution for B pictures:\n");
    printf("                            SKIP      INTRA      INTER     BIPRED      MERGE\n");
    printf("8x8-blocks (8x8):      %9d  %9d  %9d  %9d  %9d\n", bit_count.size_and_mode[B_FRAME][0][0], bit_count.size_and_mode[B_FRAME][0][1], bit_count.size_and_mode[B_FRAME][0][2], bit_count.size_and_mode[B_FRAME][0][3], bit_count.size_and_mode[B_FRAME][0][4]);
    printf("16x16-blocks (8x8):    %9d  %9d  %9d  %9d  %9d\n", bit_count.size_and_mode[B_FRAME][1][0], bit_count.size_and_mode[B_FRAME][1][1], bit_count.size_and_mode[B_FRAME][1][2], bit_count.size_and_mode[B_FRAME][1][3], bit_count.size_and_mode[B_FRAME][1][4]);
    printf("32x32-blocks (8x8):    %9d  %9d  %9d  %9d  %9d\n", bit_count.size_and_mode[B_FRAME][2][0], bit_count.size_and_mode[B_FRAME][2][1], bit_count.size_and_mode[B_FRAME][2][2], bit_count.size_and_mode[B_FRAME][2][3], bit_count.size_and_mode[B_FRAME][2][4]);
    printf("64x64-blocks (8x8):    %9d  %9d  %9d  %9d  %9d\n", bit_count.size_and_mode[B_FRAME][3][0], bit_count.size_and_mode[B_FRAME][3][1], bit_count.size_and_mode[B_FRAME][3][2], bit_count.size_and_mode[B_FRAME][3][3], bit_count.size_and_mode[B_FRAME][3][4]);

    int idx;
    int num = 5 + decoder_info.max_num_ref;
    printf("\nSuper-mode distribution for P pictures:\n");
    printf("                    SKIP   SPLIT INTERr0   MERGE   BIPRED  INTRA ");
    for (i = 1; i < decoder_info.max_num_ref; i++) printf("INTERr%1d ", i);
    printf("\n");
    for (idx=0;idx<NUM_BLOCK_SIZES;idx++){
      int size = 8<<idx;
      printf("%2d x %2d-blocks: ",size,size);
      for (i=0;i<num;i++){
        printf("%8d",bit_count.super_mode_stat[P_FRAME][idx][i]);
      }
      printf("\n");
    }
   
    printf("\nSuper-mode distribution for B pictures:\n");
    printf("                    SKIP   SPLIT INTERr0   MERGE   BIPRED  INTRA ");
    for (i = 1; i < decoder_info.max_num_ref; i++) printf("INTERr%1d ", i);
    printf("\n");
    for (idx = 0; idx<NUM_BLOCK_SIZES; idx++) {
      int size = 8 << idx;
      printf("%2d x %2d-blocks: ", size, size);
      for (i = 0; i<num; i++) {
        printf("%8d", bit_count.super_mode_stat[B_FRAME][idx][i]);
      }
      printf("\n");
    }

    int size;
    int max_num_ref = 4;
    printf("\n");
    printf("Ref_idx and size distribution for P pictures:\n");
    for (i=0;i<NUM_BLOCK_SIZES;i++){
      size = 1<<(i+3);
      printf("%2d x %2d-blocks: ",size,size);
      for (j=0;j<decoder_info.max_num_ref;j++){
        printf("%6d",bit_count.size_and_ref_idx[P_FRAME][i][j]);
      }
      printf("\n");
    }

    printf("\n");
    printf("Ref_idx and size distribution for B pictures:\n");
    for (i = 0; i<NUM_BLOCK_SIZES; i++) {
      size = 1 << (i + 3);
      printf("%2d x %2d-blocks: ", size, size);
      for (j = 0; j<decoder_info.max_num_ref; j++) {
        printf("%6d", bit_count.size_and_ref_idx[B_FRAME][i][j]);
      }
      printf("\n");
    }
    printf("\n");
    printf("bi-ref-P:  ");
    for (j=0;j<max_num_ref*max_num_ref;j++){
      printf("%7d",bit_count.bi_ref[P_FRAME][j]);
    }
    printf("\n");
    printf("bi-ref-B:  ");
    for (j = 0; j<max_num_ref*max_num_ref; j++) {
      printf("%7d", bit_count.bi_ref[B_FRAME][j]);
    }
    printf("\n");
    printf("-----------------------------------------------------------------\n");
    for (r=0;r<MAX_REORDER_BUFFER;r++){
      close_yuv_frame(&rec[r]);
    }
    for (r=0;r<MAX_REF_FRAMES;r++){
      close_yuv_frame(&ref[r]);
    }
    if (decoder_info.interp_ref) {
      for (r=0;r<MAX_SKIP_FRAMES;r++){
        close_yuv_frame(decoder_info.interp_frames[r]);
        free(decoder_info.interp_frames[r]);
      }
    }

    free(decoder_info.deblock_data);

    return 0;
}
コード例 #2
0
ファイル: temporal_interp.c プロジェクト: leloulight/thor
void interpolate_frames(yuv_frame_t* new_frame, yuv_frame_t* ref0, yuv_frame_t* ref1, int ratio, int pos)
{
  int widthin = ref0->width;
  int heightin = ref0->height;

  int max_levels=min(MAX_LEVELS, (int) (log10(min(widthin, heightin))/log10(2.0)-4.0));

  mv_data_t * mv_data[MAX_LEVELS];
  mv_data_t * spatial_mv_data[MAX_LEVELS];
  mv_data_t * guide_mv_data[NUM_GUIDES];

  yuv_frame_t* in_down[MAX_LEVELS][2];
  yuv_frame_t* out_down[MAX_LEVELS];

  int interpolate = 1;
  for (int j=1; j<max_levels; j++) {
    out_down[j]=malloc(sizeof(yuv_frame_t));
    create_yuv_frame(out_down[j],widthin>>j,heightin>>j, 32, 32, 16, 16);
  }
  out_down[0]=new_frame;

  for (int j=0; j<max_levels; j++) {
    mv_data[j] = alloc_mv_data(widthin>>j, heightin>>j, BLOCK_STEP/2, BLOCK_STEP, ratio, pos, interpolate);
    mv_data[j]->ratio = ratio;
    spatial_mv_data[j] = alloc_mv_data(widthin>>j, heightin>>j, BLOCK_STEP/2, BLOCK_STEP, ratio, pos, interpolate);
    spatial_mv_data[j]->ratio = ratio;
  }

  /* Higher levels are down-sampled*/
  for (int i=1; i<max_levels; ++i) {
    in_down[i][0]=malloc(sizeof(yuv_frame_t));
    in_down[i][1]=malloc(sizeof(yuv_frame_t));
    create_yuv_frame(in_down[i][0],widthin>>i, heightin>>i, 32, 32, 16, 16);
    create_yuv_frame(in_down[i][1],widthin>>i, heightin>>i, 32, 32, 16, 16);
  }
  // Level 0 is just the original pictures
  in_down[0][0]=ref0;
  in_down[0][1]=ref1;

  for (int l=0; l<max_levels-1; ++l) {
    if (use_simd) {
      scale_frame_down2x2_simd(in_down[l][0], in_down[l+1][0]);
      scale_frame_down2x2_simd(in_down[l][1], in_down[l+1][1]);
    } else {
      scale_frame_down2x2(in_down[l][0], in_down[l+1][0]);
      scale_frame_down2x2(in_down[l][1], in_down[l+1][1]);
    }
  }


  for (int lvl=max_levels-1; lvl>=0; --lvl) {
    int num_guides=0;
    if (lvl!=max_levels-1) {
      guide_mv_data[num_guides++]=spatial_mv_data[lvl];
    }
    motion_estimate_bi(mv_data[lvl], guide_mv_data, num_guides, in_down[lvl][0], in_down[lvl][1], pos);
    if (lvl==0) interpolate_frame(mv_data[lvl], in_down[lvl][0], in_down[lvl][1], out_down[lvl], widthin, heightin, pos, ratio);
    if (lvl>0) {
      upscale_mv_data_2x2(mv_data[lvl], spatial_mv_data[lvl-1]);
    }

  }

  for (int j=1; j<max_levels; j++) {
    close_yuv_frame(out_down[j]);
    free(out_down[j]);
  }

  for (int j=0; j<max_levels; j++) {
    free_mv_data(mv_data[j]);
    free_mv_data(spatial_mv_data[j]);
  }

  /* Higher levels are down-sampled*/
  for (int i=1; i<max_levels; ++i) {
    close_yuv_frame(in_down[i][0]);
    close_yuv_frame(in_down[i][1]);
    free(in_down[i][0]);
    free(in_down[i][1]);
  }

}