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

avcodec/mpeg12dec: Put GetBitContext on the stack where advantageous

This is in preparation for no longer using MpegEncContext.gb.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
This commit is contained in:
Andreas Rheinhardt
2025-06-15 23:12:14 +02:00
parent 21c88b29f7
commit b38f23663e

View File

@ -44,6 +44,7 @@
#include "codec_internal.h" #include "codec_internal.h"
#include "decode.h" #include "decode.h"
#include "error_resilience.h" #include "error_resilience.h"
#include "get_bits.h"
#include "hwaccel_internal.h" #include "hwaccel_internal.h"
#include "hwconfig.h" #include "hwconfig.h"
#include "idctdsp.h" #include "idctdsp.h"
@ -969,23 +970,24 @@ static int mpeg1_decode_picture(AVCodecContext *avctx, const uint8_t *buf,
{ {
Mpeg1Context *s1 = avctx->priv_data; Mpeg1Context *s1 = avctx->priv_data;
MpegEncContext *s = &s1->mpeg_enc_ctx; MpegEncContext *s = &s1->mpeg_enc_ctx;
GetBitContext gb0, *const gb = &gb0;
int ref, f_code, vbv_delay, ret; int ref, f_code, vbv_delay, ret;
ret = init_get_bits8(&s->gb, buf, buf_size); ret = init_get_bits8(gb, buf, buf_size);
if (ret < 0) if (ret < 0)
return ret; return ret;
ref = get_bits(&s->gb, 10); /* temporal ref */ ref = get_bits(gb, 10); /* temporal ref */
s->pict_type = get_bits(&s->gb, 3); s->pict_type = get_bits(gb, 3);
if (s->pict_type == 0 || s->pict_type > 3) if (s->pict_type == 0 || s->pict_type > 3)
return AVERROR_INVALIDDATA; return AVERROR_INVALIDDATA;
vbv_delay = get_bits(&s->gb, 16); vbv_delay = get_bits(gb, 16);
s1->vbv_delay = vbv_delay; s1->vbv_delay = vbv_delay;
if (s->pict_type == AV_PICTURE_TYPE_P || if (s->pict_type == AV_PICTURE_TYPE_P ||
s->pict_type == AV_PICTURE_TYPE_B) { s->pict_type == AV_PICTURE_TYPE_B) {
s->full_pel[0] = get_bits1(&s->gb); s->full_pel[0] = get_bits1(gb);
f_code = get_bits(&s->gb, 3); f_code = get_bits(gb, 3);
if (f_code == 0 && (avctx->err_recognition & (AV_EF_BITSTREAM|AV_EF_COMPLIANT))) if (f_code == 0 && (avctx->err_recognition & (AV_EF_BITSTREAM|AV_EF_COMPLIANT)))
return AVERROR_INVALIDDATA; return AVERROR_INVALIDDATA;
f_code += !f_code; f_code += !f_code;
@ -993,8 +995,8 @@ static int mpeg1_decode_picture(AVCodecContext *avctx, const uint8_t *buf,
s->mpeg_f_code[0][1] = f_code; s->mpeg_f_code[0][1] = f_code;
} }
if (s->pict_type == AV_PICTURE_TYPE_B) { if (s->pict_type == AV_PICTURE_TYPE_B) {
s->full_pel[1] = get_bits1(&s->gb); s->full_pel[1] = get_bits1(gb);
f_code = get_bits(&s->gb, 3); f_code = get_bits(gb, 3);
if (f_code == 0 && (avctx->err_recognition & (AV_EF_BITSTREAM|AV_EF_COMPLIANT))) if (f_code == 0 && (avctx->err_recognition & (AV_EF_BITSTREAM|AV_EF_COMPLIANT)))
return AVERROR_INVALIDDATA; return AVERROR_INVALIDDATA;
f_code += !f_code; f_code += !f_code;
@ -1009,38 +1011,39 @@ static int mpeg1_decode_picture(AVCodecContext *avctx, const uint8_t *buf,
return 0; return 0;
} }
static void mpeg_decode_sequence_extension(Mpeg1Context *s1) static void mpeg_decode_sequence_extension(Mpeg1Context *const s1,
GetBitContext *const gb)
{ {
MpegEncContext *s = &s1->mpeg_enc_ctx; MpegEncContext *s = &s1->mpeg_enc_ctx;
int horiz_size_ext, vert_size_ext; int horiz_size_ext, vert_size_ext;
int bit_rate_ext; int bit_rate_ext;
skip_bits(&s->gb, 1); /* profile and level esc*/ skip_bits(gb, 1); /* profile and level esc*/
s->avctx->profile = get_bits(&s->gb, 3); s->avctx->profile = get_bits(gb, 3);
s->avctx->level = get_bits(&s->gb, 4); s->avctx->level = get_bits(gb, 4);
s->progressive_sequence = get_bits1(&s->gb); /* progressive_sequence */ s->progressive_sequence = get_bits1(gb); /* progressive_sequence */
s->chroma_format = get_bits(&s->gb, 2); /* chroma_format 1=420, 2=422, 3=444 */ s->chroma_format = get_bits(gb, 2); /* chroma_format 1=420, 2=422, 3=444 */
if (!s->chroma_format) { if (!s->chroma_format) {
s->chroma_format = CHROMA_420; s->chroma_format = CHROMA_420;
av_log(s->avctx, AV_LOG_WARNING, "Chroma format invalid\n"); av_log(s->avctx, AV_LOG_WARNING, "Chroma format invalid\n");
} }
horiz_size_ext = get_bits(&s->gb, 2); horiz_size_ext = get_bits(gb, 2);
vert_size_ext = get_bits(&s->gb, 2); vert_size_ext = get_bits(gb, 2);
s->width |= (horiz_size_ext << 12); s->width |= (horiz_size_ext << 12);
s->height |= (vert_size_ext << 12); s->height |= (vert_size_ext << 12);
bit_rate_ext = get_bits(&s->gb, 12); /* XXX: handle it */ bit_rate_ext = get_bits(gb, 12); /* XXX: handle it */
s1->bit_rate += (bit_rate_ext << 18) * 400LL; s1->bit_rate += (bit_rate_ext << 18) * 400LL;
check_marker(s->avctx, &s->gb, "after bit rate extension"); check_marker(s->avctx, gb, "after bit rate extension");
s->avctx->rc_buffer_size += get_bits(&s->gb, 8) * 1024 * 16 << 10; s->avctx->rc_buffer_size += get_bits(gb, 8) * 1024 * 16 << 10;
s->low_delay = get_bits1(&s->gb); s->low_delay = get_bits1(gb);
if (s->avctx->flags & AV_CODEC_FLAG_LOW_DELAY) if (s->avctx->flags & AV_CODEC_FLAG_LOW_DELAY)
s->low_delay = 1; s->low_delay = 1;
s1->frame_rate_ext.num = get_bits(&s->gb, 2) + 1; s1->frame_rate_ext.num = get_bits(gb, 2) + 1;
s1->frame_rate_ext.den = get_bits(&s->gb, 5) + 1; s1->frame_rate_ext.den = get_bits(gb, 5) + 1;
ff_dlog(s->avctx, "sequence extension\n"); ff_dlog(s->avctx, "sequence extension\n");
s->codec_id = s->avctx->codec_id = AV_CODEC_ID_MPEG2VIDEO; s->codec_id = s->avctx->codec_id = AV_CODEC_ID_MPEG2VIDEO;
@ -1052,21 +1055,22 @@ static void mpeg_decode_sequence_extension(Mpeg1Context *s1)
s->avctx->rc_buffer_size, s1->bit_rate); s->avctx->rc_buffer_size, s1->bit_rate);
} }
static void mpeg_decode_sequence_display_extension(Mpeg1Context *s1) static void mpeg_decode_sequence_display_extension(Mpeg1Context *const s1,
GetBitContext *const gb)
{ {
MpegEncContext *s = &s1->mpeg_enc_ctx; MpegEncContext *s = &s1->mpeg_enc_ctx;
int color_description, w, h; int color_description, w, h;
skip_bits(&s->gb, 3); /* video format */ skip_bits(gb, 3); /* video format */
color_description = get_bits1(&s->gb); color_description = get_bits1(gb);
if (color_description) { if (color_description) {
s->avctx->color_primaries = get_bits(&s->gb, 8); s->avctx->color_primaries = get_bits(gb, 8);
s->avctx->color_trc = get_bits(&s->gb, 8); s->avctx->color_trc = get_bits(gb, 8);
s->avctx->colorspace = get_bits(&s->gb, 8); s->avctx->colorspace = get_bits(gb, 8);
} }
w = get_bits(&s->gb, 14); w = get_bits(gb, 14);
skip_bits(&s->gb, 1); // marker skip_bits(gb, 1); // marker
h = get_bits(&s->gb, 14); h = get_bits(gb, 14);
// remaining 3 bits are zero padding // remaining 3 bits are zero padding
s1->pan_scan.width = 16 * w; s1->pan_scan.width = 16 * w;
@ -1076,7 +1080,8 @@ static void mpeg_decode_sequence_display_extension(Mpeg1Context *s1)
av_log(s->avctx, AV_LOG_DEBUG, "sde w:%d, h:%d\n", w, h); av_log(s->avctx, AV_LOG_DEBUG, "sde w:%d, h:%d\n", w, h);
} }
static void mpeg_decode_picture_display_extension(Mpeg1Context *s1) static void mpeg_decode_picture_display_extension(Mpeg1Context *const s1,
GetBitContext *const gb)
{ {
MpegEncContext *s = &s1->mpeg_enc_ctx; MpegEncContext *s = &s1->mpeg_enc_ctx;
int i, nofco; int i, nofco;
@ -1096,10 +1101,10 @@ static void mpeg_decode_picture_display_extension(Mpeg1Context *s1)
} }
} }
for (i = 0; i < nofco; i++) { for (i = 0; i < nofco; i++) {
s1->pan_scan.position[i][0] = get_sbits(&s->gb, 16); s1->pan_scan.position[i][0] = get_sbits(gb, 16);
skip_bits(&s->gb, 1); // marker skip_bits(gb, 1); // marker
s1->pan_scan.position[i][1] = get_sbits(&s->gb, 16); s1->pan_scan.position[i][1] = get_sbits(gb, 16);
skip_bits(&s->gb, 1); // marker skip_bits(gb, 1); // marker
} }
if (s->avctx->debug & FF_DEBUG_PICT_INFO) if (s->avctx->debug & FF_DEBUG_PICT_INFO)
@ -1110,14 +1115,14 @@ static void mpeg_decode_picture_display_extension(Mpeg1Context *s1)
s1->pan_scan.position[2][0], s1->pan_scan.position[2][1]); s1->pan_scan.position[2][0], s1->pan_scan.position[2][1]);
} }
static int load_matrix(MpegEncContext *s, uint16_t matrix0[64], static int load_matrix(MPVContext *const s, GetBitContext *const gb,
uint16_t matrix1[64], int intra) uint16_t matrix0[64], uint16_t matrix1[64], int intra)
{ {
int i; int i;
for (i = 0; i < 64; i++) { for (i = 0; i < 64; i++) {
int j = s->idsp.idct_permutation[ff_zigzag_direct[i]]; int j = s->idsp.idct_permutation[ff_zigzag_direct[i]];
int v = get_bits(&s->gb, 8); int v = get_bits(gb, 8);
if (v == 0) { if (v == 0) {
av_log(s->avctx, AV_LOG_ERROR, "matrix damaged\n"); av_log(s->avctx, AV_LOG_ERROR, "matrix damaged\n");
return AVERROR_INVALIDDATA; return AVERROR_INVALIDDATA;
@ -1133,29 +1138,31 @@ static int load_matrix(MpegEncContext *s, uint16_t matrix0[64],
return 0; return 0;
} }
static void mpeg_decode_quant_matrix_extension(MpegEncContext *s) static void mpeg_decode_quant_matrix_extension(MPVContext *const s,
GetBitContext *const gb)
{ {
ff_dlog(s->avctx, "matrix extension\n"); ff_dlog(s->avctx, "matrix extension\n");
if (get_bits1(&s->gb)) if (get_bits1(gb))
load_matrix(s, s->chroma_intra_matrix, s->intra_matrix, 1); load_matrix(s, gb, s->chroma_intra_matrix, s->intra_matrix, 1);
if (get_bits1(&s->gb)) if (get_bits1(gb))
load_matrix(s, s->chroma_inter_matrix, s->inter_matrix, 0); load_matrix(s, gb, s->chroma_inter_matrix, s->inter_matrix, 0);
if (get_bits1(&s->gb)) if (get_bits1(gb))
load_matrix(s, s->chroma_intra_matrix, NULL, 1); load_matrix(s, gb, s->chroma_intra_matrix, NULL, 1);
if (get_bits1(&s->gb)) if (get_bits1(gb))
load_matrix(s, s->chroma_inter_matrix, NULL, 0); load_matrix(s, gb, s->chroma_inter_matrix, NULL, 0);
} }
static int mpeg_decode_picture_coding_extension(Mpeg1Context *s1) static int mpeg_decode_picture_coding_extension(Mpeg1Context *const s1,
GetBitContext *const gb)
{ {
MpegEncContext *s = &s1->mpeg_enc_ctx; MpegEncContext *s = &s1->mpeg_enc_ctx;
s->full_pel[0] = s->full_pel[1] = 0; s->full_pel[0] = s->full_pel[1] = 0;
s->mpeg_f_code[0][0] = get_bits(&s->gb, 4); s->mpeg_f_code[0][0] = get_bits(gb, 4);
s->mpeg_f_code[0][1] = get_bits(&s->gb, 4); s->mpeg_f_code[0][1] = get_bits(gb, 4);
s->mpeg_f_code[1][0] = get_bits(&s->gb, 4); s->mpeg_f_code[1][0] = get_bits(gb, 4);
s->mpeg_f_code[1][1] = get_bits(&s->gb, 4); s->mpeg_f_code[1][1] = get_bits(gb, 4);
s->mpeg_f_code[0][0] += !s->mpeg_f_code[0][0]; s->mpeg_f_code[0][0] += !s->mpeg_f_code[0][0];
s->mpeg_f_code[0][1] += !s->mpeg_f_code[0][1]; s->mpeg_f_code[0][1] += !s->mpeg_f_code[0][1];
s->mpeg_f_code[1][0] += !s->mpeg_f_code[1][0]; s->mpeg_f_code[1][0] += !s->mpeg_f_code[1][0];
@ -1174,17 +1181,17 @@ static int mpeg_decode_picture_coding_extension(Mpeg1Context *s1)
s->pict_type = AV_PICTURE_TYPE_B; s->pict_type = AV_PICTURE_TYPE_B;
} }
s->intra_dc_precision = get_bits(&s->gb, 2); s->intra_dc_precision = get_bits(gb, 2);
s->picture_structure = get_bits(&s->gb, 2); s->picture_structure = get_bits(gb, 2);
s->top_field_first = get_bits1(&s->gb); s->top_field_first = get_bits1(gb);
s->frame_pred_frame_dct = get_bits1(&s->gb); s->frame_pred_frame_dct = get_bits1(gb);
s->concealment_motion_vectors = get_bits1(&s->gb); s->concealment_motion_vectors = get_bits1(gb);
s->q_scale_type = get_bits1(&s->gb); s->q_scale_type = get_bits1(gb);
s->intra_vlc_format = get_bits1(&s->gb); s->intra_vlc_format = get_bits1(gb);
s->alternate_scan = get_bits1(&s->gb); s->alternate_scan = get_bits1(gb);
s->repeat_first_field = get_bits1(&s->gb); s->repeat_first_field = get_bits1(gb);
s->chroma_420_type = get_bits1(&s->gb); s->chroma_420_type = get_bits1(gb);
s->progressive_frame = get_bits1(&s->gb); s->progressive_frame = get_bits1(gb);
// We only initialize intra_scantable.permutated, as this is all we use. // We only initialize intra_scantable.permutated, as this is all we use.
ff_permute_scantable(s->intra_scantable.permutated, ff_permute_scantable(s->intra_scantable.permutated,
@ -1724,44 +1731,45 @@ static int mpeg1_decode_sequence(AVCodecContext *avctx,
{ {
Mpeg1Context *s1 = avctx->priv_data; Mpeg1Context *s1 = avctx->priv_data;
MpegEncContext *s = &s1->mpeg_enc_ctx; MpegEncContext *s = &s1->mpeg_enc_ctx;
GetBitContext gb0, *const gb = &gb0;
int width, height; int width, height;
int i, v, j; int i, v, j;
int ret = init_get_bits8(&s->gb, buf, buf_size); int ret = init_get_bits8(gb, buf, buf_size);
if (ret < 0) if (ret < 0)
return ret; return ret;
width = get_bits(&s->gb, 12); width = get_bits(gb, 12);
height = get_bits(&s->gb, 12); height = get_bits(gb, 12);
if (width == 0 || height == 0) { if (width == 0 || height == 0) {
av_log(avctx, AV_LOG_WARNING, av_log(avctx, AV_LOG_WARNING,
"Invalid horizontal or vertical size value.\n"); "Invalid horizontal or vertical size value.\n");
if (avctx->err_recognition & (AV_EF_BITSTREAM | AV_EF_COMPLIANT)) if (avctx->err_recognition & (AV_EF_BITSTREAM | AV_EF_COMPLIANT))
return AVERROR_INVALIDDATA; return AVERROR_INVALIDDATA;
} }
s1->aspect_ratio_info = get_bits(&s->gb, 4); s1->aspect_ratio_info = get_bits(gb, 4);
if (s1->aspect_ratio_info == 0) { if (s1->aspect_ratio_info == 0) {
av_log(avctx, AV_LOG_ERROR, "aspect ratio has forbidden 0 value\n"); av_log(avctx, AV_LOG_ERROR, "aspect ratio has forbidden 0 value\n");
if (avctx->err_recognition & (AV_EF_BITSTREAM | AV_EF_COMPLIANT)) if (avctx->err_recognition & (AV_EF_BITSTREAM | AV_EF_COMPLIANT))
return AVERROR_INVALIDDATA; return AVERROR_INVALIDDATA;
} }
s1->frame_rate_index = get_bits(&s->gb, 4); s1->frame_rate_index = get_bits(gb, 4);
if (s1->frame_rate_index == 0 || s1->frame_rate_index > 13) { if (s1->frame_rate_index == 0 || s1->frame_rate_index > 13) {
av_log(avctx, AV_LOG_WARNING, av_log(avctx, AV_LOG_WARNING,
"frame_rate_index %d is invalid\n", s1->frame_rate_index); "frame_rate_index %d is invalid\n", s1->frame_rate_index);
s1->frame_rate_index = 1; s1->frame_rate_index = 1;
} }
s1->bit_rate = get_bits(&s->gb, 18) * 400; s1->bit_rate = get_bits(gb, 18) * 400;
if (check_marker(s->avctx, &s->gb, "in sequence header") == 0) { if (check_marker(s->avctx, gb, "in sequence header") == 0) {
return AVERROR_INVALIDDATA; return AVERROR_INVALIDDATA;
} }
s->avctx->rc_buffer_size = get_bits(&s->gb, 10) * 1024 * 16; s->avctx->rc_buffer_size = get_bits(gb, 10) * 1024 * 16;
skip_bits(&s->gb, 1); skip_bits(gb, 1);
/* get matrix */ /* get matrix */
if (get_bits1(&s->gb)) { if (get_bits1(gb)) {
load_matrix(s, s->chroma_intra_matrix, s->intra_matrix, 1); load_matrix(s, gb, s->chroma_intra_matrix, s->intra_matrix, 1);
} else { } else {
for (i = 0; i < 64; i++) { for (i = 0; i < 64; i++) {
j = s->idsp.idct_permutation[i]; j = s->idsp.idct_permutation[i];
@ -1770,8 +1778,8 @@ static int mpeg1_decode_sequence(AVCodecContext *avctx,
s->chroma_intra_matrix[j] = v; s->chroma_intra_matrix[j] = v;
} }
} }
if (get_bits1(&s->gb)) { if (get_bits1(gb)) {
load_matrix(s, s->chroma_inter_matrix, s->inter_matrix, 0); load_matrix(s, gb, s->chroma_inter_matrix, s->inter_matrix, 0);
} else { } else {
for (i = 0; i < 64; i++) { for (i = 0; i < 64; i++) {
int j = s->idsp.idct_permutation[i]; int j = s->idsp.idct_permutation[i];
@ -1781,7 +1789,7 @@ static int mpeg1_decode_sequence(AVCodecContext *avctx,
} }
} }
if (show_bits(&s->gb, 23) != 0) { if (show_bits(gb, 23) != 0) {
av_log(s->avctx, AV_LOG_ERROR, "sequence header damaged\n"); av_log(s->avctx, AV_LOG_ERROR, "sequence header damaged\n");
return AVERROR_INVALIDDATA; return AVERROR_INVALIDDATA;
} }
@ -2158,20 +2166,21 @@ static int mpeg_decode_gop(AVCodecContext *avctx,
{ {
Mpeg1Context *s1 = avctx->priv_data; Mpeg1Context *s1 = avctx->priv_data;
MpegEncContext *s = &s1->mpeg_enc_ctx; MpegEncContext *s = &s1->mpeg_enc_ctx;
GetBitContext gb0, *const gb = &gb0;
int broken_link; int broken_link;
int64_t tc; int64_t tc;
int ret = init_get_bits8(&s->gb, buf, buf_size); int ret = init_get_bits8(gb, buf, buf_size);
if (ret < 0) if (ret < 0)
return ret; return ret;
tc = s1->timecode_frame_start = get_bits(&s->gb, 25); tc = s1->timecode_frame_start = get_bits(gb, 25);
s1->closed_gop = get_bits1(&s->gb); s1->closed_gop = get_bits1(gb);
/* broken_link indicates that after editing the /* broken_link indicates that after editing the
* reference frames of the first B-Frames after GOP I-Frame * reference frames of the first B-Frames after GOP I-Frame
* are missing (open gop) */ * are missing (open gop) */
broken_link = get_bits1(&s->gb); broken_link = get_bits1(gb);
if (s->avctx->debug & FF_DEBUG_PICT_INFO) { if (s->avctx->debug & FF_DEBUG_PICT_INFO) {
char tcbuf[AV_TIMECODE_STR_SIZE]; char tcbuf[AV_TIMECODE_STR_SIZE];
@ -2313,15 +2322,17 @@ static int decode_chunks(AVCodecContext *avctx, AVFrame *picture,
return AVERROR_INVALIDDATA; return AVERROR_INVALIDDATA;
} }
break; break;
case EXT_START_CODE: case EXT_START_CODE: {
ret = init_get_bits8(&s2->gb, buf_ptr, input_size); GetBitContext gb0, *const gb = &gb0;
ret = init_get_bits8(gb, buf_ptr, input_size);
if (ret < 0) if (ret < 0)
return ret; return ret;
switch (get_bits(&s2->gb, 4)) { switch (get_bits(gb, 4)) {
case 0x1: case 0x1:
if (last_code == 0) { if (last_code == 0) {
mpeg_decode_sequence_extension(s); mpeg_decode_sequence_extension(s, gb);
} else { } else {
av_log(avctx, AV_LOG_ERROR, av_log(avctx, AV_LOG_ERROR,
"ignoring seq ext after %X\n", last_code); "ignoring seq ext after %X\n", last_code);
@ -2330,17 +2341,17 @@ static int decode_chunks(AVCodecContext *avctx, AVFrame *picture,
} }
break; break;
case 0x2: case 0x2:
mpeg_decode_sequence_display_extension(s); mpeg_decode_sequence_display_extension(s, gb);
break; break;
case 0x3: case 0x3:
mpeg_decode_quant_matrix_extension(s2); mpeg_decode_quant_matrix_extension(s2, gb);
break; break;
case 0x7: case 0x7:
mpeg_decode_picture_display_extension(s); mpeg_decode_picture_display_extension(s, gb);
break; break;
case 0x8: case 0x8:
if (last_code == PICTURE_START_CODE) { if (last_code == PICTURE_START_CODE) {
int ret = mpeg_decode_picture_coding_extension(s); int ret = mpeg_decode_picture_coding_extension(s, gb);
if (ret < 0) if (ret < 0)
return ret; return ret;
} else { } else {
@ -2352,6 +2363,7 @@ static int decode_chunks(AVCodecContext *avctx, AVFrame *picture,
break; break;
} }
break; break;
}
case USER_START_CODE: case USER_START_CODE:
mpeg_decode_user_data(avctx, buf_ptr, input_size); mpeg_decode_user_data(avctx, buf_ptr, input_size);
break; break;