avcodec/mpegvideo: Move MPEG-4 Simple Studio Profile fields to mpeg4video

This is possible now that dealing with the Simple Studio Profile
has been moved to mpeg4videodec.c. It also allows to avoid
allocations, because one can simply put the required buffers
on the context (if one made these buffers part of MpegEncContext,
the memory would be wasted for every codec other than MPEG-4).

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
This commit is contained in:
Andreas Rheinhardt 2022-01-26 01:50:56 +01:00
parent 85ac29ad1c
commit dcdb34be91
4 changed files with 28 additions and 38 deletions

View File

@ -117,6 +117,11 @@ typedef struct Mpeg4DecContext {
int cplx_estimation_trash_b;
int rgb;
int32_t block32[12][64];
// 0 = DCT, 1 = DPCM top to bottom scan, -1 = DPCM bottom to top scan
int dpcm_direction;
int16_t dpcm_macroblock[3][256];
} Mpeg4DecContext;

View File

@ -71,32 +71,33 @@ void ff_mpeg4_decode_studio(MpegEncContext *s, uint8_t *dest_y, uint8_t *dest_cb
uint8_t *dest_cr, int block_size, int uvlinesize,
int dct_linesize, int dct_offset)
{
Mpeg4DecContext *const ctx = (Mpeg4DecContext*)s;
const int act_block_size = block_size * 2;
if (s->dpcm_direction == 0) {
s->idsp.idct_put(dest_y, dct_linesize, (int16_t*)(*s->block32)[0]);
s->idsp.idct_put(dest_y + act_block_size, dct_linesize, (int16_t*)(*s->block32)[1]);
s->idsp.idct_put(dest_y + dct_offset, dct_linesize, (int16_t*)(*s->block32)[2]);
s->idsp.idct_put(dest_y + dct_offset + act_block_size, dct_linesize, (int16_t*)(*s->block32)[3]);
if (ctx->dpcm_direction == 0) {
s->idsp.idct_put(dest_y, dct_linesize, (int16_t*)ctx->block32[0]);
s->idsp.idct_put(dest_y + act_block_size, dct_linesize, (int16_t*)ctx->block32[1]);
s->idsp.idct_put(dest_y + dct_offset, dct_linesize, (int16_t*)ctx->block32[2]);
s->idsp.idct_put(dest_y + dct_offset + act_block_size, dct_linesize, (int16_t*)ctx->block32[3]);
dct_linesize = uvlinesize << s->interlaced_dct;
dct_offset = s->interlaced_dct ? uvlinesize : uvlinesize*block_size;
s->idsp.idct_put(dest_cb, dct_linesize, (int16_t*)(*s->block32)[4]);
s->idsp.idct_put(dest_cr, dct_linesize, (int16_t*)(*s->block32)[5]);
s->idsp.idct_put(dest_cb + dct_offset, dct_linesize, (int16_t*)(*s->block32)[6]);
s->idsp.idct_put(dest_cr + dct_offset, dct_linesize, (int16_t*)(*s->block32)[7]);
s->idsp.idct_put(dest_cb, dct_linesize, (int16_t*)ctx->block32[4]);
s->idsp.idct_put(dest_cr, dct_linesize, (int16_t*)ctx->block32[5]);
s->idsp.idct_put(dest_cb + dct_offset, dct_linesize, (int16_t*)ctx->block32[6]);
s->idsp.idct_put(dest_cr + dct_offset, dct_linesize, (int16_t*)ctx->block32[7]);
if (!s->chroma_x_shift){ //Chroma444
s->idsp.idct_put(dest_cb + act_block_size, dct_linesize, (int16_t*)(*s->block32)[8]);
s->idsp.idct_put(dest_cr + act_block_size, dct_linesize, (int16_t*)(*s->block32)[9]);
s->idsp.idct_put(dest_cb + act_block_size + dct_offset, dct_linesize, (int16_t*)(*s->block32)[10]);
s->idsp.idct_put(dest_cr + act_block_size + dct_offset, dct_linesize, (int16_t*)(*s->block32)[11]);
s->idsp.idct_put(dest_cb + act_block_size, dct_linesize, (int16_t*)ctx->block32[8]);
s->idsp.idct_put(dest_cr + act_block_size, dct_linesize, (int16_t*)ctx->block32[9]);
s->idsp.idct_put(dest_cb + act_block_size + dct_offset, dct_linesize, (int16_t*)ctx->block32[10]);
s->idsp.idct_put(dest_cr + act_block_size + dct_offset, dct_linesize, (int16_t*)ctx->block32[11]);
}
} else if(s->dpcm_direction == 1) {
} else if (ctx->dpcm_direction == 1) {
uint16_t *dest_pcm[3] = {(uint16_t*)dest_y, (uint16_t*)dest_cb, (uint16_t*)dest_cr};
int linesize[3] = {dct_linesize, uvlinesize, uvlinesize};
for (int i = 0; i < 3; i++) {
const uint16_t *src = (*s->dpcm_macroblock)[i];
const uint16_t *src = ctx->dpcm_macroblock[i];
int vsub = i ? s->chroma_y_shift : 0;
int hsub = i ? s->chroma_x_shift : 0;
int lowres = s->avctx->lowres;
@ -111,9 +112,9 @@ void ff_mpeg4_decode_studio(MpegEncContext *s, uint8_t *dest_y, uint8_t *dest_cb
} else {
uint16_t *dest_pcm[3] = {(uint16_t*)dest_y, (uint16_t*)dest_cb, (uint16_t*)dest_cr};
int linesize[3] = {dct_linesize, uvlinesize, uvlinesize};
av_assert2(s->dpcm_direction == -1);
av_assert2(ctx->dpcm_direction == -1);
for (int i = 0; i < 3; i++) {
const uint16_t *src = (*s->dpcm_macroblock)[i];
const uint16_t *src = ctx->dpcm_macroblock[i];
int vsub = i ? s->chroma_y_shift : 0;
int hsub = i ? s->chroma_x_shift : 0;
int lowres = s->avctx->lowres;
@ -2078,9 +2079,10 @@ static int mpeg4_decode_dpcm_macroblock(MpegEncContext *s, int16_t macroblock[25
static int mpeg4_decode_studio_mb(MpegEncContext *s, int16_t block_[12][64])
{
Mpeg4DecContext *const ctx = (Mpeg4DecContext*)s;
int i;
s->dpcm_direction = 0;
ctx->dpcm_direction = 0;
/* StudioMacroblock */
/* Assumes I-VOP */
@ -2094,15 +2096,15 @@ static int mpeg4_decode_studio_mb(MpegEncContext *s, int16_t block_[12][64])
}
for (i = 0; i < mpeg4_block_count[s->chroma_format]; i++) {
if (mpeg4_decode_studio_block(s, (*s->block32)[i], i) < 0)
if (mpeg4_decode_studio_block(s, ctx->block32[i], i) < 0)
return AVERROR_INVALIDDATA;
}
} else {
/* DPCM */
check_marker(s->avctx, &s->gb, "DPCM block start");
s->dpcm_direction = get_bits1(&s->gb) ? -1 : 1;
ctx->dpcm_direction = get_bits1(&s->gb) ? -1 : 1;
for (i = 0; i < 3; i++) {
if (mpeg4_decode_dpcm_macroblock(s, (*s->dpcm_macroblock)[i], i) < 0)
if (mpeg4_decode_dpcm_macroblock(s, ctx->dpcm_macroblock[i], i) < 0)
return AVERROR_INVALIDDATA;
}
}

View File

@ -378,11 +378,6 @@ static int init_duplicate_context(MpegEncContext *s)
}
if (s->out_format == FMT_H263) {
if (!(s->block32 = av_mallocz(sizeof(*s->block32))) ||
!(s->dpcm_macroblock = av_mallocz(sizeof(*s->dpcm_macroblock))))
return AVERROR(ENOMEM);
s->dpcm_direction = 0;
/* ac values */
if (!FF_ALLOCZ_TYPED_ARRAY(s->ac_val_base, yc_size))
return AVERROR(ENOMEM);
@ -434,8 +429,6 @@ static void free_duplicate_context(MpegEncContext *s)
av_freep(&s->me.map);
av_freep(&s->me.score_map);
av_freep(&s->blocks);
av_freep(&s->block32);
av_freep(&s->dpcm_macroblock);
av_freep(&s->ac_val_base);
s->block = NULL;
}
@ -462,9 +455,6 @@ static void backup_duplicate_context(MpegEncContext *bak, MpegEncContext *src)
COPY(me.score_map);
COPY(blocks);
COPY(block);
COPY(block32);
COPY(dpcm_macroblock);
COPY(dpcm_direction);
COPY(start_mb_y);
COPY(end_mb_y);
COPY(me.map_generation);
@ -678,10 +668,7 @@ static void clear_context(MpegEncContext *s)
s->dct_error_sum = NULL;
s->block = NULL;
s->blocks = NULL;
s->block32 = NULL;
memset(s->pblocks, 0, sizeof(s->pblocks));
s->dpcm_direction = 0;
s->dpcm_macroblock = NULL;
s->ac_val_base = NULL;
s->ac_val[0] =
s->ac_val[1] =

View File

@ -482,10 +482,6 @@ typedef struct MpegEncContext {
int16_t (*blocks)[12][64]; // for HQ mode we need to keep the best block
int (*decode_mb)(struct MpegEncContext *s, int16_t block[12][64]); // used by some codecs to avoid a switch()
int32_t (*block32)[12][64];
int dpcm_direction; // 0 = DCT, 1 = DPCM top to bottom scan, -1 = DPCM bottom to top scan
int16_t (*dpcm_macroblock)[3][256];
#define SLICE_OK 0
#define SLICE_ERROR -1
#define SLICE_END -2 ///<end marker found