Commit 3e1507a9 authored by Michael Niedermayer's avatar Michael Niedermayer

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: 's avatarMichael Niedermayer <michael@niedermayer.cc>
parent f57665b3
...@@ -79,7 +79,7 @@ av_cold int ff_mjpeg_encode_init(MpegEncContext *s) ...@@ -79,7 +79,7 @@ av_cold int ff_mjpeg_encode_init(MpegEncContext *s)
return AVERROR(EINVAL); return AVERROR(EINVAL);
} }
m = av_malloc(sizeof(MJpegContext)); m = av_mallocz(sizeof(MJpegContext));
if (!m) if (!m)
return AVERROR(ENOMEM); return AVERROR(ENOMEM);
...@@ -117,7 +117,10 @@ av_cold int ff_mjpeg_encode_init(MpegEncContext *s) ...@@ -117,7 +117,10 @@ av_cold int ff_mjpeg_encode_init(MpegEncContext *s)
m->huff_ncode = 0; m->huff_ncode = 0;
s->mjpeg_ctx = m; 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) 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 ...@@ -224,7 +227,7 @@ static void ff_mjpeg_encode_coef(MJpegContext *s, uint8_t table_id, int val, int
* @param block The block. * @param block The block.
* @param n The block's index or number. * @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 i, j, table_id;
int component, dc, last_index, val, run; int component, dc, last_index, val, run;
...@@ -267,36 +270,127 @@ static void encode_block(MpegEncContext *s, int16_t *block, int n) ...@@ -267,36 +270,127 @@ static void encode_block(MpegEncContext *s, int16_t *block, int n)
ff_mjpeg_encode_code(m, table_id, 0); 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]) void ff_mjpeg_encode_mb(MpegEncContext *s, int16_t block[12][64])
{ {
int i; int i;
if (s->chroma_format == CHROMA_444) { if (s->huffman == HUFFMAN_TABLE_OPTIMAL) {
encode_block(s, block[0], 0); if (s->chroma_format == CHROMA_444) {
encode_block(s, block[2], 2); record_block(s, block[0], 0);
encode_block(s, block[4], 4); record_block(s, block[2], 2);
encode_block(s, block[8], 8); record_block(s, block[4], 4);
encode_block(s, block[5], 5); record_block(s, block[8], 8);
encode_block(s, block[9], 9); record_block(s, block[5], 5);
record_block(s, block[9], 9);
if (16*s->mb_x+8 < s->width) {
encode_block(s, block[1], 1); if (16*s->mb_x+8 < s->width) {
encode_block(s, block[3], 3); record_block(s, block[1], 1);
encode_block(s, block[6], 6); record_block(s, block[3], 3);
encode_block(s, block[10], 10); record_block(s, block[6], 6);
encode_block(s, block[7], 7); record_block(s, block[10], 10);
encode_block(s, block[11], 11); 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 { } else {
for(i=0;i<5;i++) { if (s->chroma_format == CHROMA_444) {
encode_block(s, block[i], i); encode_block(s, block[0], 0);
} encode_block(s, block[2], 2);
if (s->chroma_format == CHROMA_420) { encode_block(s, block[4], 4);
encode_block(s, block[8], 8);
encode_block(s, block[5], 5); 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 { } else {
encode_block(s, block[6], 6); for(i=0;i<5;i++) {
encode_block(s, block[5], 5); encode_block(s, block[i], i);
encode_block(s, block[7], 7); }
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);
} }
} }
......
...@@ -480,7 +480,8 @@ static void ff_mjpeg_build_optimal_huffman(MJpegContext *m) ...@@ -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. * Header + values + stuffing.
* *
...@@ -508,11 +509,11 @@ int ff_mjpeg_encode_stuffing(MpegEncContext *s) ...@@ -508,11 +509,11 @@ int ff_mjpeg_encode_stuffing(MpegEncContext *s)
s->intra_ac_vlc_last_length = m->uni_ac_vlc_len; s->intra_ac_vlc_last_length = m->uni_ac_vlc_len;
s->intra_chroma_ac_vlc_length = s->intra_chroma_ac_vlc_length =
s->intra_chroma_ac_vlc_last_length = m->uni_chroma_ac_vlc_len; 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, ff_mjpeg_encode_picture_header(s->avctx, &s->pb, &s->intra_scantable,
s->pred, s->intra_matrix, s->chroma_intra_matrix); s->pred, s->intra_matrix, s->chroma_intra_matrix);
ff_mjpeg_encode_picture_frame(s); ff_mjpeg_encode_picture_frame(s);
}
ret = ff_mpv_reallocate_putbitbuffer(s, put_bits_count(&s->pb) / 8 + 100, ret = ff_mpv_reallocate_putbitbuffer(s, put_bits_count(&s->pb) / 8 + 100,
put_bits_count(&s->pb) / 4 + 1000); put_bits_count(&s->pb) / 4 + 1000);
......
...@@ -3942,8 +3942,9 @@ static int encode_picture(MpegEncContext *s, int picture_number) ...@@ -3942,8 +3942,9 @@ static int encode_picture(MpegEncContext *s, int picture_number)
s->last_bits= put_bits_count(&s->pb); s->last_bits= put_bits_count(&s->pb);
switch(s->out_format) { switch(s->out_format) {
case FMT_MJPEG: case FMT_MJPEG:
/* The MJPEG headers are printed after the initial encoding so that the if (CONFIG_MJPEG_ENCODER && s->huffman != HUFFMAN_TABLE_OPTIMAL)
* optimal huffman encoding can be found. */ ff_mjpeg_encode_picture_header(s->avctx, &s->pb, &s->intra_scantable,
s->pred, s->intra_matrix, s->chroma_intra_matrix);
break; break;
case FMT_H261: case FMT_H261:
if (CONFIG_H261_ENCODER) if (CONFIG_H261_ENCODER)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment