From patchwork Thu Feb 18 03:41:53 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andreas Rheinhardt X-Patchwork-Id: 25757 Delivered-To: andriy.gelman@gmail.com Received: by 2002:a25:6d42:0:0:0:0:0 with SMTP id i63csp2518038ybc; Wed, 17 Feb 2021 19:44:44 -0800 (PST) X-Google-Smtp-Source: ABdhPJw6+u1MJzuhPfeiK1tGei17fASSt9LodC0yPGgGz37AL5EW+lK+1dQ95K2NwrRbY8Q5jF2S X-Received: by 2002:aa7:c887:: with SMTP id p7mr2019937eds.28.1613619884630; Wed, 17 Feb 2021 19:44:44 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1613619884; cv=none; d=google.com; s=arc-20160816; b=nmrrE2ieTuAClFluvaACghuUf0/aM3DLNyGWiya0GbFdLDsUqALujvaXZFXZlzkBT5 RS9EbEQqxM6nMItMkUt8atO/54wVM0Kb/EWfFwxSchZgB6+TRYYFt2MCQp7uhwB8Xmjt 81cmaOAK0w08P1vhSX4tsNp753NoGQznBqSCEKLrwXbgY3kC7voQJQLeCFNrW/3KELPI W1i6VDyG5AfiX595tKRMjTH8RnLUyOTlIGzqJfzKpBNq0mgd1ckn9mP7WkX2MjPuWkuP xPGMHph0IT/p7gRUnny1rmXVUk6T3ZNQa5fq4yt6EfwpFVH0/NqOEJtT9MY5y7/PQ0ox Sp7A== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:content-transfer-encoding:cc:reply-to :list-subscribe:list-help:list-post:list-archive:list-unsubscribe :list-id:precedence:subject:mime-version:references:in-reply-to :message-id:date:to:from:dkim-signature:delivered-to; bh=SLFKsdIzHuIVCnfQiUmyh8HqjG5EneY0jYQnhB7w0Hg=; b=Pscd+P5b6GoS7was+YH06lnGcLbD6En3ZDo1X6rcWSNteF8WsweW1ohT7TafTa9iUY CO3OBNaqnN77kdmbF/PEJrSpMlWBrLcq2Uk4PDKtX6OjIzqWFvkRx9cAsOcGYWw+a0Jg xhFnhtn4UW7NKAaGdytSYD9Y8bhoyYv2Ye4N0n0nWXlG01Pfct5SOZpGU4fuTe1wq/ml m0j3YG8UQz9XBm7Pm1un9tv9lk1kUHPIvU025Q4kjhXv67lf8HijbnHw/5tAkcfppJfg gMWCJgfQ4m9259zmo9LbnVDYxLrrwV6mcv46BnqFx3uWAwc6kkA15wmk2ZM4cfT/CqPN Mxqw== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@gmail.com header.s=20161025 header.b=oHiJ8qnM; spf=pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) smtp.mailfrom=ffmpeg-devel-bounces@ffmpeg.org; dmarc=fail (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Return-Path: Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org. [79.124.17.100]) by mx.google.com with ESMTP id kj10si2953029ejc.166.2021.02.17.19.44.44; Wed, 17 Feb 2021 19:44:44 -0800 (PST) Received-SPF: pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) client-ip=79.124.17.100; Authentication-Results: mx.google.com; dkim=neutral (body hash did not verify) header.i=@gmail.com header.s=20161025 header.b=oHiJ8qnM; spf=pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) smtp.mailfrom=ffmpeg-devel-bounces@ffmpeg.org; dmarc=fail (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id C7C7968A40E; Thu, 18 Feb 2021 05:43:03 +0200 (EET) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-wm1-f49.google.com (mail-wm1-f49.google.com [209.85.128.49]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 58B1B689E05 for ; Thu, 18 Feb 2021 05:42:50 +0200 (EET) Received: by mail-wm1-f49.google.com with SMTP id n10so1649475wmq.0 for ; Wed, 17 Feb 2021 19:42:50 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references:reply-to :mime-version:content-transfer-encoding; bh=pisTrkYongV5PS9rYpowwHcCh1aQJnfZmOQSCBbfYf4=; b=oHiJ8qnM6xfypZWzvzGCEC45G5hjGqWrZcuPhPbWpROJr5AoeJTnJnatYEUQDwa6sd XbwUQd3CD9QEPpO/tVerKUNPZRk7uK4PmSGCN83X7HrdUc8S/kUqaRe5zCXJfb0BjWRh dt+gz1ty4J1UKtA2jS2gy+HMyC2vt6nRbUzcAy1MNXlXdAKA5c1f1AvOmnFyT0IT70bv AaUR6q96KM+rvFobrynKP1IXFz04mpENGN5f33SDY+lV/P+mo8FOZ5yw2ADALEm3Cs9k FGMQog4waaf1h148WL8SuluaIEQ/FiwxSqR1EX1YU0fng8U528Gg/U5OaFrjf9hZYgjp wRGg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:reply-to:mime-version:content-transfer-encoding; bh=pisTrkYongV5PS9rYpowwHcCh1aQJnfZmOQSCBbfYf4=; b=mp13/Ml/UVvTo0eYg8TbV5zD/HIEuqJ+KF0KCJuaDLSXA6+Vq5vDmi5bsLd364GAd3 BDjCkoXeYGH+2OhOFYWY/nbT10S02tccXy67vEnaJ4yCeMbz6P75zlL3q+MAyEttK9r0 tX3Fio+anPatzauIaIeB7H+9ul3168vqZjfRyCn/TSKjrw1ettQ1+LvgIlKPNwcGvCm+ hm/bqZGOvEiv0H4eromiJ+YX74OI0v8Dz/Ss5RslaX5xAsPsqSrMVjM89kN1WRYvjIx9 yBKDz5da3LR8sYWj66IA1E0POUXNgeA+JuioTeqzTCQjZ/iEdb3Tw/dT5so5HaOfviD9 sm6Q== X-Gm-Message-State: AOAM530uDlHiHX0s+C+5MSzev2QwVJgVGKHIy5vJLxV9J3B9rM6Hi5BM AcG+CZhX0M1+zarjtv0blRX4uQsFUf4= X-Received: by 2002:a1c:9a12:: with SMTP id c18mr1620899wme.146.1613619769469; Wed, 17 Feb 2021 19:42:49 -0800 (PST) Received: from sblaptop.fritz.box (ipbcc1aa4b.dynamic.kabel-deutschland.de. [188.193.170.75]) by smtp.gmail.com with ESMTPSA id p9sm5643855wmc.1.2021.02.17.19.42.48 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 17 Feb 2021 19:42:49 -0800 (PST) From: Andreas Rheinhardt To: ffmpeg-devel@ffmpeg.org Date: Thu, 18 Feb 2021 04:41:53 +0100 Message-Id: <20210218034214.2090223-8-andreas.rheinhardt@gmail.com> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20210218034214.2090223-1-andreas.rheinhardt@gmail.com> References: <20210218034214.2090223-1-andreas.rheinhardt@gmail.com> MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH 08/29] avcodec/mjpegenc_common: Move stuff only used by mjpegenc.c to it X-BeenThere: ffmpeg-devel@ffmpeg.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: FFmpeg development discussions and patches List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-To: FFmpeg development discussions and patches Cc: Andreas Rheinhardt Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" X-TUID: A4PhjUeOUAZi Content-Length: 25800 This allows to make ff_init_uni_ac_vlc static; ff_mjpeg_encode_picture_frame has also been made static, but it could always have been made static. Signed-off-by: Andreas Rheinhardt --- libavcodec/ljpegenc.c | 2 + libavcodec/mjpegenc.c | 191 +++++++++++++++++++++++++++++++++- libavcodec/mjpegenc.h | 1 + libavcodec/mjpegenc_common.c | 194 ----------------------------------- libavcodec/mjpegenc_common.h | 5 - 5 files changed, 192 insertions(+), 201 deletions(-) diff --git a/libavcodec/ljpegenc.c b/libavcodec/ljpegenc.c index 39ce5a0089..3c68c08a3c 100644 --- a/libavcodec/ljpegenc.c +++ b/libavcodec/ljpegenc.c @@ -32,12 +32,14 @@ #include "libavutil/frame.h" #include "libavutil/mem.h" +#include "libavutil/opt.h" #include "libavutil/pixdesc.h" #include "avcodec.h" #include "idctdsp.h" #include "internal.h" #include "jpegtables.h" +#include "mathops.h" #include "mjpegenc_common.h" #include "mjpeg.h" diff --git a/libavcodec/mjpegenc.c b/libavcodec/mjpegenc.c index 466f48eba9..22af094da7 100644 --- a/libavcodec/mjpegenc.c +++ b/libavcodec/mjpegenc.c @@ -35,11 +35,198 @@ #include "avcodec.h" #include "jpegtables.h" #include "mjpegenc_common.h" +#include "mjpegenc_huffman.h" #include "mpegvideo.h" #include "mjpeg.h" #include "mjpegenc.h" #include "profiles.h" +static av_cold void init_uni_ac_vlc(const uint8_t huff_size_ac[256], + uint8_t *uni_ac_vlc_len) +{ + for (int i = 0; i < 128; i++) { + int level = i - 64; + if (!level) + continue; + for (int 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 + } + } +} + +/** + * Encodes and outputs the entire frame in the JPEG format. + * + * @param s The MpegEncContext. + */ +static void mjpeg_encode_picture_frame(MpegEncContext *s) +{ + int 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 (int 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 (int 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); +} + +/** + * Builds all 4 optimal Huffman tables. + * + * Uses the data stored in the JPEG buffer to compute the tables. + * Stores the Huffman tables in the bits_* and val_* arrays in the MJpegContext. + * + * @param m MJpegContext containing the JPEG buffer. + */ +static void mjpeg_build_optimal_huffman(MJpegContext *m) +{ + MJpegEncHuffmanContext dc_luminance_ctx; + MJpegEncHuffmanContext dc_chrominance_ctx; + MJpegEncHuffmanContext ac_luminance_ctx; + MJpegEncHuffmanContext ac_chrominance_ctx; + MJpegEncHuffmanContext *ctx[4] = { &dc_luminance_ctx, + &dc_chrominance_ctx, + &ac_luminance_ctx, + &ac_chrominance_ctx }; + for (int i = 0; i < 4; i++) + ff_mjpeg_encode_huffman_init(ctx[i]); + + for (int i = 0; i < m->huff_ncode; i++) { + int table_id = m->huff_buffer[i].table_id; + int 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) +{ + 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) { + mjpeg_build_optimal_huffman(m); + + // Replace the VLCs with the optimal ones. + // The default ones may be used for trellis during quantization. + init_uni_ac_vlc(m->huff_size_ac_luminance, m->uni_ac_vlc_len); + 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); + 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; + } + + ff_mjpeg_escape_FF(pbc, s->esc_pos); + + if ((s->avctx->active_thread_type & FF_THREAD_SLICE) && mb_y < s->mb_height - 1) + put_marker(pbc, RST0 + (mb_y&7)); + s->esc_pos = put_bits_count(pbc) >> 3; + +fail: + for (int i = 0; i < 3; i++) + s->last_dc[i] = 128 << s->intra_dc_precision; + + return ret; +} + static int alloc_huffman(MpegEncContext *s) { MJpegContext *m = s->mjpeg_ctx; @@ -106,8 +293,8 @@ av_cold int ff_mjpeg_encode_init(MpegEncContext *s) avpriv_mjpeg_bits_ac_chrominance, avpriv_mjpeg_val_ac_chrominance); - 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); + init_uni_ac_vlc(m->huff_size_ac_luminance, m->uni_ac_vlc_len); + 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 = diff --git a/libavcodec/mjpegenc.h b/libavcodec/mjpegenc.h index d7ddc35ef5..2e92511276 100644 --- a/libavcodec/mjpegenc.h +++ b/libavcodec/mjpegenc.h @@ -107,5 +107,6 @@ static inline void put_marker(PutBitContext *p, enum JpegMarker code) int ff_mjpeg_encode_init(MpegEncContext *s); void ff_mjpeg_encode_close(MpegEncContext *s); void ff_mjpeg_encode_mb(MpegEncContext *s, int16_t block[12][64]); +int ff_mjpeg_encode_stuffing(MpegEncContext *s); #endif /* AVCODEC_MJPEGENC_H */ diff --git a/libavcodec/mjpegenc_common.c b/libavcodec/mjpegenc_common.c index 720b18d448..12dd7be2e8 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) @@ -359,54 +331,6 @@ end: } } -/** - * 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; @@ -487,124 +411,6 @@ void ff_mjpeg_build_huffman_codes(uint8_t *huff_size, uint16_t *huff_code, } } -/** - * Builds all 4 optimal Huffman tables. - * - * Uses the data stored in the JPEG buffer to compute the tables. - * Stores the Huffman tables in the bits_* and val_* arrays in the MJpegContext. - * - * @param m MJpegContext containing the JPEG buffer. - */ -static void ff_mjpeg_build_optimal_huffman(MJpegContext *m) -{ - int i, table_id, code; - - MJpegEncHuffmanContext dc_luminance_ctx; - MJpegEncHuffmanContext dc_chrominance_ctx; - MJpegEncHuffmanContext ac_luminance_ctx; - MJpegEncHuffmanContext ac_chrominance_ctx; - MJpegEncHuffmanContext *ctx[4] = {&dc_luminance_ctx, - &dc_chrominance_ctx, - &ac_luminance_ctx, - &ac_chrominance_ctx}; - for (i = 0; i < 4; i++) { - ff_mjpeg_encode_huffman_init(ctx[i]); - } - for (i = 0; i < m->huff_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) -{ - 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; - } - - ff_mjpeg_escape_FF(pbc, s->esc_pos); - - if((s->avctx->active_thread_type & FF_THREAD_SLICE) && mb_y < s->mb_height - 1) - 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) { av_assert1((header_bits & 7) == 0); diff --git a/libavcodec/mjpegenc_common.h b/libavcodec/mjpegenc_common.h index b432baac3e..b4f8a08e11 100644 --- a/libavcodec/mjpegenc_common.h +++ b/libavcodec/mjpegenc_common.h @@ -25,25 +25,20 @@ #include "avcodec.h" #include "idctdsp.h" -#include "mpegvideo.h" #include "put_bits.h" void ff_mjpeg_encode_picture_header(AVCodecContext *avctx, PutBitContext *pb, ScanTable *intra_scantable, int pred, uint16_t luma_intra_matrix[64], uint16_t chroma_intra_matrix[64]); -void ff_mjpeg_encode_picture_frame(MpegEncContext *s); void ff_mjpeg_encode_picture_trailer(PutBitContext *pb, int header_bits); void ff_mjpeg_escape_FF(PutBitContext *pb, int start); 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 ff_mjpeg_encode_stuffing(MpegEncContext *s); void ff_mjpeg_init_hvsample(AVCodecContext *avctx, int hsample[4], int vsample[4]); void ff_mjpeg_encode_dc(PutBitContext *pb, int val, uint8_t *huff_size, uint16_t *huff_code); -av_cold void ff_init_uni_ac_vlc(const uint8_t huff_size_ac[256], uint8_t *uni_ac_vlc_len); - #endif /* AVCODEC_MJPEGENC_COMMON_H */