summaryrefslogtreecommitdiff
path: root/libavcodec
diff options
context:
space:
mode:
authorMichael Niedermayer <michael@niedermayer.cc>2017-02-09 23:24:15 +0100
committerMichael Niedermayer <michael@niedermayer.cc>2017-02-10 00:12:01 +0100
commit3e1507a9547ac09b6ff4372123cde09f19218f3d (patch)
tree80afbf6c25ff3d0f82e7c2a5216c2fca287959a5 /libavcodec
parentf57665b3181d5cbed680754983d9a6fdc1bfec5f (diff)
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 <michael@niedermayer.cc>
Diffstat (limited to 'libavcodec')
-rw-r--r--libavcodec/mjpegenc.c144
-rw-r--r--libavcodec/mjpegenc_common.c11
-rw-r--r--libavcodec/mpegvideo_enc.c5
3 files changed, 128 insertions, 32 deletions
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)