[Mplayer-cvslog] CVS: main/libmpcodecs vd_ffmpeg.c,1.129,1.130

Roberto Togni CVS syncmail at mplayerhq.hu
Sun Aug 29 15:52:22 CEST 2004


CVS change done by Roberto Togni CVS

Update of /cvsroot/mplayer/main/libmpcodecs
In directory mail:/var2/tmp/cvs-serv30754/libmpcodecs

Modified Files:
	vd_ffmpeg.c 
Log Message:
AVC (fourcc avc1) in mp4 support


Index: vd_ffmpeg.c
===================================================================
RCS file: /cvsroot/mplayer/main/libmpcodecs/vd_ffmpeg.c,v
retrieving revision 1.129
retrieving revision 1.130
diff -u -r1.129 -r1.130
--- vd_ffmpeg.c	21 Aug 2004 19:46:24 -0000	1.129
+++ vd_ffmpeg.c	29 Aug 2004 13:52:19 -0000	1.130
@@ -72,6 +72,11 @@
     double inv_qp_sum;
     int ip_count;
     int b_count;
+    // AVC data
+    int got_avcC;
+    int nal_length_size;
+    void *data_bak;
+    int len_bak;
 } vd_ffmpeg_ctx;
 
 //#ifdef FF_POSTPROCESS
@@ -339,6 +344,10 @@
 	memcpy(avctx->extradata, ((int*)sh->ImageDesc)+1, avctx->extradata_size);
     }
     
+    if(sh->format == mmioFOURCC('a', 'v', 'c', '1')) {
+        ctx->got_avcC = 0;
+    }
+
     if(sh->bih)
 	avctx->bits_per_sample= sh->bih->biBitCount;
 
@@ -678,6 +687,36 @@
     uint32_t chunktab;	// offset to chunk offset array
 } dp_hdr_t;
 
+
+/**
+ * Add sync to a nal and queue it in buffer, increasing buffer size as needed
+ * @param dest pointer to current buffer area
+ * @param destsize pointer to size of current dest area
+ * @param source pointer to source nal data (after length bytes)
+ * @param nal_len length of nal data
+ */
+unsigned char* avc1_addnal(unsigned char *dest, int *destsize, unsigned char* source, int nal_len)
+{
+    unsigned char *temp;
+    int tempsize;
+
+    tempsize = *destsize + nal_len + 4;
+    temp = malloc (tempsize);
+    if (dest)
+        memcpy (temp, dest, *destsize);
+    temp[*destsize] = 0;
+    temp[*destsize+1] = 0;
+    temp[*destsize+2] = 0;
+    temp[*destsize+3] = 1;
+    memcpy (temp + *destsize + 4, source, nal_len);
+    if (dest)
+        free(dest);
+    *destsize = tempsize;
+
+    return temp;
+}
+
+
 // decode a frame
 static mp_image_t* decode(sh_video_t *sh,void* data,int len,int flags){
     int got_picture=0;
@@ -687,6 +726,7 @@
     AVCodecContext *avctx = ctx->avctx;
     mp_image_t* mpi=NULL;
     int dr1= ctx->do_dr1;
+    unsigned char *buf = NULL;
 
     if(len<=0) return NULL; // skipped frame
 
@@ -736,8 +776,68 @@
         data+= sizeof(dp_hdr_t);
     }
 
+    /*
+     * Convert avc1 nals to annexb nals (remove lenght, add sync)
+     * If first frame extract and process avcC (configuration data)
+     */    
+    if(sh->format == mmioFOURCC('a', 'v', 'c', '1')) {
+        int bufsize = 0;
+        int nalsize;
+        unsigned char *p = data;
+        int i;
+        int cnt, poffs;
+
+        // Remember original values
+        ctx->data_bak = data;
+        ctx->len_bak = len;
+
+        if (!ctx->got_avcC) {
+            // Parse some parts of avcC, just for fun :)
+            mp_msg(MSGT_DECVIDEO, MSGL_V, "[ffmpeg] avcC version: %d\n", *(p));
+            mp_msg(MSGT_DECVIDEO, MSGL_V, "[ffmpeg] avcC profile: %d\n", *(p+1));
+            mp_msg(MSGT_DECVIDEO, MSGL_V, "[ffmpeg] avcC profile compatibility: %d\n", *(p+2));
+            mp_msg(MSGT_DECVIDEO, MSGL_V, "[ffmpeg] avcC level: %d\n", *(p+3));
+            mp_msg(MSGT_DECVIDEO, MSGL_V, "[ffmpeg] avcC nal length size: %d\n", ctx->nal_length_size = ((*(p+4))&0x03)+1);
+            mp_msg(MSGT_DECVIDEO, MSGL_V, "[ffmpeg] avcC number of sequence param sets: %d\n", cnt = (*(p+5) & 0x1f));
+            poffs = 6;
+            for (i = 0; i < cnt; i++) {
+                mp_msg(MSGT_DECVIDEO, MSGL_V, "[ffmpeg] avcC sps %d have length %d\n", i, nalsize = BE_16(p+poffs));
+                buf = avc1_addnal(buf, &bufsize, p + poffs + 2, nalsize);
+                poffs += nalsize + 2;
+            }
+            mp_msg(MSGT_DECVIDEO, MSGL_V, "[ffmpeg] avcC number of picture param sets: %d\n", *(p+poffs));
+            poffs++;
+            for (i = 0; i < cnt; i++) {
+                mp_msg(MSGT_DECVIDEO, MSGL_V, "[ffmpeg] avcC pps %d have length %d\n", i, nalsize = BE_16(p+poffs));
+                buf = avc1_addnal(buf, &bufsize, p + poffs + 2, nalsize);
+                poffs += nalsize + 2;
+            }
+            p += poffs;
+            ctx->got_avcC = 1;
+        }
+
+        while (p < (data + len)) {
+            nalsize = 0;
+            for(i = 0; i < ctx->nal_length_size; i++)
+                nalsize = (nalsize << 8) | (*p++);
+            mp_msg(MSGT_DECVIDEO, MSGL_DBG2, "[ffmpeg] avc1: nalsize = %d\n", nalsize);
+            buf = avc1_addnal(buf, &bufsize, p, nalsize);
+            p += nalsize;
+            len -= nalsize;
+        }
+        data = buf;
+        len = bufsize;
+    }
+
     ret = avcodec_decode_video(avctx, pic,
 	     &got_picture, data, len);
+
+    if(sh->format == mmioFOURCC('a', 'v', 'c', '1')) {
+        free(buf);
+        data = ctx->data_bak;
+        len = ctx->len_bak;
+    }
+
     dr1= ctx->do_dr1;
     if(ret<0) mp_msg(MSGT_DECVIDEO,MSGL_WARN, "Error while decoding frame!\n");
 //printf("repeat: %d\n", pic->repeat_pict);




More information about the MPlayer-cvslog mailing list