[XviD-devel] Data partitioning for encoder

sigdrak sigdrak at free.fr
Mon Apr 18 20:44:32 CEST 2005


Hello,

the attached patch should provide data partitioning abilities to the 
encoder. For reasons stated later in the mail, this patch may not apply 
cleanly - I haven't investigated much what gets broken otherwise. I 
tested IP...P sequences using mplayer. B frames should not be affected 
by data partitioning, per the standard. I could have tested with MoMuSys 
but I prefered saving myself the trouble and submit this patch right away.

For this I introduced:
- 2 additional bitstream in the encoder creator and frame structure
- 2 additional flags for signaling data partitioning (at the encoder 
level and the frame level)
- a function to concatenate bitstreams.
- a modification of functions in mbcoding.c to write in the proper 
bitstreams

For info, the bitstream should look (from my recollection of my code) 
like this with data partitioning:
- I MB: (mcbpc,dquant,interlace,dc) DC_MARKER (ac_pred_flag,ac)
- P intra MB: (mcbpc) DC_MARKER (dquant,interlace,dc) (ac_pred_flag, ac)
- P inter MB: (mcbpc,mc_sel,MV) MOTION_MARKER (cbpy,dquant,interlace) 
(coeffs)

I also wrote functions which are not used yet (or ever) and which I hope 
are self-explaining names:
- BitStreamWriteStartOfVideoPacket
- BitstreamWriteGroupOfVopHeader
- BitstreamWriteEndOfSequence
About the two last: I suspect that AVI or proper frame cutting is 
responsible for them not being used, and a new VOL is used instead of a GOV.

Globally, I had trouble with indentation: code uses tabs and not spaces 
(this is left for trolling on other occasions). So, I hope it won't 
break up too many things. Otherwise, I'd be interested if someone has 
set up a XVID coding style profile for vi or emacs famillies (see 
indentation remark).

I have decoder-side pending code, but unfortunately, it is merged with 
work on video packetization. I'd prefer not to go through the trouble of 
making a proper patch for the decoder, as data partitioning and video 
packetiztion get deeply tied at some point. Therefore, I'd prefer to see 
the present patch merged first.

By the way, my packetization seems to work on both encoder and decoder 
sides, but I haven't tested it yet on B-frames. I'm opting for a packet 
size parameter, as the profiles rather state this limit over any other.
Packetization or data partitioning or normal coding all work separately, 
but packetization+data partitioning still fails.

A proper design however is needed:
- bumping API, bitstream and any other version
- plugin interfaces for controlling the packetization process
- proper encoder/decoder interfaces based on video packets instead of 
full-frame en/decoding
- a plugin specialized in enforcing the video packet sizes whenever 
video packetization is used and a profile is selected

Regards,
sigdrak.
-------------- next part --------------
Index: src/encoder.c
===================================================================
RCS file: /xvid/xvidcore/src/encoder.c,v
retrieving revision 1.117
diff -B -b -d -u -r1.117 encoder.c
--- src/encoder.c	27 Mar 2005 03:59:42 -0000	1.117
+++ src/encoder.c	9 Apr 2005 18:22:04 -0000
@@ -54,10 +54,14 @@
  ****************************************************************************/
 
 static int FrameCodeI(Encoder * pEnc,
-					  Bitstream * bs);
+                      Bitstream * bs,
+                      void *buff2,
+                      void *buf_tex);
 
 static int FrameCodeP(Encoder * pEnc,
-					  Bitstream * bs);
+                      Bitstream * bs,
+                      void *buff2,
+                      void *buf_tex);
 
 static void FrameCodeB(Encoder * pEnc,
 					   FRAMEINFO * frame,
@@ -1102,7 +1106,7 @@
 				pEnc->queue_head, pEnc->queue_tail, pEnc->queue_size);
 				pEnc->mbParam.frame_drop_ratio = -1; /* it must be a coded vop */
 
