for(i=0;i<2;i++) {
if (USES_LIST(mb_type, i)) {
int dmx, dmy, mx, my, m;
+ const int my_shift= s->picture_structure == PICT_FRAME;
+
mx = mpeg_decode_motion(s, s->mpeg_f_code[i][0],
s->last_mv[i][0][0]);
s->last_mv[i][0][0] = mx;
s->last_mv[i][1][0] = mx;
dmx = get_dmv(s);
my = mpeg_decode_motion(s, s->mpeg_f_code[i][1],
- s->last_mv[i][0][1] >> 1);
+ s->last_mv[i][0][1] >> my_shift);
dmy = get_dmv(s);
- s->last_mv[i][0][1] = my<<1;
- s->last_mv[i][1][1] = my<<1;
+ s->last_mv[i][0][1] = my<<my_shift;
+ s->last_mv[i][1][1] = my<<my_shift;
s->mv[i][0][0] = mx;
s->mv[i][0][1] = my;
int save_aspect_info;
int save_width, save_height, save_progressive_seq;
AVRational frame_rate_ext; ///< MPEG-2 specific framerate modificator
-
+ int sync; ///< Did we reach a sync point like a GOP/SEQ/KEYFrame?
} Mpeg1Context;
static av_cold int mpeg_decode_init(AVCodecContext *avctx)
s->chroma_420_type = get_bits1(&s->gb);
s->progressive_frame = get_bits1(&s->gb);
+ if(s->progressive_sequence && !s->progressive_frame){
+ s->progressive_frame= 1;
+ av_log(s->avctx, AV_LOG_ERROR, "interlaced frame in progressive sequence, ignoring\n");
+ }
+
+ if(s->picture_structure==0 || (s->progressive_frame && s->picture_structure!=PICT_FRAME)){
+ av_log(s->avctx, AV_LOG_ERROR, "picture_structure %d invalid, ignoring\n", s->picture_structure);
+ s->picture_structure= PICT_FRAME;
+ }
+
+ if(s->progressive_sequence && !s->frame_pred_frame_dct){
+ av_log(s->avctx, AV_LOG_ERROR, "invalid frame_pred_frame_dct\n");
+ s->frame_pred_frame_dct= 1;
+ }
+
if(s->picture_structure == PICT_FRAME){
s->first_field=0;
s->v_edge_pos= 16*s->mb_height;
s->resync_mb_x=
s->resync_mb_y= -1;
- if (mb_y<<field_pic >= s->mb_height){
- av_log(s->avctx, AV_LOG_ERROR, "slice below image (%d >= %d)\n", mb_y, s->mb_height);
- return -1;
- }
+ assert(mb_y < s->mb_height);
init_get_bits(&s->gb, *buf, buf_size*8);
s->mb_x=0;
- for(;;) {
- int code = get_vlc2(&s->gb, mbincr_vlc.table, MBINCR_VLC_BITS, 2);
- if (code < 0){
- av_log(s->avctx, AV_LOG_ERROR, "first mb_incr damaged\n");
- return -1;
- }
- if (code >= 33) {
- if (code == 33) {
- s->mb_x += 33;
+ if(mb_y==0 && s->codec_tag == AV_RL32("SLIF")){
+ skip_bits1(&s->gb);
+ }else{
+ for(;;) {
+ int code = get_vlc2(&s->gb, mbincr_vlc.table, MBINCR_VLC_BITS, 2);
+ if (code < 0){
+ av_log(s->avctx, AV_LOG_ERROR, "first mb_incr damaged\n");
+ return -1;
+ }
+ if (code >= 33) {
+ if (code == 33) {
+ s->mb_x += 33;
+ }
+ /* otherwise, stuffing, nothing to do */
+ } else {
+ s->mb_x += code;
+ break;
}
- /* otherwise, stuffing, nothing to do */
- } else {
- s->mb_x += code;
- break;
}
}
+
if(s->mb_x >= (unsigned)s->mb_width){
av_log(s->avctx, AV_LOG_ERROR, "initial skip overflow\n");
return -1;
return -1;
if(s->current_picture.motion_val[0] && !s->encoding){ //note motion_val is normally NULL unless we want to extract the MVs
- const int wrap = field_pic ? 2*s->b8_stride : s->b8_stride;
+ const int wrap = s->b8_stride;
int xy = s->mb_x*2 + s->mb_y*2*wrap;
int motion_x, motion_y, dir, i;
- if(field_pic && !s->first_field)
- xy += wrap/2;
for(i=0; i<2; i++){
for(dir=0; dir<2; dir++){
if (++s->mb_x >= s->mb_width) {
const int mb_size= 16>>s->avctx->lowres;
- ff_draw_horiz_band(s, mb_size*s->mb_y, mb_size);
+ ff_draw_horiz_band(s, mb_size*(s->mb_y>>field_pic), mb_size);
s->mb_x = 0;
- s->mb_y++;
+ s->mb_y += 1<<field_pic;
- if(s->mb_y<<field_pic >= s->mb_height){
+ if(s->mb_y >= s->mb_height){
int left= get_bits_left(&s->gb);
int is_d10= s->chroma_format==2 && s->pict_type==FF_I_TYPE && avctx->profile==0 && avctx->level==5
&& s->intra_dc_precision == 2 && s->q_scale_type == 1 && s->alternate_scan == 0
MpegEncContext *s= *(void**)arg;
const uint8_t *buf= s->gb.buffer;
int mb_y= s->start_mb_y;
+ const int field_pic= s->picture_structure != PICT_FRAME;
- s->error_count= 3*(s->end_mb_y - s->start_mb_y)*s->mb_width;
+ s->error_count= (3*(s->end_mb_y - s->start_mb_y)*s->mb_width) >> field_pic;
for(;;){
uint32_t start_code;
if(last_code == 0){
mpeg1_decode_sequence(avctx, buf_ptr,
input_size);
+ s->sync=1;
}else{
av_log(avctx, AV_LOG_ERROR, "ignoring SEQ_START_CODE after %X\n", last_code);
}
s2->first_field=0;
mpeg_decode_gop(avctx,
buf_ptr, input_size);
+ s->sync=1;
}else{
av_log(avctx, AV_LOG_ERROR, "ignoring GOP_START_CODE after %X\n", last_code);
}
default:
if (start_code >= SLICE_MIN_START_CODE &&
start_code <= SLICE_MAX_START_CODE && last_code!=0) {
- int mb_y= start_code - SLICE_MIN_START_CODE;
+ const int field_pic= s2->picture_structure != PICT_FRAME;
+ int mb_y= (start_code - SLICE_MIN_START_CODE) << field_pic;
last_code= SLICE_MIN_START_CODE;
+ if(s2->picture_structure == PICT_BOTTOM_FIELD)
+ mb_y++;
+
+ if (mb_y >= s2->mb_height){
+ av_log(s2->avctx, AV_LOG_ERROR, "slice below image (%d >= %d)\n", mb_y, s2->mb_height);
+ return -1;
+ }
+
if(s2->last_picture_ptr==NULL){
/* Skip B-frames if we do not have reference frames and gop is not closed */
if(s2->pict_type==FF_B_TYPE){
break;
}
}
+ if(s2->pict_type==FF_I_TYPE)
+ s->sync=1;
if(s2->next_picture_ptr==NULL){
/* Skip P-frames if we do not have a reference frame or we have an invalid header. */
- if(s2->pict_type==FF_P_TYPE && (s2->first_field || s2->picture_structure==PICT_FRAME)) break;
+ if(s2->pict_type==FF_P_TYPE && !s->sync) break;
}
/* Skip B-frames if we are in a hurry. */
if(avctx->hurry_up && s2->pict_type==FF_B_TYPE) break;
return -1;
}
- if(s2->last_picture_ptr==NULL && s2->pict_type!=FF_I_TYPE){
- int i;
- /* Allocate a dummy frame */
- i= ff_find_unused_picture(s2, 0);
- s2->last_picture_ptr= &s2->picture[i];
- if(ff_alloc_picture(s2, s2->last_picture_ptr, 0) < 0)
- return -1;
- s2->last_picture= *s2->last_picture_ptr;
- }
- if(s2->next_picture_ptr==NULL && s2->pict_type==FF_B_TYPE){
- int i;
- /* Allocate a dummy frame */
- i= ff_find_unused_picture(s2, 0);
- s2->next_picture_ptr= &s2->picture[i];
- if(ff_alloc_picture(s2, s2->next_picture_ptr, 0) < 0)
- return -1;
- s2->next_picture= *s2->next_picture_ptr;
- }
-
if (avctx->codec->capabilities&CODEC_CAP_HWACCEL_VDPAU) {
s->slice_count++;
break;
}
}
+static void flush(AVCodecContext *avctx){
+ Mpeg1Context *s = avctx->priv_data;
+
+ s->sync=0;
+
+ ff_mpeg_flush(avctx);
+}
+
static int mpeg_decode_end(AVCodecContext *avctx)
{
Mpeg1Context *s = avctx->priv_data;
mpeg_decode_end,
mpeg_decode_frame,
CODEC_CAP_DRAW_HORIZ_BAND | CODEC_CAP_DR1 | CODEC_CAP_TRUNCATED | CODEC_CAP_DELAY,
- .flush= ff_mpeg_flush,
+ .flush= flush,
.long_name= NULL_IF_CONFIG_SMALL("MPEG-1 video"),
};
mpeg_decode_end,
mpeg_decode_frame,
CODEC_CAP_DRAW_HORIZ_BAND | CODEC_CAP_DR1 | CODEC_CAP_TRUNCATED | CODEC_CAP_DELAY,
- .flush= ff_mpeg_flush,
+ .flush= flush,
.long_name= NULL_IF_CONFIG_SMALL("MPEG-2 video"),
};
mpeg_decode_end,
mpeg_decode_frame,
CODEC_CAP_DRAW_HORIZ_BAND | CODEC_CAP_DR1 | CODEC_CAP_TRUNCATED | CODEC_CAP_DELAY,
- .flush= ff_mpeg_flush,
+ .flush= flush,
.long_name= NULL_IF_CONFIG_SMALL("MPEG-1 video"),
};
mpeg_decode_end,
mpeg_decode_frame,
CODEC_CAP_DRAW_HORIZ_BAND | CODEC_CAP_DR1 | CODEC_CAP_TRUNCATED| CODEC_CAP_HWACCEL | CODEC_CAP_DELAY,
- .flush= ff_mpeg_flush,
+ .flush= flush,
.long_name = NULL_IF_CONFIG_SMALL("MPEG-1/2 video XvMC (X-Video Motion Compensation)"),
};
mpeg_decode_end,
mpeg_decode_frame,
CODEC_CAP_DR1 | CODEC_CAP_TRUNCATED | CODEC_CAP_HWACCEL_VDPAU | CODEC_CAP_DELAY,
- .flush= ff_mpeg_flush,
+ .flush= flush,
.long_name = NULL_IF_CONFIG_SMALL("MPEG-1/2 video (VDPAU acceleration)"),
};
#endif
mpeg_decode_end,
mpeg_decode_frame,
CODEC_CAP_DR1 | CODEC_CAP_TRUNCATED | CODEC_CAP_HWACCEL_VDPAU | CODEC_CAP_DELAY,
- .flush= ff_mpeg_flush,
+ .flush= flush,
.long_name = NULL_IF_CONFIG_SMALL("MPEG-1 video (VDPAU acceleration)"),
};
#endif