]> git.sesse.net Git - ffmpeg/blobdiff - libavcodec/mpeg12.c
better non conformant divx packed bitstream detection, so unpacked (no b frames)...
[ffmpeg] / libavcodec / mpeg12.c
index c7622e86ece10ae0124fc08f08f77f4e7c55d2f6..37d9243029a57ff7f22aab357cb0b4bd6616d141 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * MPEG1 encoder / MPEG2 decoder
+ * MPEG1 codec / MPEG2 decoder
  * Copyright (c) 2000,2001 Fabrice Bellard.
  *
  * This library is free software; you can redistribute it and/or
  * License along with this library; if not, write to the Free Software
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
+/**
+ * @file mpeg12.c
+ * MPEG1 codec / MPEG2 decoder.
+ */
 //#define DEBUG
 #include "avcodec.h"
 #include "dsputil.h"
@@ -197,8 +203,10 @@ static void mpeg1_encode_sequence_header(MpegEncContext *s)
                 int i, dmin, d;
                 s->frame_rate_index = 0;
                 dmin = 0x7fffffff;
-                for(i=1;i<9;i++) {
-                    d = abs(s->frame_rate - frame_rate_tab[i]);
+                for(i=1;i<14;i++) {
+                    if(s->avctx->strict_std_compliance >= 0 && i>=9) break;
+                     
+                    d = abs(MPEG1_FRAME_RATE_BASE*(int64_t)s->avctx->frame_rate/s->avctx->frame_rate_base - frame_rate_tab[i]);
                     if (d < dmin) {
                         dmin = d;
                         s->frame_rate_index = i;
@@ -221,7 +229,7 @@ static void mpeg1_encode_sequence_header(MpegEncContext *s)
             
             put_bits(&s->pb, 4, s->aspect_ratio_info);
             put_bits(&s->pb, 4, s->frame_rate_index);
-            v = s->bit_rate / 400;
+            v = (s->bit_rate + 399) / 400;
             if (v > 0x3ffff)
                 v = 0x3ffff;
             put_bits(&s->pb, 18, v);
@@ -242,22 +250,22 @@ static void mpeg1_encode_sequence_header(MpegEncContext *s)
             /* time code : we must convert from the real frame rate to a
                fake mpeg frame rate in case of low frame rate */
             fps = frame_rate_tab[s->frame_rate_index];
-            time_code = (int64_t)s->fake_picture_number * FRAME_RATE_BASE;
+            time_code = (int64_t)s->fake_picture_number * MPEG1_FRAME_RATE_BASE;
             s->gop_picture_number = s->fake_picture_number;
             put_bits(&s->pb, 5, (uint32_t)((time_code / (fps * 3600)) % 24));
             put_bits(&s->pb, 6, (uint32_t)((time_code / (fps * 60)) % 60));
             put_bits(&s->pb, 1, 1);
             put_bits(&s->pb, 6, (uint32_t)((time_code / fps) % 60));
-            put_bits(&s->pb, 6, (uint32_t)((time_code % fps) / FRAME_RATE_BASE));
+            put_bits(&s->pb, 6, (uint32_t)((time_code % fps) / MPEG1_FRAME_RATE_BASE));
             put_bits(&s->pb, 1, 1); /* closed gop */
             put_bits(&s->pb, 1, 0); /* broken link */
         }
 
-        if (s->frame_rate < (24 * FRAME_RATE_BASE) && s->picture_number > 0) {
+        if (s->avctx->frame_rate < (24 * s->avctx->frame_rate_base) && s->picture_number > 0) {
             /* insert empty P pictures to slow down to the desired
                frame rate. Each fake pictures takes about 20 bytes */
             fps = frame_rate_tab[s->frame_rate_index];
-            n = (((int64_t)s->picture_number * fps) / s->frame_rate) - 1;
+            n = av_rescale((int64_t)s->picture_number * s->avctx->frame_rate_base, fps, s->avctx->frame_rate) / MPEG1_FRAME_RATE_BASE - 1;
             while (s->fake_picture_number < n) {
                 mpeg1_skip_picture(s, s->fake_picture_number - 
                                    s->gop_picture_number); 
@@ -1023,8 +1031,8 @@ static int mpeg_decode_mb(MpegEncContext *s,
                     }
                     break;
                 case MT_FIELD:
+                    s->mv_type = MV_TYPE_FIELD;
                     if (s->picture_structure == PICT_FRAME) {
-                        s->mv_type = MV_TYPE_FIELD;
                         for(j=0;j<2;j++) {
                             s->field_select[i][j] = get_bits1(&s->gb);
                             val = mpeg_decode_motion(s, s->mpeg_f_code[i][0],
@@ -1039,7 +1047,6 @@ static int mpeg_decode_mb(MpegEncContext *s,
                             dprintf("fmy=%d\n", val);
                         }
                     } else {
-                        s->mv_type = MV_TYPE_16X16;
                         s->field_select[i][0] = get_bits1(&s->gb);
                         for(k=0;k<2;k++) {
                             val = mpeg_decode_motion(s, s->mpeg_f_code[i][k],
@@ -1633,8 +1640,13 @@ static void mpeg_decode_sequence_extension(MpegEncContext *s)
     s->low_delay = get_bits1(&s->gb);
     frame_rate_ext_n = get_bits(&s->gb, 2);
     frame_rate_ext_d = get_bits(&s->gb, 5);
-    if (frame_rate_ext_d >= 1)
-        s->frame_rate = (s->frame_rate * frame_rate_ext_n) / frame_rate_ext_d;
+    av_reduce(
+        &s->avctx->frame_rate, 
+        &s->avctx->frame_rate_base, 
+        frame_rate_tab[s->frame_rate_index] * (frame_rate_ext_n+1),
+        MPEG1_FRAME_RATE_BASE * (frame_rate_ext_d+1),
+        1<<30);
+
     dprintf("sequence extension\n");
     s->mpeg2 = 1;
     s->avctx->sub_id = 2; /* indicates mpeg2 found */
@@ -1653,7 +1665,7 @@ static void mpeg_decode_quant_matrix_extension(MpegEncContext *s)
     if (get_bits1(&s->gb)) {
         for(i=0;i<64;i++) {
             v = get_bits(&s->gb, 8);
-            j= s->idct_permutation[ ff_zigzag_direct[i] ];
+            j= s->dsp.idct_permutation[ ff_zigzag_direct[i] ];
             s->intra_matrix[j] = v;
             s->chroma_intra_matrix[j] = v;
         }
@@ -1661,7 +1673,7 @@ static void mpeg_decode_quant_matrix_extension(MpegEncContext *s)
     if (get_bits1(&s->gb)) {
         for(i=0;i<64;i++) {
             v = get_bits(&s->gb, 8);
-            j= s->idct_permutation[ ff_zigzag_direct[i] ];
+            j= s->dsp.idct_permutation[ ff_zigzag_direct[i] ];
             s->inter_matrix[j] = v;
             s->chroma_inter_matrix[j] = v;
         }
@@ -1669,14 +1681,14 @@ static void mpeg_decode_quant_matrix_extension(MpegEncContext *s)
     if (get_bits1(&s->gb)) {
         for(i=0;i<64;i++) {
             v = get_bits(&s->gb, 8);
-            j= s->idct_permutation[ ff_zigzag_direct[i] ];
+            j= s->dsp.idct_permutation[ ff_zigzag_direct[i] ];
             s->chroma_intra_matrix[j] = v;
         }
     }
     if (get_bits1(&s->gb)) {
         for(i=0;i<64;i++) {
             v = get_bits(&s->gb, 8);
-            j= s->idct_permutation[ ff_zigzag_direct[i] ];
+            j= s->dsp.idct_permutation[ ff_zigzag_direct[i] ];
             s->chroma_inter_matrix[j] = v;
         }
     }
@@ -1701,6 +1713,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);
     
+    if(s->picture_structure == PICT_FRAME)
+        s->first_field=0;
+    else{
+        s->first_field ^= 1;
+        memset(s->mbskip_table, 0, s->mb_width*s->mb_height);
+    }
+    
     if(s->alternate_scan){
         ff_init_scantable(s, &s->inter_scantable  , ff_alternate_vertical_scan);
         ff_init_scantable(s, &s->intra_scantable  , ff_alternate_vertical_scan);
@@ -1771,6 +1790,7 @@ static int mpeg_decode_slice(AVCodecContext *avctx,
     Mpeg1Context *s1 = avctx->priv_data;
     MpegEncContext *s = &s1->mpeg_enc_ctx;
     int ret;
+    const int field_pic= s->picture_structure != PICT_FRAME;
 
     start_code = (start_code - 1) & 0xff;
     if (start_code >= s->mb_height){
@@ -1781,12 +1801,27 @@ static int mpeg_decode_slice(AVCodecContext *avctx,
     s->last_dc[1] = s->last_dc[0];
     s->last_dc[2] = s->last_dc[0];
     memset(s->last_mv, 0, sizeof(s->last_mv));
+        
     /* start frame decoding */
     if (s->first_slice) {
-        s->first_slice = 0;
+      if(s->first_field || s->picture_structure==PICT_FRAME){
         if(MPV_frame_start(s, avctx) < 0)
             return DECODE_SLICE_FATAL_ERROR;
-            
+        /* first check if we must repeat the frame */
+        s->current_picture.repeat_pict = 0;
+
+        if (s->repeat_first_field) {
+            if (s->progressive_sequence) {
+                if (s->top_field_first)
+                    s->current_picture.repeat_pict = 4;
+                else
+                    s->current_picture.repeat_pict = 2;
+            } else if (s->progressive_frame) {
+                s->current_picture.repeat_pict = 1;
+            }
+        }         
+//        printf("%d \n", s->current_picture.repeat_pict);
+
         if(s->avctx->debug&FF_DEBUG_PICT_INFO){
              printf("qp:%d fc:%2d%2d%2d%2d %s %s %s %s dc:%d pstruct:%d fdct:%d cmv:%d qtype:%d ivlc:%d rff:%d %s\n", 
                  s->qscale, s->mpeg_f_code[0][0],s->mpeg_f_code[0][1],s->mpeg_f_code[1][0],s->mpeg_f_code[1][1],
@@ -1795,7 +1830,17 @@ static int mpeg_decode_slice(AVCodecContext *avctx,
                  s->intra_dc_precision, s->picture_structure, s->frame_pred_frame_dct, s->concealment_motion_vectors,
                  s->q_scale_type, s->intra_vlc_format, s->repeat_first_field, s->chroma_420_type ? "420" :"");
         }
+      }else{ //second field
+            int i;
+            for(i=0; i<4; i++){
+                s->current_picture.data[i] = s->current_picture_ptr->data[i];
+                if(s->picture_structure == PICT_BOTTOM_FIELD){
+                    s->current_picture.data[i] += s->current_picture_ptr->linesize[i];
+                } 
+            }
+      }
     }
+    s->first_slice = 0;
 
     init_get_bits(&s->gb, buf, buf_size*8);
 
@@ -1830,11 +1875,17 @@ static int mpeg_decode_slice(AVCodecContext *avctx,
         dprintf("ret=%d\n", ret);
         if (ret < 0)
             return -1;
-    
+        
         MPV_decode_mb(s, s->block);
 
         if (++s->mb_x >= s->mb_width) {
-            ff_draw_horiz_band(s);
+            if(s->picture_structure==PICT_FRAME){
+                ff_draw_horiz_band(s, 16*s->mb_y, 16);
+            }else{
+                if(!s->first_field){
+                    ff_draw_horiz_band(s, 32*s->mb_y, 32);
+                }
+            }
 
             s->mb_x = 0;
             s->mb_y++;
@@ -1861,7 +1912,7 @@ static int mpeg_decode_slice(AVCodecContext *avctx,
                 }
             }
         }
-        if(s->mb_y >= s->mb_height){
+        if(s->mb_y<<field_pic >= s->mb_height){
             fprintf(stderr, "slice too long\n");
             return DECODE_SLICE_ERROR;
         }
@@ -1869,10 +1920,9 @@ static int mpeg_decode_slice(AVCodecContext *avctx,
 eos: //end of slice
     
     emms_c();
-
+//intf("%d %d %d %d\n", s->mb_y, s->mb_height, s->pict_type, s->picture_number);
     /* end of slice reached */
-    if (/*s->mb_x == 0 &&*/
-        s->mb_y == s->mb_height) {
+    if (s->mb_y<<field_pic == s->mb_height && !s->first_field) {
         /* end of image */
 
         if(s->mpeg2)
@@ -1886,7 +1936,7 @@ eos: //end of slice
             s->picture_number++;
             /* latency of 1 frame for I and P frames */
             /* XXX: use another variable than picture_number */
-            if (s->last_picture.data[0] == NULL) {
+            if (s->last_picture_ptr == NULL) {
                 return DECODE_SLICE_OK;
             } else {
                 *pict= *(AVFrame*)&s->last_picture;
@@ -1938,13 +1988,13 @@ static int mpeg1_decode_sequence(AVCodecContext *avctx,
         s->avctx = avctx;
         avctx->width = width;
         avctx->height = height;
-        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;
+        av_reduce(
+            &avctx->frame_rate, 
+            &avctx->frame_rate_base,
+            frame_rate_tab[s->frame_rate_index],
+            MPEG1_FRAME_RATE_BASE, //FIXME store in allready reduced form 
+            1<<30
+            );
         avctx->bit_rate = s->bit_rate;
         
         if (MPV_common_init(s) < 0)
@@ -1971,7 +2021,7 @@ static int mpeg1_decode_sequence(AVCodecContext *avctx,
 #endif
     } else {
         for(i=0;i<64;i++) {
-            int j= s->idct_permutation[i];
+            int j= s->dsp.idct_permutation[i];
             v = ff_mpeg1_default_intra_matrix[i];
             s->intra_matrix[j] = v;
             s->chroma_intra_matrix[j] = v;
@@ -1992,7 +2042,7 @@ static int mpeg1_decode_sequence(AVCodecContext *avctx,
 #endif
     } else {
         for(i=0;i<64;i++) {
-            int j= s->idct_permutation[i];
+            int j= s->dsp.idct_permutation[i];
             v = ff_mpeg1_default_non_intra_matrix[i];
             s->inter_matrix[j] = v;
             s->chroma_inter_matrix[j] = v;
@@ -2009,6 +2059,35 @@ static int mpeg1_decode_sequence(AVCodecContext *avctx,
     return 0;
 }
 
+static void mpeg_decode_user_data(AVCodecContext *avctx, 
+                                  const uint8_t *buf, int buf_size)
+{
+    const uint8_t *p;
+    int len, flags;
+    p = buf;
+    len = buf_size;
+
+    /* we parse the DTG active format information */
+    if (len >= 5 &&
+        p[0] == 'D' && p[1] == 'T' && p[2] == 'G' && p[3] == '1') {
+        flags = p[4];
+        p += 5;
+        len -= 5;
+        if (flags & 0x80) {
+            /* skip event id */
+            if (len < 2)
+                return;
+            p += 2;
+            len -= 2;
+        }
+        if (flags & 0x40) {
+            if (len < 1)
+                return;
+            avctx->dtg_active_format = p[0] & 0x0f;
+        }
+    }
+}
+
 /* handle buffering and image synchronisation */
 static int mpeg_decode_frame(AVCodecContext *avctx, 
                              void *data, int *data_size,
@@ -2099,12 +2178,16 @@ static int mpeg_decode_frame(AVCodecContext *avctx,
                     mpeg_decode_extension(avctx,
                                           s->buffer, input_size);
                     break;
+                case USER_START_CODE:
+                    mpeg_decode_user_data(avctx, 
+                                          s->buffer, input_size);
+                    break;
                 default:
                     if (start_code >= SLICE_MIN_START_CODE &&
                         start_code <= SLICE_MAX_START_CODE) {
                         
                         /* skip b frames if we dont have reference frames */
-                        if(s2->last_picture.data[0]==NULL && s2->pict_type==B_TYPE) break;
+                        if(s2->last_picture_ptr==NULL && s2->pict_type==B_TYPE) break;
                         /* skip b frames if we are in a hurry */
                         if(avctx->hurry_up && s2->pict_type==B_TYPE) break;
                         /* skip everything if we are in a hurry>=5 */
@@ -2112,30 +2195,8 @@ static int mpeg_decode_frame(AVCodecContext *avctx,
 
                         ret = mpeg_decode_slice(avctx, picture,
                                                 start_code, s->buffer, input_size);
+
                         if (ret == DECODE_SLICE_EOP) {
-                            /* 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;
-                                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;
                         }else if(ret<0){