changeset 881:d326091dae9f libavcodec

mjpegb support (need more samples)
author al3x
date Wed, 20 Nov 2002 15:18:11 +0000
parents 1c32039e7215
children 34943cb0c2fb
files allcodecs.c avcodec.h mjpeg.c
diffstat 3 files changed, 144 insertions(+), 9 deletions(-) [+]
line wrap: on
line diff
--- a/allcodecs.c	Wed Nov 20 13:08:04 2002 +0000
+++ b/allcodecs.c	Wed Nov 20 15:18:11 2002 +0000
@@ -73,6 +73,7 @@
     register_avcodec(&dvvideo_decoder);
     //    register_avcodec(&dvaudio_decoder);
     register_avcodec(&mjpeg_decoder);
+    register_avcodec(&mjpegb_decoder);
     register_avcodec(&mp2_decoder);
     register_avcodec(&mp3_decoder);
     register_avcodec(&wmav1_decoder);
--- a/avcodec.h	Wed Nov 20 13:08:04 2002 +0000
+++ b/avcodec.h	Wed Nov 20 15:18:11 2002 +0000
@@ -18,6 +18,7 @@
     CODEC_ID_VORBIS,
     CODEC_ID_AC3,
     CODEC_ID_MJPEG,
+    CODEC_ID_MJPEGB,
     CODEC_ID_MPEG4,
     CODEC_ID_RAWVIDEO,
     CODEC_ID_MSMPEG4V1,
@@ -858,6 +859,7 @@
 extern AVCodec wmav1_decoder;
 extern AVCodec wmav2_decoder;
 extern AVCodec mjpeg_decoder;
+extern AVCodec mjpegb_decoder;
 extern AVCodec mp2_decoder;
 extern AVCodec mp3_decoder;
 extern AVCodec mace3_decoder;
--- a/mjpeg.c	Wed Nov 20 13:08:04 2002 +0000
+++ b/mjpeg.c	Wed Nov 20 15:18:11 2002 +0000
@@ -17,7 +17,7 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  *
  * Support for external huffman table, various fixes (AVID workaround),
- * aspecting and new decode_frame mechanism
+ * aspecting, new decode_frame mechanism and apple mjpeg-b support
  *                                  by Alex Beregszaszi <alex@naxine.org>
  */
 //#define DEBUG
@@ -1061,7 +1061,7 @@
         h_count[0] = 1;
         v_count[0] = 1;
     }
