summaryrefslogtreecommitdiff
path: root/libavcodec/mpeg4videodec.c
diff options
context:
space:
mode:
Diffstat (limited to 'libavcodec/mpeg4videodec.c')
-rw-r--r--libavcodec/mpeg4videodec.c52
1 files changed, 36 insertions, 16 deletions
diff --git a/libavcodec/mpeg4videodec.c b/libavcodec/mpeg4videodec.c
index 66d4127884..a9d67f220c 100644
--- a/libavcodec/mpeg4videodec.c
+++ b/libavcodec/mpeg4videodec.c
@@ -3,26 +3,27 @@
* Copyright (c) 2000,2001 Fabrice Bellard
* Copyright (c) 2002-2010 Michael Niedermayer <michaelni@gmx.at>
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "mpegvideo.h"
#include "mpeg4video.h"
#include "h263.h"
+#include "thread.h"
// The defines below define the number of bits that are read at once for
// reading vlc values. Changing these may improve speed and data cache needs
@@ -373,7 +374,13 @@ int mpeg4_decode_video_packet_header(MpegEncContext *s)
return -1;
}
if(s->pict_type == AV_PICTURE_TYPE_B){
- while(s->next_picture.mbskip_table[ s->mb_index2xy[ mb_num ] ]) mb_num++;
+ int mb_x = 0, mb_y = 0;
+
+ while(s->next_picture.mbskip_table[ s->mb_index2xy[ mb_num ] ]) {
+ if (!mb_x) ff_thread_await_progress((AVFrame*)s->next_picture_ptr, mb_y++, 0);
+ mb_num++;
+ if (++mb_x == s->mb_width) mb_x = 0;
+ }
if(mb_num >= s->mb_num) return -1; // slice contains just skipped MBs which where already decoded
}
@@ -1303,6 +1310,8 @@ static int mpeg4_decode_mb(MpegEncContext *s,
s->last_mv[i][1][0]=
s->last_mv[i][1][1]= 0;
}
+
+ ff_thread_await_progress((AVFrame*)s->next_picture_ptr, s->mb_y, 0);
}
/* if we skipped it in the future P Frame than skip it now too */
@@ -1482,6 +1491,12 @@ end:
if(s->codec_id==CODEC_ID_MPEG4){
if(mpeg4_is_resync(s)){
const int delta= s->mb_x + 1 == s->mb_width ? 2 : 1;
+
+ if(s->pict_type==AV_PICTURE_TYPE_B){
+ ff_thread_await_progress((AVFrame*)s->next_picture_ptr,
+ (s->mb_x + delta >= s->mb_width) ? FFMIN(s->mb_y+1, s->mb_height-1) : s->mb_y, 0);
+ }
+
if(s->pict_type==AV_PICTURE_TYPE_B && s->next_picture.mbskip_table[xy + delta])
return SLICE_OK;
return SLICE_END;
@@ -1494,18 +1509,22 @@ end:
static int mpeg4_decode_gop_header(MpegEncContext * s, GetBitContext *gb){
int hours, minutes, seconds;
- unsigned time_code = show_bits(gb, 18);
-
- if (time_code & 0x40) { /* marker_bit */
- hours = time_code >> 13;
- minutes = time_code >> 7 & 0x3f;
- seconds = time_code & 0x3f;
- s->time_base = seconds + 60*(minutes + 60*hours);
- skip_bits(gb, 20); /* time_code, closed_gov, broken_link */
- } else {
- av_log(s->avctx, AV_LOG_WARNING, "GOP header missing marker_bit\n");
+
+ if(!show_bits(gb, 23)){
+ av_log(s->avctx, AV_LOG_WARNING, "GOP header invalid\n");
+ return -1;
}
+ hours= get_bits(gb, 5);
+ minutes= get_bits(gb, 6);
+ skip_bits1(gb);
+ seconds= get_bits(gb, 6);
+
+ s->time_base= seconds + 60*(minutes + 60*hours);
+
+ skip_bits1(gb);
+ skip_bits1(gb);
+
return 0;
}
@@ -2235,11 +2254,12 @@ AVCodec ff_mpeg4_decoder = {
NULL,
ff_h263_decode_end,
ff_h263_decode_frame,
- CODEC_CAP_DRAW_HORIZ_BAND | CODEC_CAP_DR1 | CODEC_CAP_TRUNCATED | CODEC_CAP_DELAY,
+ CODEC_CAP_DRAW_HORIZ_BAND | CODEC_CAP_DR1 | CODEC_CAP_TRUNCATED | CODEC_CAP_DELAY | CODEC_CAP_FRAME_THREADS,
.flush= ff_mpeg_flush,
.max_lowres= 3,
.long_name= NULL_IF_CONFIG_SMALL("MPEG-4 part 2"),
.pix_fmts= ff_hwaccel_pixfmt_list_420,
+ .update_thread_context= ONLY_IF_THREADS_ENABLED(ff_mpeg_update_thread_context)
};