avcodec/mpegvideo_enc: Ignore intra_dc_precision for non-MPEG-2

This option is only allowed to be set for MPEG-2, so ignore it
except for MPEG-2 and move handling of it to mpeg12enc.c.
This is in preparation for deprecating the AVCodecContext option.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
This commit is contained in:
Andreas Rheinhardt
2026-03-07 20:14:36 +01:00
parent 76a005dccf
commit cdc632efb3
3 changed files with 23 additions and 30 deletions
+23
View File
@@ -47,6 +47,7 @@
#include "mpeg12vlc.h"
#include "mpegutils.h"
#include "mpegvideo.h"
#include "mpegvideodata.h"
#include "mpegvideoenc.h"
#include "profiles.h"
#include "put_bits.h"
@@ -1125,7 +1126,29 @@ static av_cold int encode_init(AVCodecContext *avctx)
s->min_qcoeff = -2047;
s->max_qcoeff = 2047;
s->mpeg_quant = 1;
s->c.intra_dc_precision = avctx->intra_dc_precision;
// workaround some differences between how applications specify dc precision
if (s->c.intra_dc_precision < 0) {
s->c.intra_dc_precision += 8;
} else if (s->c.intra_dc_precision >= 8)
s->c.intra_dc_precision -= 8;
if (s->c.intra_dc_precision < 0) {
av_log(avctx, AV_LOG_ERROR,
"intra dc precision must be positive, note some applications use"
" 0 and some 8 as base meaning 8bit, the value must not be smaller than that\n");
return AVERROR(EINVAL);
}
if (s->c.intra_dc_precision > 3) {
av_log(avctx, AV_LOG_ERROR, "intra dc precision too large\n");
return AVERROR(EINVAL);
}
}
s->c.y_dc_scale_table =
s->c.c_dc_scale_table = ff_mpeg12_dc_scale_table[s->c.intra_dc_precision];
if (s->c.intra_vlc_format) {
s->intra_ac_vlc_length =
s->intra_ac_vlc_last_length = uni_mpeg2_ac_vlc_len;
-10
View File
@@ -22,20 +22,10 @@
#ifndef AVCODEC_MPEG12ENC_H
#define AVCODEC_MPEG12ENC_H
#include <stdint.h>
#include "mpegvideoenc.h"
#include "mpegvideodata.h"
void ff_mpeg1_encode_slice_header(MPVEncContext *s);
// Must not be called before intra_dc_precision has been sanitized in ff_mpv_encode_init()
static inline void ff_mpeg1_encode_init(MPVEncContext *s)
{
s->c.y_dc_scale_table =
s->c.c_dc_scale_table = ff_mpeg12_dc_scale_table[s->c.intra_dc_precision];
}
static inline void ff_mpeg1_clean_buffers(MPVEncContext *s)
{
s->last_dc[0] = 128 << s->c.intra_dc_precision;
-20
View File
@@ -608,25 +608,6 @@ av_cold int ff_mpv_encode_init(AVCodecContext *avctx)
s->c.quarter_sample = (avctx->flags & AV_CODEC_FLAG_QPEL) != 0;
s->rtp_mode = !!s->rtp_payload_size;
s->c.intra_dc_precision = avctx->intra_dc_precision;
// workaround some differences between how applications specify dc precision
if (s->c.intra_dc_precision < 0) {
s->c.intra_dc_precision += 8;
} else if (s->c.intra_dc_precision >= 8)
s->c.intra_dc_precision -= 8;
if (s->c.intra_dc_precision < 0) {
av_log(avctx, AV_LOG_ERROR,
"intra dc precision must be positive, note some applications use"
" 0 and some 8 as base meaning 8bit, the value must not be smaller than that\n");
return AVERROR(EINVAL);
}
if (s->c.intra_dc_precision > (avctx->codec_id == AV_CODEC_ID_MPEG2VIDEO ? 3 : 0)) {
av_log(avctx, AV_LOG_ERROR, "intra dc precision too large\n");
return AVERROR(EINVAL);
}
m->user_specified_pts = AV_NOPTS_VALUE;
if (m->gop_size <= 1) {
@@ -867,7 +848,6 @@ av_cold int ff_mpv_encode_init(AVCodecContext *avctx)
s->c.out_format = FMT_MPEG1;
s->c.low_delay = !!(avctx->flags & AV_CODEC_FLAG_LOW_DELAY);
avctx->delay = s->c.low_delay ? 0 : (m->max_b_frames + 1);
ff_mpeg1_encode_init(s);
break;
#endif
#if CONFIG_MJPEG_ENCODER || CONFIG_AMV_ENCODER