diff options
Diffstat (limited to 'src/libffmpeg/libavcodec/mpeg12.c')
-rw-r--r-- | src/libffmpeg/libavcodec/mpeg12.c | 109 |
1 files changed, 72 insertions, 37 deletions
diff --git a/src/libffmpeg/libavcodec/mpeg12.c b/src/libffmpeg/libavcodec/mpeg12.c index ac614d5ce..37e9b70ac 100644 --- a/src/libffmpeg/libavcodec/mpeg12.c +++ b/src/libffmpeg/libavcodec/mpeg12.c @@ -1,26 +1,25 @@ /* * MPEG1 encoder / MPEG2 decoder - * Copyright (c) 2000,2001 Gerard Lantau. + * Copyright (c) 2000,2001 Fabrice Bellard. * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * This library 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 of the License, or (at your option) any later version. * - * This program is distributed in the hope that it will be useful, + * This library 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 General Public License for more details. + * 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 General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ //#define DEBUG #include "avcodec.h" #include "dsputil.h" #include "mpegvideo.h" -#include "xineutils.h" #include "mpeg12data.h" @@ -34,8 +33,6 @@ #define EXT_START_CODE 0x000001b5 #define USER_START_CODE 0x000001b2 -#define ABS(a) ((a)<0 ? -(a) : (a)) - static void mpeg1_encode_block(MpegEncContext *s, DCTELEM *block, int component); @@ -400,8 +397,11 @@ void mpeg1_encode_init(MpegEncContext *s) } } s->mv_penalty= mv_penalty; - s->fcode_tab= fcode_tab; + s->min_qcoeff=-255; + s->max_qcoeff= 255; + s->intra_quant_bias= 3<<(QUANT_BIAS_SHIFT-3); //(a + x*3/8)/x + s->inter_quant_bias= 0; } static inline void encode_dc(MpegEncContext *s, int diff, int component) @@ -853,6 +853,8 @@ static int mpeg_decode_mb(MpegEncContext *s, if (cbp & (1 << (5 - i))) { if (mpeg2_decode_block_intra(s, block[i], i) < 0) return -1; + } else { + s->block_last_index[i] = -1; } } } else { @@ -860,6 +862,8 @@ static int mpeg_decode_mb(MpegEncContext *s, if (cbp & (1 << (5 - i))) { if (mpeg2_decode_block_non_intra(s, block[i], i) < 0) return -1; + } else { + s->block_last_index[i] = -1; } } } @@ -868,6 +872,8 @@ static int mpeg_decode_mb(MpegEncContext *s, if (cbp & (1 << (5 - i))) { if (mpeg1_decode_block(s, block[i], i) < 0) return -1; + } else { + s->block_last_index[i] = -1; } } } @@ -1028,9 +1034,9 @@ static int mpeg2_decode_block_non_intra(MpegEncContext *s, UINT8 *buf_ptr; i = 0; if (n < 4) - matrix = s->non_intra_matrix; + matrix = s->inter_matrix; else - matrix = s->chroma_non_intra_matrix; + matrix = s->chroma_inter_matrix; /* special case for the first coef. no need to add a second vlc table */ SAVE_BITS(&s->gb); @@ -1184,6 +1190,9 @@ static int mpeg_decode_init(AVCodecContext *avctx) s->buf_ptr = s->buffer; s->mpeg_enc_ctx.picture_number = 0; s->repeat_field = 0; + s->mpeg_enc_ctx.codec_id= avctx->codec->id; + avctx->mbskip_table= s->mpeg_enc_ctx.mbskip_table; + s->mpeg_enc_ctx.flags= avctx->flags; return 0; } @@ -1273,6 +1282,7 @@ static void mpeg_decode_sequence_extension(MpegEncContext *s) s->frame_rate = (s->frame_rate * frame_rate_ext_n) / frame_rate_ext_d; dprintf("sequence extension\n"); s->mpeg2 = 1; + s->avctx->sub_id = 2; /* indicates mpeg2 found */ } static void mpeg_decode_quant_matrix_extension(MpegEncContext *s) @@ -1293,8 +1303,8 @@ static void mpeg_decode_quant_matrix_extension(MpegEncContext *s) for(i=0;i<64;i++) { v = get_bits(&s->gb, 8); j = zigzag_direct[i]; - s->non_intra_matrix[j] = v; - s->chroma_non_intra_matrix[j] = v; + s->inter_matrix[j] = v; + s->chroma_inter_matrix[j] = v; } } if (get_bits1(&s->gb)) { @@ -1308,7 +1318,7 @@ static void mpeg_decode_quant_matrix_extension(MpegEncContext *s) for(i=0;i<64;i++) { v = get_bits(&s->gb, 8); j = zigzag_direct[i]; - s->chroma_non_intra_matrix[j] = v; + s->chroma_inter_matrix[j] = v; } } } @@ -1334,6 +1344,8 @@ static void mpeg_decode_picture_coding_extension(MpegEncContext *s) /* composite display not parsed */ dprintf("intra_dc_precision=%d\n", s->intra_dc_precision); dprintf("picture_structure=%d\n", s->picture_structure); + dprintf("top field first=%d\n", s->top_field_first); + dprintf("repeat first field=%d\n", s->repeat_first_field); 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); @@ -1387,7 +1399,6 @@ static int mpeg_decode_slice(AVCodecContext *avctx, s->mb_x = -1; s->mb_y = start_code; s->mb_incr = 0; - /* start frame decoding */ if (s->first_slice) { s->first_slice = 0; @@ -1404,6 +1415,7 @@ static int mpeg_decode_slice(AVCodecContext *avctx, for(;;) { clear_blocks(s->block[0]); + emms_c(); ret = mpeg_decode_mb(s, s->block); dprintf("ret=%d\n", ret); if (ret < 0) @@ -1460,7 +1472,7 @@ static int mpeg1_decode_sequence(AVCodecContext *avctx, Mpeg1Context *s1 = avctx->priv_data; MpegEncContext *s = &s1->mpeg_enc_ctx; int width, height, i, v, j; - + init_get_bits(&s->gb, buf, buf_size); width = get_bits(&s->gb, 12); @@ -1488,7 +1500,12 @@ static int mpeg1_decode_sequence(AVCodecContext *avctx, s->avctx = avctx; avctx->width = width; avctx->height = height; - avctx->frame_rate = frame_rate_tab[s->frame_rate_index]; + if (s->frame_rate_index >= 9) { + /* at least give a valid frame rate (some old mpeg1 have this) */ + avctx->frame_rate = 25 * FRAME_RATE_BASE; + } else { + avctx->frame_rate = frame_rate_tab[s->frame_rate_index]; + } s->frame_rate = avctx->frame_rate; avctx->bit_rate = s->bit_rate; @@ -1526,20 +1543,20 @@ static int mpeg1_decode_sequence(AVCodecContext *avctx, for(i=0;i<64;i++) { v = get_bits(&s->gb, 8); j = zigzag_direct[i]; - s->non_intra_matrix[j] = v; - s->chroma_non_intra_matrix[j] = v; + s->inter_matrix[j] = v; + s->chroma_inter_matrix[j] = v; } #ifdef DEBUG dprintf("non intra matrix present\n"); for(i=0;i<64;i++) - dprintf(" %d", s->non_intra_matrix[zigzag_direct[i]]); + dprintf(" %d", s->inter_matrix[zigzag_direct[i]]); printf("\n"); #endif } else { for(i=0;i<64;i++) { v = default_non_intra_matrix[i]; - s->non_intra_matrix[i] = v; - s->chroma_non_intra_matrix[i] = v; + s->inter_matrix[i] = v; + s->chroma_inter_matrix[i] = v; } } @@ -1549,6 +1566,7 @@ static int mpeg1_decode_sequence(AVCodecContext *avctx, s->picture_structure = PICT_FRAME; s->frame_pred_frame_dct = 1; s->mpeg2 = 0; + avctx->sub_id = 1; /* indicates mpeg1 */ return 0; } @@ -1566,7 +1584,7 @@ static int mpeg_decode_frame(AVCodecContext *avctx, dprintf("fill_buffer\n"); *data_size = 0; - + /* special case for last picture */ if (buf_size == 0) { if (s2->picture_number > 0) { @@ -1583,15 +1601,18 @@ static int mpeg_decode_frame(AVCodecContext *avctx, buf_ptr = buf; buf_end = buf + buf_size; - - if (s->repeat_field % 2 == 1) { + +#if 0 + 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 = sizeof(AVPicture); - goto the_end; + // s2->picture_number, s->repeat_field); + if (avctx->flags & CODEC_FLAG_REPEAT_FIELD) { + *data_size = sizeof(AVPicture); + goto the_end; + } } - +#endif while (buf_ptr < buf_end) { buf_start = buf_ptr; /* find start next code */ @@ -1641,13 +1662,27 @@ static int mpeg_decode_frame(AVCodecContext *avctx, if (ret == 1) { /* got a picture: exit */ /* first check if we must repeat the frame */ + avctx->repeat_pict = 0; +#if 0 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; + //s2->repeat_first_field = 0; + //s2->progressive_frame = 0; if (++s->repeat_field > 2) s->repeat_field = 0; + avctx->repeat_pict = 1; } +#endif + if (s2->repeat_first_field) { + if (s2->progressive_sequence) { + if (s2->top_field_first) + avctx->repeat_pict = 4; + else + avctx->repeat_pict = 2; + } else if (s2->progressive_frame) { + avctx->repeat_pict = 1; + } + } *data_size = sizeof(AVPicture); goto the_end; } |