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) {
- av_log(s->avctx, AV_LOG_WARNING,
- "Invalid and inefficient vfw-avi packed B frames detected\n");
+ av_log(s->avctx, AV_LOG_INFO, "Video uses a non-standard and "
+ "wasteful way to store B-frames ('packed B-frames'). "
+ "Consider using a tool like VirtualDub or avidemux to fix it.\n");
s->showed_packed_warning = 1;
}
}
return 0;
}
- if (s->xvid_build == -1 && s->divx_version == -1 && s->lavc_build == -1) {
+int ff_mpeg4_workaround_bugs(AVCodecContext *avctx)
+{
+ Mpeg4DecContext *ctx = avctx->priv_data;
+ MpegEncContext *s = &ctx->m;
+
- s->xvid_build = 0;
++ 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"))
- if (s->xvid_build == -1 && s->divx_version == -1 && s->lavc_build == -1)
++ ctx->xvid_build = 0;
+ }
+
- s->divx_version = 400; // divx 4
++ 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)
- if (s->xvid_build >= 0 && s->divx_version >= 0) {
- s->divx_version =
- s->divx_build = -1;
++ ctx->divx_version = 400; // divx 4
+
- if (s->divx_version >= 500 && s->divx_build < 1814)
++ if (ctx->xvid_build >= 0 && ctx->divx_version >= 0) {
++ ctx->divx_version =
++ ctx->divx_build = -1;
+ }
+
+ 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 (s->divx_version > 502 && s->divx_build < 1814)
++ if (ctx->divx_version >= 500 && ctx->divx_build < 1814)
+ s->workaround_bugs |= FF_BUG_QPEL_CHROMA;
+
- if (s->xvid_build <= 3U)
++ if (ctx->divx_version > 502 && ctx->divx_build < 1814)
+ s->workaround_bugs |= FF_BUG_QPEL_CHROMA2;
+
- if (s->xvid_build <= 1U)
++ if (ctx->xvid_build <= 3U)
+ s->padding_bug_score = 256 * 256 * 256 * 64;
+
- if (s->xvid_build <= 12U)
++ if (ctx->xvid_build <= 1U)
+ s->workaround_bugs |= FF_BUG_QPEL_CHROMA;
+
- if (s->xvid_build <= 32U)
++ if (ctx->xvid_build <= 12U)
+ s->workaround_bugs |= FF_BUG_EDGE;
+
- if (s->lavc_build < 4653U)
++ if (ctx->xvid_build <= 32U)
+ s->workaround_bugs |= FF_BUG_DC_CLIP;
+
+#define SET_QPEL_FUNC(postfix1, postfix2) \
+ s->dsp.put_ ## postfix1 = ff_put_ ## postfix2; \
+ s->dsp.put_no_rnd_ ## postfix1 = ff_put_no_rnd_ ## postfix2; \
+ s->dsp.avg_ ## postfix1 = ff_avg_ ## postfix2;
+
- if (s->lavc_build < 4655U)
++ if (ctx->lavc_build < 4653U)
+ s->workaround_bugs |= FF_BUG_STD_QPEL;
+
- if (s->lavc_build < 4670U)
++ if (ctx->lavc_build < 4655U)
+ s->workaround_bugs |= FF_BUG_DIRECT_BLOCKSIZE;
+
- if (s->lavc_build <= 4712U)
++ if (ctx->lavc_build < 4670U)
+ s->workaround_bugs |= FF_BUG_EDGE;
+
- if (s->divx_version >= 0)
++ if (ctx->lavc_build <= 4712U)
+ s->workaround_bugs |= FF_BUG_DC_CLIP;
+
- if (s->divx_version == 501 && s->divx_build == 20020416)
++ if (ctx->divx_version >= 0)
+ s->workaround_bugs |= FF_BUG_DIRECT_BLOCKSIZE;
- if (s->divx_version < 500U)
++ if (ctx->divx_version == 501 && ctx->divx_build == 20020416)
+ s->padding_bug_score = 256 * 256 * 256 * 64;
+
- if (s->divx_version >= 0)
++ if (ctx->divx_version < 500U)
+ s->workaround_bugs |= FF_BUG_EDGE;
+
- s->workaround_bugs, s->lavc_build, s->xvid_build,
- s->divx_version, s->divx_build, s->divx_packed ? "p" : "");
++ if (ctx->divx_version >= 0)
+ s->workaround_bugs |= FF_BUG_HPEL_CHROMA;
+ }
+
+ if (s->workaround_bugs & FF_BUG_STD_QPEL) {
+ SET_QPEL_FUNC(qpel_pixels_tab[0][5], qpel16_mc11_old_c)
+ SET_QPEL_FUNC(qpel_pixels_tab[0][7], qpel16_mc31_old_c)
+ SET_QPEL_FUNC(qpel_pixels_tab[0][9], qpel16_mc12_old_c)
+ SET_QPEL_FUNC(qpel_pixels_tab[0][11], qpel16_mc32_old_c)
+ SET_QPEL_FUNC(qpel_pixels_tab[0][13], qpel16_mc13_old_c)
+ SET_QPEL_FUNC(qpel_pixels_tab[0][15], qpel16_mc33_old_c)
+
+ SET_QPEL_FUNC(qpel_pixels_tab[1][5], qpel8_mc11_old_c)
+ SET_QPEL_FUNC(qpel_pixels_tab[1][7], qpel8_mc31_old_c)
+ SET_QPEL_FUNC(qpel_pixels_tab[1][9], qpel8_mc12_old_c)
+ SET_QPEL_FUNC(qpel_pixels_tab[1][11], qpel8_mc32_old_c)
+ SET_QPEL_FUNC(qpel_pixels_tab[1][13], qpel8_mc13_old_c)
+ SET_QPEL_FUNC(qpel_pixels_tab[1][15], qpel8_mc33_old_c)
+ }
+
+ if (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",
- if (s->codec_id == AV_CODEC_ID_MPEG4 && s->xvid_build >= 0 &&
++ s->workaround_bugs, ctx->lavc_build, ctx->xvid_build,
++ ctx->divx_version, ctx->divx_build, s->divx_packed ? "p" : "");
+
+#if HAVE_MMX
++ if (s->codec_id == AV_CODEC_ID_MPEG4 && ctx->xvid_build >= 0 &&
+ avctx->idct_algo == FF_IDCT_AUTO &&
+ (av_get_cpu_flags() & AV_CPU_FLAG_MMX)) {
+ avctx->idct_algo = FF_IDCT_XVIDMMX;
+ ff_dct_common_init(s);
+ return 1;
+ }
+#endif
+ return 0;
+}
+
static int decode_vop_header(Mpeg4DecContext *ctx, GetBitContext *gb)
{
MpegEncContext *s = &ctx->m;
for (;;) {
if (get_bits_count(gb) >= gb->size_in_bits) {
if (gb->size_in_bits == 8 &&
- (s->divx_version >= 0 || s->xvid_build >= 0) || s->codec_tag == AV_RL32("QMP4")) {
- (ctx->divx_version >= 0 || ctx->xvid_build >= 0)) {
- av_log(s->avctx, AV_LOG_WARNING, "frame skip %d\n", gb->size_in_bits);
++ (ctx->divx_version >= 0 || ctx->xvid_build >= 0) || s->codec_tag == AV_RL32("QMP4")) {
+ av_log(s->avctx, AV_LOG_VERBOSE, "frame skip %d\n", gb->size_in_bits);
return FRAME_SKIPPED; // divx bug
} else
return -1; // end of stream
Mpeg4DecContext *ctx = avctx->priv_data;
MpegEncContext *s = &ctx->m;
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;