*/
#include "error_resilience.h"
+#include "idctdsp.h"
#include "internal.h"
+#include "mpegutils.h"
#include "mpegvideo.h"
#include "mpeg4video.h"
#include "h263.h"
n == 1 || n == 3) {
/* same qscale */
for (i = 1; i < 8; i++)
- block[s->dsp.idct_permutation[i << 3]] += ac_val[i];
+ block[s->idsp.idct_permutation[i << 3]] += ac_val[i];
} else {
/* different qscale, we must rescale */
for (i = 1; i < 8; i++)
- block[s->dsp.idct_permutation[i << 3]] += ROUNDED_DIV(ac_val[i] * qscale_table[xy], s->qscale);
+ block[s->idsp.idct_permutation[i << 3]] += ROUNDED_DIV(ac_val[i] * qscale_table[xy], s->qscale);
}
} else {
const int xy = s->mb_x + s->mb_y * s->mb_stride - s->mb_stride;
n == 2 || n == 3) {
/* same qscale */
for (i = 1; i < 8; i++)
- block[s->dsp.idct_permutation[i]] += ac_val[i + 8];
+ block[s->idsp.idct_permutation[i]] += ac_val[i + 8];
} else {
/* different qscale, we must rescale */
for (i = 1; i < 8; i++)
- block[s->dsp.idct_permutation[i]] += ROUNDED_DIV(ac_val[i + 8] * qscale_table[xy], s->qscale);
+ block[s->idsp.idct_permutation[i]] += ROUNDED_DIV(ac_val[i + 8] * qscale_table[xy], s->qscale);
}
}
}
/* left copy */
for (i = 1; i < 8; i++)
- ac_val1[i] = block[s->dsp.idct_permutation[i << 3]];
+ ac_val1[i] = block[s->idsp.idct_permutation[i << 3]];
/* top copy */
for (i = 1; i < 8; i++)
- ac_val1[8 + i] = block[s->dsp.idct_permutation[i]];
+ ac_val1[8 + i] = block[s->idsp.idct_permutation[i]];
}
/**
return 0;
}
-static int mpeg4_decode_sprite_trajectory(MpegEncContext *s, GetBitContext *gb)
+static int mpeg4_decode_sprite_trajectory(Mpeg4DecContext *ctx, GetBitContext *gb)
{
+ MpegEncContext *s = &ctx->m;
int a = 2 << s->sprite_warping_accuracy;
int rho = 3 - s->sprite_warping_accuracy;
int r = 16 / a;
if (w <= 0 || h <= 0)
return AVERROR_INVALIDDATA;
- for (i = 0; i < s->num_sprite_warping_points; i++) {
+ for (i = 0; i < ctx->num_sprite_warping_points; i++) {
int length;
int x = 0, y = 0;
if (length)
x = get_xbits(gb, length);
- if (!(s->divx_version == 500 && s->divx_build == 413))
+ if (!(ctx->divx_version == 500 && ctx->divx_build == 413))
skip_bits1(gb); /* marker bit */
length = get_vlc2(gb, sprite_trajectory.table, SPRITE_TRAJ_VLC_BITS, 3);
y = get_xbits(gb, length);
skip_bits1(gb); /* marker bit */
- s->sprite_traj[i][0] = d[i][0] = x;
- s->sprite_traj[i][1] = d[i][1] = y;
+ ctx->sprite_traj[i][0] = d[i][0] = x;
+ ctx->sprite_traj[i][1] = d[i][1] = y;
}
for (; i < 4; i++)
- s->sprite_traj[i][0] = s->sprite_traj[i][1] = 0;
+ ctx->sprite_traj[i][0] = ctx->sprite_traj[i][1] = 0;
while ((1 << alpha) < w)
alpha++;
h2 = 1 << beta;
// Note, the 4th point isn't used for GMC
- if (s->divx_version == 500 && s->divx_build == 413) {
+ if (ctx->divx_version == 500 && ctx->divx_build == 413) {
sprite_ref[0][0] = a * vop_ref[0][0] + d[0][0];
sprite_ref[0][1] = a * vop_ref[0][1] + d[0][1];
sprite_ref[1][0] = a * vop_ref[1][0] + d[0][0] + d[1][0];
ROUNDED_DIV(((h - h2) * (r * sprite_ref[0][1] - 16 * vop_ref[0][1]) +
h2 * (r * sprite_ref[2][1] - 16 * vop_ref[2][1])), h);
- switch (s->num_sprite_warping_points) {
+ switch (ctx->num_sprite_warping_points) {
case 0:
s->sprite_offset[0][0] =
s->sprite_offset[0][1] =
s->sprite_delta[0][1] =
s->sprite_delta[1][0] = 0;
s->sprite_delta[1][1] = a;
- s->sprite_shift[0] =
- s->sprite_shift[1] = 0;
+ ctx->sprite_shift[0] =
+ ctx->sprite_shift[1] = 0;
break;
case 1: // GMC only
s->sprite_offset[0][0] = sprite_ref[0][0] - a * vop_ref[0][0];
s->sprite_delta[0][1] =
s->sprite_delta[1][0] = 0;
s->sprite_delta[1][1] = a;
- s->sprite_shift[0] =
- s->sprite_shift[1] = 0;
+ ctx->sprite_shift[0] =
+ ctx->sprite_shift[1] = 0;
break;
case 2:
s->sprite_offset[0][0] = (sprite_ref[0][0] << (alpha + rho)) +
s->sprite_delta[1][0] = (-r * sprite_ref[0][1] + virtual_ref[0][1]);
s->sprite_delta[1][1] = (-r * sprite_ref[0][0] + virtual_ref[0][0]);
- s->sprite_shift[0] = alpha + rho;
- s->sprite_shift[1] = alpha + rho + 2;
+ ctx->sprite_shift[0] = alpha + rho;
+ ctx->sprite_shift[1] = alpha + rho + 2;
break;
case 3:
min_ab = FFMIN(alpha, beta);
s->sprite_delta[1][0] = (-r * sprite_ref[0][1] + virtual_ref[0][1]) * h3;
s->sprite_delta[1][1] = (-r * sprite_ref[0][1] + virtual_ref[1][1]) * w3;
- s->sprite_shift[0] = alpha + beta + rho - min_ab;
- s->sprite_shift[1] = alpha + beta + rho - min_ab + 2;
+ ctx->sprite_shift[0] = alpha + beta + rho - min_ab;
+ ctx->sprite_shift[1] = alpha + beta + rho - min_ab + 2;
break;
}
/* try to simplify the situation */
- if (s->sprite_delta[0][0] == a << s->sprite_shift[0] &&
+ if (s->sprite_delta[0][0] == a << ctx->sprite_shift[0] &&
s->sprite_delta[0][1] == 0 &&
s->sprite_delta[1][0] == 0 &&
- s->sprite_delta[1][1] == a << s->sprite_shift[0]) {
- s->sprite_offset[0][0] >>= s->sprite_shift[0];
- s->sprite_offset[0][1] >>= s->sprite_shift[0];
- s->sprite_offset[1][0] >>= s->sprite_shift[1];
- s->sprite_offset[1][1] >>= s->sprite_shift[1];
+ s->sprite_delta[1][1] == a << ctx->sprite_shift[0]) {
+ s->sprite_offset[0][0] >>= ctx->sprite_shift[0];
+ s->sprite_offset[0][1] >>= ctx->sprite_shift[0];
+ s->sprite_offset[1][0] >>= ctx->sprite_shift[1];
+ s->sprite_offset[1][1] >>= ctx->sprite_shift[1];
s->sprite_delta[0][0] = a;
s->sprite_delta[0][1] = 0;
s->sprite_delta[1][0] = 0;
s->sprite_delta[1][1] = a;
- s->sprite_shift[0] = 0;
- s->sprite_shift[1] = 0;
+ ctx->sprite_shift[0] = 0;
+ ctx->sprite_shift[1] = 0;
s->real_sprite_warping_points = 1;
} else {
- int shift_y = 16 - s->sprite_shift[0];
- int shift_c = 16 - s->sprite_shift[1];
+ int shift_y = 16 - ctx->sprite_shift[0];
+ int shift_c = 16 - ctx->sprite_shift[1];
for (i = 0; i < 2; i++) {
s->sprite_offset[0][i] <<= shift_y;
s->sprite_offset[1][i] <<= shift_c;
s->sprite_delta[0][i] <<= shift_y;
s->sprite_delta[1][i] <<= shift_y;
- s->sprite_shift[i] = 16;
+ ctx->sprite_shift[i] = 16;
}
- s->real_sprite_warping_points = s->num_sprite_warping_points;
+ s->real_sprite_warping_points = ctx->num_sprite_warping_points;
}
return 0;
// FIXME don't just ignore everything
if (s->pict_type == AV_PICTURE_TYPE_S &&
ctx->vol_sprite_usage == GMC_SPRITE) {
- if (mpeg4_decode_sprite_trajectory(s, &s->gb) < 0)
+ if (mpeg4_decode_sprite_trajectory(ctx, &s->gb) < 0)
return AVERROR_INVALIDDATA;
av_log(s->avctx, AV_LOG_ERROR, "untested\n");
}
* @param n either 0 for the x component or 1 for y
* @return the average MV for a GMC MB
*/
-static inline int get_amv(MpegEncContext *s, int n)
+static inline int get_amv(Mpeg4DecContext *ctx, int n)
{
+ MpegEncContext *s = &ctx->m;
int x, y, mb_v, sum, dx, dy, shift;
int len = 1 << (s->f_code + 4);
const int a = s->sprite_warping_accuracy;
len >>= s->quarter_sample;
if (s->real_sprite_warping_points == 1) {
- if (s->divx_version == 500 && s->divx_build == 413)
+ if (ctx->divx_version == 500 && ctx->divx_build == 413)
sum = s->sprite_offset[0][n] / (1 << (a - s->quarter_sample));
else
sum = RSHIFT(s->sprite_offset[0][n] << s->quarter_sample, a);
} else {
dx = s->sprite_delta[n][0];
dy = s->sprite_delta[n][1];
- shift = s->sprite_shift[0];
+ shift = ctx->sprite_shift[0];
if (n)
dy -= 1 << (shift + a + 1);
else
MB_TYPE_16x16 |
MB_TYPE_GMC |
MB_TYPE_L0;
- mx = get_amv(s, 0);
- my = get_amv(s, 1);
+ mx = get_amv(ctx, 0);
+ my = get_amv(ctx, 1);
} else {
s->current_picture.mb_type[xy] = MB_TYPE_SKIP |
MB_TYPE_16x16 |
s->current_picture.mb_type[xy] = MB_TYPE_16x16 |
MB_TYPE_L0;
} else {
- mx = get_amv(s, 0);
- my = get_amv(s, 1);
+ mx = get_amv(ctx, 0);
+ my = get_amv(ctx, 1);
s->current_picture.mb_type[xy] = MB_TYPE_16x16 |
MB_TYPE_GMC |
MB_TYPE_L0;
* Decode a block.
* @return <0 if an error occurred
*/
-static inline int mpeg4_decode_block(MpegEncContext *s, int16_t *block,
+static inline int mpeg4_decode_block(Mpeg4DecContext *ctx, int16_t *block,
int n, int coded, int intra, int rvlc)
{
+ MpegEncContext *s = &ctx->m;
int level, i, last, run, qmul, qadd, dc_pred_dir;
RLTable *rl;
RL_VLC_ELEM *rl_vlc;
// Note intra & rvlc should be optimized away if this is inlined
if (intra) {
- if (s->use_intra_dc_vlc) {
+ if (ctx->use_intra_dc_vlc) {
/* DC coef */
if (s->partitioned_frame) {
level = s->dc_val[0][s->block_index[n]];
not_coded:
if (intra) {
- if (!s->use_intra_dc_vlc) {
+ if (!ctx->use_intra_dc_vlc) {
block[0] = ff_mpeg4_pred_dc(s, n, block[0], &dc_pred_dir, 0);
i -= i >> 31; // if (i == -1) i = 0;
mb_type = s->current_picture.mb_type[xy];
cbp = s->cbp_table[xy];
- s->use_intra_dc_vlc = s->qscale < s->intra_dc_threshold;
+ ctx->use_intra_dc_vlc = s->qscale < ctx->intra_dc_threshold;
if (s->current_picture.qscale_table[xy] != s->qscale)
ff_set_qscale(s, s->current_picture.qscale_table[xy]);
if (!IS_SKIP(mb_type)) {
int i;
- s->dsp.clear_blocks(s->block[0]);
+ s->bdsp.clear_blocks(s->block[0]);
/* decode each block */
for (i = 0; i < 6; i++) {
- if (mpeg4_decode_block(s, block[i], i, cbp & 32, s->mb_intra, ctx->rvlc) < 0) {
+ if (mpeg4_decode_block(ctx, block[i], i, cbp & 32, s->mb_intra, ctx->rvlc) < 0) {
av_log(s->avctx, AV_LOG_ERROR,
"texture corrupted at %d %d %d\n",
s->mb_x, s->mb_y, s->mb_intra);
MB_TYPE_16x16 |
MB_TYPE_L0;
s->mcsel = 1;
- s->mv[0][0][0] = get_amv(s, 0);
- s->mv[0][0][1] = get_amv(s, 1);
+ s->mv[0][0][0] = get_amv(ctx, 0);
+ s->mv[0][0][1] = get_amv(ctx, 1);
s->mb_skipped = 0;
} else {
s->current_picture.mb_type[xy] = MB_TYPE_SKIP |
}
} while (cbpc == 20);
- s->dsp.clear_blocks(s->block[0]);
+ s->bdsp.clear_blocks(s->block[0]);
dquant = cbpc & 8;
s->mb_intra = ((cbpc & 4) != 0);
if (s->mb_intra)
MB_TYPE_L0;
/* 16x16 global motion prediction */
s->mv_type = MV_TYPE_16X16;
- mx = get_amv(s, 0);
- my = get_amv(s, 1);
+ mx = get_amv(ctx, 0);
+ my = get_amv(ctx, 1);
s->mv[0][0][0] = mx;
s->mv[0][0][1] = my;
} else if ((!s->progressive_sequence) && get_bits1(&s->gb)) {
if (modb2) {
cbp = 0;
} else {
- s->dsp.clear_blocks(s->block[0]);
+ s->bdsp.clear_blocks(s->block[0]);
cbp = get_bits(&s->gb, 6);
}
}
cbp = (cbpc & 3) | (cbpy << 2);
- s->use_intra_dc_vlc = s->qscale < s->intra_dc_threshold;
+ ctx->use_intra_dc_vlc = s->qscale < ctx->intra_dc_threshold;
if (dquant)
ff_set_qscale(s, s->qscale + quant_tab[get_bits(&s->gb, 2)]);
if (!s->progressive_sequence)
s->interlaced_dct = get_bits1(&s->gb);
- s->dsp.clear_blocks(s->block[0]);
+ s->bdsp.clear_blocks(s->block[0]);
/* decode each block */
for (i = 0; i < 6; i++) {
- if (mpeg4_decode_block(s, block[i], i, cbp & 32, 1, 0) < 0)
+ if (mpeg4_decode_block(ctx, block[i], i, cbp & 32, 1, 0) < 0)
return -1;
cbp += cbp;
}
/* decode each block */
for (i = 0; i < 6; i++) {
- if (mpeg4_decode_block(s, block[i], i, cbp & 32, 0, 0) < 0)
+ if (mpeg4_decode_block(ctx, block[i], i, cbp & 32, 0, 0) < 0)
return -1;
cbp += cbp;
}
else
s->avctx->time_base.num = 1;
- s->t_frame = 0;
+ ctx->t_frame = 0;
if (ctx->shape != BIN_ONLY_SHAPE) {
if (ctx->shape == RECT_SHAPE) {
skip_bits(gb, 13); // sprite_top
skip_bits1(gb); /* marker */
}
- s->num_sprite_warping_points = get_bits(gb, 6);
- if (s->num_sprite_warping_points > 3) {
+ ctx->num_sprite_warping_points = get_bits(gb, 6);
+ if (ctx->num_sprite_warping_points > 3) {
av_log(s->avctx, AV_LOG_ERROR,
"%d sprite_warping_points\n",
- s->num_sprite_warping_points);
- s->num_sprite_warping_points = 0;
+ ctx->num_sprite_warping_points);
+ ctx->num_sprite_warping_points = 0;
return -1;
}
s->sprite_warping_accuracy = get_bits(gb, 2);
- s->sprite_brightness_change = get_bits1(gb);
+ ctx->sprite_brightness_change = get_bits1(gb);
if (ctx->vol_sprite_usage == STATIC_SPRITE)
- s->low_latency_sprite = get_bits1(gb);
+ skip_bits1(gb); // low_latency_sprite
}
// FIXME sadct disable bit if verid!=1 && shape not rect
/* load default matrixes */
for (i = 0; i < 64; i++) {
- int j = s->dsp.idct_permutation[i];
+ int j = s->idsp.idct_permutation[i];
v = ff_mpeg4_default_intra_matrix[i];
s->intra_matrix[j] = v;
s->chroma_intra_matrix[j] = v;
break;
last = v;
- j = s->dsp.idct_permutation[ff_zigzag_direct[i]];
+ j = s->idsp.idct_permutation[ff_zigzag_direct[i]];
s->intra_matrix[j] = last;
s->chroma_intra_matrix[j] = last;
}
/* replicate last value */
for (; i < 64; i++) {
- int j = s->dsp.idct_permutation[ff_zigzag_direct[i]];
+ int j = s->idsp.idct_permutation[ff_zigzag_direct[i]];
s->intra_matrix[j] = last;
s->chroma_intra_matrix[j] = last;
}
break;
last = v;
- j = s->dsp.idct_permutation[ff_zigzag_direct[i]];
+ j = s->idsp.idct_permutation[ff_zigzag_direct[i]];
s->inter_matrix[j] = v;
s->chroma_inter_matrix[j] = v;
}
/* replicate last value */
for (; i < 64; i++) {
- int j = s->dsp.idct_permutation[ff_zigzag_direct[i]];
+ int j = s->idsp.idct_permutation[ff_zigzag_direct[i]];
s->inter_matrix[j] = last;
s->chroma_inter_matrix[j] = last;
}
int estimation_method = get_bits(gb, 2);
if (estimation_method < 2) {
if (!get_bits1(gb)) {
- s->cplx_estimation_trash_i += 8 * get_bits1(gb); /* opaque */
- s->cplx_estimation_trash_i += 8 * get_bits1(gb); /* transparent */
- s->cplx_estimation_trash_i += 8 * get_bits1(gb); /* intra_cae */
- s->cplx_estimation_trash_i += 8 * get_bits1(gb); /* inter_cae */
- s->cplx_estimation_trash_i += 8 * get_bits1(gb); /* no_update */
- s->cplx_estimation_trash_i += 8 * get_bits1(gb); /* upampling */
+ ctx->cplx_estimation_trash_i += 8 * get_bits1(gb); /* opaque */
+ ctx->cplx_estimation_trash_i += 8 * get_bits1(gb); /* transparent */
+ ctx->cplx_estimation_trash_i += 8 * get_bits1(gb); /* intra_cae */
+ ctx->cplx_estimation_trash_i += 8 * get_bits1(gb); /* inter_cae */
+ ctx->cplx_estimation_trash_i += 8 * get_bits1(gb); /* no_update */
+ ctx->cplx_estimation_trash_i += 8 * get_bits1(gb); /* upampling */
}
if (!get_bits1(gb)) {
- s->cplx_estimation_trash_i += 8 * get_bits1(gb); /* intra_blocks */
- s->cplx_estimation_trash_p += 8 * get_bits1(gb); /* inter_blocks */
- s->cplx_estimation_trash_p += 8 * get_bits1(gb); /* inter4v_blocks */
- s->cplx_estimation_trash_i += 8 * get_bits1(gb); /* not coded blocks */
+ ctx->cplx_estimation_trash_i += 8 * get_bits1(gb); /* intra_blocks */
+ ctx->cplx_estimation_trash_p += 8 * get_bits1(gb); /* inter_blocks */
+ ctx->cplx_estimation_trash_p += 8 * get_bits1(gb); /* inter4v_blocks */
+ ctx->cplx_estimation_trash_i += 8 * get_bits1(gb); /* not coded blocks */
}
if (!check_marker(gb, "in complexity estimation part 1")) {
skip_bits_long(gb, pos - get_bits_count(gb));
goto no_cplx_est;
}
if (!get_bits1(gb)) {
- s->cplx_estimation_trash_i += 8 * get_bits1(gb); /* dct_coeffs */
- s->cplx_estimation_trash_i += 8 * get_bits1(gb); /* dct_lines */
- s->cplx_estimation_trash_i += 8 * get_bits1(gb); /* vlc_syms */
- s->cplx_estimation_trash_i += 4 * get_bits1(gb); /* vlc_bits */
+ ctx->cplx_estimation_trash_i += 8 * get_bits1(gb); /* dct_coeffs */
+ ctx->cplx_estimation_trash_i += 8 * get_bits1(gb); /* dct_lines */
+ ctx->cplx_estimation_trash_i += 8 * get_bits1(gb); /* vlc_syms */
+ ctx->cplx_estimation_trash_i += 4 * get_bits1(gb); /* vlc_bits */
}
if (!get_bits1(gb)) {
- s->cplx_estimation_trash_p += 8 * get_bits1(gb); /* apm */
- s->cplx_estimation_trash_p += 8 * get_bits1(gb); /* npm */
- s->cplx_estimation_trash_b += 8 * get_bits1(gb); /* interpolate_mc_q */
- s->cplx_estimation_trash_p += 8 * get_bits1(gb); /* forwback_mc_q */
- s->cplx_estimation_trash_p += 8 * get_bits1(gb); /* halfpel2 */
- s->cplx_estimation_trash_p += 8 * get_bits1(gb); /* halfpel4 */
+ ctx->cplx_estimation_trash_p += 8 * get_bits1(gb); /* apm */
+ ctx->cplx_estimation_trash_p += 8 * get_bits1(gb); /* npm */
+ ctx->cplx_estimation_trash_b += 8 * get_bits1(gb); /* interpolate_mc_q */
+ ctx->cplx_estimation_trash_p += 8 * get_bits1(gb); /* forwback_mc_q */
+ ctx->cplx_estimation_trash_p += 8 * get_bits1(gb); /* halfpel2 */
+ ctx->cplx_estimation_trash_p += 8 * get_bits1(gb); /* halfpel4 */
}
if (!check_marker(gb, "in complexity estimation part 2")) {
skip_bits_long(gb, pos - get_bits_count(gb));
goto no_cplx_est;
}
if (estimation_method == 1) {
- s->cplx_estimation_trash_i += 8 * get_bits1(gb); /* sadct */
- s->cplx_estimation_trash_p += 8 * get_bits1(gb); /* qpel */
+ ctx->cplx_estimation_trash_i += 8 * get_bits1(gb); /* sadct */
+ ctx->cplx_estimation_trash_p += 8 * get_bits1(gb); /* qpel */
}
} else
av_log(s->avctx, AV_LOG_ERROR,
} else {
no_cplx_est:
- s->cplx_estimation_trash_i =
- s->cplx_estimation_trash_p =
- s->cplx_estimation_trash_b = 0;
+ ctx->cplx_estimation_trash_i =
+ ctx->cplx_estimation_trash_p =
+ ctx->cplx_estimation_trash_b = 0;
}
ctx->resync_marker = !get_bits1(gb); /* resync_marker_disabled */
ctx->rvlc = get_bits1(gb);
if (vo_ver_id != 1) {
- s->new_pred = get_bits1(gb);
- if (s->new_pred) {
+ ctx->new_pred = get_bits1(gb);
+ if (ctx->new_pred) {
av_log(s->avctx, AV_LOG_ERROR, "new pred not supported\n");
skip_bits(gb, 2); /* requested upstream message type */
skip_bits1(gb); /* newpred segment type */
}
- s->reduced_res_vop = get_bits1(gb);
- if (s->reduced_res_vop)
+ if (get_bits1(gb)) // reduced_res_vop
av_log(s->avctx, AV_LOG_ERROR,
"reduced resolution VOP not supported\n");
} else {
- s->new_pred = 0;
- s->reduced_res_vop = 0;
+ ctx->new_pred = 0;
}
- s->scalability = get_bits1(gb);
+ ctx->scalability = get_bits1(gb);
- if (s->scalability) {
+ if (ctx->scalability) {
GetBitContext bak = *gb;
int h_sampling_factor_n;
int h_sampling_factor_m;
int v_sampling_factor_n;
int v_sampling_factor_m;
- s->hierachy_type = get_bits1(gb);
+ skip_bits1(gb); // hierarchy_type
skip_bits(gb, 4); /* ref_layer_id */
skip_bits1(gb); /* ref_layer_sampling_dir */
h_sampling_factor_n = get_bits(gb, 5);
h_sampling_factor_m = get_bits(gb, 5);
v_sampling_factor_n = get_bits(gb, 5);
v_sampling_factor_m = get_bits(gb, 5);
- s->enhancement_type = get_bits1(gb);
+ ctx->enhancement_type = get_bits1(gb);
if (h_sampling_factor_n == 0 || h_sampling_factor_m == 0 ||
v_sampling_factor_n == 0 || v_sampling_factor_m == 0) {
/* illegal scalability header (VERY broken encoder),
* trying to workaround */
- s->scalability = 0;
+ ctx->scalability = 0;
*gb = bak;
} else
av_log(s->avctx, AV_LOG_ERROR, "scalability not supported\n");
* Decode the user data stuff in the header.
* Also initializes divx/xvid/lavc_version/build.
*/
-static int decode_user_data(MpegEncContext *s, GetBitContext *gb)
+static int decode_user_data(Mpeg4DecContext *ctx, GetBitContext *gb)
{
+ MpegEncContext *s = &ctx->m;
char buf[256];
int i;
int e;
if (e < 2)
e = sscanf(buf, "DivX%db%d%c", &ver, &build, &last);
if (e >= 2) {
- s->divx_version = ver;
- s->divx_build = build;
+ ctx->divx_version = ver;
+ ctx->divx_build = build;
s->divx_packed = e == 3 && last == 'p';
- if (s->divx_packed && !s->showed_packed_warning) {
+ if (s->divx_packed && !ctx->showed_packed_warning) {
av_log(s->avctx, AV_LOG_WARNING,
"Invalid and inefficient vfw-avi packed B frames detected\n");
- s->showed_packed_warning = 1;
+ ctx->showed_packed_warning = 1;
}
}
}
if (e != 4) {
if (strcmp(buf, "ffmpeg") == 0)
- s->lavc_build = 4600;
+ ctx->lavc_build = 4600;
}
if (e == 4)
- s->lavc_build = build;
+ ctx->lavc_build = build;
/* Xvid detection */
e = sscanf(buf, "XviD%d", &build);
if (e == 1)
- s->xvid_build = build;
+ ctx->xvid_build = build;
+
+ if (ctx->xvid_build == -1 && ctx->divx_version == -1 && ctx->lavc_build == -1) {
+ if (s->stream_codec_tag == AV_RL32("XVID") ||
+ s->codec_tag == AV_RL32("XVID") ||
+ s->codec_tag == AV_RL32("XVIX") ||
+ s->codec_tag == AV_RL32("RMP4") ||
+ s->codec_tag == AV_RL32("ZMP4") ||
+ s->codec_tag == AV_RL32("SIPP"))
+ ctx->xvid_build = 0;
+ }
+
+ if (ctx->xvid_build == -1 && ctx->divx_version == -1 && ctx->lavc_build == -1)
+ if (s->codec_tag == AV_RL32("DIVX") && s->vo_type == 0 &&
+ s->vol_control_parameters == 0)
+ ctx->divx_version = 400; // divx 4
+
+ if (ctx->xvid_build >= 0 && ctx->divx_version >= 0) {
+ ctx->divx_version =
+ ctx->divx_build = -1;
+ }
+
+#if HAVE_MMX
+ if (ctx->xvid_build >= 0 &&
+ s->avctx->idct_algo == FF_IDCT_AUTO &&
+ (av_get_cpu_flags() & AV_CPU_FLAG_MMX)) {
+ s->avctx->idct_algo = FF_IDCT_XVIDMMX;
+ ff_dct_common_init(s);
+ }
+#endif
return 0;
}
}
ff_mpeg4_init_direct_mv(s);
- if (s->t_frame == 0)
- s->t_frame = s->pb_time;
- if (s->t_frame == 0)
- s->t_frame = 1; // 1/0 protection
- s->pp_field_time = (ROUNDED_DIV(s->last_non_b_time, s->t_frame) -
- ROUNDED_DIV(s->last_non_b_time - s->pp_time, s->t_frame)) * 2;
- s->pb_field_time = (ROUNDED_DIV(s->time, s->t_frame) -
- ROUNDED_DIV(s->last_non_b_time - s->pp_time, s->t_frame)) * 2;
+ if (ctx->t_frame == 0)
+ ctx->t_frame = s->pb_time;
+ if (ctx->t_frame == 0)
+ ctx->t_frame = 1; // 1/0 protection
+ s->pp_field_time = (ROUNDED_DIV(s->last_non_b_time, ctx->t_frame) -
+ ROUNDED_DIV(s->last_non_b_time - s->pp_time, ctx->t_frame)) * 2;
+ s->pb_field_time = (ROUNDED_DIV(s->time, ctx->t_frame) -
+ ROUNDED_DIV(s->last_non_b_time - s->pp_time, ctx->t_frame)) * 2;
if (!s->progressive_sequence) {
if (s->pp_field_time <= s->pb_field_time || s->pb_field_time <= 1)
return FRAME_SKIPPED;
// FIXME complexity estimation stuff
if (ctx->shape != BIN_ONLY_SHAPE) {
- skip_bits_long(gb, s->cplx_estimation_trash_i);
+ skip_bits_long(gb, ctx->cplx_estimation_trash_i);
if (s->pict_type != AV_PICTURE_TYPE_I)
- skip_bits_long(gb, s->cplx_estimation_trash_p);
+ skip_bits_long(gb, ctx->cplx_estimation_trash_p);
if (s->pict_type == AV_PICTURE_TYPE_B)
- skip_bits_long(gb, s->cplx_estimation_trash_b);
+ skip_bits_long(gb, ctx->cplx_estimation_trash_b);
- s->intra_dc_threshold = ff_mpeg4_dc_threshold[get_bits(gb, 3)];
+ ctx->intra_dc_threshold = ff_mpeg4_dc_threshold[get_bits(gb, 3)];
if (!s->progressive_sequence) {
s->top_field_first = get_bits1(gb);
s->alternate_scan = get_bits1(gb);
}
if (s->alternate_scan) {
- ff_init_scantable(s->dsp.idct_permutation, &s->inter_scantable, ff_alternate_vertical_scan);
- ff_init_scantable(s->dsp.idct_permutation, &s->intra_scantable, ff_alternate_vertical_scan);
- ff_init_scantable(s->dsp.idct_permutation, &s->intra_h_scantable, ff_alternate_vertical_scan);
- ff_init_scantable(s->dsp.idct_permutation, &s->intra_v_scantable, ff_alternate_vertical_scan);
+ ff_init_scantable(s->idsp.idct_permutation, &s->inter_scantable, ff_alternate_vertical_scan);
+ ff_init_scantable(s->idsp.idct_permutation, &s->intra_scantable, ff_alternate_vertical_scan);
+ ff_init_scantable(s->idsp.idct_permutation, &s->intra_h_scantable, ff_alternate_vertical_scan);
+ ff_init_scantable(s->idsp.idct_permutation, &s->intra_v_scantable, ff_alternate_vertical_scan);
} else {
- ff_init_scantable(s->dsp.idct_permutation, &s->inter_scantable, ff_zigzag_direct);
- ff_init_scantable(s->dsp.idct_permutation, &s->intra_scantable, ff_zigzag_direct);
- ff_init_scantable(s->dsp.idct_permutation, &s->intra_h_scantable, ff_alternate_horizontal_scan);
- ff_init_scantable(s->dsp.idct_permutation, &s->intra_v_scantable, ff_alternate_vertical_scan);
+ ff_init_scantable(s->idsp.idct_permutation, &s->inter_scantable, ff_zigzag_direct);
+ ff_init_scantable(s->idsp.idct_permutation, &s->intra_scantable, ff_zigzag_direct);
+ ff_init_scantable(s->idsp.idct_permutation, &s->intra_h_scantable, ff_alternate_horizontal_scan);
+ ff_init_scantable(s->idsp.idct_permutation, &s->intra_v_scantable, ff_alternate_vertical_scan);
}
if (s->pict_type == AV_PICTURE_TYPE_S &&
(ctx->vol_sprite_usage == STATIC_SPRITE ||
ctx->vol_sprite_usage == GMC_SPRITE)) {
- if (mpeg4_decode_sprite_trajectory(s, gb) < 0)
+ if (mpeg4_decode_sprite_trajectory(ctx, gb) < 0)
return AVERROR_INVALIDDATA;
- if (s->sprite_brightness_change)
+ if (ctx->sprite_brightness_change)
av_log(s->avctx, AV_LOG_ERROR,
"sprite_brightness_change not supported\n");
if (ctx->vol_sprite_usage == STATIC_SPRITE)
gb->size_in_bits, s->progressive_sequence, s->alternate_scan,
s->top_field_first, s->quarter_sample ? "q" : "h",
s->data_partitioning, ctx->resync_marker,
- s->num_sprite_warping_points, s->sprite_warping_accuracy,
+ ctx->num_sprite_warping_points, s->sprite_warping_accuracy,
1 - s->no_rounding, s->vo_type,
- s->vol_control_parameters ? " VOLC" : " ", s->intra_dc_threshold,
- s->cplx_estimation_trash_i, s->cplx_estimation_trash_p,
- s->cplx_estimation_trash_b);
+ s->vol_control_parameters ? " VOLC" : " ", ctx->intra_dc_threshold,
+ ctx->cplx_estimation_trash_i, ctx->cplx_estimation_trash_p,
+ ctx->cplx_estimation_trash_b);
}
- if (!s->scalability) {
+ if (!ctx->scalability) {
if (ctx->shape != RECT_SHAPE && s->pict_type != AV_PICTURE_TYPE_I)
skip_bits1(gb); // vop shape coding type
} else {
- if (s->enhancement_type) {
+ if (ctx->enhancement_type) {
int load_backward_shape = get_bits1(gb);
if (load_backward_shape)
av_log(s->avctx, AV_LOG_ERROR,
* (divx4/xvid/opendivx). Note we cannot detect divx5 without b-frames
* easily (although it's buggy too) */
if (s->vo_type == 0 && s->vol_control_parameters == 0 &&
- s->divx_version == -1 && s->picture_number == 0) {
+ ctx->divx_version == -1 && s->picture_number == 0) {
av_log(s->avctx, AV_LOG_WARNING,
"looks like this file was encoded with (divx4/(old)xvid/opendivx) -> forcing low_delay flag\n");
s->low_delay = 1;
for (;;) {
if (get_bits_count(gb) >= gb->size_in_bits) {
if (gb->size_in_bits == 8 &&
- (s->divx_version >= 0 || s->xvid_build >= 0)) {
+ (ctx->divx_version >= 0 || ctx->xvid_build >= 0)) {
av_log(s->avctx, AV_LOG_WARNING, "frame skip %d\n", gb->size_in_bits);
return FRAME_SKIPPED; // divx bug
} else
if (decode_vol_header(ctx, gb) < 0)
return -1;
} else if (startcode == USER_DATA_STARTCODE) {
- decode_user_data(s, gb);
+ decode_user_data(ctx, gb);
} else if (startcode == GOP_STARTCODE) {
mpeg4_decode_gop_header(s, gb);
} else if (startcode == VOS_STARTCODE) {
s->low_delay = 1;
s->avctx->has_b_frames = !s->low_delay;
+ if (s->workaround_bugs & FF_BUG_AUTODETECT) {
+ if (s->codec_tag == AV_RL32("XVIX"))
+ s->workaround_bugs |= FF_BUG_XVID_ILACE;
+
+ if (s->codec_tag == AV_RL32("UMP4"))
+ s->workaround_bugs |= FF_BUG_UMP4;
+
+ if (ctx->divx_version >= 500 && ctx->divx_build < 1814)
+ s->workaround_bugs |= FF_BUG_QPEL_CHROMA;
+
+ if (ctx->divx_version > 502 && ctx->divx_build < 1814)
+ s->workaround_bugs |= FF_BUG_QPEL_CHROMA2;
+
+ if (ctx->xvid_build <= 3U)
+ s->padding_bug_score = 256 * 256 * 256 * 64;
+
+ if (ctx->xvid_build <= 1U)
+ s->workaround_bugs |= FF_BUG_QPEL_CHROMA;
+
+ if (ctx->xvid_build <= 12U)
+ s->workaround_bugs |= FF_BUG_EDGE;
+
+ if (ctx->xvid_build <= 32U)
+ s->workaround_bugs |= FF_BUG_DC_CLIP;
+
+ if (ctx->lavc_build < 4653U)
+ s->workaround_bugs |= FF_BUG_STD_QPEL;
+
+ if (ctx->lavc_build < 4655U)
+ s->workaround_bugs |= FF_BUG_DIRECT_BLOCKSIZE;
+
+ if (ctx->lavc_build < 4670U)
+ s->workaround_bugs |= FF_BUG_EDGE;
+
+ if (ctx->lavc_build <= 4712U)
+ s->workaround_bugs |= FF_BUG_DC_CLIP;
+
+ if (ctx->divx_version >= 0)
+ s->workaround_bugs |= FF_BUG_DIRECT_BLOCKSIZE;
+
+ if (ctx->divx_version == 501 && ctx->divx_build == 20020416)
+ s->padding_bug_score = 256 * 256 * 256 * 64;
+
+ if (ctx->divx_version < 500U)
+ s->workaround_bugs |= FF_BUG_EDGE;
+
+ if (ctx->divx_version >= 0)
+ s->workaround_bugs |= FF_BUG_HPEL_CHROMA;
+ }
+
+
+ if (s->avctx->debug & FF_DEBUG_BUGS)
+ av_log(s->avctx, AV_LOG_DEBUG,
+ "bugs: %X lavc_build:%d xvid_build:%d divx_version:%d divx_build:%d %s\n",
+ s->workaround_bugs, ctx->lavc_build, ctx->xvid_build,
+ ctx->divx_version, ctx->divx_build, s->divx_packed ? "p" : "");
+
return decode_vop_header(ctx, gb);
}
+int ff_mpeg4_frame_end(AVCodecContext *avctx, const uint8_t *buf, int buf_size)
+{
+ Mpeg4DecContext *ctx = avctx->priv_data;
+ MpegEncContext *s = &ctx->m;
+
+ /* divx 5.01+ bistream reorder stuff */
+ if (s->divx_packed) {
+ int current_pos = get_bits_count(&s->gb) >> 3;
+ int startcode_found = 0;
+
+ if (buf_size - current_pos > 5) {
+ int i;
+ for (i = current_pos; i < buf_size - 3; i++)
+ if (buf[i] == 0 &&
+ buf[i + 1] == 0 &&
+ buf[i + 2] == 1 &&
+ buf[i + 3] == 0xB6) {
+ startcode_found = 1;
+ break;
+ }
+ }
+ if (s->gb.buffer == s->bitstream_buffer && buf_size > 7 &&
+ ctx->xvid_build >= 0) { // xvid style
+ startcode_found = 1;
+ current_pos = 0;
+ }
+
+ if (startcode_found) {
+ av_fast_malloc(&s->bitstream_buffer,
+ &s->allocated_bitstream_buffer_size,
+ buf_size - current_pos +
+ FF_INPUT_BUFFER_PADDING_SIZE);
+ if (!s->bitstream_buffer)
+ return AVERROR(ENOMEM);
+ memcpy(s->bitstream_buffer, buf + current_pos,
+ buf_size - current_pos);
+ s->bitstream_buffer_size = buf_size - current_pos;
+ }
+ }
+
+ return 0;
+}
+
static int mpeg4_update_thread_context(AVCodecContext *dst,
const AVCodecContext *src)
{
int ret;
static int done = 0;
- s->divx_version =
- s->divx_build =
- s->xvid_build =
- s->lavc_build = -1;
+ ctx->divx_version =
+ ctx->divx_build =
+ ctx->xvid_build =
+ ctx->lavc_build = -1;
if ((ret = ff_h263_decode_init(avctx)) < 0)
return ret;