aboutsummaryrefslogtreecommitdiffstats
path: root/libavcodec/mpegvideo_unquantize.c
diff options
context:
space:
mode:
authorAndreas Rheinhardt <andreas.rheinhardt@outlook.com>2025-03-02 05:44:09 +0100
committerAndreas Rheinhardt <andreas.rheinhardt@outlook.com>2025-03-26 04:14:49 +0100
commit63864545cdc8da42f4cb99824293cabf136454e9 (patch)
treee8a8266e3381fec748a72404bf2bca543afb8099 /libavcodec/mpegvideo_unquantize.c
parent34b624d98cb8199befaba2ffc8a7b92c881cf03b (diff)
downloadffmpeg-63864545cdc8da42f4cb99824293cabf136454e9.tar.gz
avcodec/mpegvideo: Move unquantize functions into a file of their own
This is in preparation for only keeping the actually used unquantize functions in MpegEncContext. Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Diffstat (limited to 'libavcodec/mpegvideo_unquantize.c')
-rw-r--r--libavcodec/mpegvideo_unquantize.c273
1 files changed, 273 insertions, 0 deletions
diff --git a/libavcodec/mpegvideo_unquantize.c b/libavcodec/mpegvideo_unquantize.c
new file mode 100644
index 0000000000..12bacdf424
--- /dev/null
+++ b/libavcodec/mpegvideo_unquantize.c
@@ -0,0 +1,273 @@
+/*
+ * Unquantize functions for mpegvideo
+ * Copyright (c) 2000,2001 Fabrice Bellard
+ * Copyright (c) 2002-2004 Michael Niedermayer <michaelni@gmx.at>
+ *
+ * 4MV & hq & B-frame encoding stuff by Michael Niedermayer <michaelni@gmx.at>
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <stdint.h>
+
+#include "config.h"
+
+#include "libavutil/attributes.h"
+#include "libavutil/avassert.h"
+#include "avcodec.h"
+#include "mpegvideo.h"
+#include "mpegvideodata.h"
+#include "mpegvideo_unquantize.h"
+
+static void dct_unquantize_mpeg1_intra_c(MpegEncContext *s,
+ int16_t *block, int n, int qscale)
+{
+ int i, level, nCoeffs;
+ const uint16_t *quant_matrix;
+
+ nCoeffs= s->block_last_index[n];
+
+ block[0] *= n < 4 ? s->y_dc_scale : s->c_dc_scale;
+ /* XXX: only MPEG-1 */
+ quant_matrix = s->intra_matrix;
+ for(i=1;i<=nCoeffs;i++) {
+ int j= s->intra_scantable.permutated[i];
+ level = block[j];
+ if (level) {
+ if (level < 0) {
+ level = -level;
+ level = (int)(level * qscale * quant_matrix[j]) >> 3;
+ level = (level - 1) | 1;
+ level = -level;
+ } else {
+ level = (int)(level * qscale * quant_matrix[j]) >> 3;
+ level = (level - 1) | 1;
+ }
+ block[j] = level;
+ }
+ }
+}
+
+static void dct_unquantize_mpeg1_inter_c(MpegEncContext *s,
+ int16_t *block, int n, int qscale)
+{
+ int i, level, nCoeffs;
+ const uint16_t *quant_matrix;
+
+ nCoeffs= s->block_last_index[n];
+
+ quant_matrix = s->inter_matrix;
+ for(i=0; i<=nCoeffs; i++) {
+ int j= s->intra_scantable.permutated[i];
+ level = block[j];
+ if (level) {
+ if (level < 0) {
+ level = -level;
+ level = (((level << 1) + 1) * qscale *
+ ((int) (quant_matrix[j]))) >> 4;
+ level = (level - 1) | 1;
+ level = -level;
+ } else {
+ level = (((level << 1) + 1) * qscale *
+ ((int) (quant_matrix[j]))) >> 4;
+ level = (level - 1) | 1;
+ }
+ block[j] = level;
+ }
+ }
+}
+
+static void dct_unquantize_mpeg2_intra_c(MpegEncContext *s,
+ int16_t *block, int n, int qscale)
+{
+ int i, level, nCoeffs;
+ const uint16_t *quant_matrix;
+
+ if (s->q_scale_type) qscale = ff_mpeg2_non_linear_qscale[qscale];
+ else qscale <<= 1;
+
+ nCoeffs= s->block_last_index[n];
+
+ block[0] *= n < 4 ? s->y_dc_scale : s->c_dc_scale;
+ quant_matrix = s->intra_matrix;
+ for(i=1;i<=nCoeffs;i++) {
+ int j= s->intra_scantable.permutated[i];
+ level = block[j];
+ if (level) {
+ if (level < 0) {
+ level = -level;
+ level = (int)(level * qscale * quant_matrix[j]) >> 4;
+ level = -level;
+ } else {
+ level = (int)(level * qscale * quant_matrix[j]) >> 4;
+ }
+ block[j] = level;
+ }
+ }
+}
+
+static void dct_unquantize_mpeg2_intra_bitexact(MpegEncContext *s,
+ int16_t *block, int n, int qscale)
+{
+ int i, level, nCoeffs;
+ const uint16_t *quant_matrix;
+ int sum=-1;
+
+ if (s->q_scale_type) qscale = ff_mpeg2_non_linear_qscale[qscale];
+ else qscale <<= 1;
+
+ nCoeffs= s->block_last_index[n];
+
+ block[0] *= n < 4 ? s->y_dc_scale : s->c_dc_scale;
+ sum += block[0];
+ quant_matrix = s->intra_matrix;
+ for(i=1;i<=nCoeffs;i++) {
+ int j= s->intra_scantable.permutated[i];
+ level = block[j];
+ if (level) {
+ if (level < 0) {
+ level = -level;
+ level = (int)(level * qscale * quant_matrix[j]) >> 4;
+ level = -level;
+ } else {
+ level = (int)(level * qscale * quant_matrix[j]) >> 4;
+ }
+ block[j] = level;
+ sum+=level;
+ }
+ }
+ block[63]^=sum&1;
+}
+
+static void dct_unquantize_mpeg2_inter_c(MpegEncContext *s,
+ int16_t *block, int n, int qscale)
+{
+ int i, level, nCoeffs;
+ const uint16_t *quant_matrix;
+ int sum=-1;
+
+ if (s->q_scale_type) qscale = ff_mpeg2_non_linear_qscale[qscale];
+ else qscale <<= 1;
+
+ nCoeffs= s->block_last_index[n];
+
+ quant_matrix = s->inter_matrix;
+ for(i=0; i<=nCoeffs; i++) {
+ int j= s->intra_scantable.permutated[i];
+ level = block[j];
+ if (level) {
+ if (level < 0) {
+ level = -level;
+ level = (((level << 1) + 1) * qscale *
+ ((int) (quant_matrix[j]))) >> 5;
+ level = -level;
+ } else {
+ level = (((level << 1) + 1) * qscale *
+ ((int) (quant_matrix[j]))) >> 5;
+ }
+ block[j] = level;
+ sum+=level;
+ }
+ }
+ block[63]^=sum&1;
+}
+
+static void dct_unquantize_h263_intra_c(MpegEncContext *s,
+ int16_t *block, int n, int qscale)
+{
+ int i, level, qmul, qadd;
+ int nCoeffs;
+
+ av_assert2(s->block_last_index[n]>=0 || s->h263_aic);
+
+ qmul = qscale << 1;
+
+ if (!s->h263_aic) {
+ block[0] *= n < 4 ? s->y_dc_scale : s->c_dc_scale;
+ qadd = (qscale - 1) | 1;
+ }else{
+ qadd = 0;
+ }
+ if(s->ac_pred)
+ nCoeffs=63;
+ else
+ nCoeffs= s->intra_scantable.raster_end[ s->block_last_index[n] ];
+
+ for(i=1; i<=nCoeffs; i++) {
+ level = block[i];
+ if (level) {
+ if (level < 0) {
+ level = level * qmul - qadd;
+ } else {
+ level = level * qmul + qadd;
+ }
+ block[i] = level;
+ }
+ }
+}
+
+static void dct_unquantize_h263_inter_c(MpegEncContext *s,
+ int16_t *block, int n, int qscale)
+{
+ int i, level, qmul, qadd;
+ int nCoeffs;
+
+ av_assert2(s->block_last_index[n]>=0);
+
+ qadd = (qscale - 1) | 1;
+ qmul = qscale << 1;
+
+ nCoeffs= s->inter_scantable.raster_end[ s->block_last_index[n] ];
+
+ for(i=0; i<=nCoeffs; i++) {
+ level = block[i];
+ if (level) {
+ if (level < 0) {
+ level = level * qmul - qadd;
+ } else {
+ level = level * qmul + qadd;
+ }
+ block[i] = level;
+ }
+ }
+}
+
+av_cold void ff_mpv_unquantize_init(MpegEncContext *s)
+{
+ s->dct_unquantize_h263_intra = dct_unquantize_h263_intra_c;
+ s->dct_unquantize_h263_inter = dct_unquantize_h263_inter_c;
+ s->dct_unquantize_mpeg1_intra = dct_unquantize_mpeg1_intra_c;
+ s->dct_unquantize_mpeg1_inter = dct_unquantize_mpeg1_inter_c;
+ s->dct_unquantize_mpeg2_intra = dct_unquantize_mpeg2_intra_c;
+ if (s->avctx->flags & AV_CODEC_FLAG_BITEXACT)
+ s->dct_unquantize_mpeg2_intra = dct_unquantize_mpeg2_intra_bitexact;
+ s->dct_unquantize_mpeg2_inter = dct_unquantize_mpeg2_inter_c;
+
+#if HAVE_INTRINSICS_NEON
+ ff_mpv_common_init_neon(s);
+#endif
+
+#if ARCH_ARM
+ ff_mpv_common_init_arm(s);
+#elif ARCH_PPC
+ ff_mpv_common_init_ppc(s);
+#elif ARCH_X86
+ ff_mpv_common_init_x86(s);
+#elif ARCH_MIPS
+ ff_mpv_common_init_mips(s);
+#endif
+}