1
0
mirror of https://github.com/FFmpeg/FFmpeg.git synced 2025-08-04 22:03:09 +02:00

avcodec/mpegvideoenc: Allocate blocks as part of MPVEncContext

This avoids mpegvideo.c having to deal with the fact that
the encoders use two sets of blocks and is in preparation
for not allocating blocks at all.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
This commit is contained in:
Andreas Rheinhardt
2025-06-15 22:01:09 +02:00
parent 1c258b5581
commit 3b87a480fe
7 changed files with 54 additions and 49 deletions

View File

@ -87,7 +87,7 @@ static inline int get_p_cbp(MPVEncContext *const s,
for (int i = 0; i < 6; i++) {
if (s->c.block_last_index[i] >= 0 && !((cbp >> (5 - i)) & 1)) {
s->c.block_last_index[i] = -1;
s->c.bdsp.clear_block(s->c.block[i]);
s->c.bdsp.clear_block(s->block[i]);
}
}
} else {

View File

@ -3826,7 +3826,6 @@ static av_cold void clear_context(MpegEncContext *s)
memset(s->thread_context, 0, sizeof(s->thread_context));
s->block = NULL;
s->blocks = NULL;
s->ac_val_base = NULL;
s->ac_val = NULL;
memset(&s->sc, 0, sizeof(s->sc));

View File

@ -433,7 +433,7 @@ static inline int get_b_cbp(MPVEncContext *const s, int16_t block[6][64],
for (i = 0; i < 6; i++) {
if (s->c.block_last_index[i] >= 0 && ((cbp >> (5 - i)) & 1) == 0) {
s->c.block_last_index[i] = -1;
s->c.bdsp.clear_block(s->c.block[i]);
s->c.bdsp.clear_block(s->block[i]);
}
}
} else {

View File

@ -116,9 +116,11 @@ av_cold void ff_mpv_idct_init(MpegEncContext *s)
static av_cold int init_duplicate_context(MpegEncContext *s)
{
if (!FF_ALLOCZ_TYPED_ARRAY(s->blocks, 1 + s->encoding))
return AVERROR(ENOMEM);
s->block = s->blocks[0];
if (!s->encoding) {
s->block = av_mallocz(12 * sizeof(*s->block));
if (!s->block)
return AVERROR(ENOMEM);
}
return 0;
}
@ -158,8 +160,7 @@ static av_cold void free_duplicate_context(MpegEncContext *s)
s->sc.obmc_scratchpad = NULL;
s->sc.linesize = 0;
av_freep(&s->blocks);
s->block = NULL;
av_freep(&s->block);
}
static av_cold void free_duplicate_contexts(MpegEncContext *s)
@ -175,7 +176,6 @@ int ff_update_duplicate_context(MpegEncContext *dst, const MpegEncContext *src)
{
#define COPY(M) \
M(ScratchpadContext, sc) \
M(void*, blocks) \
M(void*, block) \
M(int, start_mb_y) \
M(int, end_mb_y) \

View File

@ -309,8 +309,7 @@ typedef struct MpegEncContext {
int interlaced_dct;
int first_field; ///< is 1 for the first field of a field picture 0 otherwise
int16_t (*block)[64]; ///< points to one of the following blocks
int16_t (*blocks)[12][64]; // for HQ mode we need to keep the best block
int16_t (*block)[64];
int (*decode_mb)(struct MpegEncContext *s, int16_t block[12][64]); // used by some codecs to avoid a switch()
#define SLICE_OK 0

View File

@ -538,6 +538,8 @@ static av_cold int init_slice_buffers(MPVMainEncContext *const m)
for (unsigned i = 0; i < nb_slices; ++i) {
MPVEncContext *const s2 = s->c.enc_contexts[i];
s2->block = s2->blocks[0];
if (dct_error) {
s2->dct_offset = s->dct_offset;
s2->dct_error_sum = (void*)dct_error;
@ -2184,7 +2186,7 @@ static inline void dct_single_coeff_elimination(MPVEncContext *const s,
int score = 0;
int run = 0;
int i;
int16_t *block = s->c.block[n];
int16_t *block = s->block[n];
const int last_index = s->c.block_last_index[n];
int skip_dc;
@ -2399,27 +2401,27 @@ static av_always_inline void encode_mb_internal(MPVEncContext *const s,
}
}
s->pdsp.get_pixels(s->c.block[0], ptr_y, wrap_y);
s->pdsp.get_pixels(s->c.block[1], ptr_y + 8, wrap_y);
s->pdsp.get_pixels(s->c.block[2], ptr_y + dct_offset, wrap_y);
s->pdsp.get_pixels(s->c.block[3], ptr_y + dct_offset + 8, wrap_y);
s->pdsp.get_pixels(s->block[0], ptr_y, wrap_y);
s->pdsp.get_pixels(s->block[1], ptr_y + 8, wrap_y);
s->pdsp.get_pixels(s->block[2], ptr_y + dct_offset, wrap_y);
s->pdsp.get_pixels(s->block[3], ptr_y + dct_offset + 8, wrap_y);
if (s->c.avctx->flags & AV_CODEC_FLAG_GRAY) {
skip_dct[4] = 1;
skip_dct[5] = 1;
} else {
s->pdsp.get_pixels(s->c.block[4], ptr_cb, wrap_c);
s->pdsp.get_pixels(s->c.block[5], ptr_cr, wrap_c);
s->pdsp.get_pixels(s->block[4], ptr_cb, wrap_c);
s->pdsp.get_pixels(s->block[5], ptr_cr, wrap_c);
if (chroma_format == CHROMA_422) {
s->pdsp.get_pixels(s->c.block[6], ptr_cb + uv_dct_offset, wrap_c);
s->pdsp.get_pixels(s->c.block[7], ptr_cr + uv_dct_offset, wrap_c);
s->pdsp.get_pixels(s->block[6], ptr_cb + uv_dct_offset, wrap_c);
s->pdsp.get_pixels(s->block[7], ptr_cr + uv_dct_offset, wrap_c);
} else if (chroma_format == CHROMA_444) {
s->pdsp.get_pixels(s->c.block[ 6], ptr_cb + 8, wrap_c);
s->pdsp.get_pixels(s->c.block[ 7], ptr_cr + 8, wrap_c);
s->pdsp.get_pixels(s->c.block[ 8], ptr_cb + uv_dct_offset, wrap_c);
s->pdsp.get_pixels(s->c.block[ 9], ptr_cr + uv_dct_offset, wrap_c);
s->pdsp.get_pixels(s->c.block[10], ptr_cb + uv_dct_offset + 8, wrap_c);
s->pdsp.get_pixels(s->c.block[11], ptr_cr + uv_dct_offset + 8, wrap_c);
s->pdsp.get_pixels(s->block[ 6], ptr_cb + 8, wrap_c);
s->pdsp.get_pixels(s->block[ 7], ptr_cr + 8, wrap_c);
s->pdsp.get_pixels(s->block[ 8], ptr_cb + uv_dct_offset, wrap_c);
s->pdsp.get_pixels(s->block[ 9], ptr_cr + uv_dct_offset, wrap_c);
s->pdsp.get_pixels(s->block[10], ptr_cb + uv_dct_offset + 8, wrap_c);
s->pdsp.get_pixels(s->block[11], ptr_cr + uv_dct_offset + 8, wrap_c);
}
}
} else {
@ -2483,23 +2485,23 @@ static av_always_inline void encode_mb_internal(MPVEncContext *const s,
}
}
s->pdsp.diff_pixels(s->c.block[0], ptr_y, dest_y, wrap_y);
s->pdsp.diff_pixels(s->c.block[1], ptr_y + 8, dest_y + 8, wrap_y);
s->pdsp.diff_pixels(s->c.block[2], ptr_y + dct_offset,
s->pdsp.diff_pixels(s->block[0], ptr_y, dest_y, wrap_y);
s->pdsp.diff_pixels(s->block[1], ptr_y + 8, dest_y + 8, wrap_y);
s->pdsp.diff_pixels(s->block[2], ptr_y + dct_offset,
dest_y + dct_offset, wrap_y);
s->pdsp.diff_pixels(s->c.block[3], ptr_y + dct_offset + 8,
s->pdsp.diff_pixels(s->block[3], ptr_y + dct_offset + 8,
dest_y + dct_offset + 8, wrap_y);
if (s->c.avctx->flags & AV_CODEC_FLAG_GRAY) {
skip_dct[4] = 1;
skip_dct[5] = 1;
} else {
s->pdsp.diff_pixels(s->c.block[4], ptr_cb, dest_cb, wrap_c);
s->pdsp.diff_pixels(s->c.block[5], ptr_cr, dest_cr, wrap_c);
s->pdsp.diff_pixels(s->block[4], ptr_cb, dest_cb, wrap_c);
s->pdsp.diff_pixels(s->block[5], ptr_cr, dest_cr, wrap_c);
if (!chroma_y_shift) { /* 422 */
s->pdsp.diff_pixels(s->c.block[6], ptr_cb + uv_dct_offset,
s->pdsp.diff_pixels(s->block[6], ptr_cb + uv_dct_offset,
dest_cb + uv_dct_offset, wrap_c);
s->pdsp.diff_pixels(s->c.block[7], ptr_cr + uv_dct_offset,
s->pdsp.diff_pixels(s->block[7], ptr_cr + uv_dct_offset,
dest_cr + uv_dct_offset, wrap_c);
}
}
@ -2554,7 +2556,7 @@ static av_always_inline void encode_mb_internal(MPVEncContext *const s,
get_visual_weight(weight[7], ptr_cr + uv_dct_offset,
wrap_c);
}
memcpy(orig[0], s->c.block[0], sizeof(int16_t) * 64 * mb_block_count);
memcpy(orig[0], s->block[0], sizeof(int16_t) * 64 * mb_block_count);
}
/* DCT & quantize */
@ -2563,14 +2565,14 @@ static av_always_inline void encode_mb_internal(MPVEncContext *const s,
for (i = 0; i < mb_block_count; i++) {
if (!skip_dct[i]) {
int overflow;
s->c.block_last_index[i] = s->dct_quantize(s, s->c.block[i], i, s->c.qscale, &overflow);
s->c.block_last_index[i] = s->dct_quantize(s, s->block[i], i, s->c.qscale, &overflow);
// FIXME we could decide to change to quantizer instead of
// clipping
// JS: I don't think that would be a good idea it could lower
// quality instead of improve it. Just INTRADC clipping
// deserves changes in quantizer
if (overflow)
clip_coeffs(s, s->c.block[i], s->c.block_last_index[i]);
clip_coeffs(s, s->block[i], s->c.block_last_index[i]);
} else
s->c.block_last_index[i] = -1;
}
@ -2578,7 +2580,7 @@ static av_always_inline void encode_mb_internal(MPVEncContext *const s,
for (i = 0; i < mb_block_count; i++) {
if (!skip_dct[i]) {
s->c.block_last_index[i] =
dct_quantize_refine(s, s->c.block[i], weight[i],
dct_quantize_refine(s, s->block[i], weight[i],
orig[i], i, s->c.qscale);
}
}
@ -2602,12 +2604,12 @@ static av_always_inline void encode_mb_internal(MPVEncContext *const s,
if ((s->c.avctx->flags & AV_CODEC_FLAG_GRAY) && s->c.mb_intra) {
s->c.block_last_index[4] =
s->c.block_last_index[5] = 0;
s->c.block[4][0] =
s->c.block[5][0] = (1024 + s->c.c_dc_scale / 2) / s->c.c_dc_scale;
s->block[4][0] =
s->block[5][0] = (1024 + s->c.c_dc_scale / 2) / s->c.c_dc_scale;
if (!chroma_y_shift) { /* 422 / 444 */
for (i=6; i<12; i++) {
s->c.block_last_index[i] = 0;
s->c.block[i][0] = s->c.block[4][0];
s->block[i][0] = s->block[4][0];
}
}
}
@ -2618,7 +2620,7 @@ static av_always_inline void encode_mb_internal(MPVEncContext *const s,
int j;
if (s->c.block_last_index[i] > 0) {
for (j = 63; j > 0; j--) {
if (s->c.block[i][s->c.intra_scantable.permutated[j]])
if (s->block[i][s->c.intra_scantable.permutated[j]])
break;
}
s->c.block_last_index[i] = j;
@ -2626,7 +2628,7 @@ static av_always_inline void encode_mb_internal(MPVEncContext *const s,
}
}
s->encode_mb(s, s->c.block, motion_x, motion_y);
s->encode_mb(s, s->block, motion_x, motion_y);
}
static void encode_mb(MPVEncContext *const s, int motion_x, int motion_y)
@ -2649,11 +2651,11 @@ typedef struct MBBackup {
int qscale;
int block_last_index[8];
int interlaced_dct;
int16_t (*block)[64];
} c;
int mv_bits, i_tex_bits, p_tex_bits, i_count, misc_bits, last_bits;
int dquant;
int esc3_level_length;
int16_t (*block)[64];
PutBitContext pb, pb2, tex_pb;
} MBBackup;
@ -2713,7 +2715,7 @@ static inline void AFTER ## _context_after_encode(DST_TYPE *const d, \
d->pb2 = s->pb2; \
d->tex_pb = s->tex_pb; \
} \
d->c.block = s->c.block; \
d->block = s->block; \
for (int i = 0; i < 8; i++) \
d->c.block_last_index[i] = s->c.block_last_index[i]; \
d->c.interlaced_dct = s->c.interlaced_dct; \
@ -2734,7 +2736,7 @@ static void encode_mb_hq(MPVEncContext *const s, MBBackup *const backup, MBBacku
reset_context_before_encode(s, backup);
s->c.block = s->c.blocks[*next_block];
s->block = s->blocks[*next_block];
s->pb = pb[*next_block];
if (s->c.data_partitioning) {
s->pb2 = pb2 [*next_block];
@ -2758,7 +2760,7 @@ static void encode_mb_hq(MPVEncContext *const s, MBBackup *const backup, MBBacku
}
if (s->c.avctx->mb_decision == FF_MB_DECISION_RD) {
mpv_reconstruct_mb(s, s->c.block);
mpv_reconstruct_mb(s, s->block);
score *= s->lambda2;
score += sse_mb(s) << FF_LAMBDA_SHIFT;
@ -3446,7 +3448,7 @@ static int encode_thread(AVCodecContext *c, void *arg){
}
if (s->c.avctx->mb_decision == FF_MB_DECISION_BITS)
mpv_reconstruct_mb(s, s->c.block);
mpv_reconstruct_mb(s, s->block);
} else {
int motion_x = 0, motion_y = 0;
s->c.mv_type = MV_TYPE_16X16;
@ -3569,7 +3571,7 @@ static int encode_thread(AVCodecContext *c, void *arg){
s->c.out_format == FMT_H263 && s->c.pict_type != AV_PICTURE_TYPE_B)
ff_h263_update_mb(s);
mpv_reconstruct_mb(s, s->c.block);
mpv_reconstruct_mb(s, s->block);
}
s->c.cur_pic.qscale_table[xy] = s->c.qscale;

View File

@ -31,6 +31,7 @@
#include <float.h>
#include "libavutil/avassert.h"
#include "libavutil/mem_internal.h"
#include "libavutil/opt.h"
#include "fdctdsp.h"
#include "motion_est.h"
@ -110,6 +111,8 @@ typedef struct MPVEncContext {
int coded_score[12];
int16_t (*block)[64]; ///< points into blocks below
/** precomputed matrix (combine qscale and DCT renorm) */
int (*q_intra_matrix)[64];
int (*q_chroma_intra_matrix)[64];
@ -173,6 +176,8 @@ typedef struct MPVEncContext {
int (*sum_abs_dctelem)(const int16_t *block);
int intra_penalty;
DECLARE_ALIGNED_32(int16_t, blocks)[2][12][64]; // for HQ mode we need to keep the best block
} MPVEncContext;
typedef struct MPVMainEncContext {