Originally committed as revision 1172 to svn://svn.ffmpeg.org/ffmpeg/trunktags/v0.5
| @@ -87,33 +87,6 @@ void flush_put_bits(PutBitContext *s) | |||
| #endif | |||
| } | |||
| /* pad the end of the output stream with zeros */ | |||
| #ifndef ALT_BITSTREAM_WRITER | |||
| void jflush_put_bits(PutBitContext *s) | |||
| { | |||
| unsigned int b; | |||
| s->bit_buf<<= s->bit_left; | |||
| s->bit_buf |= ~1U >> (32 - s->bit_left); /* set all the unused bits to one */ | |||
| while (s->bit_left < 32) { | |||
| b = s->bit_buf >> 24; | |||
| *s->buf_ptr++ = b; | |||
| if (b == 0xff) | |||
| *s->buf_ptr++ = 0; | |||
| s->bit_buf<<=8; | |||
| s->bit_left+=8; | |||
| } | |||
| s->bit_left=32; | |||
| s->bit_buf=0; | |||
| } | |||
| #else | |||
| void jflush_put_bits(PutBitContext *s) | |||
| { | |||
| int num= ( - s->index) & 7; | |||
| jput_bits(s, num,0xFF>>(8-num)); | |||
| } | |||
| #endif | |||
| void put_string(PutBitContext * pbc, char *s) | |||
| { | |||
| while(*s){ | |||
| @@ -108,7 +108,6 @@ typedef signed int INT32; | |||
| typedef signed long long INT64; | |||
| # ifdef HAVE_AV_CONFIG_H | |||
| # ifndef INT64_C | |||
| # define INT64_C(c) (c ## LL) | |||
| # define UINT64_C(c) (c ## ULL) | |||
| @@ -117,7 +116,6 @@ typedef signed long long INT64; | |||
| # ifdef USE_FASTMEMCPY | |||
| # include "fastmemcpy.h" | |||
| # endif | |||
| # endif /* HAVE_AV_CONFIG_H */ | |||
| #endif /* !CONFIG_WIN32 */ | |||
| @@ -220,9 +218,6 @@ void align_put_bits(PutBitContext *s); | |||
| void flush_put_bits(PutBitContext *s); | |||
| void put_string(PutBitContext * pbc, char *s); | |||
| /* jpeg specific put_bits */ | |||
| void jflush_put_bits(PutBitContext *s); | |||
| /* bit input */ | |||
| typedef struct GetBitContext { | |||
| @@ -383,94 +378,6 @@ static inline void put_bits(PutBitContext *s, int n, unsigned int value) | |||
| } | |||
| #endif | |||
| #ifndef ALT_BITSTREAM_WRITER | |||
| /* for jpeg : escape 0xff with 0x00 after it */ | |||
| static inline void jput_bits(PutBitContext *s, int n, unsigned int value) | |||
| { | |||
| unsigned int bit_buf, b; | |||
| int bit_left, i; | |||
| assert(n == 32 || value < (1U << n)); | |||
| bit_buf = s->bit_buf; | |||
| bit_left = s->bit_left; | |||
| //printf("n=%d value=%x cnt=%d buf=%x\n", n, value, bit_cnt, bit_buf); | |||
| /* XXX: optimize */ | |||
| if (n < bit_left) { | |||
| bit_buf = (bit_buf<<n) | value; | |||
| bit_left-=n; | |||
| } else { | |||
| bit_buf<<=bit_left; | |||
| bit_buf |= value >> (n - bit_left); | |||
| /* handle escape */ | |||
| for(i=0;i<4;i++) { | |||
| b = (bit_buf >> 24); | |||
| *(s->buf_ptr++) = b; | |||
| if (b == 0xff) | |||
| *(s->buf_ptr++) = 0; | |||
| bit_buf <<= 8; | |||
| } | |||
| bit_left+= 32 - n; | |||
| bit_buf = value; | |||
| } | |||
| s->bit_buf = bit_buf; | |||
| s->bit_left = bit_left; | |||
| } | |||
| #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) | |||
| { | |||
| @@ -470,9 +470,71 @@ void mjpeg_picture_header(MpegEncContext *s) | |||
| put_bits(&s->pb, 8, 0); /* Ah/Al (not used) */ | |||
| } | |||
| static void escape_FF(MpegEncContext *s) | |||
| { | |||
| int size= get_bit_count(&s->pb) - s->header_bits; | |||
| int i, ff_count; | |||
| uint8_t *buf= s->pb.buf + (s->header_bits>>3); | |||
| int align= (-(int)(buf))&3; | |||
| assert((size&7) == 0); | |||
| size >>= 3; | |||
| ff_count=0; | |||
| for(i=0; i<size && i<align; i++){ | |||
| if(buf[i]==0xFF) ff_count++; | |||
| } | |||
| for(; i<size-15; i+=16){ | |||
| int acc, v; | |||
| v= *(uint32_t*)(&buf[i]); | |||
| acc= (((v & (v>>4))&0x0F0F0F0F)+0x01010101)&0x10101010; | |||
| v= *(uint32_t*)(&buf[i+4]); | |||
| acc+=(((v & (v>>4))&0x0F0F0F0F)+0x01010101)&0x10101010; | |||
| v= *(uint32_t*)(&buf[i+8]); | |||
| acc+=(((v & (v>>4))&0x0F0F0F0F)+0x01010101)&0x10101010; | |||
| v= *(uint32_t*)(&buf[i+12]); | |||
| acc+=(((v & (v>>4))&0x0F0F0F0F)+0x01010101)&0x10101010; | |||
| acc>>=4; | |||
| acc+= (acc>>16); | |||
| acc+= (acc>>8); | |||
| ff_count+= acc&0xFF; | |||
| } | |||
| for(; i<size; i++){ | |||
| if(buf[i]==0xFF) ff_count++; | |||
| } | |||
| if(ff_count==0) return; | |||
| /* skip put bits */ | |||
| for(i=0; i<ff_count-3; i+=4) | |||
| put_bits(&s->pb, 32, 0); | |||
| put_bits(&s->pb, (ff_count-i)*8, 0); | |||
| flush_put_bits(&s->pb); | |||
| for(i=size-1; ff_count; i--){ | |||
| int v= buf[i]; | |||
| if(v==0xFF){ | |||
| //printf("%d %d\n", i, ff_count); | |||
| buf[i+ff_count]= 0; | |||
| ff_count--; | |||
| } | |||
| buf[i+ff_count]= v; | |||
| } | |||
| } | |||
| void mjpeg_picture_trailer(MpegEncContext *s) | |||
| { | |||
| jflush_put_bits(&s->pb); | |||
| int pad= (-get_bit_count(&s->pb))&7; | |||
| put_bits(&s->pb, pad,0xFF>>(8-pad)); | |||
| flush_put_bits(&s->pb); | |||
| escape_FF(s); | |||
| put_marker(&s->pb, EOI); | |||
| } | |||
| @@ -482,7 +544,7 @@ static inline void mjpeg_encode_dc(MpegEncContext *s, int val, | |||
| int mant, nbits; | |||
| if (val == 0) { | |||
| jput_bits(&s->pb, huff_size[0], huff_code[0]); | |||
| put_bits(&s->pb, huff_size[0], huff_code[0]); | |||
| } else { | |||
| mant = val; | |||
| if (val < 0) { | |||
| @@ -497,9 +559,9 @@ static inline void mjpeg_encode_dc(MpegEncContext *s, int val, | |||
| nbits++; | |||
| } | |||
| jput_bits(&s->pb, huff_size[nbits], huff_code[nbits]); | |||
| put_bits(&s->pb, huff_size[nbits], huff_code[nbits]); | |||
| jput_bits(&s->pb, nbits, mant & ((1 << nbits) - 1)); | |||
| put_bits(&s->pb, nbits, mant & ((1 << nbits) - 1)); | |||
| } | |||
| } | |||
| @@ -537,7 +599,7 @@ static void encode_block(MpegEncContext *s, DCTELEM *block, int n) | |||
| run++; | |||
| } else { | |||
| while (run >= 16) { | |||
| jput_bits(&s->pb, huff_size_ac[0xf0], huff_code_ac[0xf0]); | |||
| put_bits(&s->pb, huff_size_ac[0xf0], huff_code_ac[0xf0]); | |||
| run -= 16; | |||
| } | |||
| mant = val; | |||
| @@ -554,16 +616,16 @@ static void encode_block(MpegEncContext *s, DCTELEM *block, int n) | |||
| } | |||
| code = (run << 4) | nbits; | |||
| jput_bits(&s->pb, huff_size_ac[code], huff_code_ac[code]); | |||
| put_bits(&s->pb, huff_size_ac[code], huff_code_ac[code]); | |||
| jput_bits(&s->pb, nbits, mant & ((1 << nbits) - 1)); | |||
| put_bits(&s->pb, nbits, mant & ((1 << nbits) - 1)); | |||
| run = 0; | |||
| } | |||
| } | |||
| /* output EOB only if not already 64 values */ | |||
| if (last_index < 63 || run != 0) | |||
| jput_bits(&s->pb, huff_size_ac[0], huff_code_ac[0]); | |||
| put_bits(&s->pb, huff_size_ac[0], huff_code_ac[0]); | |||
| } | |||
| void mjpeg_encode_mb(MpegEncContext *s, | |||
| @@ -1316,6 +1378,8 @@ static int mjpeg_decode_frame(AVCodecContext *avctx, | |||
| *(dst++) = x; | |||
| if (x == 0xff) | |||
| { | |||
| while(*src == 0xff) src++; | |||
| x = *(src++); | |||
| if (x >= 0xd0 && x <= 0xd7) | |||
| *(dst++) = x; | |||