static int dnxhd_init_vlc(DNXHDEncContext *ctx) { int i; CHECKED_ALLOCZ(ctx->table_vlc_codes, 449*2); CHECKED_ALLOCZ(ctx->table_vlc_bits, 449); CHECKED_ALLOCZ(ctx->table_run_codes, 63*2); CHECKED_ALLOCZ(ctx->table_run_bits, 63); for (i = 0; i < 257; i++) { int level = ctx->cid_table->ac_level[i] + (ctx->cid_table->ac_run_flag[i] << 7) + (ctx->cid_table->ac_index_flag[i] << 8); assert(level < 449); if (ctx->cid_table->ac_level[i] == 64 && ctx->cid_table->ac_index_flag[i]) level -= 64; // use 0+(1<<8) level ctx->table_vlc_codes[level] = ctx->cid_table->ac_codes[i]; ctx->table_vlc_bits [level] = ctx->cid_table->ac_bits[i]; } for (i = 0; i < 62; i++) { int run = ctx->cid_table->run[i]; assert(run < 63); ctx->table_run_codes[run] = ctx->cid_table->run_codes[i]; ctx->table_run_bits [run] = ctx->cid_table->run_bits[i]; } return 0; fail: return -1; }
static int dnxhd_init_qmat(DNXHDEncContext *ctx, int lbias, int cbias) { // init first elem to 1 to avoid div by 0 in convert_matrix uint16_t weight_matrix[64] = {1,}; // convert_matrix needs uint16_t* int qscale, i; CHECKED_ALLOCZ(ctx->qmatrix_l, (ctx->m.avctx->qmax+1) * 64 * sizeof(int)); CHECKED_ALLOCZ(ctx->qmatrix_c, (ctx->m.avctx->qmax+1) * 64 * sizeof(int)); CHECKED_ALLOCZ(ctx->qmatrix_l16, (ctx->m.avctx->qmax+1) * 64 * 2 * sizeof(uint16_t)); CHECKED_ALLOCZ(ctx->qmatrix_c16, (ctx->m.avctx->qmax+1) * 64 * 2 * sizeof(uint16_t)); for (i = 1; i < 64; i++) { int j = ctx->m.dsp.idct_permutation[ff_zigzag_direct[i]]; weight_matrix[j] = ctx->cid_table->luma_weight[i]; } ff_convert_matrix(&ctx->m.dsp, ctx->qmatrix_l, ctx->qmatrix_l16, weight_matrix, ctx->m.intra_quant_bias, 1, ctx->m.avctx->qmax, 1); for (i = 1; i < 64; i++) { int j = ctx->m.dsp.idct_permutation[ff_zigzag_direct[i]]; weight_matrix[j] = ctx->cid_table->chroma_weight[i]; } ff_convert_matrix(&ctx->m.dsp, ctx->qmatrix_c, ctx->qmatrix_c16, weight_matrix, ctx->m.intra_quant_bias, 1, ctx->m.avctx->qmax, 1); for (qscale = 1; qscale <= ctx->m.avctx->qmax; qscale++) { for (i = 0; i < 64; i++) { ctx->qmatrix_l [qscale] [i] <<= 2; ctx->qmatrix_c [qscale] [i] <<= 2; ctx->qmatrix_l16[qscale][0][i] <<= 2; ctx->qmatrix_l16[qscale][1][i] <<= 2; ctx->qmatrix_c16[qscale][0][i] <<= 2; ctx->qmatrix_c16[qscale][1][i] <<= 2; } } return 0; fail: return -1; }
static int dnxhd_init_rc(DNXHDEncContext *ctx) { CHECKED_ALLOCZ(ctx->mb_rc, 8160*ctx->m.avctx->qmax*sizeof(RCEntry)); if (ctx->m.avctx->mb_decision != FF_MB_DECISION_RD) CHECKED_ALLOCZ(ctx->mb_cmp, ctx->m.mb_num*sizeof(RCCMPEntry)); ctx->frame_bits = (ctx->cid_table->coding_unit_size - 640 - 4) * 8; ctx->qscale = 1; ctx->lambda = 2<<LAMBDA_FRAC_BITS; // qscale 2 return 0; fail: return -1; }
static int alloc_picture(MpegEncContext *s, Picture *pic, int shared) { const int big_mb_num= s->mb_stride*(s->mb_height+1) + 1; //the +1 is needed so memset(,,stride*height) doesnt sig11 const int mb_array_size= s->mb_stride*s->mb_height; const int b8_array_size= s->b8_stride*s->mb_height*2; const int b4_array_size= s->b4_stride*s->mb_height*4; int i; int r; r= avcodec_default_get_buffer(s->avctx, (AVFrame*)pic); if(r<0 || !pic->data[0]) return -1; if(s->linesize && (s->linesize != pic->linesize[0] || s->uvlinesize != pic->linesize[1])) return -1; if(pic->linesize[1] != pic->linesize[2]) return -1; s->linesize = pic->linesize[0]; s->uvlinesize= pic->linesize[1]; if(pic->qscale_table==NULL) { CHECKED_ALLOCZ(pic->qscale_table , mb_array_size * sizeof(uint8_t)); CHECKED_ALLOCZ(pic->mb_type_base , big_mb_num * sizeof(uint32_t)); pic->mb_type= pic->mb_type_base + s->mb_stride+1; for(i=0; i<2; i++) { CHECKED_ALLOCZ(pic->motion_val_base[i], 2 * (b4_array_size+2) * sizeof(int16_t)); pic->motion_val[i]= pic->motion_val_base[i]+2; CHECKED_ALLOCZ(pic->ref_index[i] , b8_array_size * sizeof(uint8_t)); } } return 0; fail: //for the CHECKED_ALLOCZ macro return -1; }
static int dnxhd_encode_init(AVCodecContext *avctx) { DNXHDEncContext *ctx = avctx->priv_data; int i, index; ctx->cid = ff_dnxhd_find_cid(avctx); if (!ctx->cid || avctx->pix_fmt != PIX_FMT_YUV422P) { av_log(avctx, AV_LOG_ERROR, "video parameters incompatible with DNxHD\n"); return -1; } av_log(avctx, AV_LOG_DEBUG, "cid %d\n", ctx->cid); index = ff_dnxhd_get_cid_table(ctx->cid); ctx->cid_table = &ff_dnxhd_cid_table[index]; ctx->m.avctx = avctx; ctx->m.mb_intra = 1; ctx->m.h263_aic = 1; dsputil_init(&ctx->m.dsp, avctx); ff_dct_common_init(&ctx->m); if (!ctx->m.dct_quantize) ctx->m.dct_quantize = dct_quantize_c; ctx->m.mb_height = (avctx->height + 15) / 16; ctx->m.mb_width = (avctx->width + 15) / 16; if (avctx->flags & CODEC_FLAG_INTERLACED_DCT) { ctx->interlaced = 1; ctx->m.mb_height /= 2; } ctx->m.mb_num = ctx->m.mb_height * ctx->m.mb_width; if (avctx->intra_quant_bias != FF_DEFAULT_QUANT_BIAS) ctx->m.intra_quant_bias = avctx->intra_quant_bias; if (dnxhd_init_qmat(ctx, ctx->m.intra_quant_bias, 0) < 0) // XXX tune lbias/cbias return -1; if (dnxhd_init_vlc(ctx) < 0) return -1; if (dnxhd_init_rc(ctx) < 0) return -1; CHECKED_ALLOCZ(ctx->slice_size, ctx->m.mb_height*sizeof(uint32_t)); CHECKED_ALLOCZ(ctx->mb_bits, ctx->m.mb_num *sizeof(uint16_t)); CHECKED_ALLOCZ(ctx->mb_qscale, ctx->m.mb_num *sizeof(uint8_t)); ctx->frame.key_frame = 1; ctx->frame.pict_type = FF_I_TYPE; ctx->m.avctx->coded_frame = &ctx->frame; if (avctx->thread_count > MAX_THREADS || (avctx->thread_count > ctx->m.mb_height)) { av_log(avctx, AV_LOG_ERROR, "too many threads\n"); return -1; } ctx->thread[0] = ctx; for (i = 1; i < avctx->thread_count; i++) { ctx->thread[i] = av_malloc(sizeof(DNXHDEncContext)); memcpy(ctx->thread[i], ctx, sizeof(DNXHDEncContext)); } for (i = 0; i < avctx->thread_count; i++) { ctx->thread[i]->m.start_mb_y = (ctx->m.mb_height*(i ) + avctx->thread_count/2) / avctx->thread_count; ctx->thread[i]->m.end_mb_y = (ctx->m.mb_height*(i+1) + avctx->thread_count/2) / avctx->thread_count; } return 0; fail: //for CHECKED_ALLOCZ return -1; }