diff options
Diffstat (limited to 'src/libffmpeg/libavcodec/mpegvideo.c')
-rw-r--r-- | src/libffmpeg/libavcodec/mpegvideo.c | 216 |
1 files changed, 163 insertions, 53 deletions
diff --git a/src/libffmpeg/libavcodec/mpegvideo.c b/src/libffmpeg/libavcodec/mpegvideo.c index 77d6691af..f1c1b34bb 100644 --- a/src/libffmpeg/libavcodec/mpegvideo.c +++ b/src/libffmpeg/libavcodec/mpegvideo.c @@ -55,6 +55,8 @@ static void dct_unquantize_mpeg1_inter_c(MpegEncContext *s, DCTELEM *block, int n, int qscale); static void dct_unquantize_mpeg2_intra_c(MpegEncContext *s, DCTELEM *block, int n, int qscale); +static void dct_unquantize_mpeg2_intra_bitexact(MpegEncContext *s, + DCTELEM *block, int n, int qscale); static void dct_unquantize_mpeg2_inter_c(MpegEncContext *s, DCTELEM *block, int n, int qscale); static void dct_unquantize_h263_intra_c(MpegEncContext *s, @@ -239,6 +241,7 @@ void ff_write_quant_matrix(PutBitContext *pb, int16_t *matrix){ const uint8_t *ff_find_start_code(const uint8_t * restrict p, const uint8_t *end, uint32_t * restrict state){ int i; + assert(p<=end); if(p>=end) return end; @@ -273,6 +276,8 @@ int DCT_common_init(MpegEncContext *s) s->dct_unquantize_mpeg1_intra = dct_unquantize_mpeg1_intra_c; s->dct_unquantize_mpeg1_inter = dct_unquantize_mpeg1_inter_c; s->dct_unquantize_mpeg2_intra = dct_unquantize_mpeg2_intra_c; + if(s->flags & CODEC_FLAG_BITEXACT) + s->dct_unquantize_mpeg2_intra = dct_unquantize_mpeg2_intra_bitexact; s->dct_unquantize_mpeg2_inter = dct_unquantize_mpeg2_inter_c; #ifdef CONFIG_ENCODERS @@ -490,8 +495,8 @@ static int init_duplicate_context(MpegEncContext *s, MpegEncContext *base){ int i; // edge emu needs blocksize + filter length - 1 (=17x17 for halfpel / 21x21 for h264) - CHECKED_ALLOCZ(s->allocated_edge_emu_buffer, (s->width+64)*2*17*2); //(width + edge + align)*interlaced*MBsize*tolerance - s->edge_emu_buffer= s->allocated_edge_emu_buffer + (s->width+64)*2*17; + CHECKED_ALLOCZ(s->allocated_edge_emu_buffer, (s->width+64)*2*21*2); //(width + edge + align)*interlaced*MBsize*tolerance + s->edge_emu_buffer= s->allocated_edge_emu_buffer + (s->width+64)*2*21; //FIXME should be linesize instead of s->width*2 but that isnt known before get_buffer() CHECKED_ALLOCZ(s->me.scratchpad, (s->width+64)*4*16*2*sizeof(uint8_t)) @@ -930,27 +935,43 @@ int MPV_encode_init(AVCodecContext *avctx) MPV_encode_defaults(s); - if(avctx->pix_fmt != PIX_FMT_YUVJ420P && avctx->pix_fmt != PIX_FMT_YUV420P){ - av_log(avctx, AV_LOG_ERROR, "only YUV420 is supported\n"); - return -1; - } - - if(avctx->codec_id == CODEC_ID_MJPEG || avctx->codec_id == CODEC_ID_LJPEG){ - if(avctx->strict_std_compliance>FF_COMPLIANCE_INOFFICIAL && avctx->pix_fmt != PIX_FMT_YUVJ420P){ + switch (avctx->codec_id) { + case CODEC_ID_MPEG2VIDEO: + if(avctx->pix_fmt != PIX_FMT_YUV420P && avctx->pix_fmt != PIX_FMT_YUV422P){ + av_log(avctx, AV_LOG_ERROR, "only YUV420 and YUV422 are supported\n"); + return -1; + } + break; + case CODEC_ID_LJPEG: + case CODEC_ID_MJPEG: + if(avctx->pix_fmt != PIX_FMT_YUVJ420P && (avctx->pix_fmt != PIX_FMT_YUV420P || avctx->strict_std_compliance>FF_COMPLIANCE_INOFFICIAL)){ av_log(avctx, AV_LOG_ERROR, "colorspace not supported in jpeg\n"); return -1; } - }else{ - if(avctx->strict_std_compliance>FF_COMPLIANCE_INOFFICIAL && avctx->pix_fmt != PIX_FMT_YUV420P){ - av_log(avctx, AV_LOG_ERROR, "colorspace not supported\n"); + break; + default: + if(avctx->pix_fmt != PIX_FMT_YUV420P){ + av_log(avctx, AV_LOG_ERROR, "only YUV420 is supported\n"); return -1; } } + switch (avctx->pix_fmt) { + case PIX_FMT_YUVJ422P: + case PIX_FMT_YUV422P: + s->chroma_format = CHROMA_422; + break; + case PIX_FMT_YUVJ420P: + case PIX_FMT_YUV420P: + default: + s->chroma_format = CHROMA_420; + break; + } + s->bit_rate = avctx->bit_rate; s->width = avctx->width; s->height = avctx->height; - if(avctx->gop_size > 600){ + if(avctx->gop_size > 600 && avctx->strict_std_compliance>FF_COMPLIANCE_EXPERIMENTAL){ av_log(avctx, AV_LOG_ERROR, "Warning keyframe interval too large! reducing it ...\n"); avctx->gop_size=600; } @@ -994,6 +1015,7 @@ int MPV_encode_init(AVCodecContext *avctx) s->obmc= !!(s->flags & CODEC_FLAG_OBMC); s->loop_filter= !!(s->flags & CODEC_FLAG_LOOP_FILTER); s->alternate_scan= !!(s->flags & CODEC_FLAG_ALT_SCAN); + s->intra_vlc_format= !!(s->flags2 & CODEC_FLAG2_INTRA_VLC); if(avctx->rc_max_rate && !avctx->rc_buffer_size){ av_log(avctx, AV_LOG_ERROR, "a vbv buffer size is needed, for encoding with a maximum bitrate\n"); @@ -1078,6 +1100,11 @@ int MPV_encode_init(AVCodecContext *avctx) return -1; } + if((s->flags2 & CODEC_FLAG2_INTRA_VLC) && s->codec_id != CODEC_ID_MPEG2VIDEO){ + av_log(avctx, AV_LOG_ERROR, "intra vlc table not supported by codec\n"); + return -1; + } + if(s->avctx->thread_count > 1 && s->codec_id != CODEC_ID_MPEG4 && s->codec_id != CODEC_ID_MPEG1VIDEO && s->codec_id != CODEC_ID_MPEG2VIDEO && (s->codec_id != CODEC_ID_H263P || !(s->flags & CODEC_FLAG_H263P_SLICE_STRUCT))){ @@ -1104,8 +1131,8 @@ int MPV_encode_init(AVCodecContext *avctx) } if(avctx->b_frame_strategy && (avctx->flags&CODEC_FLAG_PASS2)){ - av_log(avctx, AV_LOG_ERROR, "b_frame_strategy must be 0 on the second pass\n"); - return -1; + av_log(avctx, AV_LOG_INFO, "notice: b_frame_strategy only affects the first pass\n"); + avctx->b_frame_strategy = 0; } i= ff_gcd(avctx->time_base.den, avctx->time_base.num); @@ -1359,10 +1386,6 @@ int MPV_encode_end(AVCodecContext *avctx) { MpegEncContext *s = avctx->priv_data; -#ifdef STATS - print_stats(); -#endif - ff_rate_control_uninit(s); /* xine: do not need this for decode or MPEG-1 encoding modes */ @@ -1848,7 +1871,7 @@ void ff_print_debug_info(MpegEncContext *s, AVFrame *pict){ const int width = s->avctx->width; const int height= s->avctx->height; const int mv_sample_log2= 4 - pict->motion_subsample_log2; - const int mv_stride= (s->mb_width << mv_sample_log2) + 1; + const int mv_stride= (s->mb_width << mv_sample_log2) + (s->codec_id == CODEC_ID_H264 ? 0 : 1); s->low_delay=0; //needed to see the vectors without trashing the buffers avcodec_get_chroma_sub_sample(s->avctx->pix_fmt, &h_chroma_shift, &v_chroma_shift); @@ -2197,10 +2220,11 @@ static int estimate_best_b_count(MpegEncContext *s){ int i, j, out_size, p_lambda, b_lambda, lambda2; int outbuf_size= s->width * s->height; //FIXME uint8_t *outbuf= av_malloc(outbuf_size); - ImgReSampleContext *resample; int64_t best_rd= INT64_MAX; int best_b_count= -1; + assert(scale>=0 && scale <=3); + // emms_c(); p_lambda= s->last_lambda_for[P_TYPE]; //s->next_picture_ptr->quality; b_lambda= s->last_lambda_for[B_TYPE]; //p_lambda *ABS(s->avctx->b_quant_factor) + s->avctx->b_quant_offset; @@ -2222,8 +2246,6 @@ static int estimate_best_b_count(MpegEncContext *s){ if (avcodec_open(c, codec) < 0) return -1; - resample= img_resample_init(c->width, c->height, s->width, s->height); //FIXME use sws - for(i=0; i<s->max_b_frames+2; i++){ int ysize= c->width*c->height; int csize= (c->width/2)*(c->height/2); @@ -2246,8 +2268,11 @@ static int estimate_best_b_count(MpegEncContext *s){ input[i].linesize[1]= input[i].linesize[2]= c->width/2; - if(!i || s->input_picture[i-1]) - img_resample(resample, &input[i], &pre_input); + if(!i || s->input_picture[i-1]){ + s->dsp.shrink[scale](input[i].data[0], input[i].linesize[0], pre_input.data[0], pre_input.linesize[0], c->width, c->height); + s->dsp.shrink[scale](input[i].data[1], input[i].linesize[1], pre_input.data[1], pre_input.linesize[1], c->width>>1, c->height>>1); + s->dsp.shrink[scale](input[i].data[2], input[i].linesize[2], pre_input.data[2], pre_input.linesize[2], c->width>>1, c->height>>1); + } } for(j=0; j<s->max_b_frames+1; j++){ @@ -2289,7 +2314,6 @@ static int estimate_best_b_count(MpegEncContext *s){ av_freep(&outbuf); avcodec_close(c); av_freep(&c); - img_resample_close(resample); for(i=0; i<s->max_b_frames+2; i++){ av_freep(&input[i].data[0]); @@ -2365,7 +2389,7 @@ static void select_input_picture(MpegEncContext *s){ } } for(i=0; i<s->max_b_frames+1; i++){ - if(s->input_picture[i]==NULL || s->input_picture[i]->b_frame_score - 1 > s->mb_num/40) break; + if(s->input_picture[i]==NULL || s->input_picture[i]->b_frame_score - 1 > s->mb_num/s->avctx->b_sensitivity) break; } b_frames= FFMAX(0, i-1); @@ -2472,11 +2496,6 @@ int MPV_encode_picture(AVCodecContext *avctx, AVFrame *pic_arg = data; int i, stuffing_count; - if(avctx->pix_fmt != PIX_FMT_YUV420P && avctx->pix_fmt != PIX_FMT_YUVJ420P){ - av_log(avctx, AV_LOG_ERROR, "this codec supports only YUV420P\n"); - return -1; - } - for(i=0; i<avctx->thread_count; i++){ int start_y= s->thread_context[i]->start_mb_y; int end_y= s->thread_context[i]-> end_mb_y; @@ -3378,6 +3397,18 @@ static inline void chroma_4mv_motion_lowres(MpegEncContext *s, pix_op[lowres](dest_cr, ptr, s->uvlinesize, block_s, sx, sy); } +static inline void prefetch_motion(MpegEncContext *s, uint8_t **pix, int dir){ + /* fetch pixels for estimated mv 4 macroblocks ahead + * optimized for 64byte cache lines */ + const int shift = s->quarter_sample ? 2 : 1; + const int mx= (s->mv[dir][0][0]>>shift) + 16*s->mb_x + 8; + const int my= (s->mv[dir][0][1]>>shift) + 16*s->mb_y; + int off= mx + (my + (s->mb_x&3)*4)*s->linesize + 64; + s->dsp.prefetch(pix[0]+off, s->linesize, 4); + off= (mx>>1) + ((my>>1) + (s->mb_x&7))*s->uvlinesize + 64; + s->dsp.prefetch(pix[1]+off, pix[2]-pix[1], 2); +} + /** * motion compensation of a single macroblock * @param s context @@ -3402,6 +3433,8 @@ static inline void MPV_motion(MpegEncContext *s, mb_x = s->mb_x; mb_y = s->mb_y; + prefetch_motion(s, ref_picture, dir); + if(s->obmc && s->pict_type != B_TYPE){ int16_t mv_cache[4][4][2]; const int xy= s->mb_x + s->mb_y*s->mb_stride; @@ -3963,8 +3996,17 @@ static always_inline void MPV_decode_mb_internal(MpegEncContext *s, DCTELEM bloc add_dequant_dct(s, block[3], 3, dest_y + dct_offset + block_size, dct_linesize, s->qscale); if(!(s->flags&CODEC_FLAG_GRAY)){ - add_dequant_dct(s, block[4], 4, dest_cb, uvlinesize, s->chroma_qscale); - add_dequant_dct(s, block[5], 5, dest_cr, uvlinesize, s->chroma_qscale); + if (s->chroma_y_shift){ + add_dequant_dct(s, block[4], 4, dest_cb, uvlinesize, s->chroma_qscale); + add_dequant_dct(s, block[5], 5, dest_cr, uvlinesize, s->chroma_qscale); + }else{ + dct_linesize >>= 1; + dct_offset >>=1; + add_dequant_dct(s, block[4], 4, dest_cb, dct_linesize, s->chroma_qscale); + add_dequant_dct(s, block[5], 5, dest_cr, dct_linesize, s->chroma_qscale); + add_dequant_dct(s, block[6], 6, dest_cb + dct_offset, dct_linesize, s->chroma_qscale); + add_dequant_dct(s, block[7], 7, dest_cr + dct_offset, dct_linesize, s->chroma_qscale); + } } } else if(s->codec_id != CODEC_ID_WMV2){ add_dct(s, block[0], 0, dest_y , dct_linesize); @@ -4006,8 +4048,17 @@ static always_inline void MPV_decode_mb_internal(MpegEncContext *s, DCTELEM bloc put_dct(s, block[3], 3, dest_y + dct_offset + block_size, dct_linesize, s->qscale); if(!(s->flags&CODEC_FLAG_GRAY)){ - put_dct(s, block[4], 4, dest_cb, uvlinesize, s->chroma_qscale); - put_dct(s, block[5], 5, dest_cr, uvlinesize, s->chroma_qscale); + if(s->chroma_y_shift){ + put_dct(s, block[4], 4, dest_cb, uvlinesize, s->chroma_qscale); + put_dct(s, block[5], 5, dest_cr, uvlinesize, s->chroma_qscale); + }else{ + dct_offset >>=1; + dct_linesize >>=1; + put_dct(s, block[4], 4, dest_cb, dct_linesize, s->chroma_qscale); + put_dct(s, block[5], 5, dest_cr, dct_linesize, s->chroma_qscale); + put_dct(s, block[6], 6, dest_cb + dct_offset, dct_linesize, s->chroma_qscale); + put_dct(s, block[7], 7, dest_cr + dct_offset, dct_linesize, s->chroma_qscale); + } } }else{ s->dsp.idct_put(dest_y , dct_linesize, block[0]); @@ -4229,19 +4280,19 @@ static void get_vissual_weight(int16_t *weight, uint8_t *ptr, int stride){ } } -static void encode_mb(MpegEncContext *s, int motion_x, int motion_y) +static always_inline void encode_mb_internal(MpegEncContext *s, int motion_x, int motion_y, int mb_block_height, int mb_block_count) { - int16_t weight[6][64]; - DCTELEM orig[6][64]; + int16_t weight[8][64]; + DCTELEM orig[8][64]; const int mb_x= s->mb_x; const int mb_y= s->mb_y; int i; - int skip_dct[6]; + int skip_dct[8]; int dct_offset = s->linesize*8; //default for progressive frames uint8_t *ptr_y, *ptr_cb, *ptr_cr; int wrap_y, wrap_c; - for(i=0; i<6; i++) skip_dct[i]=0; + for(i=0; i<mb_block_count; i++) skip_dct[i]=0; if(s->adaptive_quant){ const int last_qp= s->qscale; @@ -4277,16 +4328,16 @@ static void encode_mb(MpegEncContext *s, int motion_x, int motion_y) wrap_y = s->linesize; wrap_c = s->uvlinesize; ptr_y = s->new_picture.data[0] + (mb_y * 16 * wrap_y) + mb_x * 16; - ptr_cb = s->new_picture.data[1] + (mb_y * 8 * wrap_c) + mb_x * 8; - ptr_cr = s->new_picture.data[2] + (mb_y * 8 * wrap_c) + mb_x * 8; + ptr_cb = s->new_picture.data[1] + (mb_y * mb_block_height * wrap_c) + mb_x * 8; + ptr_cr = s->new_picture.data[2] + (mb_y * mb_block_height * wrap_c) + mb_x * 8; if(mb_x*16+16 > s->width || mb_y*16+16 > s->height){ uint8_t *ebuf= s->edge_emu_buffer + 32; ff_emulated_edge_mc(ebuf , ptr_y , wrap_y,16,16,mb_x*16,mb_y*16, s->width , s->height); ptr_y= ebuf; - ff_emulated_edge_mc(ebuf+18*wrap_y , ptr_cb, wrap_c, 8, 8, mb_x*8, mb_y*8, s->width>>1, s->height>>1); + ff_emulated_edge_mc(ebuf+18*wrap_y , ptr_cb, wrap_c, 8, mb_block_height, mb_x*8, mb_y*8, s->width>>1, s->height>>1); ptr_cb= ebuf+18*wrap_y; - ff_emulated_edge_mc(ebuf+18*wrap_y+8, ptr_cr, wrap_c, 8, 8, mb_x*8, mb_y*8, s->width>>1, s->height>>1); + ff_emulated_edge_mc(ebuf+18*wrap_y+8, ptr_cr, wrap_c, 8, mb_block_height, mb_x*8, mb_y*8, s->width>>1, s->height>>1); ptr_cr= ebuf+18*wrap_y+8; } @@ -4306,6 +4357,8 @@ static void encode_mb(MpegEncContext *s, int motion_x, int motion_y) dct_offset= wrap_y; wrap_y<<=1; + if (s->chroma_format == CHROMA_422) + wrap_c<<=1; } } } @@ -4321,6 +4374,10 @@ static void encode_mb(MpegEncContext *s, int motion_x, int motion_y) }else{ s->dsp.get_pixels(s->block[4], ptr_cb, wrap_c); s->dsp.get_pixels(s->block[5], ptr_cr, wrap_c); + if(!s->chroma_y_shift){ /* 422 */ + s->dsp.get_pixels(s->block[6], ptr_cb + (dct_offset>>1), wrap_c); + s->dsp.get_pixels(s->block[7], ptr_cr + (dct_offset>>1), wrap_c); + } } }else{ op_pixels_func (*op_pix)[4]; @@ -4366,6 +4423,8 @@ static void encode_mb(MpegEncContext *s, int motion_x, int motion_y) dct_offset= wrap_y; wrap_y<<=1; + if (s->chroma_format == CHROMA_422) + wrap_c<<=1; } } } @@ -4381,6 +4440,10 @@ static void encode_mb(MpegEncContext *s, int motion_x, int motion_y) }else{ s->dsp.diff_pixels(s->block[4], ptr_cb, dest_cb, wrap_c); s->dsp.diff_pixels(s->block[5], ptr_cr, dest_cr, wrap_c); + if(!s->chroma_y_shift){ /* 422 */ + s->dsp.diff_pixels(s->block[6], ptr_cb + (dct_offset>>1), dest_cb + (dct_offset>>1), wrap_c); + s->dsp.diff_pixels(s->block[7], ptr_cr + (dct_offset>>1), dest_cr + (dct_offset>>1), wrap_c); + } } /* pre quantization */ if(s->current_picture.mc_mb_var[s->mb_stride*mb_y+ mb_x]<2*s->qscale*s->qscale){ @@ -4391,6 +4454,10 @@ static void encode_mb(MpegEncContext *s, int motion_x, int motion_y) if(s->dsp.sad[1](NULL, ptr_y +dct_offset+ 8, dest_y +dct_offset+ 8, wrap_y, 8) < 20*s->qscale) skip_dct[3]= 1; if(s->dsp.sad[1](NULL, ptr_cb , dest_cb , wrap_c, 8) < 20*s->qscale) skip_dct[4]= 1; if(s->dsp.sad[1](NULL, ptr_cr , dest_cr , wrap_c, 8) < 20*s->qscale) skip_dct[5]= 1; + if(!s->chroma_y_shift){ /* 422 */ + if(s->dsp.sad[1](NULL, ptr_cb +(dct_offset>>1), dest_cb +(dct_offset>>1), wrap_c, 8) < 20*s->qscale) skip_dct[6]= 1; + if(s->dsp.sad[1](NULL, ptr_cr +(dct_offset>>1), dest_cr +(dct_offset>>1), wrap_c, 8) < 20*s->qscale) skip_dct[7]= 1; + } } } @@ -4401,13 +4468,17 @@ static void encode_mb(MpegEncContext *s, int motion_x, int motion_y) if(!skip_dct[3]) get_vissual_weight(weight[3], ptr_y + dct_offset + 8, wrap_y); if(!skip_dct[4]) get_vissual_weight(weight[4], ptr_cb , wrap_c); if(!skip_dct[5]) get_vissual_weight(weight[5], ptr_cr , wrap_c); - memcpy(orig[0], s->block[0], sizeof(DCTELEM)*64*6); + if(!s->chroma_y_shift){ /* 422 */ + if(!skip_dct[6]) get_vissual_weight(weight[6], ptr_cb + (dct_offset>>1), wrap_c); + if(!skip_dct[7]) get_vissual_weight(weight[7], ptr_cr + (dct_offset>>1), wrap_c); + } + memcpy(orig[0], s->block[0], sizeof(DCTELEM)*64*mb_block_count); } /* DCT & quantize */ assert(s->out_format!=FMT_MJPEG || s->qscale==8); { - for(i=0;i<6;i++) { + for(i=0;i<mb_block_count;i++) { if(!skip_dct[i]){ int overflow; s->block_last_index[i] = s->dct_quantize(s, s->block[i], i, s->qscale, &overflow); @@ -4419,7 +4490,7 @@ static void encode_mb(MpegEncContext *s, int motion_x, int motion_y) s->block_last_index[i]= -1; } if(s->avctx->quantizer_noise_shaping){ - for(i=0;i<6;i++) { + for(i=0;i<mb_block_count;i++) { if(!skip_dct[i]){ s->block_last_index[i] = dct_quantize_refine(s, s->block[i], weight[i], orig[i], i, s->qscale); } @@ -4430,11 +4501,11 @@ static void encode_mb(MpegEncContext *s, int motion_x, int motion_y) for(i=0; i<4; i++) dct_single_coeff_elimination(s, i, s->luma_elim_threshold); if(s->chroma_elim_threshold && !s->mb_intra) - for(i=4; i<6; i++) + for(i=4; i<mb_block_count; i++) dct_single_coeff_elimination(s, i, s->chroma_elim_threshold); if(s->flags & CODEC_FLAG_CBP_RD){ - for(i=0;i<6;i++) { + for(i=0;i<mb_block_count;i++) { if(s->block_last_index[i] == -1) s->coded_score[i]= INT_MAX/256; } @@ -4450,7 +4521,7 @@ static void encode_mb(MpegEncContext *s, int motion_x, int motion_y) //non c quantize code returns incorrect block_last_index FIXME if(s->alternate_scan && s->dct_quantize != dct_quantize_c){ - for(i=0; i<6; i++){ + for(i=0; i<mb_block_count; i++){ int j; if(s->block_last_index[i]>0){ for(j=63; j>0; j--){ @@ -4494,6 +4565,12 @@ static void encode_mb(MpegEncContext *s, int motion_x, int motion_y) } } +static always_inline void encode_mb(MpegEncContext *s, int motion_x, int motion_y) +{ + if (s->chroma_format == CHROMA_420) encode_mb_internal(s, motion_x, motion_y, 8, 6); + else encode_mb_internal(s, motion_x, motion_y, 16, 8); +} + #endif //CONFIG_ENCODERS void ff_mpeg_flush(AVCodecContext *avctx){ @@ -4603,7 +4680,7 @@ static inline void copy_context_after_encode(MpegEncContext *d, MpegEncContext * d->tex_pb= s->tex_pb; } d->block= s->block; - for(i=0; i<6; i++) + for(i=0; i<8; i++) d->block_last_index[i]= s->block_last_index[i]; d->interlaced_dct= s->interlaced_dct; d->qscale= s->qscale; @@ -5621,7 +5698,7 @@ static void encode_picture(MpegEncContext *s, int picture_number) for(i=1;i<64;i++){ int j= s->dsp.idct_permutation[i]; - s->intra_matrix[j] = clip_uint8((ff_mpeg1_default_intra_matrix[i] * s->qscale) >> 3) & 0xFF; + s->intra_matrix[j] = clip_uint8((ff_mpeg1_default_intra_matrix[i] * s->qscale) >> 3); } convert_matrix(&s->dsp, s->q_intra_matrix, s->q_intra_matrix16, s->intra_matrix, s->intra_quant_bias, 8, 8, 1); @@ -6581,6 +6658,39 @@ static void dct_unquantize_mpeg2_intra_c(MpegEncContext *s, } } +static void dct_unquantize_mpeg2_intra_bitexact(MpegEncContext *s, + DCTELEM *block, int n, int qscale) +{ + int i, level, nCoeffs; + const uint16_t *quant_matrix; + int sum=-1; + + if(s->alternate_scan) nCoeffs= 63; + else nCoeffs= s->block_last_index[n]; + + if (n < 4) + block[0] = block[0] * s->y_dc_scale; + else + block[0] = block[0] * s->c_dc_scale; + quant_matrix = s->intra_matrix; + for(i=1;i<=nCoeffs;i++) { + int j= s->intra_scantable.permutated[i]; + level = block[j]; + if (level) { + if (level < 0) { + level = -level; + level = (int)(level * qscale * quant_matrix[j]) >> 3; + level = -level; + } else { + level = (int)(level * qscale * quant_matrix[j]) >> 3; + } + block[j] = level; + sum+=level; + } + } + block[63]^=sum&1; +} + static void dct_unquantize_mpeg2_inter_c(MpegEncContext *s, DCTELEM *block, int n, int qscale) { |