X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavcodec%2Fdnxhdenc.c;h=639debfa06eacca3b7340311a7a32474c36d769b;hb=5085f25ace1e74846a0de3369bedd0e22d1a1bdc;hp=92e69daa958cf9bec393a380fc3cebe761d5e348;hpb=89ef08c992c484a46711b1a68a988303679c288e;p=ffmpeg diff --git a/libavcodec/dnxhdenc.c b/libavcodec/dnxhdenc.c index 92e69daa958..639debfa06e 100644 --- a/libavcodec/dnxhdenc.c +++ b/libavcodec/dnxhdenc.c @@ -29,12 +29,14 @@ #include "libavutil/timer.h" #include "avcodec.h" -#include "dsputil.h" +#include "blockdsp.h" +#include "fdctdsp.h" #include "internal.h" #include "mpegvideo.h" +#include "pixblockdsp.h" #include "dnxhdenc.h" -// The largest value that will not lead to overflow for 10bit samples. +// The largest value that will not lead to overflow for 10-bit samples. #define DNX10BIT_QMAT_SHIFT 18 #define RC_VARIANCE 1 // use variance or ssd for fast rc #define LAMBDA_FRAC_BITS 10 @@ -43,19 +45,22 @@ static const AVOption options[] = { { "nitris_compat", "encode with Avid Nitris compatibility", offsetof(DNXHDEncContext, nitris_compat), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, VE }, + { "ibias", "intra quant bias", + offsetof(DNXHDEncContext, intra_quant_bias), AV_OPT_TYPE_INT, + { .i64 = FF_DEFAULT_QUANT_BIAS }, INT_MIN, INT_MAX, VE }, { NULL } }; static const AVClass class = { - "dnxhd", - av_default_item_name, - options, - LIBAVUTIL_VERSION_INT + .class_name = "dnxhd", + .item_name = av_default_item_name, + .option = options, + .version = LIBAVUTIL_VERSION_INT, }; static void dnxhd_8bit_get_pixels_8x4_sym(int16_t *restrict block, const uint8_t *pixels, - int line_size) + ptrdiff_t line_size) { int i; for (i = 0; i < 4; i++) { @@ -79,7 +84,7 @@ static void dnxhd_8bit_get_pixels_8x4_sym(int16_t *restrict block, static av_always_inline void dnxhd_10bit_get_pixels_8x4_sym(int16_t *restrict block, const uint8_t *pixels, - int line_size) + ptrdiff_t line_size) { int i; @@ -99,14 +104,14 @@ static int dnxhd_10bit_dct_quantize(MpegEncContext *ctx, int16_t *block, int last_non_zero = 0; int i; - ctx->dsp.fdct(block); + ctx->fdsp.fdct(block); // Divide by 4 with rounding, to compensate scaling of DCT coefficients block[0] = (block[0] + 2) >> 2; for (i = 1; i < 64; ++i) { int j = scantable[i]; - int sign = block[j] >> 31; + int sign = FF_SIGNBIT(block[j]); int level = (block[j] ^ sign) - sign; level = level * qmat[j] >> DNX10BIT_QMAT_SHIFT; block[j] = (level ^ sign) - sign; @@ -199,18 +204,18 @@ static av_cold int dnxhd_init_qmat(DNXHDEncContext *ctx, int lbias, int cbias) if (ctx->cid_table->bit_depth == 8) { for (i = 1; i < 64; i++) { - int j = ctx->m.dsp.idct_permutation[ff_zigzag_direct[i]]; + int j = ctx->m.idsp.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, + ff_convert_matrix(&ctx->m, ctx->qmatrix_l, ctx->qmatrix_l16, + weight_matrix, ctx->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]]; + int j = ctx->m.idsp.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, + ff_convert_matrix(&ctx->m, ctx->qmatrix_c, ctx->qmatrix_c16, + weight_matrix, ctx->intra_quant_bias, 1, ctx->m.avctx->qmax, 1); for (qscale = 1; qscale <= ctx->m.avctx->qmax; qscale++) { @@ -227,7 +232,7 @@ static av_cold int dnxhd_init_qmat(DNXHDEncContext *ctx, int lbias, int cbias) // 10-bit for (qscale = 1; qscale <= ctx->m.avctx->qmax; qscale++) { for (i = 1; i < 64; i++) { - int j = ctx->m.dsp.idct_permutation[ff_zigzag_direct[i]]; + int j = ctx->m.idsp.idct_permutation[ff_zigzag_direct[i]]; /* The quantization formula from the VC-3 standard is: * quantized = sign(block[i]) * floor(abs(block[i]/s) * p / @@ -284,19 +289,22 @@ static av_cold int dnxhd_encode_init(AVCodecContext *avctx) break; default: av_log(avctx, AV_LOG_ERROR, - "pixel format is incompatible with DNxHD\n"); + "Pixel format is incompatible with DNxHD, use yuv422p or yuv422p10.\n"); return AVERROR(EINVAL); } ctx->cid = ff_dnxhd_find_cid(avctx, bit_depth); if (!ctx->cid) { av_log(avctx, AV_LOG_ERROR, - "video parameters incompatible with DNxHD\n"); + "Video parameters incompatible with DNxHD, available CIDs:\n"); + ff_dnxhd_list_cid(avctx); return AVERROR(EINVAL); } av_log(avctx, AV_LOG_DEBUG, "cid %d\n", ctx->cid); index = ff_dnxhd_get_cid_table(ctx->cid); + if (index < 0) + return index; ctx->cid_table = &ff_dnxhd_cid_table[index]; ctx->m.avctx = avctx; @@ -305,8 +313,11 @@ static av_cold int dnxhd_encode_init(AVCodecContext *avctx) avctx->bits_per_raw_sample = ctx->cid_table->bit_depth; - ff_dsputil_init(&ctx->m.dsp, avctx); - ff_dct_common_init(&ctx->m); + ff_blockdsp_init(&ctx->bdsp); + ff_fdctdsp_init(&ctx->m.fdsp, avctx); + ff_mpv_idct_init(&ctx->m); + ff_mpegvideoencdsp_init(&ctx->m.mpvencdsp, avctx); + ff_pixblockdsp_init(&ctx->m.pdsp, avctx); if (!ctx->m.dct_quantize) ctx->m.dct_quantize = ff_dct_quantize_c; @@ -325,17 +336,15 @@ static av_cold int dnxhd_encode_init(AVCodecContext *avctx) ctx->m.mb_height = (avctx->height + 15) / 16; ctx->m.mb_width = (avctx->width + 15) / 16; - if (avctx->flags & CODEC_FLAG_INTERLACED_DCT) { + if (avctx->flags & AV_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; // XXX tune lbias/cbias - if ((ret = dnxhd_init_qmat(ctx, ctx->m.intra_quant_bias, 0)) < 0) + if ((ret = dnxhd_init_qmat(ctx, ctx->intra_quant_bias, 0)) < 0) return ret; /* Avid Nitris hardware decoder requires a minimum amount of padding @@ -357,12 +366,12 @@ static av_cold int dnxhd_encode_init(AVCodecContext *avctx) FF_ALLOCZ_OR_GOTO(ctx->m.avctx, ctx->mb_qscale, ctx->m.mb_num * sizeof(uint8_t), fail); - avctx->coded_frame = av_frame_alloc(); - if (!avctx->coded_frame) - return AVERROR(ENOMEM); - +#if FF_API_CODED_FRAME +FF_DISABLE_DEPRECATION_WARNINGS avctx->coded_frame->key_frame = 1; avctx->coded_frame->pict_type = AV_PICTURE_TYPE_I; +FF_ENABLE_DEPRECATION_WARNINGS +#endif if (avctx->thread_count > MAX_THREADS) { av_log(avctx, AV_LOG_ERROR, "too many threads\n"); @@ -383,7 +392,7 @@ fail: // for FF_ALLOCZ_OR_GOTO static int dnxhd_write_header(AVCodecContext *avctx, uint8_t *buf) { DNXHDEncContext *ctx = avctx->priv_data; - const uint8_t header_prefix[5] = { 0x00, 0x00, 0x02, 0x80, 0x01 }; + static const uint8_t header_prefix[5] = { 0x00, 0x00, 0x02, 0x80, 0x01 }; memset(buf, 0, 640); @@ -534,12 +543,12 @@ void dnxhd_get_blocks(DNXHDEncContext *ctx, int mb_x, int mb_y) ((mb_y << 4) * ctx->m.uvlinesize) + (mb_x << bs); const uint8_t *ptr_v = ctx->thread[0]->src[2] + ((mb_y << 4) * ctx->m.uvlinesize) + (mb_x << bs); - DSPContext *dsp = &ctx->m.dsp; + PixblockDSPContext *pdsp = &ctx->m.pdsp; - dsp->get_pixels(ctx->blocks[0], ptr_y, ctx->m.linesize); - dsp->get_pixels(ctx->blocks[1], ptr_y + bw, ctx->m.linesize); - dsp->get_pixels(ctx->blocks[2], ptr_u, ctx->m.uvlinesize); - dsp->get_pixels(ctx->blocks[3], ptr_v, ctx->m.uvlinesize); + pdsp->get_pixels(ctx->blocks[0], ptr_y, ctx->m.linesize); + pdsp->get_pixels(ctx->blocks[1], ptr_y + bw, ctx->m.linesize); + pdsp->get_pixels(ctx->blocks[2], ptr_u, ctx->m.uvlinesize); + pdsp->get_pixels(ctx->blocks[3], ptr_v, ctx->m.uvlinesize); if (mb_y + 1 == ctx->m.mb_height && ctx->m.avctx->height == 1080) { if (ctx->interlaced) { @@ -556,20 +565,20 @@ void dnxhd_get_blocks(DNXHDEncContext *ctx, int mb_x, int mb_y) ptr_v + ctx->dct_uv_offset, ctx->m.uvlinesize); } else { - dsp->clear_block(ctx->blocks[4]); - dsp->clear_block(ctx->blocks[5]); - dsp->clear_block(ctx->blocks[6]); - dsp->clear_block(ctx->blocks[7]); + ctx->bdsp.clear_block(ctx->blocks[4]); + ctx->bdsp.clear_block(ctx->blocks[5]); + ctx->bdsp.clear_block(ctx->blocks[6]); + ctx->bdsp.clear_block(ctx->blocks[7]); } } else { - dsp->get_pixels(ctx->blocks[4], - ptr_y + ctx->dct_y_offset, ctx->m.linesize); - dsp->get_pixels(ctx->blocks[5], - ptr_y + ctx->dct_y_offset + bw, ctx->m.linesize); - dsp->get_pixels(ctx->blocks[6], - ptr_u + ctx->dct_uv_offset, ctx->m.uvlinesize); - dsp->get_pixels(ctx->blocks[7], - ptr_v + ctx->dct_uv_offset, ctx->m.uvlinesize); + pdsp->get_pixels(ctx->blocks[4], + ptr_y + ctx->dct_y_offset, ctx->m.linesize); + pdsp->get_pixels(ctx->blocks[5], + ptr_y + ctx->dct_y_offset + bw, ctx->m.linesize); + pdsp->get_pixels(ctx->blocks[6], + ptr_u + ctx->dct_uv_offset, ctx->m.uvlinesize); + pdsp->get_pixels(ctx->blocks[7], + ptr_v + ctx->dct_uv_offset, ctx->m.uvlinesize); } } @@ -632,7 +641,7 @@ static int dnxhd_calc_bits_thread(AVCodecContext *avctx, void *arg, if (avctx->mb_decision == FF_MB_DECISION_RD || !RC_VARIANCE) { dnxhd_unquantize_c(ctx, block, i, qscale, last_index); - ctx->m.dsp.idct(block); + ctx->m.idsp.idct(block); ssd += dnxhd_ssd_block(block, src_block); } } @@ -716,8 +725,8 @@ static int dnxhd_mb_var_thread(AVCodecContext *avctx, void *arg, int varc; if (!partial_last_row && mb_x * 16 <= avctx->width - 16) { - sum = ctx->m.dsp.pix_sum(pix, ctx->m.linesize); - varc = ctx->m.dsp.pix_norm1(pix, ctx->m.linesize); + sum = ctx->m.mpvencdsp.pix_sum(pix, ctx->m.linesize); + varc = ctx->m.mpvencdsp.pix_norm1(pix, ctx->m.linesize); } else { int bw = FFMIN(avctx->width - 16 * mb_x, 16); int bh = FFMIN((avctx->height >> ctx->interlaced) - 16 * mb_y, 16); @@ -736,7 +745,7 @@ static int dnxhd_mb_var_thread(AVCodecContext *avctx, void *arg, ctx->mb_cmp[mb].mb = mb; } } else { // 10-bit - int const linesize = ctx->m.linesize >> 1; + const int linesize = ctx->m.linesize >> 1; for (mb_x = 0; mb_x < ctx->m.mb_width; ++mb_x) { uint16_t *pix = (uint16_t *)ctx->thread[0]->src[0] + ((mb_y << 4) * linesize) + (mb_x << 4); @@ -749,7 +758,7 @@ static int dnxhd_mb_var_thread(AVCodecContext *avctx, void *arg, for (i = 0; i < 16; ++i) { for (j = 0; j < 16; ++j) { // Turn 16-bit pixels into 10-bit ones. - int const sample = (unsigned) pix[j] >> 6; + const int sample = (unsigned) pix[j] >> 6; sum += sample; sqsum += sample * sample; // 2^10 * 2^10 * 16 * 16 = 2^28, which is less than INT_MAX @@ -807,9 +816,6 @@ static int dnxhd_encode_rdo(AVCodecContext *avctx, DNXHDEncContext *ctx) if (bits > ctx->frame_bits) break; } - // av_dlog(ctx->m.avctx, - // "lambda %d, up %u, down %u, bits %d, frame %d\n", - // lambda, last_higher, last_lower, bits, ctx->frame_bits); if (end) { if (bits > ctx->frame_bits) return AVERROR(EINVAL); @@ -838,7 +844,6 @@ static int dnxhd_encode_rdo(AVCodecContext *avctx, DNXHDEncContext *ctx) down_step = 1<m.avctx, "out lambda %d\n", lambda); ctx->lambda = lambda; return 0; } @@ -867,10 +872,6 @@ static int dnxhd_find_qscale(DNXHDEncContext *ctx) if (bits > ctx->frame_bits) break; } - // av_dlog(ctx->m.avctx, - // "%d, qscale %d, bits %d, frame %d, higher %d, lower %d\n", - // ctx->m.avctx->frame_number, qscale, bits, ctx->frame_bits, - // last_higher, last_lower); if (bits < ctx->frame_bits) { if (qscale == 1) return 1; @@ -899,7 +900,6 @@ static int dnxhd_find_qscale(DNXHDEncContext *ctx) return AVERROR(EINVAL); } } - //av_dlog(ctx->m.avctx, "out qscale %d\n", qscale); ctx->qscale = qscale; return 0; } @@ -1015,7 +1015,11 @@ static void dnxhd_load_picture(DNXHDEncContext *ctx, const AVFrame *frame) ctx->thread[i]->dct_uv_offset = ctx->m.uvlinesize*8; } +#if FF_API_CODED_FRAME +FF_DISABLE_DEPRECATION_WARNINGS ctx->m.avctx->coded_frame->interlaced_frame = frame->interlaced_frame; +FF_ENABLE_DEPRECATION_WARNINGS +#endif ctx->cur_field = frame->interlaced_frame && !frame->top_field_first; } @@ -1025,7 +1029,7 @@ static int dnxhd_encode_picture(AVCodecContext *avctx, AVPacket *pkt, DNXHDEncContext *ctx = avctx->priv_data; int first_field = 1; int offset, i, ret; - uint8_t *buf; + uint8_t *buf, *sd; if ((ret = ff_alloc_packet(pkt, ctx->cid_table->frame_size)) < 0) { av_log(avctx, AV_LOG_ERROR, @@ -1079,7 +1083,16 @@ encode_coding_unit: goto encode_coding_unit; } +#if FF_API_CODED_FRAME +FF_DISABLE_DEPRECATION_WARNINGS avctx->coded_frame->quality = ctx->qscale * FF_QP2LAMBDA; +FF_ENABLE_DEPRECATION_WARNINGS +#endif + + sd = av_packet_new_side_data(pkt, AV_PKT_DATA_QUALITY_FACTOR, sizeof(int)); + if (!sd) + return AVERROR(ENOMEM); + *(int *)sd = ctx->qscale * FF_QP2LAMBDA; pkt->flags |= AV_PKT_FLAG_KEY; *got_packet = 1; @@ -1112,8 +1125,6 @@ static av_cold int dnxhd_encode_end(AVCodecContext *avctx) for (i = 1; i < avctx->thread_count; i++) av_freep(&ctx->thread[i]); - av_frame_free(&avctx->coded_frame); - return 0; } @@ -1126,7 +1137,7 @@ AVCodec ff_dnxhd_encoder = { .init = dnxhd_encode_init, .encode2 = dnxhd_encode_picture, .close = dnxhd_encode_end, - .capabilities = CODEC_CAP_SLICE_THREADS, + .capabilities = AV_CODEC_CAP_SLICE_THREADS, .pix_fmts = (const enum AVPixelFormat[]) { AV_PIX_FMT_YUV422P, AV_PIX_FMT_YUV422P10,