-				FrameCodeP(pEnc, &bs);
+				FrameCodeP(pEnc, &bs, xFrame->secondary_bitstream, xFrame->texture_bitstream);
 
 
 				if ((pEnc->mbParam.global_flags & XVID_GLOBAL_PACKED) && pEnc->bframenum_tail==0) {
@@ -1329,7 +1333,7 @@
 				   pEnc->mbParam.edged_width, pEnc->mbParam.height);
 		}
 
-		FrameCodeI(pEnc, &bs);
+		FrameCodeI(pEnc, &bs, xFrame->secondary_bitstream, xFrame->texture_bitstream);
 		xFrame->out_flags |= XVID_KEYFRAME;
 
 	/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -1351,7 +1355,7 @@
 				   pEnc->mbParam.edged_width, pEnc->mbParam.height);
 		}
 
-		if ( FrameCodeP(pEnc, &bs) == 0 ) {
+		if ( FrameCodeP(pEnc, &bs, xFrame->secondary_bitstream, xFrame->texture_bitstream) == 0 ) {
 			/* N-VOP, we mustn't code b-frames yet */
 			call_plugins(pEnc, pEnc->current, &pEnc->sOriginal, XVID_PLG_AFTER, 0, 0, stats);
 			goto done;
@@ -1435,8 +1439,13 @@
 
 static int
 FrameCodeI(Encoder * pEnc,
-		   Bitstream * bs)
+           Bitstream * bs,
+           void *buf2,
+           void *buf_tex)
 {
+        Bitstream bs2_instance, *bs2 = NULL; /* Second part of headers */
+        Bitstream bs_tex_instance, *bs_tex = NULL; /* Texture bitstream */
+
 	int bits = BitstreamPos(bs);
 	int mb_width = pEnc->mbParam.mb_width;
 	int mb_height = pEnc->mbParam.mb_height;
@@ -1450,11 +1459,45 @@
 	pEnc->current->rounding_type = pEnc->mbParam.m_rounding_type;
 	pEnc->current->coding_type = I_VOP;
 
+        /* TODO: allow dynamic setting of the data partitioning */
+        if (pEnc->mbParam.global_flags & XVID_GLOBAL_DATA_PARTITIONING) {
+                pEnc->current->vop_flags |= XVID_VOP_DATA_PARTITIONED;
+        }
+
+        /* Set it for data paritioning */
+        if (pEnc->current->vop_flags & XVID_VOP_DATA_PARTITIONED)
+        {
+                /* bs2 uses secondary_bitstream, so the application could use
+                 * that to split back the frame into packets.
+                 * TODO: Implement a callback for GOB/VideoPacket
+                 */
+                bs2 = &bs2_instance;
+                bs_tex = &bs_tex_instance;
+                BitstreamInit(bs2, buf2, 0);
+                BitstreamInit(bs_tex, buf_tex, 0);
+                BitstreamPutBits(bs2, DC_MARKER, 19);
+                DPRINTF(XVID_DEBUG_HEADER, "Data partitioned I frame\n");
+        }
+        else
+        {
+                bs2 = bs;
+                bs_tex = bs;
+        }
+        
 	call_plugins(pEnc, pEnc->current, NULL, XVID_PLG_FRAME, NULL, NULL, NULL);
 
 	SetMacroblockQuants(&pEnc->mbParam, pEnc->current);
 
+#if 1
 	BitstreamWriteVolHeader(bs, &pEnc->mbParam, pEnc->current);
+#else
+        /* Probably don't cope well with AVI frame cuts */
+        if (pEnc->m_framenum == 0)
+                BitstreamWriteVolHeader(bs, &pEnc->mbParam, pEnc->current);
+        else
+                BitstreamWriteGroupOfVopHeader(bs, &pEnc->mbParam,
+                                               pEnc->global_flags&XVID_GLOBAL_CLOSED_GOP);
+#endif
 
 	set_timecodes(pEnc->current,pEnc->reference,pEnc->mbParam.fbase);
 
@@ -1481,10 +1524,16 @@
 			stop_prediction_timer();
 
 			start_timer();
-			MBCoding(pEnc->current, pMB, qcoeff, bs, &pEnc->current->sStat);
+			MBCoding(pEnc->current, pMB, qcoeff, bs, bs2, bs_tex, &pEnc->current->sStat);
 			stop_coding_timer();
 		}
 
+        if (pEnc->current->vop_flags & XVID_VOP_DATA_PARTITIONED) {
+                /* The resynch marker isn't byte-aligned !! */
+                BitstreamsConcatenate(bs, bs2, 0);
+                BitstreamsConcatenate(bs, bs_tex, 0);
+        }
+
 	emms();
 
 	BitstreamPadAlways(bs); /* next_start_code() at the end of VideoObjectPlane() */
@@ -1529,8 +1578,13 @@
 /* FrameCodeP also handles S(GMC)-VOPs */
 static int
 FrameCodeP(Encoder * pEnc,
-		   Bitstream * bs)
+           Bitstream * bs,
+           void *buf2,
+           void *buf_tex)
 {
+    Bitstream bs2_instance, *bs2; /* Second part of headers */
+    Bitstream bs_tex_instance, *bs_tex; /* Texture bitstream */
+
 	int bits = BitstreamPos(bs);
 
 	DECLARE_ALIGNED_MATRIX(dct_codes, 6, 64, int16_t, CACHE_LINE);
@@ -1546,6 +1600,31 @@
 
 	IMAGE *pRef = &reference->image;
 
+    /* TODO: allow dynamic setting of the data partitioning */
+    if (pEnc->mbParam.global_flags & XVID_GLOBAL_DATA_PARTITIONING) {
+        pEnc->current->vop_flags |= XVID_VOP_DATA_PARTITIONED;
+    }
+
+    /* Set it for data paritioning */
+    if (pEnc->current->vop_flags & XVID_VOP_DATA_PARTITIONED)
+    {
+        /* bs2 uses secondary_bitstream, so the application could use
+         * that to split back the frame into packets.
+         * TODO: Implement a callback for GOB/VideoPacket
+         */
+        bs2 = &bs2_instance;
+        bs_tex = &bs_tex_instance;
+        BitstreamInit(bs2, buf2, 0);
+        BitstreamInit(bs_tex, buf_tex, 0);
+        BitstreamPutBits(bs2, MOTION_MARKER, 17);
+        DPRINTF(XVID_DEBUG_HEADER, "Data partitioned P frame\n");
+    }
+    else
+    {
+        bs2 = bs;
+        bs_tex = bs;
+    }
+    
 	if (!reference->is_edged) {	
 		start_timer();
 		image_setedges(pRef, pParam->edged_width, pParam->edged_height,
@@ -1658,7 +1737,7 @@
 
 				current->sStat.kblks++;
 
-				MBCoding(current, pMB, qcoeff, bs, &current->sStat);
+				MBCoding(current, pMB, qcoeff, bs, bs2, bs_tex, &current->sStat);
 				stop_coding_timer();
 				continue;
 			}
@@ -1748,7 +1827,7 @@
 			}
 
 			/* ordinary case: normal coded INTER/INTER4V block */
-			MBCoding(current, pMB, qcoeff, bs, &pEnc->current->sStat);
+			MBCoding(current, pMB, qcoeff, bs, bs2, bs_tex, &pEnc->current->sStat);
 			stop_coding_timer();
 		}
 	}
