From 1cb0edb40b8e94e1a50ad40c40d43e34ed8435fe Mon Sep 17 00:00:00 2001 From: Juanjo Date: Sat, 16 Mar 2002 02:41:00 +0000 Subject: [PATCH] - Bug fix MPEG-2 decoder to handle "repeat_first_field" (Telecine) - Hack in MPEG-2 demux to cope with buggy VOBs. Originally committed as revision 333 to svn://svn.ffmpeg.org/ffmpeg/trunk --- libav/mpeg.c | 6 +++++- libavcodec/mpeg12.c | 30 ++++++++++++++++++++++++++---- libavcodec/utils.c | 3 ++- 3 files changed, 33 insertions(+), 6 deletions(-) diff --git a/libav/mpeg.c b/libav/mpeg.c index 2c09a85970..f112a773b0 100644 --- a/libav/mpeg.c +++ b/libav/mpeg.c @@ -473,9 +473,13 @@ static int mpeg_mux_read_header(AVFormatContext *s, know that this codec will be used */ type = CODEC_TYPE_AUDIO; codec_id = CODEC_ID_AC3; + /* XXX: Another hack for DVD: it seems, that AC3 streams + aren't signaled on audio_bound on some DVDs (Matrix) */ + if (audio_bound == 0) + audio_bound++; n = audio_bound; c = 0x80; - /* c = 0x1c0; */ + //c = 0x1c0; } else if (c == 0xb9) { /* all video streams */ type = CODEC_TYPE_VIDEO; diff --git a/libavcodec/mpeg12.c b/libavcodec/mpeg12.c index 41bf524e4a..e366702273 100644 --- a/libavcodec/mpeg12.c +++ b/libavcodec/mpeg12.c @@ -1119,6 +1119,7 @@ typedef struct Mpeg1Context { UINT8 *buf_ptr; int buffer_size; int mpeg_enc_ctx_allocated; /* true if decoding context allocated */ + int repeat_field; /* true if we must repeat the field */ } Mpeg1Context; static int mpeg_decode_init(AVCodecContext *avctx) @@ -1131,6 +1132,7 @@ static int mpeg_decode_init(AVCodecContext *avctx) s->start_code = -1; s->buf_ptr = s->buffer; s->mpeg_enc_ctx.picture_number = 0; + s->repeat_field = 0; return 0; } @@ -1203,7 +1205,7 @@ static void mpeg_decode_sequence_extension(MpegEncContext *s) int frame_rate_ext_n, frame_rate_ext_d; skip_bits(&s->gb, 8); /* profil and level */ - skip_bits(&s->gb, 1); /* progressive_sequence */ + s->progressive_sequence = get_bits1(&s->gb); /* progressive_sequence */ skip_bits(&s->gb, 2); /* chroma_format */ horiz_size_ext = get_bits(&s->gb, 2); vert_size_ext = get_bits(&s->gb, 2); @@ -1279,12 +1281,13 @@ static void mpeg_decode_picture_coding_extension(MpegEncContext *s) s->chroma_420_type = get_bits1(&s->gb); s->progressive_frame = get_bits1(&s->gb); /* composite display not parsed */ - dprintf("intra_dc_precion=%d\n", s->intra_dc_precision); + dprintf("intra_dc_precision=%d\n", s->intra_dc_precision); dprintf("picture_structure=%d\n", s->picture_structure); dprintf("conceal=%d\n", s->concealment_motion_vectors); dprintf("intra_vlc_format=%d\n", s->intra_vlc_format); dprintf("alternate_scan=%d\n", s->alternate_scan); dprintf("frame_pred_frame_dct=%d\n", s->frame_pred_frame_dct); + dprintf("progressive_frame=%d\n", s->progressive_frame); } static void mpeg_decode_extension(AVCodecContext *avctx, @@ -1434,6 +1437,7 @@ static int mpeg1_decode_sequence(AVCodecContext *avctx, avctx->width = width; avctx->height = height; avctx->frame_rate = frame_rate_tab[s->frame_rate_index]; + s->frame_rate = avctx->frame_rate; avctx->bit_rate = s->bit_rate; if (MPV_common_init(s) < 0) @@ -1505,13 +1509,14 @@ static int mpeg_decode_frame(AVCodecContext *avctx, UINT8 *buf_end, *buf_ptr, *buf_start; int len, start_code_found, ret, code, start_code, input_size; AVPicture *picture = data; - + MpegEncContext *s2 = &s->mpeg_enc_ctx; + dprintf("fill_buffer\n"); *data_size = 0; + /* special case for last picture */ if (buf_size == 0) { - MpegEncContext *s2 = &s->mpeg_enc_ctx; if (s2->picture_number > 0) { picture->data[0] = s2->next_picture[0]; picture->data[1] = s2->next_picture[1]; @@ -1526,6 +1531,15 @@ static int mpeg_decode_frame(AVCodecContext *avctx, buf_ptr = buf; buf_end = buf + buf_size; + + if (s->repeat_field % 2 == 1) { + s->repeat_field++; + //fprintf(stderr,"\nRepeating last frame: %d -> %d! pict: %d %d", avctx->frame_number-1, avctx->frame_number, + // s2->picture_number, s->repeat_field); + *data_size = 1; + goto the_end; + } + while (buf_ptr < buf_end) { buf_start = buf_ptr; /* find start next code */ @@ -1574,6 +1588,14 @@ static int mpeg_decode_frame(AVCodecContext *avctx, start_code, s->buffer, input_size); if (ret == 1) { /* got a picture: exit */ + /* first check if we must repeat the frame */ + if (s2->progressive_frame && s2->repeat_first_field) { + //fprintf(stderr,"\nRepeat this frame: %d! pict: %d",avctx->frame_number,s2->picture_number); + s2->repeat_first_field = 0; + s2->progressive_frame = 0; + if (++s->repeat_field > 2) + s->repeat_field = 0; + } *data_size = sizeof(AVPicture); goto the_end; } diff --git a/libavcodec/utils.c b/libavcodec/utils.c index 2d7b6a9070..406966c729 100644 --- a/libavcodec/utils.c +++ b/libavcodec/utils.c @@ -113,7 +113,8 @@ int avcodec_decode_video(AVCodecContext *avctx, AVPicture *picture, ret = avctx->codec->decode(avctx, picture, got_picture_ptr, buf, buf_size); - avctx->frame_number++; + if (*got_picture_ptr) + avctx->frame_number++; return ret; }