From 17592475b3ee4c45ab43ac38e46fe8063b314811 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Tue, 12 Feb 2002 15:43:16 +0000 Subject: [PATCH] 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 --- libav/mpeg.c | 4 +- libav/swf.c | 6 +-- libavcodec/ac3enc.c | 4 +- libavcodec/common.c | 42 +++++++++++++++++-- libavcodec/common.h | 107 ++++++++++++++++++++++++++++++++++++++++++++++++- libavcodec/h263.c | 17 ++++---- libavcodec/mjpeg.c | 2 +- libavcodec/mpegaudio.c | 2 +- libavcodec/mpegvideo.c | 17 ++++---- 9 files changed, 172 insertions(+), 29 deletions(-) diff --git a/libav/mpeg.c b/libav/mpeg.c index 57dae4c..2c09a85 100644 --- a/libav/mpeg.c +++ b/libav/mpeg.c @@ -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; diff --git a/libav/swf.c b/libav/swf.c index 879d7cd..ebd4ada 100644 --- a/libav/swf.c +++ b/libav/swf.c @@ -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); diff --git a/libavcodec/ac3enc.c b/libavcodec/ac3enc.c index d443473..05e0619 100644 --- a/libavcodec/ac3enc.c +++ b/libavcodec/ac3enc.c @@ -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... */ diff --git a/libavcodec/common.c b/libavcodec/common.c index b3436eb..50b546d 100644 --- a/libavcodec/common.c +++ b/libavcodec/common.c @@ -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 + * alternative bitstream reader & writer by Michael Niedermayer */ #include "common.h" #include @@ -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 */ diff --git a/libavcodec/common.h b/libavcodec/common.h index f359216..98e7ec2 100644 --- a/libavcodec/common.h +++ b/libavcodec/common.h @@ -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); diff --git a/libavcodec/h263.c b/libavcodec/h263.c index 3710af8..37087dc 100644 --- a/libavcodec/h263.c +++ b/libavcodec/h263.c @@ -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; } diff --git a/libavcodec/mjpeg.c b/libavcodec/mjpeg.c index cb86344..9307685 100644 --- a/libavcodec/mjpeg.c +++ b/libavcodec/mjpeg.c @@ -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); diff --git a/libavcodec/mpegaudio.c b/libavcodec/mpegaudio.c index e8ec337..d1040a4 100644 --- a/libavcodec/mpegaudio.c +++ b/libavcodec/mpegaudio.c @@ -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; } diff --git a/libavcodec/mpegvideo.c b/libavcodec/mpegvideo.c index f38ee13..261a847 100644 --- a/libavcodec/mpegvideo.c +++ b/libavcodec/mpegvideo.c @@ -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); } -- 2.7.4