@@ -1767,7 +1846,8 @@
 		current->sStat.kblks = current->sStat.mblks = 0;
 		current->sStat.ublks = mb_width * mb_height;
 
-		BitstreamReset(bs);
+                /* XXX: what if the bitstreams are used for packetization */
+		BitstreamReset(bs); /* No need to reset other bitstreams */
 
 		set_timecodes(current,reference,pParam->fbase);
 		BitstreamWriteVopHeader(bs, &pEnc->mbParam, current, 0, current->mbs[0].quant);
@@ -1796,6 +1876,12 @@
 		image_swap(&pEnc->vInterHV, &pEnc->f_refhv);
 	}
 
+        if (pEnc->current->vop_flags & XVID_VOP_DATA_PARTITIONED) {
+                /* The resynch marker isn't byte-aligned !! */
+                BitstreamsConcatenate(bs, bs2, 0);
+                BitstreamsConcatenate(bs, bs_tex, 0);
+        }
+
 	/* XXX: debug
 	{
 		char s[100];
Index: src/xvid.h
===================================================================
RCS file: /xvid/xvidcore/src/xvid.h,v
retrieving revision 1.50
diff -B -b -d -u -r1.50 xvid.h
--- src/xvid.h	4 Apr 2005 23:49:37 -0000	1.50
+++ src/xvid.h	9 Apr 2005 18:22:04 -0000
@@ -595,6 +595,7 @@
 #endif
 #define XVID_GLOBAL_DIVX5_USERDATA    (1<<5) /* write divx5 userdata string 
                                                 this is implied if XVID_GLOBAL_PACKED is set */