-
+    
     for(mb_y = 0; mb_y < mb_height; mb_y++) {
         for(mb_x = 0; mb_x < mb_width; mb_x++) {
             for(i=0;i<nb_components;i++) {
@@ -1098,8 +1098,8 @@
                 }
             }
 	    /* (< 1350) buggy workaround for Spectralfan.mov, should be fixed */
-	    
-            if ((s->restart_interval < 1350) && !--s->restart_count) {
+            if (s->restart_interval && (s->restart_interval < 1350) &&
+		!--s->restart_count) {
                 align_get_bits(&s->gb);
                 skip_bits(&s->gb, 16); /* skip RSTn */
                 for (j=0; j<nb_components; j++) /* reset dc */
@@ -1373,10 +1373,6 @@
 		    {
 			UINT8 x = *(src++);
 
-#if 0
-			if (x == 0xff && *src == 0xff)
-			    break;
-#endif
 			*(dst++) = x;
 			if (x == 0xff)
 			{
@@ -1510,12 +1506,135 @@
         }
     }
 the_end:
-
     dprintf("mjpeg decode frame unused %d bytes\n", buf_end - buf_ptr);
 //    return buf_end - buf_ptr;
     return buf_ptr - buf;
 }
 
+static int mjpegb_decode_frame(AVCodecContext *avctx, 
+                              void *data, int *data_size,
+                              UINT8 *buf, int buf_size)
+{
+    MJpegDecodeContext *s = avctx->priv_data;
+    UINT8 *buf_end, *buf_ptr;
+    int i;
+    AVPicture *picture = data;
+    GetBitContext hgb; /* for the header */
+    uint32_t dqt_offs, dht_offs, sof_offs, sos_offs, second_field_offs;
+    uint32_t field_size;
+
+    *data_size = 0;
+
+    /* no supplementary picture */
+    if (buf_size == 0)
+        return 0;
+
+    buf_ptr = buf;
+    buf_end = buf + buf_size;
+    
+read_header:
+    /* reset on every SOI */
+    s->restart_interval = 0;
+
+    init_get_bits(&hgb, buf_ptr, /*buf_size*/buf_end - buf_ptr);
+
+    skip_bits(&hgb, 32); /* reserved zeros */
+    
+    if (get_bits(&hgb, 32) != be2me_32(ff_get_fourcc("mjpg")))
+    {
+	dprintf("not mjpeg-b (bad fourcc)\n");
+	return 0;
+    }
+
+    field_size = get_bits(&hgb, 32); /* field size */
+    dprintf("field size: 0x%x\n", field_size);
+    skip_bits(&hgb, 32); /* padded field size */
+    second_field_offs = get_bits(&hgb, 32);
+    dprintf("second field offs: 0x%x\n", second_field_offs);
+    if (second_field_offs)
+	s->interlaced = 1;
+
+    dqt_offs = get_bits(&hgb, 32);
+    dprintf("dqt offs: 0x%x\n", dqt_offs);
+    if (dqt_offs)
+    {
+	init_get_bits(&s->gb, buf+dqt_offs, buf_end - (buf+dqt_offs));
+	s->start_code = DQT;
+	mjpeg_decode_dqt(s);
+    }
+    
+    dht_offs = get_bits(&hgb, 32);
+    dprintf("dht offs: 0x%x\n", dht_offs);
+    if (dht_offs)
+    {
+	init_get_bits(&s->gb, buf+dht_offs, buf_end - (buf+dht_offs));
+	s->start_code = DHT;
+	mjpeg_decode_dht(s);
+    }
+
+    sof_offs = get_bits(&hgb, 32);
+    dprintf("sof offs: 0x%x\n", sof_offs);
+    if (sof_offs)
+    {
+	init_get_bits(&s->gb, buf+sof_offs, buf_end - (buf+sof_offs));
+	s->start_code = SOF0;
+	mjpeg_decode_sof0(s);
+    }
+
+    sos_offs = get_bits(&hgb, 32);
+    dprintf("sos offs: 0x%x\n", sos_offs);
+    if (sos_offs)
+    {
+//	init_get_bits(&s->gb, buf+sos_offs, buf_end - (buf+sos_offs));
+	init_get_bits(&s->gb, buf+sos_offs, field_size);
+	s->start_code = SOS;
+	mjpeg_decode_sos(s);
+    }
+
+    skip_bits(&hgb, 32); /* start of data offset */
+
+    if (s->interlaced) {
+        s->bottom_field ^= 1;
+        /* if not bottom field, do not output image yet */
+        if (s->bottom_field && second_field_offs)
+	{
+	    buf_ptr = buf + second_field_offs;
+	    second_field_offs = 0;
+	    goto read_header;
+    	}
+    }
+
+    for(i=0;i<3;i++) {
+        picture->data[i] = s->current_picture[i];
+        picture->linesize[i] = (s->interlaced) ?
+    	    s->linesize[i] >> 1 : s->linesize[i];
+    }
+    *data_size = sizeof(AVPicture);
+    avctx->height = s->height;
+    if (s->interlaced)
+        avctx->height *= 2;
+    avctx->width = s->width;
+    /* XXX: not complete test ! */
+    switch((s->h_count[0] << 4) | s->v_count[0]) {
+        case 0x11:
+    	    avctx->pix_fmt = PIX_FMT_YUV444P;
+            break;
+        case 0x21:
+            avctx->pix_fmt = PIX_FMT_YUV422P;
+            break;
+        default:
+	case 0x22:
+            avctx->pix_fmt = PIX_FMT_YUV420P;
+            break;
+    }
+    /* dummy quality */
+    /* XXX: infer it with matrix */
+    avctx->quality = 3; 
+
+    return buf_ptr - buf;
+}
+
+
 static int mjpeg_decode_end(AVCodecContext *avctx)
 {
     MJpegDecodeContext *s = avctx->priv_data;
@@ -1543,3 +1662,16 @@
     0,
     NULL
 };
+
+AVCodec mjpegb_decoder = {
+    "mjpegb",
+    CODEC_TYPE_VIDEO,
+    CODEC_ID_MJPEGB,
+    sizeof(MJpegDecodeContext),
+    mjpeg_decode_init,
+    NULL,
+    mjpeg_decode_end,
+    mjpegb_decode_frame,
+    0,
+    NULL
+};