/*! ************************************************************************ * \brief * Dynamic memory allocation of frame size related global buffers * buffers are defined in global.h, allocated memory must be freed in * void free_global_buffers() * * \par Input: * Input Parameters struct inp_par *inp, Image Parameters struct img_par *img * * \par Output: * Number of allocated bytes *********************************************************************** */ int init_global_buffers() { int memory_size=0; if (global_init_done) { free_global_buffers(); } // allocate memory for reference frame in find_snr memory_size += get_mem2D(&imgY_ref, img->height, img->width); memory_size += get_mem3D(&imgUV_ref, 2, img->height_cr, img->width_cr); // allocate memory in structure img if(((img->mb_data) = (Macroblock *) calloc(img->FrameSizeInMbs, sizeof(Macroblock))) == NULL) no_mem_exit("init_global_buffers: img->mb_data"); if(((img->intra_block) = (int*)calloc(img->FrameSizeInMbs, sizeof(int))) == NULL) no_mem_exit("init_global_buffers: img->intra_block"); memory_size += get_mem2Dint(&(img->ipredmode), 4*img->PicWidthInMbs , 4*img->FrameHeightInMbs); memory_size += get_mem2Dint(&(img->field_anchor),4*img->FrameHeightInMbs, 4*img->PicWidthInMbs); memory_size += get_mem3Dint(&(img->wp_weight), 2, MAX_REFERENCE_PICTURES, 3); memory_size += get_mem3Dint(&(img->wp_offset), 6, MAX_REFERENCE_PICTURES, 3); memory_size += get_mem4Dint(&(img->wbp_weight), 6, MAX_REFERENCE_PICTURES, MAX_REFERENCE_PICTURES, 3); // CAVLC mem memory_size += get_mem3Dint(&(img->nz_coeff), img->FrameSizeInMbs, 4, 6); memory_size += get_mem2Dint(&(img->siblock),img->PicWidthInMbs , img->FrameHeightInMbs); global_init_done = 1; img->oldFrameSizeInMbs = img->FrameSizeInMbs; return (memory_size); }
/*! ************************************************************************ * \brief * Interpret the spare picture SEI message * \param payload * a pointer that point to the sei payload * \param size * the size of the sei message * \param img * the image pointer * ************************************************************************ */ void interpret_spare_pic( byte* payload, int size, ImageParameters *img ) { int i,x,y; Bitstream* buf; int bit0, bit1, bitc, no_bit0; int target_frame_num; int num_spare_pics; int delta_spare_frame_num, CandidateSpareFrameNum, SpareFrameNum = 0; int ref_area_indicator; int m, n, left, right, top, bottom,directx, directy; byte ***map; #ifdef WRITE_MAP_IMAGE int j, k, i0, j0, tmp, kk; char filename[20] = "map_dec.yuv"; FILE *fp; byte** Y; static int old_pn=-1; static int first = 1; printf("Spare picture SEI message\n"); #endif UsedBits = 0; assert( payload!=NULL); assert( img!=NULL); #ifdef ESLCPP buf = (Bitstream*)malloc(sizeof(Bitstream)); #else buf = malloc(sizeof(Bitstream)); #endif buf->bitstream_length = size; buf->streamBuffer = payload; buf->frame_bitoffset = 0; target_frame_num = ue_v("SEI: target_frame_num", buf); #ifdef WRITE_MAP_IMAGE printf( "target_frame_num is %d\n", target_frame_num ); #endif num_spare_pics = 1 + ue_v("SEI: num_spare_pics_minus1", buf); #ifdef WRITE_MAP_IMAGE printf( "num_spare_pics is %d\n", num_spare_pics ); #endif get_mem3D(&map, num_spare_pics, img->height/16, img->width/16); for (i=0; i<num_spare_pics; i++) { if (i==0) { CandidateSpareFrameNum = target_frame_num - 1; if ( CandidateSpareFrameNum < 0 ) CandidateSpareFrameNum = MAX_FN - 1; } else CandidateSpareFrameNum = SpareFrameNum; delta_spare_frame_num = ue_v("SEI: delta_spare_frame_num", buf); SpareFrameNum = CandidateSpareFrameNum - delta_spare_frame_num; if( SpareFrameNum < 0 ) SpareFrameNum = MAX_FN + SpareFrameNum; ref_area_indicator = ue_v("SEI: ref_area_indicator", buf); switch ( ref_area_indicator ) { case 0: // The whole frame can serve as spare picture for (y=0; y<img->height/16; y++) for (x=0; x<img->width/16; x++) map[i][y][x] = 0; break; case 1: // The map is not compressed for (y=0; y<img->height/16; y++) for (x=0; x<img->width/16; x++) { map[i][y][x] = u_1("SEI: ref_mb_indicator", buf); } break; case 2: // The map is compressed //!KS: could not check this function, description is unclear (as stated in Ed. Note) bit0 = 0; bit1 = 1; bitc = bit0; no_bit0 = -1; x = ( img->width/16 - 1 ) / 2; y = ( img->height/16 - 1 ) / 2; left = right = x; top = bottom = y; directx = 0; directy = 1; for (m=0; m<img->height/16; m++) for (n=0; n<img->width/16; n++) { if (no_bit0<0) { no_bit0 = ue_v("SEI: zero_run_length", buf); } if (no_bit0>0) map[i][y][x] = bit0; else map[i][y][x] = bit1; no_bit0--; // go to the next mb: if ( directx == -1 && directy == 0 ) { if (x > left) x--; else if (x == 0) { y = bottom + 1; bottom++; directx = 1; directy = 0; } else if (x == left) { x--; left--; directx = 0; directy = 1; } } else if ( directx == 1 && directy == 0 ) { if (x < right) x++; else if (x == img->width/16 - 1) { y = top - 1; top--; directx = -1; directy = 0; } else if (x == right) { x++; right++; directx = 0; directy = -1; } } else if ( directx == 0 && directy == -1 ) { if ( y > top) y--; else if (y == 0) { x = left - 1; left--; directx = 0; directy = 1; } else if (y == top) { y--; top--; directx = -1; directy = 0; } } else if ( directx == 0 && directy == 1 ) { if (y < bottom) y++; else if (y == img->height/16 - 1) { x = right+1; right++; directx = 0; directy = -1; } else if (y == bottom) { y++; bottom++; directx = 1; directy = 0; } } } break; default: printf( "Wrong ref_area_indicator %d!\n", ref_area_indicator ); exit(0); break; } } // end of num_spare_pics #ifdef WRITE_MAP_IMAGE // begin to write map seq if ( old_pn != img->number ) { old_pn = img->number; get_mem2D(&Y, img->height, img->width); if (first) { fp = fopen( filename, "wb" ); first = 0; } else fp = fopen( filename, "ab" ); assert( fp != NULL ); for (kk=0; kk<num_spare_pics; kk++) { for (i=0; i < img->height/16; i++) for (j=0; j < img->width/16; j++) { tmp=map[kk][i][j]==0? 255 : 0; for (i0=0; i0<16; i0++) for (j0=0; j0<16; j0++) Y[i*16+i0][j*16+j0]=tmp; } // write the map image for (i=0; i < img->height; i++) for (j=0; j < img->width; j++) fputc(Y[i][j], fp); for (k=0; k < 2; k++) for (i=0; i < img->height/2; i++) for (j=0; j < img->width/2; j++) fputc(128, fp); } fclose( fp ); free_mem2D( Y ); } // end of writing map image #undef WRITE_MAP_IMAGE #endif free_mem3D( map, num_spare_pics ); free(buf); }
/*! ************************************************************************ * \brief * Dynamic memory allocation of frame size related global buffers * buffers are defined in global.h, allocated memory must be freed in * void free_global_buffers() * * \par Input: * Input Parameters struct inp_par *inp, Image Parameters struct img_par *img * * \par Output: * Number of allocated bytes *********************************************************************** */ int init_global_buffers(struct inp_par *inp, struct img_par *img) { int memory_size=0; if (global_init_done) { free_global_buffers(inp, img); } if (img->structure != FRAME) { img->height *= 2; // set height to frame (twice of field) for normal variables img->height_cr *= 2; // set height to frame (twice of field) for normal variables } // allocate memory for reference frame in find_snr memory_size += get_mem2D(&imgY_ref, img->height, img->width); memory_size += get_mem3D(&imgUV_ref, 2, img->height_cr, img->width_cr); // allocate memory in structure img #ifndef STATIC_ALLOC if(((img->mb_data) = (Macroblock *) calloc((img->width/MB_BLOCK_SIZE) * (img->height/MB_BLOCK_SIZE),sizeof(Macroblock))) == NULL) no_mem_exit("init_global_buffers: img->mb_data"); if(((img->intra_block) = (int*)calloc((img->width/MB_BLOCK_SIZE) * (img->height/MB_BLOCK_SIZE),sizeof(int))) == NULL) no_mem_exit("init_global_buffers: img->intra_block"); memory_size += get_mem2Dint(&(img->ipredmode),img->width/BLOCK_SIZE , img->height/BLOCK_SIZE); // CAVLC mem memory_size += get_mem3Dint(&(img->nz_coeff), img->FrameSizeInMbs, 4, 6); memory_size += get_mem2Dint(&(img->siblock),img->width/MB_BLOCK_SIZE , img->height/MB_BLOCK_SIZE); #else // ipredmode memory_size += (1920/BLOCK_SIZE) * (1088/BLOCK_SIZE) * sizeof(int); // CAVLC mem // nz_coeff memory_size += (1920/MB_BLOCK_SIZE) * (1088/MB_BLOCK_SIZE) * 4 * 6 * sizeof(int); // siblock memory_size += (176/MB_BLOCK_SIZE) * (144/MB_BLOCK_SIZE) * sizeof(int); #endif memory_size += get_mem2Dint(&(img->field_anchor),img->height/BLOCK_SIZE,img->width/BLOCK_SIZE); memory_size += get_mem3Dint(&(img->wp_weight), 2, MAX_REFERENCE_PICTURES, 3); memory_size += get_mem3Dint(&(img->wp_offset), 2, MAX_REFERENCE_PICTURES, 3); memory_size += get_mem4Dint(&(img->wbp_weight), 2, MAX_REFERENCE_PICTURES, MAX_REFERENCE_PICTURES, 3); if (img->structure != FRAME) { img->height /= 2; // reset height for normal variables img->height_cr /= 2; // reset height for normal variables } global_init_done = 1; return (memory_size); }
/*! ************************************************************************************* * \brief * allocate storable picture memory for errdo * ************************************************************************************* */ void errdo_alloc_storable_picture(StorablePicture *p, VideoParameters *p_Vid, InputParameters *p_Inp, int size_x, int size_y, int size_x_cr, int size_y_cr) { Dist_Estm *s; int dec, ndec, nplane; p->de_mem = (Dist_Estm *)malloc( sizeof(Dist_Estm) ); s = p->de_mem; s->res_con_diff_Y = NULL; s->res_con_diff_UV = NULL; s->MV_con_diff_Y = NULL; s->MV_con_diff_UV = NULL; s->error_sign_flag_Y = NULL; s->error_sign_flag_UV = NULL; s->transmission_dist_Y = NULL; s->transmission_dist_UV = NULL; s->transmission_err_Y = NULL; s->transmission_err_UV = NULL; s->dec_imgY = NULL; s->dec_imgUV = NULL; s->mb_error_map = NULL; s->first_moment_Y = NULL; s->first_moment_UV = NULL; s->second_moment_Y = NULL; s->second_moment_UV = NULL; for (nplane = 0; nplane < 3; nplane++) { s->p_res_con_diff[nplane] = NULL; s->p_MV_con_diff[nplane] = NULL; s->p_error_sign_flag[nplane] = NULL; s->p_transmission_dist[nplane] = NULL; s->p_transmission_err[nplane] = NULL; s->p_dec_img[nplane] = NULL; s->p_first_moment[nplane] = NULL; s->p_second_moment[nplane] = NULL; } switch (p_Inp->de) { case LLN: ndec = p_Inp->NoOfDecoders; //check the consistent if (ndec == 0) { printf("Number of decoders cannot be zero for LLN and fast LLN algorithms, resetting to 30"); ndec = 30; } get_mem3D(&(s->mb_error_map), ndec, size_y/MB_BLOCK_SIZE, size_x/MB_BLOCK_SIZE); get_mem3Dpel(&(s->dec_imgY), ndec, size_y, size_x); // This seems somewhat inefficient. Why not allocate array as [ndec][x] where x goes from 0 to 2? if ((s->p_dec_img[0] = (imgpel***)calloc(ndec,sizeof(imgpel**))) == NULL) { no_mem_exit("errdo.c: p_dec_img[0]"); } if (p_Vid->yuv_format != YUV400) { get_mem4Dpel(&(s->dec_imgUV), ndec, 2, size_y_cr, size_x_cr); if ((s->p_dec_img[1] = (imgpel***)calloc(ndec,sizeof(imgpel**))) == NULL) { no_mem_exit("errdo.c: p_dec_img[1]"); } if ((s->p_dec_img[2] = (imgpel***)calloc(ndec,sizeof(imgpel**))) == NULL) { no_mem_exit("errdo.c: p_dec_img[2]"); } } for (dec = 0; dec < ndec; dec++) { s->p_dec_img[0][dec] = s->dec_imgY[dec]; } if (p_Vid->yuv_format != YUV400) { for (dec = 0; dec < ndec; dec++) { s->p_dec_img[1][dec] = s->dec_imgUV[dec][0]; s->p_dec_img[2][dec] = s->dec_imgUV[dec][1]; } } break; default: ; } }
/*! ************************************************************************ * \brief * Writes out a storable picture * If the picture is a field, the output buffers the picture and tries * to pair it with the next field. * \param p * Picture to be written * \param p_out * Output file ************************************************************************ */ void write_picture(StorablePicture *p, FILE *p_out, int real_structure) { int i, add; if (real_structure==FRAME) { flush_pending_output(p_out); write_out_picture(p, p_out); return; } if (real_structure==pending_output_state) { flush_pending_output(p_out); write_picture(p, p_out, real_structure); return; } if (pending_output_state == FRAME) { pending_output->size_x = p->size_x; pending_output->size_y = p->size_y; pending_output->size_x_cr = p->size_x_cr; pending_output->size_y_cr = p->size_y_cr; pending_output->frame_mbs_only_flag = p->frame_mbs_only_flag; pending_output->frame_cropping_flag = p->frame_cropping_flag; if (pending_output->frame_cropping_flag) { pending_output->frame_cropping_rect_left_offset = p->frame_cropping_rect_left_offset; pending_output->frame_cropping_rect_right_offset = p->frame_cropping_rect_right_offset; pending_output->frame_cropping_rect_top_offset = p->frame_cropping_rect_top_offset; pending_output->frame_cropping_rect_bottom_offset = p->frame_cropping_rect_bottom_offset; } get_mem2D (&(pending_output->imgY), pending_output->size_y, pending_output->size_x); get_mem3D (&(pending_output->imgUV), 2, pending_output->size_y_cr, pending_output->size_x_cr ); clear_picture(pending_output); // copy first field if (real_structure == TOP_FIELD) { add = 0; } else { add = 1; } for (i=0; i<pending_output->size_y; i+=2) { memcpy(pending_output->imgY[(i+add)], p->imgY[(i+add)], p->size_x); } for (i=0; i<pending_output->size_y_cr; i+=2) { memcpy(pending_output->imgUV[0][(i+add)], p->imgUV[0][(i+add)], p->size_x_cr); memcpy(pending_output->imgUV[1][(i+add)], p->imgUV[1][(i+add)], p->size_x_cr); } pending_output_state = real_structure; } else { if ( (pending_output->size_x!=p->size_x) || (pending_output->size_y!= p->size_y) || (pending_output->frame_mbs_only_flag != p->frame_mbs_only_flag) || (pending_output->frame_cropping_flag != p->frame_cropping_flag) || ( pending_output->frame_cropping_flag && ( (pending_output->frame_cropping_rect_left_offset != p->frame_cropping_rect_left_offset) ||(pending_output->frame_cropping_rect_right_offset != p->frame_cropping_rect_right_offset) ||(pending_output->frame_cropping_rect_top_offset != p->frame_cropping_rect_top_offset) ||(pending_output->frame_cropping_rect_bottom_offset != p->frame_cropping_rect_bottom_offset) ) ) ) { flush_pending_output(p_out); write_picture (p, p_out, real_structure); return; } // copy second field if (real_structure == TOP_FIELD) { add = 0; } else { add = 1; } for (i=0; i<pending_output->size_y; i+=2) { memcpy(pending_output->imgY[(i+add)], p->imgY[(i+add)], p->size_x); } for (i=0; i<pending_output->size_y_cr; i+=2) { memcpy(pending_output->imgUV[0][(i+add)], p->imgUV[0][(i+add)], p->size_x_cr); memcpy(pending_output->imgUV[1][(i+add)], p->imgUV[1][(i+add)], p->size_x_cr); } flush_pending_output(p_out); } }