+#define XVID_GLOBAL_DATA_PARTITIONING (1<<6) /* Use data partitioning */
 
 /*----------------------------------------------------------------------------
  * "VOL" flags
@@ -630,6 +631,7 @@
 #define XVID_VOP_MODEDECISION_RD      (1<< 8) /* enable DCT-ME and use it for mode decision */
 #define XVID_VOP_FAST_MODEDECISION_RD (1<<12) /* use simplified R-D mode decision */
 #define XVID_VOP_RD_BVOP              (1<<13) /* enable rate-distortion mode decision in b-frames */
+#define XVID_VOP_DATA_PARTITIONED     (1<<14) /* per-frame data partitioning signal */
 
 /* Only valid for vol_flags|=XVID_VOL_INTERLACING */
 #define XVID_VOP_TOPFIELDFIRST        (1<< 9) /* set top-field-first flag  */
@@ -775,11 +777,17 @@
 	int bframe_threshold;
 
 	void *bitstream;                   /* [in:opt] bitstream ptr (written to)*/
-	int length;                        /* [in:opt] bitstream length (bytes) */
+	void *secondary_bitstream;         /* [in:opt] secondary bitstream ptr (written to)*/
+	void *texture_bitstream;           /* [in:opt] texture bitstream ptr (written to)*/
+        int length;                        /* [in:opt] total bitstream length (bytes) */
 
 	int out_flags;                     /* [out] bitstream output flags */
 } xvid_enc_frame_t;
 
+/* Markers */
+#define DC_MARKER     0x6B001
+#define MOTION_MARKER 0x1F001
+
 #ifdef __cplusplus
 }
 #endif
Index: src/bitstream/bitstream.c
===================================================================
RCS file: /xvid/xvidcore/src/bitstream/bitstream.c,v
retrieving revision 1.49
diff -B -b -d -u -r1.49 bitstream.c
--- src/bitstream/bitstream.c	27 Mar 2005 03:59:42 -0000	1.49
+++ src/bitstream/bitstream.c	9 Apr 2005 18:22:04 -0000
@@ -702,7 +702,8 @@
 
 				BitstreamSkip(bs, 1);	/* resync_marker_disable */
 
-				if (BitstreamGetBit(bs))	/* data_partitioned */
+                dec->data_partitioning = BitstreamGetBit(bs);
+				if (dec->data_partitioning)	/* data_partitioned */
 				{
 					DPRINTF(XVID_DEBUG_ERROR, "data_partitioned not supported\n");
 					BitstreamSkip(bs, 1);	/* reversible_vlc */
@@ -1239,7 +1240,16 @@
 
 	BitstreamPutBit(bs, 1);		/* complexity_estimation_disable */
 	BitstreamPutBit(bs, 1);		/* resync_marker_disable */
-	BitstreamPutBit(bs, 0);		/* data_partitioned */
+        
+    if (frame->vop_flags & XVID_VOP_DATA_PARTITIONED) {
+        BitstreamPutBit(bs, 1); /* data_partitioned */
+        BitstreamPutBit(bs, 0); /* not use_reversible_vlc */
+        DPRINTF(XVID_DEBUG_HEADER, "Using data partitioning\n");
+    }
+    else
+    {
+        BitstreamPutBit(bs, 0); /* not data_partitioned */
+    }
 
 	if (vol_ver_id != 1) {
 		BitstreamPutBit(bs, 0);		/* newpred_enable */
@@ -1271,6 +1281,31 @@
 	}
 }
 
