You've already forked FFmpeg
							
							
				mirror of
				https://github.com/FFmpeg/FFmpeg.git
				synced 2025-10-30 23:18:11 +02:00 
			
		
		
		
	alternative bitstream writer (disabled by default, uncomment #define ALT_BISTREAM_WRITER in common.h if u want to try it)
Originally committed as revision 295 to svn://svn.ffmpeg.org/ffmpeg/trunk
This commit is contained in:
		| @@ -80,7 +80,7 @@ static int put_pack_header(AVFormatContext *ctx, | ||||
|     put_bits(&pb, 1, 1); | ||||
|  | ||||
|     flush_put_bits(&pb); | ||||
|     return pb.buf_ptr - pb.buf; | ||||
|     return pbBufPtr(&pb) - pb.buf; | ||||
| } | ||||
|  | ||||
| static int put_system_header(AVFormatContext *ctx, UINT8 *buf) | ||||
| @@ -135,7 +135,7 @@ static int put_system_header(AVFormatContext *ctx, UINT8 *buf) | ||||
|         } | ||||
|     } | ||||
|     flush_put_bits(&pb); | ||||
|     size = pb.buf_ptr - pb.buf; | ||||
|     size = pbBufPtr(&pb) - pb.buf; | ||||
|     /* patch packet size */ | ||||
|     buf[4] = (size - 6) >> 8; | ||||
|     buf[5] = (size - 6) & 0xff; | ||||
|   | ||||
| @@ -127,7 +127,7 @@ static void put_swf_rect(ByteIOContext *pb, | ||||
|     put_bits(&p, nbits, ymax & mask); | ||||
|      | ||||
|     flush_put_bits(&p); | ||||
|     put_buffer(pb, buf, p.buf_ptr - p.buf); | ||||
|     put_buffer(pb, buf, pbBufPtr(&p) - p.buf); | ||||
| } | ||||
|  | ||||
| static void put_swf_line_edge(PutBitContext *pb, int dx, int dy) | ||||
| @@ -183,7 +183,7 @@ static void put_swf_matrix(ByteIOContext *pb, | ||||
|     put_bits(&p, 20, ty); | ||||
|  | ||||
|     flush_put_bits(&p); | ||||
|     put_buffer(pb, buf, p.buf_ptr - p.buf); | ||||
|     put_buffer(pb, buf, pbBufPtr(&p) - p.buf); | ||||
| } | ||||
|  | ||||
| /* XXX: handle audio only */ | ||||
| @@ -271,7 +271,7 @@ static int swf_write_header(AVFormatContext *s) | ||||
|     put_bits(&p, 5, 0); | ||||
|  | ||||
|     flush_put_bits(&p); | ||||
|     put_buffer(pb, buf1, p.buf_ptr - p.buf); | ||||
|     put_buffer(pb, buf1, pbBufPtr(&p) - p.buf); | ||||
|  | ||||
|     put_swf_end_tag(s); | ||||
|  | ||||
|   | ||||
| @@ -1227,9 +1227,9 @@ static int output_frame_end(AC3EncodeContext *s) | ||||
|     flush_put_bits(&s->pb); | ||||
|     /* add zero bytes to reach the frame size */ | ||||
|     frame = s->pb.buf; | ||||
|     n = 2 * s->frame_size - (s->pb.buf_ptr - frame) - 2; | ||||
|     n = 2 * s->frame_size - (pbBufPtr(&s->pb) - frame) - 2; | ||||
|     assert(n >= 0); | ||||
|     memset(s->pb.buf_ptr, 0, n); | ||||
|     memset(pbBufPtr(&s->pb), 0, n); | ||||
|      | ||||
|     /* Now we must compute both crcs : this is not so easy for crc1 | ||||
|        because it is at the beginning of the data... */ | ||||
|   | ||||
| @@ -16,7 +16,7 @@ | ||||
|  * along with this program; if not, write to the Free Software | ||||
|  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||||
|  * | ||||
|  * alternative bitstream reader by Michael Niedermayer <michaelni@gmx.at> | ||||
|  * alternative bitstream reader & writer by Michael Niedermayer <michaelni@gmx.at> | ||||
|  */ | ||||
| #include "common.h" | ||||
| #include <math.h> | ||||
| @@ -27,15 +27,26 @@ void init_put_bits(PutBitContext *s, | ||||
|                    void (*write_data)(void *, UINT8 *, int)) | ||||
| { | ||||
|     s->buf = buffer; | ||||
|     s->buf_ptr = s->buf; | ||||
|     s->buf_end = s->buf + buffer_size; | ||||
|     s->bit_cnt=0; | ||||
|     s->bit_buf=0; | ||||
|     s->data_out_size = 0; | ||||
| #ifdef ALT_BITSTREAM_WRITER | ||||
|     s->index=0; | ||||
|     ((uint32_t*)(s->buf))[0]=0; | ||||
| //    memset(buffer, 0, buffer_size); | ||||
|     if(write_data!=NULL)  | ||||
|     { | ||||
|     	fprintf(stderr, "write Data callback is not supported\n"); | ||||
|     } | ||||
| #else | ||||
|     s->write_data = write_data; | ||||
|     s->opaque = opaque; | ||||
|     s->buf_ptr = s->buf; | ||||
|     s->bit_cnt=0; | ||||
|     s->bit_buf=0; | ||||
| #endif | ||||
| } | ||||
|  | ||||
| #ifndef ALT_BITSTREAM_WRITER | ||||
| static void flush_buffer(PutBitContext *s) | ||||
| { | ||||
|     int size; | ||||
| @@ -85,21 +96,33 @@ void put_bits(PutBitContext *s, int n, unsigned int value) | ||||
|     s->bit_buf = bit_buf; | ||||
|     s->bit_cnt = bit_cnt; | ||||
| } | ||||
| #endif | ||||
|  | ||||
| /* return the number of bits output */ | ||||
| INT64 get_bit_count(PutBitContext *s) | ||||
| { | ||||
| #ifdef ALT_BITSTREAM_WRITER | ||||
|     return s->data_out_size * 8 + s->index; | ||||
| #else | ||||
|     return (s->buf_ptr - s->buf + s->data_out_size) * 8 + (INT64)s->bit_cnt; | ||||
| #endif | ||||
| } | ||||
|  | ||||
| void align_put_bits(PutBitContext *s) | ||||
| { | ||||
| #ifdef ALT_BITSTREAM_WRITER | ||||
|     put_bits(s,(  - s->index) & 7,0); | ||||
| #else | ||||
|     put_bits(s,(8 - s->bit_cnt) & 7,0); | ||||
| #endif | ||||
| } | ||||
|  | ||||
| /* pad the end of the output stream with zeros */ | ||||
| void flush_put_bits(PutBitContext *s) | ||||
| { | ||||
| #ifdef ALT_BITSTREAM_WRITER | ||||
|     align_put_bits(s); | ||||
| #else | ||||
|     while (s->bit_cnt > 0) { | ||||
|         /* XXX: should test end of buffer */ | ||||
|         *s->buf_ptr++=s->bit_buf >> 24; | ||||
| @@ -109,8 +132,10 @@ void flush_put_bits(PutBitContext *s) | ||||
|     flush_buffer(s); | ||||
|     s->bit_cnt=0; | ||||
|     s->bit_buf=0; | ||||
| #endif | ||||
| } | ||||
|  | ||||
| #ifndef ALT_BITSTREAM_WRITER | ||||
| /* for jpeg : escape 0xff with 0x00 after it */ | ||||
| void jput_bits(PutBitContext *s, int n, unsigned int value) | ||||
| { | ||||
| @@ -152,8 +177,10 @@ void jput_bits(PutBitContext *s, int n, unsigned int value) | ||||
|     s->bit_buf = bit_buf; | ||||
|     s->bit_cnt = bit_cnt; | ||||
| } | ||||
| #endif | ||||
|  | ||||
| /* pad the end of the output stream with zeros */ | ||||
| #ifndef ALT_BITSTREAM_WRITER | ||||
| void jflush_put_bits(PutBitContext *s) | ||||
| { | ||||
|     unsigned int b; | ||||
| @@ -171,6 +198,13 @@ void jflush_put_bits(PutBitContext *s) | ||||
|     s->bit_cnt=0; | ||||
|     s->bit_buf=0; | ||||
| } | ||||
| #else | ||||
| void jflush_put_bits(PutBitContext *s) | ||||
| { | ||||
|     int num= (  - s->index) & 7; | ||||
|     jput_bits(s, num,0xFF>>(8-num)); | ||||
| } | ||||
| #endif | ||||
|  | ||||
| /* bit input functions */ | ||||
|  | ||||
|   | ||||
| @@ -8,6 +8,7 @@ | ||||
| #define CONFIG_WIN32 | ||||
| #endif | ||||
|  | ||||
| //#define ALT_BITSTREAM_WRITER | ||||
| //#define ALT_BITSTREAM_READER | ||||
| //#define ALIGNED_BITSTREAM | ||||
| #define FAST_GET_FIRST_VLC | ||||
| @@ -161,25 +162,36 @@ struct PutBitContext; | ||||
| typedef void (*WriteDataFunc)(void *, UINT8 *, int); | ||||
|  | ||||
| typedef struct PutBitContext { | ||||
| #ifdef ALT_BITSTREAM_WRITER | ||||
|     UINT8 *buf, *buf_end; | ||||
|     int index; | ||||
| #else | ||||
|     UINT32 bit_buf; | ||||
|     int bit_cnt; | ||||
|     UINT8 *buf, *buf_ptr, *buf_end; | ||||
|     INT64 data_out_size; /* in bytes */ | ||||
|     void *opaque; | ||||
|     WriteDataFunc write_data; | ||||
| #endif | ||||
|     INT64 data_out_size; /* in bytes */ | ||||
| } PutBitContext; | ||||
|  | ||||
| void init_put_bits(PutBitContext *s,  | ||||
|                    UINT8 *buffer, int buffer_size, | ||||
|                    void *opaque, | ||||
|                    void (*write_data)(void *, UINT8 *, int)); | ||||
|  | ||||
| #ifndef ALT_BITSTREAM_WRITER | ||||
| void put_bits(PutBitContext *s, int n, unsigned int value); | ||||
| #endif | ||||
|  | ||||
| INT64 get_bit_count(PutBitContext *s); /* XXX: change function name */ | ||||
| void align_put_bits(PutBitContext *s); | ||||
| void flush_put_bits(PutBitContext *s); | ||||
|  | ||||
| /* jpeg specific put_bits */ | ||||
| #ifndef ALT_BITSTREAM_WRITER | ||||
| void jput_bits(PutBitContext *s, int n, unsigned int value); | ||||
| #endif | ||||
| void jflush_put_bits(PutBitContext *s); | ||||
|  | ||||
| /* bit input */ | ||||
| @@ -225,6 +237,99 @@ static inline uint32_t unaligned32(const void *v) { | ||||
| #endif | ||||
| #endif //!ARCH_X86 | ||||
|  | ||||
| #ifdef ALT_BITSTREAM_WRITER | ||||
| static inline void put_bits(PutBitContext *s, int n, int value) | ||||
| { | ||||
| #ifdef ARCH_X86 | ||||
|     asm volatile( | ||||
| 	"movl $7, %%ecx			\n\t" | ||||
| 	"andl %0, %%ecx			\n\t" | ||||
| 	"addl %3, %%ecx			\n\t" | ||||
| 	"negl %%ecx			\n\t" | ||||
| 	"shll %%cl, %1			\n\t" | ||||
| 	"bswapl %1			\n\t" | ||||
| 	"movl %0, %%ecx			\n\t" | ||||
| 	"shrl $3, %%ecx			\n\t" | ||||
| 	"orl %1, (%%ecx, %2)		\n\t" | ||||
| 	"addl %3, %0			\n\t" | ||||
| 	"movl $0, 4(%%ecx, %2)		\n\t" | ||||
| 	: "=&r" (s->index), "=&r" (value) | ||||
| 	: "r" (s->buf), "r" (n), "0" (s->index), "1" (value) | ||||
| 	: "%ecx" | ||||
|     ); | ||||
| #else | ||||
|     int index= s->index; | ||||
|     uint32_t *ptr= (uint32_t*)(((uint8_t *)s->buf)+(index>>3)); | ||||
|      | ||||
|     ptr[0] |= be2me_32(value<<(32-n-(index&7) )); | ||||
|     ptr[1] = 0; | ||||
| //if(n>24) printf("%d %d\n", n, value); | ||||
|     index+= n; | ||||
|     s->index= index; | ||||
| #endif | ||||
| } | ||||
| #endif | ||||
|  | ||||
| #ifdef ALT_BITSTREAM_WRITER | ||||
| static inline void jput_bits(PutBitContext *s, int n, int value) | ||||
| { | ||||
|     int index= s->index; | ||||
|     uint32_t *ptr= (uint32_t*)(((uint8_t *)s->buf)+(index>>3)); | ||||
|     int v= ptr[0]; | ||||
| //if(n>24) printf("%d %d\n", n, value); | ||||
|      | ||||
|     v |= be2me_32(value<<(32-n-(index&7) )); | ||||
|     if(((v+0x01010101)^0xFFFFFFFF)&v&0x80808080) | ||||
|     { | ||||
| 	/* handle idiotic (m)jpeg escapes */ | ||||
| 	uint8_t *bPtr= (uint8_t*)ptr; | ||||
| 	int numChecked= ((index+n)>>3) - (index>>3); | ||||
| 	 | ||||
| 	v= be2me_32(v); | ||||
|  | ||||
| 	*(bPtr++)= v>>24; | ||||
| 	if((v&0xFF000000)==0xFF000000 && numChecked>0){ | ||||
| 		*(bPtr++)= 0x00; | ||||
| 		index+=8; | ||||
| 	} | ||||
| 	*(bPtr++)= (v>>16)&0xFF; | ||||
| 	if((v&0x00FF0000)==0x00FF0000 && numChecked>1){ | ||||
| 		*(bPtr++)= 0x00; | ||||
| 		index+=8; | ||||
| 	} | ||||
| 	*(bPtr++)= (v>>8)&0xFF; | ||||
| 	if((v&0x0000FF00)==0x0000FF00 && numChecked>2){ | ||||
| 		*(bPtr++)= 0x00; | ||||
| 		index+=8; | ||||
| 	} | ||||
| 	*(bPtr++)= v&0xFF; | ||||
| 	if((v&0x000000FF)==0x000000FF && numChecked>3){ | ||||
| 		*(bPtr++)= 0x00; | ||||
| 		index+=8; | ||||
| 	} | ||||
| 	*((uint32_t*)bPtr)= 0; | ||||
|     } | ||||
|     else | ||||
|     { | ||||
| 	ptr[0] = v; | ||||
| 	ptr[1] = 0; | ||||
|     } | ||||
|  | ||||
|     index+= n; | ||||
|     s->index= index; | ||||
|  } | ||||
| #endif | ||||
|  | ||||
|  | ||||
| static inline uint8_t* pbBufPtr(PutBitContext *s) | ||||
| { | ||||
| #ifdef ALT_BITSTREAM_WRITER | ||||
| 	return s->buf + (s->index>>3); | ||||
| #else | ||||
| 	return s->buf_ptr; | ||||
| #endif | ||||
| } | ||||
|  | ||||
| void init_get_bits(GetBitContext *s,  | ||||
|                    UINT8 *buffer, int buffer_size); | ||||
|  | ||||
|   | ||||
| @@ -64,7 +64,7 @@ void h263_encode_picture_header(MpegEncContext * s, int picture_number) | ||||
|     align_put_bits(&s->pb); | ||||
|  | ||||
|     /* Update the pointer to last GOB */ | ||||
|     s->ptr_lastgob = s->pb.buf_ptr; | ||||
|     s->ptr_lastgob = pbBufPtr(&s->pb); | ||||
|     s->gob_number = 0; | ||||
|  | ||||
|     put_bits(&s->pb, 22, 0x20); /* PSC */ | ||||
| @@ -152,17 +152,17 @@ int h263_encode_gob_header(MpegEncContext * s, int mb_line) | ||||
|     /* Check to see if we need to put a new GBSC */ | ||||
|     /* for RTP packetization                    */ | ||||
|     if (s->rtp_mode) { | ||||
|         pdif = s->pb.buf_ptr - s->ptr_lastgob; | ||||
|         pdif = pbBufPtr(&s->pb) - s->ptr_lastgob; | ||||
|         if (pdif >= s->rtp_payload_size) { | ||||
|             /* Bad luck, packet must be cut before */ | ||||
|             align_put_bits(&s->pb); | ||||
|             flush_put_bits(&s->pb); | ||||
|             /* Call the RTP callback to send the last GOB */ | ||||
|             if (s->rtp_callback) { | ||||
|                 pdif = s->pb.buf_ptr - s->ptr_lastgob; | ||||
|                 pdif = pbBufPtr(&s->pb) - s->ptr_lastgob; | ||||
|                 s->rtp_callback(s->ptr_lastgob, pdif, s->gob_number); | ||||
|             } | ||||
|             s->ptr_lastgob = s->pb.buf_ptr; | ||||
|             s->ptr_lastgob = pbBufPtr(&s->pb); | ||||
|             put_bits(&s->pb, 17, 1); /* GBSC */ | ||||
|             s->gob_number = mb_line / s->gob_index; | ||||
|             put_bits(&s->pb, 5, s->gob_number); /* GN */ | ||||
| @@ -176,10 +176,10 @@ int h263_encode_gob_header(MpegEncContext * s, int mb_line) | ||||
|            flush_put_bits(&s->pb); | ||||
|            /* Call the RTP callback to send the last GOB */ | ||||
|            if (s->rtp_callback) { | ||||
|                pdif = s->pb.buf_ptr - s->ptr_lastgob; | ||||
|                pdif = pbBufPtr(&s->pb) - s->ptr_lastgob; | ||||
|                s->rtp_callback(s->ptr_lastgob, pdif, s->gob_number); | ||||
|            } | ||||
|            s->ptr_lastgob = s->pb.buf_ptr; | ||||
|            s->ptr_lastgob = pbBufPtr(&s->pb); | ||||
|            put_bits(&s->pb, 17, 1); /* GBSC */ | ||||
|            s->gob_number = mb_line / s->gob_index; | ||||
|            put_bits(&s->pb, 5, s->gob_number); /* GN */ | ||||
| @@ -489,7 +489,8 @@ void mpeg4_encode_picture_header(MpegEncContext * s, int picture_number) | ||||
| { | ||||
|     align_put_bits(&s->pb); | ||||
|  | ||||
|     put_bits(&s->pb, 32, 0x1B6);	/* vop header */ | ||||
|     put_bits(&s->pb, 16, 0);	        /* vop header */ | ||||
|     put_bits(&s->pb, 16, 0x1B6);	/* vop header */ | ||||
|     put_bits(&s->pb, 2, s->pict_type - 1);	/* pict type: I = 0 , P = 1 */ | ||||
|     /* XXX: time base + 1 not always correct */ | ||||
|     put_bits(&s->pb, 1, 1); | ||||
| @@ -846,7 +847,7 @@ int h263_decode_gob_header(MpegEncContext *s) | ||||
|         gfid = get_bits(&s->gb, 2); /* GFID */ | ||||
|         s->qscale = get_bits(&s->gb, 5); /* GQUANT */ | ||||
| #ifdef DEBUG | ||||
|         fprintf(stderr, "\nGN: %u GFID: %u Quant: %u\n", gn, gfid, s->qscale); | ||||
|         fprintf(stderr, "\nGN: %u GFID: %u Quant: %u\n", s->gob_number, gfid, s->qscale); | ||||
| #endif | ||||
|         return 1; | ||||
|     } | ||||
|   | ||||
| @@ -243,7 +243,7 @@ static void jpeg_table_header(MpegEncContext *s) | ||||
|     /* huffman table */ | ||||
|     put_marker(p, DHT); | ||||
|     flush_put_bits(p); | ||||
|     ptr = p->buf_ptr; | ||||
|     ptr = pbBufPtr(p); | ||||
|     put_bits(p, 16, 0); /* patched later */ | ||||
|     size = 2; | ||||
|     size += put_huffman_table(s, 0, 0, bits_dc_luminance, val_dc_luminance); | ||||
|   | ||||
| @@ -763,7 +763,7 @@ int MPA_encode_frame(AVCodecContext *avctx, | ||||
|     encode_frame(s, bit_alloc, padding); | ||||
|      | ||||
|     s->nb_samples += MPA_FRAME_SIZE; | ||||
|     return s->pb.buf_ptr - s->pb.buf; | ||||
|     return pbBufPtr(&s->pb) - s->pb.buf; | ||||
| } | ||||
|  | ||||
|  | ||||
|   | ||||
| @@ -532,9 +532,10 @@ int MPV_encode_picture(AVCodecContext *avctx, | ||||
|         mjpeg_picture_trailer(s); | ||||
|  | ||||
|     flush_put_bits(&s->pb); | ||||
|     s->total_bits += (s->pb.buf_ptr - s->pb.buf) * 8; | ||||
|     s->total_bits += (pbBufPtr(&s->pb) - s->pb.buf) * 8; | ||||
|  | ||||
|     avctx->quality = s->qscale; | ||||
|     return s->pb.buf_ptr - s->pb.buf; | ||||
|     return pbBufPtr(&s->pb) - s->pb.buf; | ||||
| } | ||||
|  | ||||
| static inline int clip(int a, int amin, int amax) | ||||
| @@ -1115,13 +1116,15 @@ static void encode_picture(MpegEncContext *s, int picture_number) | ||||
|  | ||||
|             MPV_decode_mb(s, s->block); | ||||
|         } | ||||
|  | ||||
|  | ||||
|         /* Obtain average GOB size for RTP */ | ||||
|         if (s->rtp_mode) { | ||||
|             if (!mb_y) | ||||
|                 s->mb_line_avgsize = s->pb.buf_ptr - s->ptr_last_mb_line; | ||||
|                 s->mb_line_avgsize = pbBufPtr(&s->pb) - s->ptr_last_mb_line; | ||||
|             else if (!(mb_y % s->gob_index)) {     | ||||
|                 s->mb_line_avgsize = (s->mb_line_avgsize + s->pb.buf_ptr - s->ptr_last_mb_line) >> 1; | ||||
|                 s->ptr_last_mb_line = s->pb.buf_ptr; | ||||
|                 s->mb_line_avgsize = (s->mb_line_avgsize + pbBufPtr(&s->pb) - s->ptr_last_mb_line) >> 1; | ||||
|                 s->ptr_last_mb_line = pbBufPtr(&s->pb); | ||||
|             } | ||||
|             //fprintf(stderr, "\nMB line: %d\tSize: %u\tAvg. Size: %u", s->mb_y,  | ||||
|             //                    (s->pb.buf_ptr - s->ptr_last_mb_line), s->mb_line_avgsize); | ||||
| @@ -1138,11 +1141,11 @@ static void encode_picture(MpegEncContext *s, int picture_number) | ||||
|     /* Send the last GOB if RTP */     | ||||
|     if (s->rtp_mode) { | ||||
|         flush_put_bits(&s->pb); | ||||
|         pdif = s->pb.buf_ptr - s->ptr_lastgob; | ||||
|         pdif = pbBufPtr(&s->pb) - s->ptr_lastgob; | ||||
|         /* Call the RTP callback to send the last GOB */ | ||||
|         if (s->rtp_callback) | ||||
|             s->rtp_callback(s->ptr_lastgob, pdif, s->gob_number); | ||||
|         s->ptr_lastgob = s->pb.buf_ptr; | ||||
|         s->ptr_lastgob = pbBufPtr(&s->pb); | ||||
|         //fprintf(stderr,"\nGOB: %2d size: %d (last)", s->gob_number, pdif); | ||||
|     } | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user