X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavcodec%2Fmjpegenc_common.c;h=c1b842d547fa250e04da74f02e0d82f9555a69fb;hb=1c7f252783aec37e4ff8049476386f63afe91756;hp=31868c9bedac1517e28d4a78955a884dbdec0458;hpb=26148e923613e718787c6fc4bf3f64e8909f597c;p=ffmpeg diff --git a/libavcodec/mjpegenc_common.c b/libavcodec/mjpegenc_common.c index 31868c9beda..c1b842d547f 100644 --- a/libavcodec/mjpegenc_common.c +++ b/libavcodec/mjpegenc_common.c @@ -23,7 +23,6 @@ #include #include -#include "libavutil/common.h" #include "libavutil/pixdesc.h" #include "libavutil/pixfmt.h" @@ -33,35 +32,8 @@ #include "put_bits.h" #include "mjpegenc.h" #include "mjpegenc_common.h" -#include "mjpegenc_huffman.h" #include "mjpeg.h" -av_cold void ff_init_uni_ac_vlc(const uint8_t huff_size_ac[256], uint8_t *uni_ac_vlc_len) -{ - int i; - - for (i = 0; i < 128; i++) { - int level = i - 64; - int run; - if (!level) - continue; - for (run = 0; run < 64; run++) { - int len, code, nbits; - int alevel = FFABS(level); - - len = (run >> 4) * huff_size_ac[0xf0]; - - nbits= av_log2_16bit(alevel) + 1; - code = ((15&run) << 4) | nbits; - - len += huff_size_ac[code] + nbits; - - uni_ac_vlc_len[UNI_AC_ENC_INDEX(run, i)] = len; - // We ignore EOB as its just a constant which does not change generally - } - } -} - /* table_class: 0 = DC coef, 1 = AC coefs */ static int put_huffman_table(PutBitContext *p, int table_class, int table_id, const uint8_t *bits_table, const uint8_t *value_table) @@ -181,7 +153,7 @@ static void jpeg_put_comments(AVCodecContext *avctx, PutBitContext *p) /* JFIF header */ put_marker(p, APP0); put_bits(p, 16, 16); - avpriv_put_string(p, "JFIF", 1); /* this puts the trailing zero-byte too */ + ff_put_string(p, "JFIF", 1); /* this puts the trailing zero-byte too */ /* The most significant byte is used for major revisions, the least * significant byte for minor revisions. Version 1.02 is the current * released revision. */ @@ -199,7 +171,7 @@ static void jpeg_put_comments(AVCodecContext *avctx, PutBitContext *p) flush_put_bits(p); ptr = put_bits_ptr(p); put_bits(p, 16, 0); /* patched later */ - avpriv_put_string(p, LIBAVCODEC_IDENT, 1); + ff_put_string(p, LIBAVCODEC_IDENT, 1); size = strlen(LIBAVCODEC_IDENT)+3; AV_WB16(ptr, size); } @@ -212,7 +184,7 @@ static void jpeg_put_comments(AVCodecContext *avctx, PutBitContext *p) flush_put_bits(p); ptr = put_bits_ptr(p); put_bits(p, 16, 0); /* patched later */ - avpriv_put_string(p, "CS=ITU601", 1); + ff_put_string(p, "CS=ITU601", 1); size = strlen("CS=ITU601")+3; AV_WB16(ptr, size); } @@ -353,60 +325,12 @@ end: MpegEncContext *s = avctx->priv_data; av_assert0(avctx->codec->priv_data_size == sizeof(MpegEncContext)); - s->esc_pos = put_bits_count(pb) >> 3; + s->esc_pos = put_bytes_count(pb, 0); for(i=1; islice_context_count; i++) s->thread_context[i]->esc_pos = 0; } } -/** - * Encodes and outputs the entire frame in the JPEG format. - * - * @param s The MpegEncContext. - */ -void ff_mjpeg_encode_picture_frame(MpegEncContext *s) -{ - int i, nbits, code, table_id; - MJpegContext *m = s->mjpeg_ctx; - uint8_t *huff_size[4] = {m->huff_size_dc_luminance, - m->huff_size_dc_chrominance, - m->huff_size_ac_luminance, - m->huff_size_ac_chrominance}; - uint16_t *huff_code[4] = {m->huff_code_dc_luminance, - m->huff_code_dc_chrominance, - m->huff_code_ac_luminance, - m->huff_code_ac_chrominance}; - size_t total_bits = 0; - size_t bytes_needed; - - s->header_bits = get_bits_diff(s); - // Estimate the total size first - for (i = 0; i < m->huff_ncode; i++) { - table_id = m->huff_buffer[i].table_id; - code = m->huff_buffer[i].code; - nbits = code & 0xf; - - total_bits += huff_size[table_id][code] + nbits; - } - - bytes_needed = (total_bits + 7) / 8; - ff_mpv_reallocate_putbitbuffer(s, bytes_needed, bytes_needed); - - for (i = 0; i < m->huff_ncode; i++) { - table_id = m->huff_buffer[i].table_id; - code = m->huff_buffer[i].code; - nbits = code & 0xf; - - put_bits(&s->pb, huff_size[table_id][code], huff_code[table_id][code]); - if (nbits != 0) { - put_sbits(&s->pb, nbits, m->huff_buffer[i].mant); - } - } - - m->huff_ncode = 0; - s->i_tex_bits = get_bits_diff(s); -} - void ff_mjpeg_escape_FF(PutBitContext *pb, int start) { int size; @@ -419,10 +343,7 @@ void ff_mjpeg_escape_FF(PutBitContext *pb, int start) put_bits(pb, pad, (1<>= 3; + size = put_bytes_output(pb) - start; ff_count=0; for(i=0; ihuff_ncode; i++) { - table_id = m->huff_buffer[i].table_id; - code = m->huff_buffer[i].code; - - ff_mjpeg_encode_huffman_increment(ctx[table_id], code); - } - - ff_mjpeg_encode_huffman_close(&dc_luminance_ctx, - m->bits_dc_luminance, - m->val_dc_luminance, 12); - ff_mjpeg_encode_huffman_close(&dc_chrominance_ctx, - m->bits_dc_chrominance, - m->val_dc_chrominance, 12); - ff_mjpeg_encode_huffman_close(&ac_luminance_ctx, - m->bits_ac_luminance, - m->val_ac_luminance, 256); - ff_mjpeg_encode_huffman_close(&ac_chrominance_ctx, - m->bits_ac_chrominance, - m->val_ac_chrominance, 256); - - ff_mjpeg_build_huffman_codes(m->huff_size_dc_luminance, - m->huff_code_dc_luminance, - m->bits_dc_luminance, - m->val_dc_luminance); - ff_mjpeg_build_huffman_codes(m->huff_size_dc_chrominance, - m->huff_code_dc_chrominance, - m->bits_dc_chrominance, - m->val_dc_chrominance); - ff_mjpeg_build_huffman_codes(m->huff_size_ac_luminance, - m->huff_code_ac_luminance, - m->bits_ac_luminance, - m->val_ac_luminance); - ff_mjpeg_build_huffman_codes(m->huff_size_ac_chrominance, - m->huff_code_ac_chrominance, - m->bits_ac_chrominance, - m->val_ac_chrominance); -} - -/** - * Writes the complete JPEG frame when optimal huffman tables are enabled, - * otherwise writes the stuffing. - * - * Header + values + stuffing. - * - * @param s The MpegEncContext. - * @return int Error code, 0 if successful. - */ -int ff_mjpeg_encode_stuffing(MpegEncContext *s) +/* isn't this function nicer than the one in the libjpeg ? */ +void ff_mjpeg_build_huffman_codes(uint8_t *huff_size, uint16_t *huff_code, + const uint8_t *bits_table, + const uint8_t *val_table) { - int i; - PutBitContext *pbc = &s->pb; - int mb_y = s->mb_y - !s->mb_x; - int ret; - MJpegContext *m; - - m = s->mjpeg_ctx; - - if (s->huffman == HUFFMAN_TABLE_OPTIMAL) { - ff_mjpeg_build_optimal_huffman(m); - - // Replace the VLCs with the optimal ones. - // The default ones may be used for trellis during quantization. - ff_init_uni_ac_vlc(m->huff_size_ac_luminance, m->uni_ac_vlc_len); - ff_init_uni_ac_vlc(m->huff_size_ac_chrominance, m->uni_chroma_ac_vlc_len); - s->intra_ac_vlc_length = - 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); - } - - ret = ff_mpv_reallocate_putbitbuffer(s, put_bits_count(&s->pb) / 8 + 100, - put_bits_count(&s->pb) / 4 + 1000); - - if (ret < 0) { - av_log(s->avctx, AV_LOG_ERROR, "Buffer reallocation failed\n"); - goto fail; + int k, code; + + k = 0; + code = 0; + for (int i = 1; i <= 16; i++) { + int nb = bits_table[i]; + for (int j = 0; j < nb; j++) { + int sym = val_table[k++]; + huff_size[sym] = i; + huff_code[sym] = code; + code++; + } + code <<= 1; } - - ff_mjpeg_escape_FF(pbc, s->esc_pos); - - if((s->avctx->active_thread_type & FF_THREAD_SLICE) && mb_y < s->mb_height) - put_marker(pbc, RST0 + (mb_y&7)); - s->esc_pos = put_bits_count(pbc) >> 3; -fail: - - for(i=0; i<3; i++) - s->last_dc[i] = 128 << s->intra_dc_precision; - - return ret; } void ff_mjpeg_encode_picture_trailer(PutBitContext *pb, int header_bits) @@ -612,3 +436,19 @@ void ff_mjpeg_encode_dc(PutBitContext *pb, int val, put_sbits(pb, nbits, mant); } } + +int ff_mjpeg_encode_check_pix_fmt(AVCodecContext *avctx) +{ + if (avctx->strict_std_compliance > FF_COMPLIANCE_UNOFFICIAL && + avctx->color_range != AVCOL_RANGE_JPEG && + (avctx->pix_fmt == AV_PIX_FMT_YUV420P || + avctx->pix_fmt == AV_PIX_FMT_YUV422P || + avctx->pix_fmt == AV_PIX_FMT_YUV444P || + avctx->color_range == AVCOL_RANGE_MPEG)) { + av_log(avctx, AV_LOG_ERROR, + "Non full-range YUV is non-standard, set strict_std_compliance " + "to at most unofficial to use it.\n"); + return AVERROR(EINVAL); + } + return 0; +}