+/*
+  write group of vops header
+  XXX: we should get FRAMEINFO.seconds ...
+*/
+void
+BitstreamWriteGroupOfVopHeader(Bitstream * const bs,
+                               const MBParam * pParam,
+                               uint32_t is_closed_gov)
+{
+        int64_t time = (pParam->m_stamp + (pParam->fbase/2)) / pParam->fbase;
+        int hours, minutes, seconds;
+
+        /* compute time_code */
+        seconds = time % 60; time /= 60;
+        minutes = time % 60; time /= 60;
+        hours = time % 24; /* don't overflow */
+            
+        BitstreamPutBits(bs, GRPOFVOP_START_CODE, 32);
+        BitstreamPutBits(bs, hours, 5);
+        BitstreamPutBits(bs, minutes, 6);
+        BitstreamPutBit(bs, 1);
+        BitstreamPutBits(bs, seconds, 6);
+        BitstreamPutBits(bs, is_closed_gov, 1);
+        BitstreamPutBits(bs, 0, 1); /* broken_link */
+}
 
 /*
   write vop header
@@ -1401,3 +1436,41 @@
 	}
 
 }
+
+void
+BitstreamWriteEndOfSequence(Bitstream * const bs)
+{
+        BitstreamPad(bs);
+	BitstreamPutBits(bs, VISOBJSEQ_STOP_CODE, 32);
+}
+
+void BitStreamWriteStartOfVideoPacket(Bitstream * const bs,
+                                      const MBParam * pParam,
+                                      const FRAMEINFO * const frame,
+                                      unsigned int quant,
+                                      uint32_t macroblock_number)
+{
+        int rm_length = 0; /* resynch marker length */
+        uint32_t i;
+
+        BitstreamPad(bs);
+
+        /* Set total resynch marker length ('0's followed by '1') */
+        switch(frame->coding_type) {
+        case I_VOP: rm_length = 17; break;
+        case P_VOP:
+        case S_VOP: rm_length = 16+frame->fcode; break;
+        case B_VOP: rm_length = MAX(18, 17+frame->fcode); break;
+        default: DPRINTF(XVID_DEBUG_HEADER, "type=%i", quant);
+        }
+        /* Write it */
+        BitstreamPutBits(bs, 1, rm_length);
+
+        /* Write macroblock number */
+        BitstreamPutBits(bs, macroblock_number,
+                         log2bin(pParam->mb_width *  pParam->mb_height - 1));
+
+        
+        BitstreamPutBits(bs, quant, 5); /* quant_scale */
+        BitstreamPutBits(bs, 0, 1); /* No HEC */
+};
Index: src/bitstream/bitstream.h
===================================================================
RCS file: /xvid/xvidcore/src/bitstream/bitstream.h,v
retrieving revision 1.20
diff -B -b -d -u -r1.20 bitstream.h
--- src/bitstream/bitstream.h	5 Dec 2004 13:56:13 -0000	1.20
+++ src/bitstream/bitstream.h	9 Apr 2005 18:22:04 -0000
@@ -149,6 +149,13 @@
 							uint8_t * data,
 							const int length);
 
+void BitstreamWriteEndOfSequence(Bitstream * const bs);
+void BitStreamWriteStartOfVideoPacket(Bitstream * const bs,
+                                      const MBParam * pParam,
+                                      const FRAMEINFO * const frame,
+                                      unsigned int quant,
+                                      uint32_t macroblock_number);
+
 /* initialise bitstream structure */
 
 static void __inline
@@ -452,4 +459,44 @@
 	BitstreamPutBits(bs, stuffing_codes[bits - 1], bits);
 }
 
