static int decode_slice(MpegEncContext *s)
{
- const int part_mask = s->partitioned_frame ? (ER_AC_END | ER_AC_ERROR) : 0x7F;
+ const int part_mask = s->partitioned_frame
+ ? (ER_AC_END | ER_AC_ERROR) : 0x7F;
- const int mb_size = 16;
+ const int mb_size = 16 >> s->avctx->lowres;
int ret;
s->last_resync_gb = s->gb;
return buf_size;
}
+retry:
+ if (s->divx_packed && s->bitstream_buffer_size) {
+ int i;
+ for(i=0; i < buf_size-3; i++) {
+ if (buf[i]==0 && buf[i+1]==0 && buf[i+2]==1) {
+ if (buf[i+3]==0xB0) {
+ av_log(s->avctx, AV_LOG_WARNING, "Discarding excessive bitstream in packed xvid\n");
+ s->bitstream_buffer_size = 0;
+ }
+ break;
+ }
+ }
+ }
+
if (s->bitstream_buffer_size && (s->divx_packed || buf_size < 20)) // divx 5.01+/xvid frame reorder
- init_get_bits(&s->gb, s->bitstream_buffer,
- s->bitstream_buffer_size * 8);
+ ret = init_get_bits8(&s->gb, s->bitstream_buffer, s->bitstream_buffer_size);
else
- init_get_bits(&s->gb, buf, buf_size * 8);
+ ret = init_get_bits8(&s->gb, buf, buf_size);
+
s->bitstream_buffer_size = 0;
+ if (ret < 0)
+ return ret;
if (!s->context_initialized)
- if ((ret = ff_MPV_common_init(s)) < 0) // we need the idct permutaton for reading a custom matrix
+ // we need the idct permutaton for reading a custom matrix
+ if ((ret = ff_MPV_common_init(s)) < 0)
return ret;
/* We need to set current_picture_ptr before reading the header,
if (!s->divx_packed && !avctx->hwaccel)
ff_thread_finish_setup(avctx);
- if (avctx->hwaccel)
- if ((ret = avctx->hwaccel->start_frame(avctx, s->gb.buffer,
- s->gb.buffer_end - s->gb.buffer)) < 0)
+ if (CONFIG_MPEG4_VDPAU_DECODER && (s->avctx->codec->capabilities & CODEC_CAP_HWACCEL_VDPAU)) {
+ ff_vdpau_mpeg4_decode_picture(s, s->gb.buffer, s->gb.buffer_end - s->gb.buffer);
+ goto frame_end;
+ }
+
+ if (avctx->hwaccel) {
+ ret = avctx->hwaccel->start_frame(avctx, s->gb.buffer,
+ s->gb.buffer_end - s->gb.buffer);
+ if (ret < 0 )
return ret;
+ }
ff_mpeg_er_frame_start(s);
ff_msmpeg4_decode_ext_header(s, buf_size) < 0)
s->er.error_status_table[s->mb_num - 1] = ER_MB_ERROR;
- assert(s->bitstream_buffer_size == 0);
- /* divx 5.01+ bistream reorder stuff */
+ av_assert1(s->bitstream_buffer_size == 0);
+frame_end:
+ ff_er_frame_end(&s->er);
+
- if (avctx->hwaccel)
- if ((ret = avctx->hwaccel->end_frame(avctx)) < 0)
++ if (avctx->hwaccel) {
++ ret = avctx->hwaccel->end_frame(avctx);
++ if (ret < 0)
+ return ret;
++ }
+
+ ff_MPV_frame_end(s);
+
+ /* divx 5.01+ bitstream reorder stuff */
+ /* Since this clobbers the input buffer and hwaccel codecs still need the
+ * data during hwaccel->end_frame we should not do this any earlier */
if (s->codec_id == AV_CODEC_ID_MPEG4 && s->divx_packed) {
- int current_pos = get_bits_count(&s->gb) >> 3;
+ int current_pos = s->gb.buffer == s->bitstream_buffer ? 0 : (get_bits_count(&s->gb) >> 3);
int startcode_found = 0;
- if (buf_size - current_pos > 5) {
+ if (buf_size - current_pos > 7) {
int i;
- for (i = current_pos; i < buf_size - 3; i++)
+ for (i = current_pos; i < buf_size - 4; i++)
if (buf[i] == 0 &&
buf[i + 1] == 0 &&
buf[i + 2] == 1 &&