From 3e1507a9547ac09b6ff4372123cde09f19218f3d Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Thu, 9 Feb 2017 23:24:15 +0100 Subject: avcodec/mjpegenc: Bypass the 2 pass encoding when optimal tables are not requested This limits the bugs, speedloss and extra memory allocation to the case when optimal tables are needed. Fixes regressions with slice multi-threading Signed-off-by: Michael Niedermayer --- libavcodec/mjpegenc.c | 144 +++++++++++++++++++++++++++++++++++-------- libavcodec/mjpegenc_common.c | 11 ++-- libavcodec/mpegvideo_enc.c | 5 +- 3 files changed, 128 insertions(+), 32 deletions(-) (limited to 'libavcodec') diff --git a/libavcodec/mjpegenc.c b/libavcodec/mjpegenc.c index 550338fd66..cc917edb7f 100644 --- a/libavcodec/mjpegenc.c +++ b/libavcodec/mjpegenc.c @@ -79,7 +79,7 @@ av_cold int ff_mjpeg_encode_init(MpegEncContext *s) return AVERROR(EINVAL); } - m = av_malloc(sizeof(MJpegContext)); + m = av_mallocz(sizeof(MJpegContext)); if (!m) return AVERROR(ENOMEM); @@ -117,7 +117,10 @@ av_cold int ff_mjpeg_encode_init(MpegEncContext *s) m->huff_ncode = 0; s->mjpeg_ctx = m; - return alloc_huffman(s); + if(s->huffman == HUFFMAN_TABLE_OPTIMAL) + return alloc_huffman(s); + + return 0; } av_cold void ff_mjpeg_encode_close(MpegEncContext *s) @@ -224,7 +227,7 @@ static void ff_mjpeg_encode_coef(MJpegContext *s, uint8_t table_id, int val, int * @param block The block. * @param n The block's index or number. */ -static void encode_block(MpegEncContext *s, int16_t *block, int n) +static void record_block(MpegEncContext *s, int16_t *block, int n) { int i, j, table_id; int component, dc, last_index, val, run; @@ -267,36 +270,127 @@ static void encode_block(MpegEncContext *s, int16_t *block, int n) ff_mjpeg_encode_code(m, table_id, 0); } +static void encode_block(MpegEncContext *s, int16_t *block, int n) +{ + int mant, nbits, code, i, j; + int component, dc, run, last_index, val; + MJpegContext *m = s->mjpeg_ctx; + uint8_t *huff_size_ac; + uint16_t *huff_code_ac; + + /* DC coef */ + component = (n <= 3 ? 0 : (n&1) + 1); + dc = block[0]; /* overflow is impossible */ + val = dc - s->last_dc[component]; + if (n < 4) { + ff_mjpeg_encode_dc(&s->pb, val, m->huff_size_dc_luminance, m->huff_code_dc_luminance); + huff_size_ac = m->huff_size_ac_luminance; + huff_code_ac = m->huff_code_ac_luminance; + } else { + ff_mjpeg_encode_dc(&s->pb, val, m->huff_size_dc_chrominance, m->huff_code_dc_chrominance); + huff_size_ac = m->huff_size_ac_chrominance; + huff_code_ac = m->huff_code_ac_chrominance; + } + s->last_dc[component] = dc; + + /* AC coefs */ + + run = 0; + last_index = s->block_last_index[n]; + for(i=1;i<=last_index;i++) { + j = s->intra_scantable.permutated[i]; + val = block[j]; + if (val == 0) { + run++; + } else { + while (run >= 16) { + put_bits(&s->pb, huff_size_ac[0xf0], huff_code_ac[0xf0]); + run -= 16; + } + mant = val; + if (val < 0) { + val = -val; + mant--; + } + + nbits= av_log2_16bit(val) + 1; + code = (run << 4) | nbits; + + put_bits(&s->pb, huff_size_ac[code], huff_code_ac[code]); + + put_sbits(&s->pb, nbits, mant); + run = 0; + } + } + + /* output EOB only if not already 64 values */ + if (last_index < 63 || run != 0) + put_bits(&s->pb, huff_size_ac[0], huff_code_ac[0]); +} + void ff_mjpeg_encode_mb(MpegEncContext *s, int16_t block[12][64]) { int i; - if (s->chroma_format == CHROMA_444) { - encode_block(s, block[0], 0); - encode_block(s, block[2], 2); - encode_block(s, block[4], 4); - encode_block(s, block[8], 8); - encode_block(s, block[5], 5); - encode_block(s, block[9], 9); - - if (16*s->mb_x+8 < s->width) { - encode_block(s, block[1], 1); - encode_block(s, block[3], 3); - encode_block(s, block[6], 6); - encode_block(s, block[10], 10); - encode_block(s, block[7], 7); - encode_block(s, block[11], 11); + if (s->huffman == HUFFMAN_TABLE_OPTIMAL) { + if (s->chroma_format == CHROMA_444) { + record_block(s, block[0], 0); + record_block(s, block[2], 2); + record_block(s, block[4], 4); + record_block(s, block[8], 8); + record_block(s, block[5], 5); + record_block(s, block[9], 9); + + if (16*s->mb_x+8 < s->width) { + record_block(s, block[1], 1); + record_block(s, block[3], 3); + record_block(s, block[6], 6); + record_block(s, block[10], 10); + record_block(s, block[7], 7); + record_block(s, block[11], 11); + } + } else { + for(i=0;i<5;i++) { + record_block(s, block[i], i); + } + if (s->chroma_format == CHROMA_420) { + record_block(s, block[5], 5); + } else { + record_block(s, block[6], 6); + record_block(s, block[5], 5); + record_block(s, block[7], 7); + } } } else { - for(i=0;i<5;i++) { - encode_block(s, block[i], i); - } - if (s->chroma_format == CHROMA_420) { + if (s->chroma_format == CHROMA_444) { + encode_block(s, block[0], 0); + encode_block(s, block[2], 2); + encode_block(s, block[4], 4); + encode_block(s, block[8], 8); encode_block(s, block[5], 5); + encode_block(s, block[9], 9); + + if (16*s->mb_x+8 < s->width) { + encode_block(s, block[1], 1); + encode_block(s, block[3], 3); + encode_block(s, block[6], 6); + encode_block(s, block[10], 10); + encode_block(s, block[7], 7); + encode_block(s, block[11], 11); + } } else { - encode_block(s, block[6], 6); - encode_block(s, block[5], 5); - encode_block(s, block[7], 7); + for(i=0;i<5;i++) { + encode_block(s, block[i], i); + } + if (s->chroma_format == CHROMA_420) { + encode_block(s, block[5], 5); + } else { + encode_block(s, block[6], 6); + encode_block(s, block[5], 5); + encode_block(s, block[7], 7); + } } + + s->i_tex_bits += get_bits_diff(s); } } diff --git a/libavcodec/mjpegenc_common.c b/libavcodec/mjpegenc_common.c index e53a45ca4d..722ad5e4da 100644 --- a/libavcodec/mjpegenc_common.c +++ b/libavcodec/mjpegenc_common.c @@ -480,7 +480,8 @@ static void ff_mjpeg_build_optimal_huffman(MJpegContext *m) } /** - * Writes the complete JPEG frame. + * Writes the complete JPEG frame when optimal huffman tables are enabled, + * otherwise writes the stuffing. * * Header + values + stuffing. * @@ -508,11 +509,11 @@ int ff_mjpeg_encode_stuffing(MpegEncContext *s) s->intra_ac_vlc_last_length = m->uni_ac_vlc_len; s->intra_chroma_ac_vlc_length = s->intra_chroma_ac_vlc_last_length = m->uni_chroma_ac_vlc_len; - } - ff_mjpeg_encode_picture_header(s->avctx, &s->pb, &s->intra_scantable, - s->pred, s->intra_matrix, s->chroma_intra_matrix); - ff_mjpeg_encode_picture_frame(s); + ff_mjpeg_encode_picture_header(s->avctx, &s->pb, &s->intra_scantable, + s->pred, s->intra_matrix, s->chroma_intra_matrix); + ff_mjpeg_encode_picture_frame(s); + } ret = ff_mpv_reallocate_putbitbuffer(s, put_bits_count(&s->pb) / 8 + 100, put_bits_count(&s->pb) / 4 + 1000); diff --git a/libavcodec/mpegvideo_enc.c b/libavcodec/mpegvideo_enc.c index b1d8dae4b2..0e4cbe8682 100644 --- a/libavcodec/mpegvideo_enc.c +++ b/libavcodec/mpegvideo_enc.c @@ -3942,8 +3942,9 @@ static int encode_picture(MpegEncContext *s, int picture_number) s->last_bits= put_bits_count(&s->pb); switch(s->out_format) { case FMT_MJPEG: - /* The MJPEG headers are printed after the initial encoding so that the - * optimal huffman encoding can be found. */ + if (CONFIG_MJPEG_ENCODER && s->huffman != HUFFMAN_TABLE_OPTIMAL) + ff_mjpeg_encode_picture_header(s->avctx, &s->pb, &s->intra_scantable, + s->pred, s->intra_matrix, s->chroma_intra_matrix); break; case FMT_H261: if (CONFIG_H261_ENCODER) -- cgit v1.2.3