+
+/*
+ * Concatenate 2 bitstreams without padding
+ */
+static void __inline
+BitstreamsConcatenate(Bitstream * bso, Bitstream * const bsi, int padd)
+{
+        uint32_t dwords;
+        uint32_t b;
+        int i;
+
+        switch (padd) {
+        case 1: BitstreamPad(bso); break;
+        case 2: BitstreamPadAlways(bso); break;
+        default: break;
+        }
+
+        /* Get size */
+        dwords = ((ptr_t)bsi->tail - (ptr_t)bsi->start)>>2;
+
+        /* Loop on dwords */
+        for (i=0; i<dwords; i++)
+        {
+#ifndef ARCH_IS_BIG_ENDIAN
+                b = bsi->start[i];
+                BSWAP(b);
+                BitstreamPutBits(bso, b, 32);
+#else
+                BitstreamPutBits(bso, bsi->start[i], 32);
+#endif
+        }
+        
+        /* XXX: how to flush the latest buf ? */
+	if (bsi->pos) {
+                b = bsi->buf >> (32 - bsi->pos);
+                /* (bsi->buf & (0xffffffff >> bsi->pos)) >> (32 - bsi->pos); */
+		BitstreamPutBits(bso, b, bsi->pos);
+	}
+}
+
 #endif /* _BITSTREAM_H_ */
Index: src/bitstream/mbcoding.c
===================================================================
RCS file: /xvid/xvidcore/src/bitstream/mbcoding.c,v
retrieving revision 1.51
diff -B -b -d -u -r1.51 mbcoding.c
--- src/bitstream/mbcoding.c	4 Apr 2005 23:49:37 -0000	1.51
+++ src/bitstream/mbcoding.c	9 Apr 2005 18:22:04 -0000
@@ -63,7 +63,7 @@
 int bs_get_spritetrajectory(Bitstream * bs)
 {
 	int i;
-	for (i = 0; i < 12; i++)
+	for (i = 0; i < 15; i++)
 	{
 		if (BitstreamShowBits(bs, sprite_trajectory_len[i].len) == sprite_trajectory_len[i].code)
 		{
@@ -462,14 +462,17 @@
 			   const MACROBLOCK * pMB,
 			   int16_t qcoeff[6 * 64],
 			   Bitstream * bs,
+			   Bitstream * bs2,
+			   Bitstream * bs_tex,
 			   Statistics * pStat)
 {
 
 	uint32_t i, mcbpc, cbpy, bits;
+        Bitstream * bs_local;
 
 	cbpy = pMB->cbp >> 2;
 
-	/* write mcbpc */
+	/* write mcbpc - first bs */
 	if (frame->coding_type == I_VOP) {
 		mcbpc = ((pMB->mode >> 1) & 3) | ((pMB->cbp & 3) << 2);
 		BitstreamPutBits(bs, mcbpc_intra_tab[mcbpc].code,
@@ -480,42 +483,46 @@
 						 mcbpc_inter_tab[mcbpc].len);
 	}
 
-	/* ac prediction flag */
+	/* ac prediction flag - second bs */
 	if (pMB->acpred_directions[0])
-		BitstreamPutBits(bs, 1, 1);
+		BitstreamPutBits(bs2, 1, 1);
 	else
-		BitstreamPutBits(bs, 0, 1);
+		BitstreamPutBits(bs2, 0, 1);
 
-	/* write cbpy */
-	BitstreamPutBits(bs, xvid_cbpy_tab[cbpy].code, xvid_cbpy_tab[cbpy].len);
+	/* write cbpy - second bs */
+	BitstreamPutBits(bs2, xvid_cbpy_tab[cbpy].code, xvid_cbpy_tab[cbpy].len);
 
-	/* write dquant */
+	/* write dquant - first bs for I_VOP, second otherwise */
+        bs_local = (frame->coding_type == I_VOP) ? bs : bs2;
 	if (pMB->mode == MODE_INTRA_Q)
-		BitstreamPutBits(bs, DQ_VALUE2INDEX(pMB->dquant), 2);
+                BitstreamPutBits(bs_local, DQ_VALUE2INDEX(pMB->dquant), 2);
 
-	/* write interlacing */
+	/* write interlacing - same */
 	if (frame->vol_flags & XVID_VOL_INTERLACING) {
-		BitstreamPutBit(bs, pMB->field_dct);
+                BitstreamPutBit(bs_local, pMB->field_dct);
 	}
 	/* code block coeffs */
 	for (i = 0; i < 6; i++) {
+                /* DC goes to first bs for I-VOP, second otherwise */
 		if (i < 4)
-			BitstreamPutBits(bs, dcy_tab[qcoeff[i * 64 + 0] + 255].code,
+			BitstreamPutBits(bs_local,
+                                         dcy_tab[qcoeff[i * 64 + 0] + 255].code,
 							 dcy_tab[qcoeff[i * 64 + 0] + 255].len);
 		else
-			BitstreamPutBits(bs, dcc_tab[qcoeff[i * 64 + 0] + 255].code,
+			BitstreamPutBits(bs_local,
+                                         dcc_tab[qcoeff[i * 64 + 0] + 255].code,
 							 dcc_tab[qcoeff[i * 64 + 0] + 255].len);
 
+                /* AC goes to texture bs */
 		if (pMB->cbp & (1 << (5 - i))) {
 			const uint16_t *scan_table =
 				frame->vop_flags & XVID_VOP_ALTERNATESCAN ?
 				scan_tables[2] : scan_tables[pMB->acpred_directions[i]];
+			bits = BitstreamPos(bs_tex);
 
-			bits = BitstreamPos(bs);
-
-			CodeCoeffIntra(bs, &qcoeff[i * 64], scan_table);
+			CodeCoeffIntra(bs_tex, &qcoeff[i * 64], scan_table);
 
-			bits = BitstreamPos(bs) - bits;
+			bits = BitstreamPos(bs_tex) - bits;
 			pStat->iTextBits += bits;
 		}
 	}
@@ -528,6 +535,8 @@
 			   const MACROBLOCK * pMB,
 			   int16_t qcoeff[6 * 64],
 			   Bitstream * bs,
+			   Bitstream * bs2,
+			   Bitstream * bs_tex,
 			   Statistics * pStat)
 {
 
@@ -537,61 +546,62 @@
 	mcbpc = (pMB->mode & 7) | ((pMB->cbp & 3) << 3);
 	cbpy = 15 - (pMB->cbp >> 2);
 
-	/* write mcbpc */
+	/* write mcbpc - first bs */
 	BitstreamPutBits(bs, mcbpc_inter_tab[mcbpc].code,
 					 mcbpc_inter_tab[mcbpc].len);
 
+        /* XXX: Is it its actual place ? */
 	if ( (frame->coding_type == S_VOP) && (pMB->mode == MODE_INTER || pMB->mode == MODE_INTER_Q) )
 		BitstreamPutBit(bs, pMB->mcsel);		/* mcsel: '0'=local motion, '1'=GMC */
 
-	/* write cbpy */
-	BitstreamPutBits(bs, xvid_cbpy_tab[cbpy].code, xvid_cbpy_tab[cbpy].len);
+	/* write cbpy - second bs */
+	BitstreamPutBits(bs2, xvid_cbpy_tab[cbpy].code, xvid_cbpy_tab[cbpy].len);
 
-	/* write dquant */
+	/* write dquant - second bs */
 	if (pMB->mode == MODE_INTER_Q)
-		BitstreamPutBits(bs, DQ_VALUE2INDEX(pMB->dquant), 2);
+		BitstreamPutBits(bs2, DQ_VALUE2INDEX(pMB->dquant), 2);
 
-	/* interlacing */
+	/* interlacing - second bs */
 	if (frame->vol_flags & XVID_VOL_INTERLACING) {
 		if (pMB->cbp) {
-			BitstreamPutBit(bs, pMB->field_dct);
+			BitstreamPutBit(bs2, pMB->field_dct);
 			DPRINTF(XVID_DEBUG_MB,"codep: field_dct: %i\n", pMB->field_dct);
 		}
 
 		/* if inter block, write field ME flag */
 		if ((pMB->mode == MODE_INTER || pMB->mode == MODE_INTER_Q) && (pMB->mcsel == 0)) {
-			BitstreamPutBit(bs, 0 /*pMB->field_pred*/); /* not implemented yet */
+			BitstreamPutBit(bs2, 0 /*pMB->field_pred*/); /* not implemented yet */
 			DPRINTF(XVID_DEBUG_MB,"codep: field_pred: %i\n", pMB->field_pred);
 
 			/* write field prediction references */
 #if 0 /* Remove the #if once field_pred is supported */
 			if (pMB->field_pred) {
-				BitstreamPutBit(bs, pMB->field_for_top);
-				BitstreamPutBit(bs, pMB->field_for_bot);
+				BitstreamPutBit(bs2, pMB->field_for_top);
+				BitstreamPutBit(bs2, pMB->field_for_bot);
 			}
 #endif
 		}
 	}
-	/* code motion vector(s) if motion is local  */
+	/* code motion vector(s) if motion is local - first bs */
 	if (!pMB->mcsel)
 		for (i = 0; i < (pMB->mode == MODE_INTER4V ? 4 : 1); i++) {
 			CodeVector(bs, pMB->pmvs[i].x, frame->fcode);
 			CodeVector(bs, pMB->pmvs[i].y, frame->fcode);
 		}
 
-	bits = BitstreamPos(bs);
+	/* code block coeffs - texture bs */
+	bits = BitstreamPos(bs_tex);
 
-	/* code block coeffs */
 	for (i = 0; i < 6; i++)
 		if (pMB->cbp & (1 << (5 - i))) {
 			const uint16_t *scan_table =
 				frame->vop_flags & XVID_VOP_ALTERNATESCAN ?
 				scan_tables[2] : scan_tables[0];
 
-			CodeCoeffInter(bs, &qcoeff[i * 64], scan_table);
+			CodeCoeffInter(bs_tex, &qcoeff[i * 64], scan_table);
 		}
 
-	bits = BitstreamPos(bs) - bits;
+	bits = BitstreamPos(bs_tex) - bits;
 	pStat->iTextBits += bits;
 }
 
@@ -601,10 +611,12 @@
 		 MACROBLOCK * pMB,
 		 int16_t qcoeff[6 * 64],
 		 Bitstream * bs,
+		 Bitstream * bs2,
+		 Bitstream * bs_tex,
 		 Statistics * pStat)
 {
 	if (frame->coding_type != I_VOP)
-			BitstreamPutBit(bs, 0);	/* not_coded */
+                BitstreamPutBit(bs, 0);	/* not_coded = 0 */
 
 	if (frame->vop_flags & XVID_VOP_GREYSCALE) {
 		pMB->cbp &= 0x3C;		/* keep only bits 5-2 */
@@ -613,9 +625,9 @@
 	}
 
 	if (pMB->mode == MODE_INTRA || pMB->mode == MODE_INTRA_Q)
-		CodeBlockIntra(frame, pMB, qcoeff, bs, pStat);
+                CodeBlockIntra(frame, pMB, qcoeff, bs, bs2, bs_tex, pStat);
 	else
-		CodeBlockInter(frame, pMB, qcoeff, bs, pStat);
+		CodeBlockInter(frame, pMB, qcoeff, bs, bs2, bs_tex, pStat);
 
 }
 
Index: src/utils/mbfunctions.h
===================================================================
RCS file: /xvid/xvidcore/src/utils/mbfunctions.h,v
retrieving revision 1.20
diff -B -b -d -u -r1.20 mbfunctions.h
--- src/utils/mbfunctions.h	5 Jan 2005 23:02:15 -0000	1.20
+++ src/utils/mbfunctions.h	9 Apr 2005 18:22:05 -0000
@@ -84,6 +84,8 @@
 			MACROBLOCK * pMB,	/* <-- Info of the MB to be coded */
 			int16_t qcoeff[6 * 64],	/* <-- the quantized DCT coefficients */
 			Bitstream * bs,	/* <-> the bitstream */
+			Bitstream * bs2,	/* <-> the secondary bitstream with data partitioning */
+			Bitstream * bs_tex,	/* <-> the texture bitstream with data partitioning */
 			Statistics * pStat);	/* <-> statistical data collected for current frame */
 
 #endif


More information about the XviD-devel mailing list