| /* |
| * H263/MPEG4 backend for ffmpeg encoder and decoder |
| * Copyright (c) 2000,2001 Fabrice Bellard |
| * H263+ support. |
| * Copyright (c) 2001 Juan J. Sierralta P |
| * Copyright (c) 2002-2004 Michael Niedermayer <michaelni@gmx.at> |
| * |
| * ac prediction encoding, B-frame support, error resilience, optimizations, |
| * qpel decoding, gmc decoding, interlaced decoding |
| * by Michael Niedermayer <michaelni@gmx.at> |
| * |
| * This file is part of FFmpeg. |
| * |
| * FFmpeg is free software; you can redistribute it and/or |
| * modify it under the terms of the GNU Lesser General Public |
| * License as published by the Free Software Foundation; either |
| * version 2.1 of the License, or (at your option) any later version. |
| * |
| * FFmpeg is distributed in the hope that it will be useful, |
| * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| * Lesser General Public License for more details. |
| * |
| * You should have received a copy of the GNU Lesser General Public |
| * License along with FFmpeg; if not, write to the Free Software |
| * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
| */ |
| |
| /** |
| * @file libavcodec/h263.c |
| * h263/mpeg4 codec. |
| */ |
| |
| //#define DEBUG |
| #include <limits.h> |
| |
| #include "dsputil.h" |
| #include "avcodec.h" |
| #include "mpegvideo.h" |
| #include "h263data.h" |
| #include "mpeg4data.h" |
| #include "mathops.h" |
| #include "unary.h" |
| |
| //#undef NDEBUG |
| //#include <assert.h> |
| |
| #define INTRA_MCBPC_VLC_BITS 6 |
| #define INTER_MCBPC_VLC_BITS 7 |
| #define CBPY_VLC_BITS 6 |
| #define MV_VLC_BITS 9 |
| #define DC_VLC_BITS 9 |
| #define SPRITE_TRAJ_VLC_BITS 6 |
| #define MB_TYPE_B_VLC_BITS 4 |
| #define TEX_VLC_BITS 9 |
| #define H263_MBTYPE_B_VLC_BITS 6 |
| #define CBPC_B_VLC_BITS 3 |
| |
| static void h263_encode_block(MpegEncContext * s, DCTELEM * block, |
| int n); |
| static void h263p_encode_umotion(MpegEncContext * s, int val); |
| static inline void mpeg4_encode_block(MpegEncContext * s, DCTELEM * block, |
| int n, int dc, uint8_t *scan_table, |
| PutBitContext *dc_pb, PutBitContext *ac_pb); |
| static int mpeg4_get_block_length(MpegEncContext * s, DCTELEM * block, int n, int intra_dc, |
| uint8_t *scan_table); |
| |
| static int h263_decode_motion(MpegEncContext * s, int pred, int fcode); |
| static int h263p_decode_umotion(MpegEncContext * s, int pred); |
| static int h263_decode_block(MpegEncContext * s, DCTELEM * block, |
| int n, int coded); |
| static inline int mpeg4_decode_dc(MpegEncContext * s, int n, int *dir_ptr); |
| static inline int mpeg4_decode_block(MpegEncContext * s, DCTELEM * block, |
| int n, int coded, int intra, int rvlc); |
| |
| static int h263_pred_dc(MpegEncContext * s, int n, int16_t **dc_val_ptr); |
| static void mpeg4_encode_visual_object_header(MpegEncContext * s); |
| static void mpeg4_encode_vol_header(MpegEncContext * s, int vo_number, int vol_number); |
| |
| static void mpeg4_decode_sprite_trajectory(MpegEncContext * s, GetBitContext *gb); |
| static inline int ff_mpeg4_pred_dc(MpegEncContext * s, int n, int level, int *dir_ptr, int encoding); |
| |
| #if CONFIG_ENCODERS |
| static uint8_t uni_DCtab_lum_len[512]; |
| static uint8_t uni_DCtab_chrom_len[512]; |
| static uint16_t uni_DCtab_lum_bits[512]; |
| static uint16_t uni_DCtab_chrom_bits[512]; |
| |
| static uint8_t mv_penalty[MAX_FCODE+1][MAX_MV*2+1]; |
| static uint8_t fcode_tab[MAX_MV*2+1]; |
| static uint8_t umv_fcode_tab[MAX_MV*2+1]; |
| |
| static uint32_t uni_mpeg4_intra_rl_bits[64*64*2*2]; |
| static uint8_t uni_mpeg4_intra_rl_len [64*64*2*2]; |
| static uint32_t uni_mpeg4_inter_rl_bits[64*64*2*2]; |
| static uint8_t uni_mpeg4_inter_rl_len [64*64*2*2]; |
| static uint8_t uni_h263_intra_aic_rl_len [64*64*2*2]; |
| static uint8_t uni_h263_inter_rl_len [64*64*2*2]; |
| //#define UNI_MPEG4_ENC_INDEX(last,run,level) ((last)*128 + (run)*256 + (level)) |
| //#define UNI_MPEG4_ENC_INDEX(last,run,level) ((last)*128*64 + (run) + (level)*64) |
| #define UNI_MPEG4_ENC_INDEX(last,run,level) ((last)*128*64 + (run)*128 + (level)) |
| |
| /* mpeg4 |
| inter |
| max level: 24/6 |
| max run: 53/63 |
| |
| intra |
| max level: 53/16 |
| max run: 29/41 |
| */ |
| #endif |
| |
| static uint8_t static_rl_table_store[5][2][2*MAX_RUN + MAX_LEVEL + 3]; |
| |
| #if 0 //3IV1 is quite rare and it slows things down a tiny bit |
| #define IS_3IV1 s->codec_tag == AV_RL32("3IV1") |
| #else |
| #define IS_3IV1 0 |
| #endif |
| |
| int h263_get_picture_format(int width, int height) |
| { |
| int format; |
| |
| if (width == 128 && height == 96) |
| format = 1; |
| else if (width == 176 && height == 144) |
| format = 2; |
| else if (width == 352 && height == 288) |
| format = 3; |
| else if (width == 704 && height == 576) |
| format = 4; |
| else if (width == 1408 && height == 1152) |
| format = 5; |
| else |
| format = 7; |
| return format; |
| } |
| |
| static void show_pict_info(MpegEncContext *s){ |
| av_log(s->avctx, AV_LOG_DEBUG, "qp:%d %c size:%d rnd:%d%s%s%s%s%s%s%s%s%s %d/%d\n", |
| s->qscale, av_get_pict_type_char(s->pict_type), |
| s->gb.size_in_bits, 1-s->no_rounding, |
| s->obmc ? " AP" : "", |
| s->umvplus ? " UMV" : "", |
| s->h263_long_vectors ? " LONG" : "", |
| s->h263_plus ? " +" : "", |
| s->h263_aic ? " AIC" : "", |
| s->alt_inter_vlc ? " AIV" : "", |
| s->modified_quant ? " MQ" : "", |
| s->loop_filter ? " LOOP" : "", |
| s->h263_slice_structured ? " SS" : "", |
| s->avctx->time_base.den, s->avctx->time_base.num |
| ); |
| } |
| |
| #if CONFIG_ENCODERS |
| |
| static void aspect_to_info(MpegEncContext * s, AVRational aspect){ |
| int i; |
| |
| if(aspect.num==0) aspect= (AVRational){1,1}; |
| |
| for(i=1; i<6; i++){ |
| if(av_cmp_q(pixel_aspect[i], aspect) == 0){ |
| s->aspect_ratio_info=i; |
| return; |
| } |
| } |
| |
| s->aspect_ratio_info= FF_ASPECT_EXTENDED; |
| } |
| |
| void ff_flv_encode_picture_header(MpegEncContext * s, int picture_number) |
| { |
| int format; |
| |
| align_put_bits(&s->pb); |
| |
| put_bits(&s->pb, 17, 1); |
| put_bits(&s->pb, 5, (s->h263_flv-1)); /* 0: h263 escape codes 1: 11-bit escape codes */ |
| put_bits(&s->pb, 8, (((int64_t)s->picture_number * 30 * s->avctx->time_base.num) / //FIXME use timestamp |
| s->avctx->time_base.den) & 0xff); /* TemporalReference */ |
| if (s->width == 352 && s->height == 288) |
| format = 2; |
| else if (s->width == 176 && s->height == 144) |
| format = 3; |
| else if (s->width == 128 && s->height == 96) |
| format = 4; |
| else if (s->width == 320 && s->height == 240) |
| format = 5; |
| else if (s->width == 160 && s->height == 120) |
| format = 6; |
| else if (s->width <= 255 && s->height <= 255) |
| format = 0; /* use 1 byte width & height */ |
| else |
| format = 1; /* use 2 bytes width & height */ |
| put_bits(&s->pb, 3, format); /* PictureSize */ |
| if (format == 0) { |
| put_bits(&s->pb, 8, s->width); |
| put_bits(&s->pb, 8, s->height); |
| } else if (format == 1) { |
| put_bits(&s->pb, 16, s->width); |
| put_bits(&s->pb, 16, s->height); |
| } |
| put_bits(&s->pb, 2, s->pict_type == FF_P_TYPE); /* PictureType */ |
| put_bits(&s->pb, 1, 1); /* DeblockingFlag: on */ |
| put_bits(&s->pb, 5, s->qscale); /* Quantizer */ |
| put_bits(&s->pb, 1, 0); /* ExtraInformation */ |
| |
| if(s->h263_aic){ |
| s->y_dc_scale_table= |
| s->c_dc_scale_table= ff_aic_dc_scale_table; |
| }else{ |
| s->y_dc_scale_table= |
| s->c_dc_scale_table= ff_mpeg1_dc_scale_table; |
| } |
| } |
| |
| void h263_encode_picture_header(MpegEncContext * s, int picture_number) |
| { |
| int format, coded_frame_rate, coded_frame_rate_base, i, temp_ref; |
| int best_clock_code=1; |
| int best_divisor=60; |
| int best_error= INT_MAX; |
| |
| if(s->h263_plus){ |
| for(i=0; i<2; i++){ |
| int div, error; |
| div= (s->avctx->time_base.num*1800000LL + 500LL*s->avctx->time_base.den) / ((1000LL+i)*s->avctx->time_base.den); |
| div= av_clip(div, 1, 127); |
| error= FFABS(s->avctx->time_base.num*1800000LL - (1000LL+i)*s->avctx->time_base.den*div); |
| if(error < best_error){ |
| best_error= error; |
| best_divisor= div; |
| best_clock_code= i; |
| } |
| } |
| } |
| s->custom_pcf= best_clock_code!=1 || best_divisor!=60; |
| coded_frame_rate= 1800000; |
| coded_frame_rate_base= (1000+best_clock_code)*best_divisor; |
| |
| align_put_bits(&s->pb); |
| |
| /* Update the pointer to last GOB */ |
| s->ptr_lastgob = pbBufPtr(&s->pb); |
| put_bits(&s->pb, 22, 0x20); /* PSC */ |
| temp_ref= s->picture_number * (int64_t)coded_frame_rate * s->avctx->time_base.num / //FIXME use timestamp |
| (coded_frame_rate_base * (int64_t)s->avctx->time_base.den); |
| put_sbits(&s->pb, 8, temp_ref); /* TemporalReference */ |
| |
| put_bits(&s->pb, 1, 1); /* marker */ |
| put_bits(&s->pb, 1, 0); /* h263 id */ |
| put_bits(&s->pb, 1, 0); /* split screen off */ |
| put_bits(&s->pb, 1, 0); /* camera off */ |
| put_bits(&s->pb, 1, 0); /* freeze picture release off */ |
| |
| format = h263_get_picture_format(s->width, s->height); |
| if (!s->h263_plus) { |
| /* H.263v1 */ |
| put_bits(&s->pb, 3, format); |
| put_bits(&s->pb, 1, (s->pict_type == FF_P_TYPE)); |
| /* By now UMV IS DISABLED ON H.263v1, since the restrictions |
| of H.263v1 UMV implies to check the predicted MV after |
| calculation of the current MB to see if we're on the limits */ |
| put_bits(&s->pb, 1, 0); /* Unrestricted Motion Vector: off */ |
| put_bits(&s->pb, 1, 0); /* SAC: off */ |
| put_bits(&s->pb, 1, s->obmc); /* Advanced Prediction */ |
| put_bits(&s->pb, 1, 0); /* only I/P frames, no PB frame */ |
| put_bits(&s->pb, 5, s->qscale); |
| put_bits(&s->pb, 1, 0); /* Continuous Presence Multipoint mode: off */ |
| } else { |
| int ufep=1; |
| /* H.263v2 */ |
| /* H.263 Plus PTYPE */ |
| |
| put_bits(&s->pb, 3, 7); |
| put_bits(&s->pb,3,ufep); /* Update Full Extended PTYPE */ |
| if (format == 7) |
| put_bits(&s->pb,3,6); /* Custom Source Format */ |
| else |
| put_bits(&s->pb, 3, format); |
| |
| put_bits(&s->pb,1, s->custom_pcf); |
| put_bits(&s->pb,1, s->umvplus); /* Unrestricted Motion Vector */ |
| put_bits(&s->pb,1,0); /* SAC: off */ |
| put_bits(&s->pb,1,s->obmc); /* Advanced Prediction Mode */ |
| put_bits(&s->pb,1,s->h263_aic); /* Advanced Intra Coding */ |
| put_bits(&s->pb,1,s->loop_filter); /* Deblocking Filter */ |
| put_bits(&s->pb,1,s->h263_slice_structured); /* Slice Structured */ |
| put_bits(&s->pb,1,0); /* Reference Picture Selection: off */ |
| put_bits(&s->pb,1,0); /* Independent Segment Decoding: off */ |
| put_bits(&s->pb,1,s->alt_inter_vlc); /* Alternative Inter VLC */ |
| put_bits(&s->pb,1,s->modified_quant); /* Modified Quantization: */ |
| put_bits(&s->pb,1,1); /* "1" to prevent start code emulation */ |
| put_bits(&s->pb,3,0); /* Reserved */ |
| |
| put_bits(&s->pb, 3, s->pict_type == FF_P_TYPE); |
| |
| put_bits(&s->pb,1,0); /* Reference Picture Resampling: off */ |
| put_bits(&s->pb,1,0); /* Reduced-Resolution Update: off */ |
| put_bits(&s->pb,1,s->no_rounding); /* Rounding Type */ |
| put_bits(&s->pb,2,0); /* Reserved */ |
| put_bits(&s->pb,1,1); /* "1" to prevent start code emulation */ |
| |
| /* This should be here if PLUSPTYPE */ |
| put_bits(&s->pb, 1, 0); /* Continuous Presence Multipoint mode: off */ |
| |
| if (format == 7) { |
| /* Custom Picture Format (CPFMT) */ |
| aspect_to_info(s, s->avctx->sample_aspect_ratio); |
| |
| put_bits(&s->pb,4,s->aspect_ratio_info); |
| put_bits(&s->pb,9,(s->width >> 2) - 1); |
| put_bits(&s->pb,1,1); /* "1" to prevent start code emulation */ |
| put_bits(&s->pb,9,(s->height >> 2)); |
| if (s->aspect_ratio_info == FF_ASPECT_EXTENDED){ |
| put_bits(&s->pb, 8, s->avctx->sample_aspect_ratio.num); |
| put_bits(&s->pb, 8, s->avctx->sample_aspect_ratio.den); |
| } |
| } |
| if(s->custom_pcf){ |
| if(ufep){ |
| put_bits(&s->pb, 1, best_clock_code); |
| put_bits(&s->pb, 7, best_divisor); |
| } |
| put_sbits(&s->pb, 2, temp_ref>>8); |
| } |
| |
| /* Unlimited Unrestricted Motion Vectors Indicator (UUI) */ |
| if (s->umvplus) |
| // put_bits(&s->pb,1,1); /* Limited according tables of Annex D */ |
| //FIXME check actual requested range |
| put_bits(&s->pb,2,1); /* unlimited */ |
| if(s->h263_slice_structured) |
| put_bits(&s->pb,2,0); /* no weird submodes */ |
| |
| put_bits(&s->pb, 5, s->qscale); |
| } |
| |
| put_bits(&s->pb, 1, 0); /* no PEI */ |
| |
| if(s->h263_slice_structured){ |
| put_bits(&s->pb, 1, 1); |
| |
| assert(s->mb_x == 0 && s->mb_y == 0); |
| ff_h263_encode_mba(s); |
| |
| put_bits(&s->pb, 1, 1); |
| } |
| |
| if(s->h263_aic){ |
| s->y_dc_scale_table= |
| s->c_dc_scale_table= ff_aic_dc_scale_table; |
| }else{ |
| s->y_dc_scale_table= |
| s->c_dc_scale_table= ff_mpeg1_dc_scale_table; |
| } |
| } |
| |
| /** |
| * Encodes a group of blocks header. |
| */ |
| void h263_encode_gob_header(MpegEncContext * s, int mb_line) |
| { |
| put_bits(&s->pb, 17, 1); /* GBSC */ |
| |
| if(s->h263_slice_structured){ |
| put_bits(&s->pb, 1, 1); |
| |
| ff_h263_encode_mba(s); |
| |
| if(s->mb_num > 1583) |
| put_bits(&s->pb, 1, 1); |
| put_bits(&s->pb, 5, s->qscale); /* GQUANT */ |
| put_bits(&s->pb, 1, 1); |
| put_bits(&s->pb, 2, s->pict_type == FF_I_TYPE); /* GFID */ |
| }else{ |
| int gob_number= mb_line / s->gob_index; |
| |
| put_bits(&s->pb, 5, gob_number); /* GN */ |
| put_bits(&s->pb, 2, s->pict_type == FF_I_TYPE); /* GFID */ |
| put_bits(&s->pb, 5, s->qscale); /* GQUANT */ |
| } |
| } |
| |
| static inline int get_block_rate(MpegEncContext * s, DCTELEM block[64], int block_last_index, uint8_t scantable[64]){ |
| int last=0; |
| int j; |
| int rate=0; |
| |
| for(j=1; j<=block_last_index; j++){ |
| const int index= scantable[j]; |
| int level= block[index]; |
| if(level){ |
| level+= 64; |
| if((level&(~127)) == 0){ |
| if(j<block_last_index) rate+= s->intra_ac_vlc_length [UNI_AC_ENC_INDEX(j-last-1, level)]; |
| else rate+= s->intra_ac_vlc_last_length[UNI_AC_ENC_INDEX(j-last-1, level)]; |
| }else |
| rate += s->ac_esc_length; |
| level-= 64; |
| |
| last= j; |
| } |
| } |
| |
| return rate; |
| } |
| |
| static inline int decide_ac_pred(MpegEncContext * s, DCTELEM block[6][64], int dir[6], uint8_t *st[6], int zigzag_last_index[6]) |
| { |
| int score= 0; |
| int i, n; |
| int8_t * const qscale_table= s->current_picture.qscale_table; |
| |
| memcpy(zigzag_last_index, s->block_last_index, sizeof(int)*6); |
| |
| for(n=0; n<6; n++){ |
| int16_t *ac_val, *ac_val1; |
| |
| score -= get_block_rate(s, block[n], s->block_last_index[n], s->intra_scantable.permutated); |
| |
| ac_val = s->ac_val[0][0] + s->block_index[n] * 16; |
| ac_val1= ac_val; |
| if(dir[n]){ |
| const int xy= s->mb_x + s->mb_y*s->mb_stride - s->mb_stride; |
| /* top prediction */ |
| ac_val-= s->block_wrap[n]*16; |
| if(s->mb_y==0 || s->qscale == qscale_table[xy] || n==2 || n==3){ |
| /* same qscale */ |
| for(i=1; i<8; i++){ |
| const int level= block[n][s->dsp.idct_permutation[i ]]; |
| block[n][s->dsp.idct_permutation[i ]] = level - ac_val[i+8]; |
| ac_val1[i ]= block[n][s->dsp.idct_permutation[i<<3]]; |
| ac_val1[i+8]= level; |
| } |
| }else{ |
| /* different qscale, we must rescale */ |
| for(i=1; i<8; i++){ |
| const int level= block[n][s->dsp.idct_permutation[i ]]; |
| block[n][s->dsp.idct_permutation[i ]] = level - ROUNDED_DIV(ac_val[i + 8]*qscale_table[xy], s->qscale); |
| ac_val1[i ]= block[n][s->dsp.idct_permutation[i<<3]]; |
| ac_val1[i+8]= level; |
| } |
| } |
| st[n]= s->intra_h_scantable.permutated; |
| }else{ |
| const int xy= s->mb_x-1 + s->mb_y*s->mb_stride; |
| /* left prediction */ |
| ac_val-= 16; |
| if(s->mb_x==0 || s->qscale == qscale_table[xy] || n==1 || n==3){ |
| /* same qscale */ |
| for(i=1; i<8; i++){ |
| const int level= block[n][s->dsp.idct_permutation[i<<3]]; |
| block[n][s->dsp.idct_permutation[i<<3]]= level - ac_val[i]; |
| ac_val1[i ]= level; |
| ac_val1[i+8]= block[n][s->dsp.idct_permutation[i ]]; |
| } |
| }else{ |
| /* different qscale, we must rescale */ |
| for(i=1; i<8; i++){ |
| const int level= block[n][s->dsp.idct_permutation[i<<3]]; |
| block[n][s->dsp.idct_permutation[i<<3]]= level - ROUNDED_DIV(ac_val[i]*qscale_table[xy], s->qscale); |
| ac_val1[i ]= level; |
| ac_val1[i+8]= block[n][s->dsp.idct_permutation[i ]]; |
| } |
| } |
| st[n]= s->intra_v_scantable.permutated; |
| } |
| |
| for(i=63; i>0; i--) //FIXME optimize |
| if(block[n][ st[n][i] ]) break; |
| s->block_last_index[n]= i; |
| |
| score += get_block_rate(s, block[n], s->block_last_index[n], st[n]); |
| } |
| |
| return score < 0; |
| } |
| |
| static inline void restore_ac_coeffs(MpegEncContext * s, DCTELEM block[6][64], int dir[6], uint8_t *st[6], int zigzag_last_index[6]) |
| { |
| int i, n; |
| memcpy(s->block_last_index, zigzag_last_index, sizeof(int)*6); |
| |
| for(n=0; n<6; n++){ |
| int16_t *ac_val = s->ac_val[0][0] + s->block_index[n] * 16; |
| |
| st[n]= s->intra_scantable.permutated; |
| if(dir[n]){ |
| /* top prediction */ |
| for(i=1; i<8; i++){ |
| block[n][s->dsp.idct_permutation[i ]] = ac_val[i+8]; |
| } |
| }else{ |
| /* left prediction */ |
| for(i=1; i<8; i++){ |
| block[n][s->dsp.idct_permutation[i<<3]]= ac_val[i ]; |
| } |
| } |
| } |
| } |
| |
| /** |
| * init s->current_picture.qscale_table from s->lambda_table |
| */ |
| static void ff_init_qscale_tab(MpegEncContext *s){ |
| int8_t * const qscale_table= s->current_picture.qscale_table; |
| int i; |
| |
| for(i=0; i<s->mb_num; i++){ |
| unsigned int lam= s->lambda_table[ s->mb_index2xy[i] ]; |
| int qp= (lam*139 + FF_LAMBDA_SCALE*64) >> (FF_LAMBDA_SHIFT + 7); |
| qscale_table[ s->mb_index2xy[i] ]= av_clip(qp, s->avctx->qmin, s->avctx->qmax); |
| } |
| } |
| |
| /** |
| * modify qscale so that encoding is acually possible in h263 (limit difference to -2..2) |
| */ |
| void ff_clean_h263_qscales(MpegEncContext *s){ |
| int i; |
| int8_t * const qscale_table= s->current_picture.qscale_table; |
| |
| ff_init_qscale_tab(s); |
| |
| for(i=1; i<s->mb_num; i++){ |
| if(qscale_table[ s->mb_index2xy[i] ] - qscale_table[ s->mb_index2xy[i-1] ] >2) |
| qscale_table[ s->mb_index2xy[i] ]= qscale_table[ s->mb_index2xy[i-1] ]+2; |
| } |
| for(i=s->mb_num-2; i>=0; i--){ |
| if(qscale_table[ s->mb_index2xy[i] ] - qscale_table[ s->mb_index2xy[i+1] ] >2) |
| qscale_table[ s->mb_index2xy[i] ]= qscale_table[ s->mb_index2xy[i+1] ]+2; |
| } |
| |
| if(s->codec_id != CODEC_ID_H263P){ |
| for(i=1; i<s->mb_num; i++){ |
| int mb_xy= s->mb_index2xy[i]; |
| |
| if(qscale_table[mb_xy] != qscale_table[s->mb_index2xy[i-1]] && (s->mb_type[mb_xy]&CANDIDATE_MB_TYPE_INTER4V)){ |
| s->mb_type[mb_xy]|= CANDIDATE_MB_TYPE_INTER; |
| } |
| } |
| } |
| } |
| |
| /** |
| * modify mb_type & qscale so that encoding is acually possible in mpeg4 |
| */ |
| void ff_clean_mpeg4_qscales(MpegEncContext *s){ |
| int i; |
| int8_t * const qscale_table= s->current_picture.qscale_table; |
| |
| ff_clean_h263_qscales(s); |
| |
| if(s->pict_type== FF_B_TYPE){ |
| int odd=0; |
| /* ok, come on, this isn't funny anymore, there's more code for handling this mpeg4 mess than for the actual adaptive quantization */ |
| |
| for(i=0; i<s->mb_num; i++){ |
| int mb_xy= s->mb_index2xy[i]; |
| odd += qscale_table[mb_xy]&1; |
| } |
| |
| if(2*odd > s->mb_num) odd=1; |
| else odd=0; |
| |
| for(i=0; i<s->mb_num; i++){ |
| int mb_xy= s->mb_index2xy[i]; |
| if((qscale_table[mb_xy]&1) != odd) |
| qscale_table[mb_xy]++; |
| if(qscale_table[mb_xy] > 31) |
| qscale_table[mb_xy]= 31; |
| } |
| |
| for(i=1; i<s->mb_num; i++){ |
| int mb_xy= s->mb_index2xy[i]; |
| if(qscale_table[mb_xy] != qscale_table[s->mb_index2xy[i-1]] && (s->mb_type[mb_xy]&CANDIDATE_MB_TYPE_DIRECT)){ |
| s->mb_type[mb_xy]|= CANDIDATE_MB_TYPE_BIDIR; |
| } |
| } |
| } |
| } |
| |
| #endif //CONFIG_ENCODERS |
| |
| #define tab_size ((signed)FF_ARRAY_ELEMS(s->direct_scale_mv[0])) |
| #define tab_bias (tab_size/2) |
| |
| void ff_mpeg4_init_direct_mv(MpegEncContext *s){ |
| int i; |
| for(i=0; i<tab_size; i++){ |
| s->direct_scale_mv[0][i] = (i-tab_bias)*s->pb_time/s->pp_time; |
| s->direct_scale_mv[1][i] = (i-tab_bias)*(s->pb_time-s->pp_time)/s->pp_time; |
| } |
| } |
| |
| static inline void ff_mpeg4_set_one_direct_mv(MpegEncContext *s, int mx, int my, int i){ |
| int xy= s->block_index[i]; |
| uint16_t time_pp= s->pp_time; |
| uint16_t time_pb= s->pb_time; |
| int p_mx, p_my; |
| |
| p_mx= s->next_picture.motion_val[0][xy][0]; |
| if((unsigned)(p_mx + tab_bias) < tab_size){ |
| s->mv[0][i][0] = s->direct_scale_mv[0][p_mx + tab_bias] + mx; |
| s->mv[1][i][0] = mx ? s->mv[0][i][0] - p_mx |
| : s->direct_scale_mv[1][p_mx + tab_bias]; |
| }else{ |
| s->mv[0][i][0] = p_mx*time_pb/time_pp + mx; |
| s->mv[1][i][0] = mx ? s->mv[0][i][0] - p_mx |
| : p_mx*(time_pb - time_pp)/time_pp; |
| } |
| p_my= s->next_picture.motion_val[0][xy][1]; |
| if((unsigned)(p_my + tab_bias) < tab_size){ |
| s->mv[0][i][1] = s->direct_scale_mv[0][p_my + tab_bias] + my; |
| s->mv[1][i][1] = my ? s->mv[0][i][1] - p_my |
| : s->direct_scale_mv[1][p_my + tab_bias]; |
| }else{ |
| s->mv[0][i][1] = p_my*time_pb/time_pp + my; |
| s->mv[1][i][1] = my ? s->mv[0][i][1] - p_my |
| : p_my*(time_pb - time_pp)/time_pp; |
| } |
| } |
| |
| #undef tab_size |
| #undef tab_bias |
| |
| /** |
| * |
| * @return the mb_type |
| */ |
| int ff_mpeg4_set_direct_mv(MpegEncContext *s, int mx, int my){ |
| const int mb_index= s->mb_x + s->mb_y*s->mb_stride; |
| const int colocated_mb_type= s->next_picture.mb_type[mb_index]; |
| uint16_t time_pp= s->pp_time; |
| uint16_t time_pb= s->pb_time; |
| int i; |
| |
| //FIXME avoid divides |
| // try special case with shifts for 1 and 3 B-frames? |
| |
| if(IS_8X8(colocated_mb_type)){ |
| s->mv_type = MV_TYPE_8X8; |
| for(i=0; i<4; i++){ |
| ff_mpeg4_set_one_direct_mv(s, mx, my, i); |
| } |
| return MB_TYPE_DIRECT2 | MB_TYPE_8x8 | MB_TYPE_L0L1; |
| } else if(IS_INTERLACED(colocated_mb_type)){ |
| s->mv_type = MV_TYPE_FIELD; |
| for(i=0; i<2; i++){ |
| int field_select= s->next_picture.ref_index[0][s->block_index[2*i]]; |
| s->field_select[0][i]= field_select; |
| s->field_select[1][i]= i; |
| if(s->top_field_first){ |
| time_pp= s->pp_field_time - field_select + i; |
| time_pb= s->pb_field_time - field_select + i; |
| }else{ |
| time_pp= s->pp_field_time + field_select - i; |
| time_pb= s->pb_field_time + field_select - i; |
| } |
| // NARFLEX: SageTV Fix divide by zero errors that can happen here |
| s->mv[0][i][0] = (time_pp == 0) ? 0 : (s->p_field_mv_table[i][0][mb_index][0]*time_pb/time_pp + mx); |
| s->mv[0][i][1] = (time_pp == 0) ? 0 : (s->p_field_mv_table[i][0][mb_index][1]*time_pb/time_pp + my); |
| s->mv[1][i][0] = mx ? s->mv[0][i][0] - s->p_field_mv_table[i][0][mb_index][0] |
| : ((time_pp == 0) ? 0 : (s->p_field_mv_table[i][0][mb_index][0]*(time_pb - time_pp)/time_pp)); |
| s->mv[1][i][1] = my ? s->mv[0][i][1] - s->p_field_mv_table[i][0][mb_index][1] |
| : ((time_pp == 0) ? 0 : (s->p_field_mv_table[i][0][mb_index][1]*(time_pb - time_pp)/time_pp)); |
| } |
| return MB_TYPE_DIRECT2 | MB_TYPE_16x8 | MB_TYPE_L0L1 | MB_TYPE_INTERLACED; |
| }else{ |
| ff_mpeg4_set_one_direct_mv(s, mx, my, 0); |
| s->mv[0][1][0] = s->mv[0][2][0] = s->mv[0][3][0] = s->mv[0][0][0]; |
| s->mv[0][1][1] = s->mv[0][2][1] = s->mv[0][3][1] = s->mv[0][0][1]; |
| s->mv[1][1][0] = s->mv[1][2][0] = s->mv[1][3][0] = s->mv[1][0][0]; |
| s->mv[1][1][1] = s->mv[1][2][1] = s->mv[1][3][1] = s->mv[1][0][1]; |
| if((s->avctx->workaround_bugs & FF_BUG_DIRECT_BLOCKSIZE) || !s->quarter_sample) |
| s->mv_type= MV_TYPE_16X16; |
| else |
| s->mv_type= MV_TYPE_8X8; |
| return MB_TYPE_DIRECT2 | MB_TYPE_16x16 | MB_TYPE_L0L1; //Note see prev line |
| } |
| } |
| |
| void ff_h263_update_motion_val(MpegEncContext * s){ |
| const int mb_xy = s->mb_y * s->mb_stride + s->mb_x; |
| //FIXME a lot of that is only needed for !low_delay |
| const int wrap = s->b8_stride; |
| const int xy = s->block_index[0]; |
| |
| s->current_picture.mbskip_table[mb_xy]= s->mb_skipped; |
| |
| if(s->mv_type != MV_TYPE_8X8){ |
| int motion_x, motion_y; |
| if (s->mb_intra) { |
| motion_x = 0; |
| motion_y = 0; |
| } else if (s->mv_type == MV_TYPE_16X16) { |
| motion_x = s->mv[0][0][0]; |
| motion_y = s->mv[0][0][1]; |
| } else /*if (s->mv_type == MV_TYPE_FIELD)*/ { |
| int i; |
| motion_x = s->mv[0][0][0] + s->mv[0][1][0]; |
| motion_y = s->mv[0][0][1] + s->mv[0][1][1]; |
| motion_x = (motion_x>>1) | (motion_x&1); |
| for(i=0; i<2; i++){ |
| s->p_field_mv_table[i][0][mb_xy][0]= s->mv[0][i][0]; |
| s->p_field_mv_table[i][0][mb_xy][1]= s->mv[0][i][1]; |
| } |
| s->current_picture.ref_index[0][xy ]= |
| s->current_picture.ref_index[0][xy + 1]= s->field_select[0][0]; |
| s->current_picture.ref_index[0][xy + wrap ]= |
| s->current_picture.ref_index[0][xy + wrap + 1]= s->field_select[0][1]; |
| } |
| |
| /* no update if 8X8 because it has been done during parsing */ |
| s->current_picture.motion_val[0][xy][0] = motion_x; |
| s->current_picture.motion_val[0][xy][1] = motion_y; |
| s->current_picture.motion_val[0][xy + 1][0] = motion_x; |
| s->current_picture.motion_val[0][xy + 1][1] = motion_y; |
| s->current_picture.motion_val[0][xy + wrap][0] = motion_x; |
| s->current_picture.motion_val[0][xy + wrap][1] = motion_y; |
| s->current_picture.motion_val[0][xy + 1 + wrap][0] = motion_x; |
| s->current_picture.motion_val[0][xy + 1 + wrap][1] = motion_y; |
| } |
| |
| if(s->encoding){ //FIXME encoding MUST be cleaned up |
| if (s->mv_type == MV_TYPE_8X8) |
| s->current_picture.mb_type[mb_xy]= MB_TYPE_L0 | MB_TYPE_8x8; |
| else if(s->mb_intra) |
| s->current_picture.mb_type[mb_xy]= MB_TYPE_INTRA; |
| else |
| s->current_picture.mb_type[mb_xy]= MB_TYPE_L0 | MB_TYPE_16x16; |
| } |
| } |
| |
| #if CONFIG_ENCODERS |
| |
| static inline int h263_get_motion_length(MpegEncContext * s, int val, int f_code){ |
| int l, bit_size, code; |
| |
| if (val == 0) { |
| return mvtab[0][1]; |
| } else { |
| bit_size = f_code - 1; |
| /* modulo encoding */ |
| l= INT_BIT - 6 - bit_size; |
| val = (val<<l)>>l; |
| val--; |
| code = (val >> bit_size) + 1; |
| |
| return mvtab[code][1] + 1 + bit_size; |
| } |
| } |
| |
| static inline void ff_h263_encode_motion_vector(MpegEncContext * s, int x, int y, int f_code){ |
| if(s->flags2 & CODEC_FLAG2_NO_OUTPUT){ |
| skip_put_bits(&s->pb, |
| h263_get_motion_length(s, x, f_code) |
| +h263_get_motion_length(s, y, f_code)); |
| }else{ |
| ff_h263_encode_motion(s, x, f_code); |
| ff_h263_encode_motion(s, y, f_code); |
| } |
| } |
| |
| static inline int get_p_cbp(MpegEncContext * s, |
| DCTELEM block[6][64], |
| int motion_x, int motion_y){ |
| int cbp, i; |
| |
| if(s->flags & CODEC_FLAG_CBP_RD){ |
| int best_cbpy_score= INT_MAX; |
| int best_cbpc_score= INT_MAX; |
| int cbpc = (-1), cbpy= (-1); |
| const int offset= (s->mv_type==MV_TYPE_16X16 ? 0 : 16) + (s->dquant ? 8 : 0); |
| const int lambda= s->lambda2 >> (FF_LAMBDA_SHIFT - 6); |
| |
| for(i=0; i<4; i++){ |
| int score= inter_MCBPC_bits[i + offset] * lambda; |
| if(i&1) score += s->coded_score[5]; |
| if(i&2) score += s->coded_score[4]; |
| |
| if(score < best_cbpc_score){ |
| best_cbpc_score= score; |
| cbpc= i; |
| } |
| } |
| |
| for(i=0; i<16; i++){ |
| int score= cbpy_tab[i ^ 0xF][1] * lambda; |
| if(i&1) score += s->coded_score[3]; |
| if(i&2) score += s->coded_score[2]; |
| if(i&4) score += s->coded_score[1]; |
| if(i&8) score += s->coded_score[0]; |
| |
| if(score < best_cbpy_score){ |
| best_cbpy_score= score; |
| cbpy= i; |
| } |
| } |
| cbp= cbpc + 4*cbpy; |
| if ((motion_x | motion_y | s->dquant) == 0 && s->mv_type==MV_TYPE_16X16){ |
| if(best_cbpy_score + best_cbpc_score + 2*lambda >= 0) |
| cbp= 0; |
| } |
| |
| for (i = 0; i < 6; i++) { |
| if (s->block_last_index[i] >= 0 && ((cbp >> (5 - i))&1)==0 ){ |
| s->block_last_index[i]= -1; |
| s->dsp.clear_block(s->block[i]); |
| } |
| } |
| }else{ |
| cbp= 0; |
| for (i = 0; i < 6; i++) { |
| if (s->block_last_index[i] >= 0) |
| cbp |= 1 << (5 - i); |
| } |
| } |
| return cbp; |
| } |
| |
| static inline int get_b_cbp(MpegEncContext * s, DCTELEM block[6][64], |
| int motion_x, int motion_y, int mb_type){ |
| int cbp=0, i; |
| |
| if(s->flags & CODEC_FLAG_CBP_RD){ |
| int score=0; |
| const int lambda= s->lambda2 >> (FF_LAMBDA_SHIFT - 6); |
| |
| for(i=0; i<6; i++){ |
| if(s->coded_score[i] < 0){ |
| score += s->coded_score[i]; |
| cbp |= 1 << (5 - i); |
| } |
| } |
| |
| if(cbp){ |
| int zero_score= -6; |
| if ((motion_x | motion_y | s->dquant | mb_type) == 0){ |
| zero_score-= 4; //2*MV + mb_type + cbp bit |
| } |
| |
| zero_score*= lambda; |
| if(zero_score <= score){ |
| cbp=0; |
| } |
| } |
| |
| for (i = 0; i < 6; i++) { |
| if (s->block_last_index[i] >= 0 && ((cbp >> (5 - i))&1)==0 ){ |
| s->block_last_index[i]= -1; |
| s->dsp.clear_block(s->block[i]); |
| } |
| } |
| }else{ |
| for (i = 0; i < 6; i++) { |
| if (s->block_last_index[i] >= 0) |
| cbp |= 1 << (5 - i); |
| } |
| } |
| return cbp; |
| } |
| |
| static inline void mpeg4_encode_blocks(MpegEncContext * s, DCTELEM block[6][64], int intra_dc[6], |
| uint8_t **scan_table, PutBitContext *dc_pb, PutBitContext *ac_pb){ |
| int i; |
| |
| if(scan_table){ |
| if(s->flags2 & CODEC_FLAG2_NO_OUTPUT){ |
| for (i = 0; i < 6; i++) { |
| skip_put_bits(&s->pb, mpeg4_get_block_length(s, block[i], i, intra_dc[i], scan_table[i])); |
| } |
| }else{ |
| /* encode each block */ |
| for (i = 0; i < 6; i++) { |
| mpeg4_encode_block(s, block[i], i, intra_dc[i], scan_table[i], dc_pb, ac_pb); |
| } |
| } |
| }else{ |
| if(s->flags2 & CODEC_FLAG2_NO_OUTPUT){ |
| for (i = 0; i < 6; i++) { |
| skip_put_bits(&s->pb, mpeg4_get_block_length(s, block[i], i, 0, s->intra_scantable.permutated)); |
| } |
| }else{ |
| /* encode each block */ |
| for (i = 0; i < 6; i++) { |
| mpeg4_encode_block(s, block[i], i, 0, s->intra_scantable.permutated, dc_pb, ac_pb); |
| } |
| } |
| } |
| } |
| |
| static const int dquant_code[5]= {1,0,9,2,3}; |
| |
| void mpeg4_encode_mb(MpegEncContext * s, |
| DCTELEM block[6][64], |
| int motion_x, int motion_y) |
| { |
| int cbpc, cbpy, pred_x, pred_y; |
| PutBitContext * const pb2 = s->data_partitioning ? &s->pb2 : &s->pb; |
| PutBitContext * const tex_pb = s->data_partitioning && s->pict_type!=FF_B_TYPE ? &s->tex_pb : &s->pb; |
| PutBitContext * const dc_pb = s->data_partitioning && s->pict_type!=FF_I_TYPE ? &s->pb2 : &s->pb; |
| const int interleaved_stats= (s->flags&CODEC_FLAG_PASS1) && !s->data_partitioning ? 1 : 0; |
| |
| // printf("**mb x=%d y=%d\n", s->mb_x, s->mb_y); |
| if (!s->mb_intra) { |
| int i, cbp; |
| |
| if(s->pict_type==FF_B_TYPE){ |
| static const int mb_type_table[8]= {-1, 3, 2, 1,-1,-1,-1, 0}; /* convert from mv_dir to type */ |
| int mb_type= mb_type_table[s->mv_dir]; |
| |
| if(s->mb_x==0){ |
| for(i=0; i<2; i++){ |
| s->last_mv[i][0][0]= |
| s->last_mv[i][0][1]= |
| s->last_mv[i][1][0]= |
| s->last_mv[i][1][1]= 0; |
| } |
| } |
| |
| assert(s->dquant>=-2 && s->dquant<=2); |
| assert((s->dquant&1)==0); |
| assert(mb_type>=0); |
| |
| /* nothing to do if this MB was skipped in the next P Frame */ |
| if(s->next_picture.mbskip_table[s->mb_y * s->mb_stride + s->mb_x]){ //FIXME avoid DCT & ... |
| s->skip_count++; |
| s->mv[0][0][0]= |
| s->mv[0][0][1]= |
| s->mv[1][0][0]= |
| s->mv[1][0][1]= 0; |
| s->mv_dir= MV_DIR_FORWARD; //doesn't matter |
| s->qscale -= s->dquant; |
| // s->mb_skipped=1; |
| |
| return; |
| } |
| |
| cbp= get_b_cbp(s, block, motion_x, motion_y, mb_type); |
| |
| if ((cbp | motion_x | motion_y | mb_type) ==0) { |
| /* direct MB with MV={0,0} */ |
| assert(s->dquant==0); |
| |
| put_bits(&s->pb, 1, 1); /* mb not coded modb1=1 */ |
| |
| if(interleaved_stats){ |
| s->misc_bits++; |
| s->last_bits++; |
| } |
| s->skip_count++; |
| return; |
| } |
| |
| put_bits(&s->pb, 1, 0); /* mb coded modb1=0 */ |
| put_bits(&s->pb, 1, cbp ? 0 : 1); /* modb2 */ //FIXME merge |
| put_bits(&s->pb, mb_type+1, 1); // this table is so simple that we don't need it :) |
| if(cbp) put_bits(&s->pb, 6, cbp); |
| |
| if(cbp && mb_type){ |
| if(s->dquant) |
| put_bits(&s->pb, 2, (s->dquant>>2)+3); |
| else |
| put_bits(&s->pb, 1, 0); |
| }else |
| s->qscale -= s->dquant; |
| |
| if(!s->progressive_sequence){ |
| if(cbp) |
| put_bits(&s->pb, 1, s->interlaced_dct); |
| if(mb_type) // not direct mode |
| put_bits(&s->pb, 1, s->mv_type == MV_TYPE_FIELD); |
| } |
| |
| if(interleaved_stats){ |
| s->misc_bits+= get_bits_diff(s); |
| } |
| |
| if(mb_type == 0){ |
| assert(s->mv_dir & MV_DIRECT); |
| ff_h263_encode_motion_vector(s, motion_x, motion_y, 1); |
| s->b_count++; |
| s->f_count++; |
| }else{ |
| assert(mb_type > 0 && mb_type < 4); |
| if(s->mv_type != MV_TYPE_FIELD){ |
| if(s->mv_dir & MV_DIR_FORWARD){ |
| ff_h263_encode_motion_vector(s, s->mv[0][0][0] - s->last_mv[0][0][0], |
| s->mv[0][0][1] - s->last_mv[0][0][1], s->f_code); |
| s->last_mv[0][0][0]= s->last_mv[0][1][0]= s->mv[0][0][0]; |
| s->last_mv[0][0][1]= s->last_mv[0][1][1]= s->mv[0][0][1]; |
| s->f_count++; |
| } |
| if(s->mv_dir & MV_DIR_BACKWARD){ |
| ff_h263_encode_motion_vector(s, s->mv[1][0][0] - s->last_mv[1][0][0], |
| s->mv[1][0][1] - s->last_mv[1][0][1], s->b_code); |
| s->last_mv[1][0][0]= s->last_mv[1][1][0]= s->mv[1][0][0]; |
| s->last_mv[1][0][1]= s->last_mv[1][1][1]= s->mv[1][0][1]; |
| s->b_count++; |
| } |
| }else{ |
| if(s->mv_dir & MV_DIR_FORWARD){ |
| put_bits(&s->pb, 1, s->field_select[0][0]); |
| put_bits(&s->pb, 1, s->field_select[0][1]); |
| } |
| if(s->mv_dir & MV_DIR_BACKWARD){ |
| put_bits(&s->pb, 1, s->field_select[1][0]); |
| put_bits(&s->pb, 1, s->field_select[1][1]); |
| } |
| if(s->mv_dir & MV_DIR_FORWARD){ |
| for(i=0; i<2; i++){ |
| ff_h263_encode_motion_vector(s, s->mv[0][i][0] - s->last_mv[0][i][0] , |
| s->mv[0][i][1] - s->last_mv[0][i][1]/2, s->f_code); |
| s->last_mv[0][i][0]= s->mv[0][i][0]; |
| s->last_mv[0][i][1]= s->mv[0][i][1]*2; |
| } |
| s->f_count++; |
| } |
| if(s->mv_dir & MV_DIR_BACKWARD){ |
| for(i=0; i<2; i++){ |
| ff_h263_encode_motion_vector(s, s->mv[1][i][0] - s->last_mv[1][i][0] , |
| s->mv[1][i][1] - s->last_mv[1][i][1]/2, s->b_code); |
| s->last_mv[1][i][0]= s->mv[1][i][0]; |
| s->last_mv[1][i][1]= s->mv[1][i][1]*2; |
| } |
| s->b_count++; |
| } |
| } |
| } |
| |
| if(interleaved_stats){ |
| s->mv_bits+= get_bits_diff(s); |
| } |
| |
| mpeg4_encode_blocks(s, block, NULL, NULL, NULL, &s->pb); |
| |
| if(interleaved_stats){ |
| s->p_tex_bits+= get_bits_diff(s); |
| } |
| |
| }else{ /* s->pict_type==FF_B_TYPE */ |
| cbp= get_p_cbp(s, block, motion_x, motion_y); |
| |
| if ((cbp | motion_x | motion_y | s->dquant) == 0 && s->mv_type==MV_TYPE_16X16) { |
| /* check if the B frames can skip it too, as we must skip it if we skip here |
| why didn't they just compress the skip-mb bits instead of reusing them ?! */ |
| if(s->max_b_frames>0){ |
| int i; |
| int x,y, offset; |
| uint8_t *p_pic; |
| |
| x= s->mb_x*16; |
| y= s->mb_y*16; |
| if(x+16 > s->width) x= s->width-16; |
| if(y+16 > s->height) y= s->height-16; |
| |
| offset= x + y*s->linesize; |
| p_pic= s->new_picture.data[0] + offset; |
| |
| s->mb_skipped=1; |
| for(i=0; i<s->max_b_frames; i++){ |
| uint8_t *b_pic; |
| int diff; |
| Picture *pic= s->reordered_input_picture[i+1]; |
| |
| if(pic==NULL || pic->pict_type!=FF_B_TYPE) break; |
| |
| b_pic= pic->data[0] + offset; |
| if(pic->type != FF_BUFFER_TYPE_SHARED) |
| b_pic+= INPLACE_OFFSET; |
| diff= s->dsp.sad[0](NULL, p_pic, b_pic, s->linesize, 16); |
| if(diff>s->qscale*70){ //FIXME check that 70 is optimal |
| s->mb_skipped=0; |
| break; |
| } |
| } |
| }else |
| s->mb_skipped=1; |
| |
| if(s->mb_skipped==1){ |
| /* skip macroblock */ |
| put_bits(&s->pb, 1, 1); |
| |
| if(interleaved_stats){ |
| s->misc_bits++; |
| s->last_bits++; |
| } |
| s->skip_count++; |
| |
| return; |
| } |
| } |
| |
| put_bits(&s->pb, 1, 0); /* mb coded */ |
| cbpc = cbp & 3; |
| cbpy = cbp >> 2; |
| cbpy ^= 0xf; |
| if(s->mv_type==MV_TYPE_16X16){ |
| if(s->dquant) cbpc+= 8; |
| put_bits(&s->pb, |
| inter_MCBPC_bits[cbpc], |
| inter_MCBPC_code[cbpc]); |
| |
| put_bits(pb2, cbpy_tab[cbpy][1], cbpy_tab[cbpy][0]); |
| if(s->dquant) |
| put_bits(pb2, 2, dquant_code[s->dquant+2]); |
| |
| if(!s->progressive_sequence){ |
| if(cbp) |
| put_bits(pb2, 1, s->interlaced_dct); |
| put_bits(pb2, 1, 0); |
| } |
| |
| if(interleaved_stats){ |
| s->misc_bits+= get_bits_diff(s); |
| } |
| |
| /* motion vectors: 16x16 mode */ |
| h263_pred_motion(s, 0, 0, &pred_x, &pred_y); |
| |
| ff_h263_encode_motion_vector(s, motion_x - pred_x, |
| motion_y - pred_y, s->f_code); |
| }else if(s->mv_type==MV_TYPE_FIELD){ |
| if(s->dquant) cbpc+= 8; |
| put_bits(&s->pb, |
| inter_MCBPC_bits[cbpc], |
| inter_MCBPC_code[cbpc]); |
| |
| put_bits(pb2, cbpy_tab[cbpy][1], cbpy_tab[cbpy][0]); |
| if(s->dquant) |
| put_bits(pb2, 2, dquant_code[s->dquant+2]); |
| |
| assert(!s->progressive_sequence); |
| if(cbp) |
| put_bits(pb2, 1, s->interlaced_dct); |
| put_bits(pb2, 1, 1); |
| |
| if(interleaved_stats){ |
| s->misc_bits+= get_bits_diff(s); |
| } |
| |
| /* motion vectors: 16x8 interlaced mode */ |
| h263_pred_motion(s, 0, 0, &pred_x, &pred_y); |
| pred_y /=2; |
| |
| put_bits(&s->pb, 1, s->field_select[0][0]); |
| put_bits(&s->pb, 1, s->field_select[0][1]); |
| |
| ff_h263_encode_motion_vector(s, s->mv[0][0][0] - pred_x, |
| s->mv[0][0][1] - pred_y, s->f_code); |
| ff_h263_encode_motion_vector(s, s->mv[0][1][0] - pred_x, |
| s->mv[0][1][1] - pred_y, s->f_code); |
| }else{ |
| assert(s->mv_type==MV_TYPE_8X8); |
| put_bits(&s->pb, |
| inter_MCBPC_bits[cbpc+16], |
| inter_MCBPC_code[cbpc+16]); |
| put_bits(pb2, cbpy_tab[cbpy][1], cbpy_tab[cbpy][0]); |
| |
| if(!s->progressive_sequence){ |
| if(cbp) |
| put_bits(pb2, 1, s->interlaced_dct); |
| } |
| |
| if(interleaved_stats){ |
| s->misc_bits+= get_bits_diff(s); |
| } |
| |
| for(i=0; i<4; i++){ |
| /* motion vectors: 8x8 mode*/ |
| h263_pred_motion(s, i, 0, &pred_x, &pred_y); |
| |
| ff_h263_encode_motion_vector(s, s->current_picture.motion_val[0][ s->block_index[i] ][0] - pred_x, |
| s->current_picture.motion_val[0][ s->block_index[i] ][1] - pred_y, s->f_code); |
| } |
| } |
| |
| if(interleaved_stats){ |
| s->mv_bits+= get_bits_diff(s); |
| } |
| |
| mpeg4_encode_blocks(s, block, NULL, NULL, NULL, tex_pb); |
| |
| if(interleaved_stats){ |
| s->p_tex_bits+= get_bits_diff(s); |
| } |
| s->f_count++; |
| } |
| } else { |
| int cbp; |
| int dc_diff[6]; //dc values with the dc prediction subtracted |
| int dir[6]; //prediction direction |
| int zigzag_last_index[6]; |
| uint8_t *scan_table[6]; |
| int i; |
| |
| for(i=0; i<6; i++){ |
| dc_diff[i]= ff_mpeg4_pred_dc(s, i, block[i][0], &dir[i], 1); |
| } |
| |
| if(s->flags & CODEC_FLAG_AC_PRED){ |
| s->ac_pred= decide_ac_pred(s, block, dir, scan_table, zigzag_last_index); |
| if(!s->ac_pred) |
| restore_ac_coeffs(s, block, dir, scan_table, zigzag_last_index); |
| }else{ |
| for(i=0; i<6; i++) |
| scan_table[i]= s->intra_scantable.permutated; |
| } |
| |
| /* compute cbp */ |
| cbp = 0; |
| for (i = 0; i < 6; i++) { |
| if (s->block_last_index[i] >= 1) |
| cbp |= 1 << (5 - i); |
| } |
| |
| cbpc = cbp & 3; |
| if (s->pict_type == FF_I_TYPE) { |
| if(s->dquant) cbpc+=4; |
| put_bits(&s->pb, |
| intra_MCBPC_bits[cbpc], |
| intra_MCBPC_code[cbpc]); |
| } else { |
| if(s->dquant) cbpc+=8; |
| put_bits(&s->pb, 1, 0); /* mb coded */ |
| put_bits(&s->pb, |
| inter_MCBPC_bits[cbpc + 4], |
| inter_MCBPC_code[cbpc + 4]); |
| } |
| put_bits(pb2, 1, s->ac_pred); |
| cbpy = cbp >> 2; |
| put_bits(pb2, cbpy_tab[cbpy][1], cbpy_tab[cbpy][0]); |
| if(s->dquant) |
| put_bits(dc_pb, 2, dquant_code[s->dquant+2]); |
| |
| if(!s->progressive_sequence){ |
| put_bits(dc_pb, 1, s->interlaced_dct); |
| } |
| |
| if(interleaved_stats){ |
| s->misc_bits+= get_bits_diff(s); |
| } |
| |
| mpeg4_encode_blocks(s, block, dc_diff, scan_table, dc_pb, tex_pb); |
| |
| if(interleaved_stats){ |
| s->i_tex_bits+= get_bits_diff(s); |
| } |
| s->i_count++; |
| |
| /* restore ac coeffs & last_index stuff if we messed them up with the prediction */ |
| if(s->ac_pred) |
| restore_ac_coeffs(s, block, dir, scan_table, zigzag_last_index); |
| } |
| } |
| |
| void h263_encode_mb(MpegEncContext * s, |
| DCTELEM block[6][64], |
| int motion_x, int motion_y) |
| { |
| int cbpc, cbpy, i, cbp, pred_x, pred_y; |
| int16_t pred_dc; |
| int16_t rec_intradc[6]; |
| int16_t *dc_ptr[6]; |
| const int interleaved_stats= (s->flags&CODEC_FLAG_PASS1); |
| |
| //printf("**mb x=%d y=%d\n", s->mb_x, s->mb_y); |
| if (!s->mb_intra) { |
| /* compute cbp */ |
| cbp= get_p_cbp(s, block, motion_x, motion_y); |
| |
| if ((cbp | motion_x | motion_y | s->dquant | (s->mv_type - MV_TYPE_16X16)) == 0) { |
| /* skip macroblock */ |
| put_bits(&s->pb, 1, 1); |
| if(interleaved_stats){ |
| s->misc_bits++; |
| s->last_bits++; |
| } |
| s->skip_count++; |
| |
| return; |
| } |
| put_bits(&s->pb, 1, 0); /* mb coded */ |
| |
| cbpc = cbp & 3; |
| cbpy = cbp >> 2; |
| if(s->alt_inter_vlc==0 || cbpc!=3) |
| cbpy ^= 0xF; |
| if(s->dquant) cbpc+= 8; |
| if(s->mv_type==MV_TYPE_16X16){ |
| put_bits(&s->pb, |
| inter_MCBPC_bits[cbpc], |
| inter_MCBPC_code[cbpc]); |
| |
| put_bits(&s->pb, cbpy_tab[cbpy][1], cbpy_tab[cbpy][0]); |
| if(s->dquant) |
| put_bits(&s->pb, 2, dquant_code[s->dquant+2]); |
| |
| if(interleaved_stats){ |
| s->misc_bits+= get_bits_diff(s); |
| } |
| |
| /* motion vectors: 16x16 mode */ |
| h263_pred_motion(s, 0, 0, &pred_x, &pred_y); |
| |
| if (!s->umvplus) { |
| ff_h263_encode_motion_vector(s, motion_x - pred_x, |
| motion_y - pred_y, 1); |
| } |
| else { |
| h263p_encode_umotion(s, motion_x - pred_x); |
| h263p_encode_umotion(s, motion_y - pred_y); |
| if (((motion_x - pred_x) == 1) && ((motion_y - pred_y) == 1)) |
| /* To prevent Start Code emulation */ |
| put_bits(&s->pb,1,1); |
| } |
| }else{ |
| put_bits(&s->pb, |
| inter_MCBPC_bits[cbpc+16], |
| inter_MCBPC_code[cbpc+16]); |
| put_bits(&s->pb, cbpy_tab[cbpy][1], cbpy_tab[cbpy][0]); |
| if(s->dquant) |
| put_bits(&s->pb, 2, dquant_code[s->dquant+2]); |
| |
| if(interleaved_stats){ |
| s->misc_bits+= get_bits_diff(s); |
| } |
| |
| for(i=0; i<4; i++){ |
| /* motion vectors: 8x8 mode*/ |
| h263_pred_motion(s, i, 0, &pred_x, &pred_y); |
| |
| motion_x= s->current_picture.motion_val[0][ s->block_index[i] ][0]; |
| motion_y= s->current_picture.motion_val[0][ s->block_index[i] ][1]; |
| if (!s->umvplus) { |
| ff_h263_encode_motion_vector(s, motion_x - pred_x, |
| motion_y - pred_y, 1); |
| } |
| else { |
| h263p_encode_umotion(s, motion_x - pred_x); |
| h263p_encode_umotion(s, motion_y - pred_y); |
| if (((motion_x - pred_x) == 1) && ((motion_y - pred_y) == 1)) |
| /* To prevent Start Code emulation */ |
| put_bits(&s->pb,1,1); |
| } |
| } |
| } |
| |
| if(interleaved_stats){ |
| s->mv_bits+= get_bits_diff(s); |
| } |
| } else { |
| assert(s->mb_intra); |
| |
| cbp = 0; |
| if (s->h263_aic) { |
| /* Predict DC */ |
| for(i=0; i<6; i++) { |
| int16_t level = block[i][0]; |
| int scale; |
| |
| if(i<4) scale= s->y_dc_scale; |
| else scale= s->c_dc_scale; |
| |
| pred_dc = h263_pred_dc(s, i, &dc_ptr[i]); |
| level -= pred_dc; |
| /* Quant */ |
| if (level >= 0) |
| level = (level + (scale>>1))/scale; |
| else |
| level = (level - (scale>>1))/scale; |
| |
| /* AIC can change CBP */ |
| if (level == 0 && s->block_last_index[i] == 0) |
| s->block_last_index[i] = -1; |
| |
| if(!s->modified_quant){ |
| if (level < -127) |
| level = -127; |
| else if (level > 127) |
| level = 127; |
| } |
| |
| block[i][0] = level; |
| /* Reconstruction */ |
| rec_intradc[i] = scale*level + pred_dc; |
| /* Oddify */ |
| rec_intradc[i] |= 1; |
| //if ((rec_intradc[i] % 2) == 0) |
| // rec_intradc[i]++; |
| /* Clipping */ |
| if (rec_intradc[i] < 0) |
| rec_intradc[i] = 0; |
| else if (rec_intradc[i] > 2047) |
| rec_intradc[i] = 2047; |
| |
| /* Update AC/DC tables */ |
| *dc_ptr[i] = rec_intradc[i]; |
| if (s->block_last_index[i] >= 0) |
| cbp |= 1 << (5 - i); |
| } |
| }else{ |
| for(i=0; i<6; i++) { |
| /* compute cbp */ |
| if (s->block_last_index[i] >= 1) |
| cbp |= 1 << (5 - i); |
| } |
| } |
| |
| cbpc = cbp & 3; |
| if (s->pict_type == FF_I_TYPE) { |
| if(s->dquant) cbpc+=4; |
| put_bits(&s->pb, |
| intra_MCBPC_bits[cbpc], |
| intra_MCBPC_code[cbpc]); |
| } else { |
| if(s->dquant) cbpc+=8; |
| put_bits(&s->pb, 1, 0); /* mb coded */ |
| put_bits(&s->pb, |
| inter_MCBPC_bits[cbpc + 4], |
| inter_MCBPC_code[cbpc + 4]); |
| } |
| if (s->h263_aic) { |
| /* XXX: currently, we do not try to use ac prediction */ |
| put_bits(&s->pb, 1, 0); /* no AC prediction */ |
| } |
| cbpy = cbp >> 2; |
| put_bits(&s->pb, cbpy_tab[cbpy][1], cbpy_tab[cbpy][0]); |
| if(s->dquant) |
| put_bits(&s->pb, 2, dquant_code[s->dquant+2]); |
| |
| if(interleaved_stats){ |
| s->misc_bits+= get_bits_diff(s); |
| } |
| } |
| |
| for(i=0; i<6; i++) { |
| /* encode each block */ |
| h263_encode_block(s, block[i], i); |
| |
| /* Update INTRADC for decoding */ |
| if (s->h263_aic && s->mb_intra) { |
| block[i][0] = rec_intradc[i]; |
| |
| } |
| } |
| |
| if(interleaved_stats){ |
| if (!s->mb_intra) { |
| s->p_tex_bits+= get_bits_diff(s); |
| s->f_count++; |
| }else{ |
| s->i_tex_bits+= get_bits_diff(s); |
| s->i_count++; |
| } |
| } |
| } |
| #endif |
| |
| void ff_h263_loop_filter(MpegEncContext * s){ |
| int qp_c; |
| const int linesize = s->linesize; |
| const int uvlinesize= s->uvlinesize; |
| const int xy = s->mb_y * s->mb_stride + s->mb_x; |
| uint8_t *dest_y = s->dest[0]; |
| uint8_t *dest_cb= s->dest[1]; |
| uint8_t *dest_cr= s->dest[2]; |
| |
| // if(s->pict_type==FF_B_TYPE && !s->readable) return; |
| |
| /* |
| Diag Top |
| Left Center |
| */ |
| if(!IS_SKIP(s->current_picture.mb_type[xy])){ |
| qp_c= s->qscale; |
| s->dsp.h263_v_loop_filter(dest_y+8*linesize , linesize, qp_c); |
| s->dsp.h263_v_loop_filter(dest_y+8*linesize+8, linesize, qp_c); |
| }else |
| qp_c= 0; |
| |
| if(s->mb_y){ |
| int qp_dt, qp_tt, qp_tc; |
| |
| if(IS_SKIP(s->current_picture.mb_type[xy-s->mb_stride])) |
| qp_tt=0; |
| else |
| qp_tt= s->current_picture.qscale_table[xy-s->mb_stride]; |
| |
| if(qp_c) |
| qp_tc= qp_c; |
| else |
| qp_tc= qp_tt; |
| |
| if(qp_tc){ |
| const int chroma_qp= s->chroma_qscale_table[qp_tc]; |
| s->dsp.h263_v_loop_filter(dest_y , linesize, qp_tc); |
| s->dsp.h263_v_loop_filter(dest_y+8, linesize, qp_tc); |
| |
| s->dsp.h263_v_loop_filter(dest_cb , uvlinesize, chroma_qp); |
| s->dsp.h263_v_loop_filter(dest_cr , uvlinesize, chroma_qp); |
| } |
| |
| if(qp_tt) |
| s->dsp.h263_h_loop_filter(dest_y-8*linesize+8 , linesize, qp_tt); |
| |
| if(s->mb_x){ |
| if(qp_tt || IS_SKIP(s->current_picture.mb_type[xy-1-s->mb_stride])) |
| qp_dt= qp_tt; |
| else |
| qp_dt= s->current_picture.qscale_table[xy-1-s->mb_stride]; |
| |
| if(qp_dt){ |
| const int chroma_qp= s->chroma_qscale_table[qp_dt]; |
| s->dsp.h263_h_loop_filter(dest_y -8*linesize , linesize, qp_dt); |
| s->dsp.h263_h_loop_filter(dest_cb-8*uvlinesize, uvlinesize, chroma_qp); |
| s->dsp.h263_h_loop_filter(dest_cr-8*uvlinesize, uvlinesize, chroma_qp); |
| } |
| } |
| } |
| |
| if(qp_c){ |
| s->dsp.h263_h_loop_filter(dest_y +8, linesize, qp_c); |
| if(s->mb_y + 1 == s->mb_height) |
| s->dsp.h263_h_loop_filter(dest_y+8*linesize+8, linesize, qp_c); |
| } |
| |
| if(s->mb_x){ |
| int qp_lc; |
| if(qp_c || IS_SKIP(s->current_picture.mb_type[xy-1])) |
| qp_lc= qp_c; |
| else |
| qp_lc= s->current_picture.qscale_table[xy-1]; |
| |
| if(qp_lc){ |
| s->dsp.h263_h_loop_filter(dest_y, linesize, qp_lc); |
| if(s->mb_y + 1 == s->mb_height){ |
| const int chroma_qp= s->chroma_qscale_table[qp_lc]; |
| s->dsp.h263_h_loop_filter(dest_y +8* linesize, linesize, qp_lc); |
| s->dsp.h263_h_loop_filter(dest_cb , uvlinesize, chroma_qp); |
| s->dsp.h263_h_loop_filter(dest_cr , uvlinesize, chroma_qp); |
| } |
| } |
| } |
| } |
| |
| #if CONFIG_ENCODERS |
| static int h263_pred_dc(MpegEncContext * s, int n, int16_t **dc_val_ptr) |
| { |
| int x, y, wrap, a, c, pred_dc, scale; |
| int16_t *dc_val; |
| |
| /* find prediction */ |
| if (n < 4) { |
| x = 2 * s->mb_x + (n & 1); |
| y = 2 * s->mb_y + ((n & 2) >> 1); |
| wrap = s->b8_stride; |
| dc_val = s->dc_val[0]; |
| scale = s->y_dc_scale; |
| } else { |
| x = s->mb_x; |
| y = s->mb_y; |
| wrap = s->mb_stride; |
| dc_val = s->dc_val[n - 4 + 1]; |
| scale = s->c_dc_scale; |
| } |
| /* B C |
| * A X |
| */ |
| a = dc_val[(x - 1) + (y) * wrap]; |
| c = dc_val[(x) + (y - 1) * wrap]; |
| |
| /* No prediction outside GOB boundary */ |
| if(s->first_slice_line && n!=3){ |
| if(n!=2) c= 1024; |
| if(n!=1 && s->mb_x == s->resync_mb_x) a= 1024; |
| } |
| pred_dc = 1024; |
| /* just DC prediction */ |
| if (a != 1024 && c != 1024) |
| pred_dc = (a + c) >> 1; |
| else if (a != 1024) |
| pred_dc = a; |
| else |
| pred_dc = c; |
| |
| /* we assume pred is positive */ |
| //pred_dc = (pred_dc + (scale >> 1)) / scale; |
| *dc_val_ptr = &dc_val[x + y * wrap]; |
| return pred_dc; |
| } |
| #endif /* CONFIG_ENCODERS */ |
| |
| static void h263_pred_acdc(MpegEncContext * s, DCTELEM *block, int n) |
| { |
| int x, y, wrap, a, c, pred_dc, scale, i; |
| int16_t *dc_val, *ac_val, *ac_val1; |
| |
| /* find prediction */ |
| if (n < 4) { |
| x = 2 * s->mb_x + (n & 1); |
| y = 2 * s->mb_y + (n>> 1); |
| wrap = s->b8_stride; |
| dc_val = s->dc_val[0]; |
| ac_val = s->ac_val[0][0]; |
| scale = s->y_dc_scale; |
| } else { |
| x = s->mb_x; |
| y = s->mb_y; |
| wrap = s->mb_stride; |
| dc_val = s->dc_val[n - 4 + 1]; |
| ac_val = s->ac_val[n - 4 + 1][0]; |
| scale = s->c_dc_scale; |
| } |
| |
| ac_val += ((y) * wrap + (x)) * 16; |
| ac_val1 = ac_val; |
| |
| /* B C |
| * A X |
| */ |
| a = dc_val[(x - 1) + (y) * wrap]; |
| c = dc_val[(x) + (y - 1) * wrap]; |
| |
| /* No prediction outside GOB boundary */ |
| if(s->first_slice_line && n!=3){ |
| if(n!=2) c= 1024; |
| if(n!=1 && s->mb_x == s->resync_mb_x) a= 1024; |
| } |
| |
| if (s->ac_pred) { |
| pred_dc = 1024; |
| if (s->h263_aic_dir) { |
| /* left prediction */ |
| if (a != 1024) { |
| ac_val -= 16; |
| for(i=1;i<8;i++) { |
| block[s->dsp.idct_permutation[i<<3]] += ac_val[i]; |
| } |
| pred_dc = a; |
| } |
| } else { |
| /* top prediction */ |
| if (c != 1024) { |
| ac_val -= 16 * wrap; |
| for(i=1;i<8;i++) { |
| block[s->dsp.idct_permutation[i ]] += ac_val[i + 8]; |
| } |
| pred_dc = c; |
| } |
| } |
| } else { |
| /* just DC prediction */ |
| if (a != 1024 && c != 1024) |
| pred_dc = (a + c) >> 1; |
| else if (a != 1024) |
| pred_dc = a; |
| else |
| pred_dc = c; |
| } |
| |
| /* we assume pred is positive */ |
| block[0]=block[0]*scale + pred_dc; |
| |
| if (block[0] < 0) |
| block[0] = 0; |
| else |
| block[0] |= 1; |
| |
| /* Update AC/DC tables */ |
| dc_val[(x) + (y) * wrap] = block[0]; |
| |
| /* left copy */ |
| for(i=1;i<8;i++) |
| ac_val1[i ] = block[s->dsp.idct_permutation[i<<3]]; |
| /* top copy */ |
| for(i=1;i<8;i++) |
| ac_val1[8 + i] = block[s->dsp.idct_permutation[i ]]; |
| } |
| |
| int16_t *h263_pred_motion(MpegEncContext * s, int block, int dir, |
| int *px, int *py) |
| { |
| int wrap; |
| int16_t *A, *B, *C, (*mot_val)[2]; |
| static const int off[4]= {2, 1, 1, -1}; |
| |
| wrap = s->b8_stride; |
| mot_val = s->current_picture.motion_val[dir] + s->block_index[block]; |
| |
| A = mot_val[ - 1]; |
| /* special case for first (slice) line */ |
| if (s->first_slice_line && block<3) { |
| // we can't just change some MVs to simulate that as we need them for the B frames (and ME) |
| // and if we ever support non rectangular objects than we need to do a few ifs here anyway :( |
| if(block==0){ //most common case |
| if(s->mb_x == s->resync_mb_x){ //rare |
| *px= *py = 0; |
| }else if(s->mb_x + 1 == s->resync_mb_x && s->h263_pred){ //rare |
| C = mot_val[off[block] - wrap]; |
| if(s->mb_x==0){ |
| *px = C[0]; |
| *py = C[1]; |
| }else{ |
| *px = mid_pred(A[0], 0, C[0]); |
| *py = mid_pred(A[1], 0, C[1]); |
| } |
| }else{ |
| *px = A[0]; |
| *py = A[1]; |
| } |
| }else if(block==1){ |
| if(s->mb_x + 1 == s->resync_mb_x && s->h263_pred){ //rare |
| C = mot_val[off[block] - wrap]; |
| *px = mid_pred(A[0], 0, C[0]); |
| *py = mid_pred(A[1], 0, C[1]); |
| }else{ |
| *px = A[0]; |
| *py = A[1]; |
| } |
| }else{ /* block==2*/ |
| B = mot_val[ - wrap]; |
| C = mot_val[off[block] - wrap]; |
| if(s->mb_x == s->resync_mb_x) //rare |
| A[0]=A[1]=0; |
| |
| *px = mid_pred(A[0], B[0], C[0]); |
| *py = mid_pred(A[1], B[1], C[1]); |
| } |
| } else { |
| B = mot_val[ - wrap]; |
| C = mot_val[off[block] - wrap]; |
| *px = mid_pred(A[0], B[0], C[0]); |
| *py = mid_pred(A[1], B[1], C[1]); |
| } |
| return *mot_val; |
| } |
| |
| #if CONFIG_ENCODERS |
| void ff_h263_encode_motion(MpegEncContext * s, int val, int f_code) |
| { |
| int range, l, bit_size, sign, code, bits; |
| |
| if (val == 0) { |
| /* zero vector */ |
| code = 0; |
| put_bits(&s->pb, mvtab[code][1], mvtab[code][0]); |
| } else { |
| bit_size = f_code - 1; |
| range = 1 << bit_size; |
| /* modulo encoding */ |
| l= INT_BIT - 6 - bit_size; |
| val = (val<<l)>>l; |
| sign = val>>31; |
| val= (val^sign)-sign; |
| sign&=1; |
| |
| val--; |
| code = (val >> bit_size) + 1; |
| bits = val & (range - 1); |
| |
| put_bits(&s->pb, mvtab[code][1] + 1, (mvtab[code][0] << 1) | sign); |
| if (bit_size > 0) { |
| put_bits(&s->pb, bit_size, bits); |
| } |
| } |
| } |
| |
| /* Encode MV differences on H.263+ with Unrestricted MV mode */ |
| static void h263p_encode_umotion(MpegEncContext * s, int val) |
| { |
| short sval = 0; |
| short i = 0; |
| short n_bits = 0; |
| short temp_val; |
| int code = 0; |
| int tcode; |
| |
| if ( val == 0) |
| put_bits(&s->pb, 1, 1); |
| else if (val == 1) |
| put_bits(&s->pb, 3, 0); |
| else if (val == -1) |
| put_bits(&s->pb, 3, 2); |
| else { |
| |
| sval = ((val < 0) ? (short)(-val):(short)val); |
| temp_val = sval; |
| |
| while (temp_val != 0) { |
| temp_val = temp_val >> 1; |
| n_bits++; |
| } |
| |
| i = n_bits - 1; |
| while (i > 0) { |
| tcode = (sval & (1 << (i-1))) >> (i-1); |
| tcode = (tcode << 1) | 1; |
| code = (code << 2) | tcode; |
| i--; |
| } |
| code = ((code << 1) | (val < 0)) << 1; |
| put_bits(&s->pb, (2*n_bits)+1, code); |
| //printf("\nVal = %d\tCode = %d", sval, code); |
| } |
| } |
| |
| static void init_mv_penalty_and_fcode(MpegEncContext *s) |
| { |
| int f_code; |
| int mv; |
| |
| for(f_code=1; f_code<=MAX_FCODE; f_code++){ |
| for(mv=-MAX_MV; mv<=MAX_MV; mv++){ |
| int len; |
| |
| if(mv==0) len= mvtab[0][1]; |
| else{ |
| int val, bit_size, range, code; |
| |
| bit_size = f_code - 1; |
| range = 1 << bit_size; |
| |
| val=mv; |
| if (val < 0) |
| val = -val; |
| val--; |
| code = (val >> bit_size) + 1; |
| if(code<33){ |
| len= mvtab[code][1] + 1 + bit_size; |
| }else{ |
| len= mvtab[32][1] + av_log2(code>>5) + 2 + bit_size; |
| } |
| } |
| |
| mv_penalty[f_code][mv+MAX_MV]= len; |
| } |
| } |
| |
| for(f_code=MAX_FCODE; f_code>0; f_code--){ |
| for(mv=-(16<<f_code); mv<(16<<f_code); mv++){ |
| fcode_tab[mv+MAX_MV]= f_code; |
| } |
| } |
| |
| for(mv=0; mv<MAX_MV*2+1; mv++){ |
| umv_fcode_tab[mv]= 1; |
| } |
| } |
| |
| static void init_uni_dc_tab(void) |
| { |
| int level, uni_code, uni_len; |
| |
| for(level=-256; level<256; level++){ |
| int size, v, l; |
| /* find number of bits */ |
| size = 0; |
| v = abs(level); |
| while (v) { |
| v >>= 1; |
| size++; |
| } |
| |
| if (level < 0) |
| l= (-level) ^ ((1 << size) - 1); |
| else |
| l= level; |
| |
| /* luminance */ |
| uni_code= DCtab_lum[size][0]; |
| uni_len = DCtab_lum[size][1]; |
| |
| if (size > 0) { |
| uni_code<<=size; uni_code|=l; |
| uni_len+=size; |
| if (size > 8){ |
| uni_code<<=1; uni_code|=1; |
| uni_len++; |
| } |
| } |
| uni_DCtab_lum_bits[level+256]= uni_code; |
| uni_DCtab_lum_len [level+256]= uni_len; |
| |
| /* chrominance */ |
| uni_code= DCtab_chrom[size][0]; |
| uni_len = DCtab_chrom[size][1]; |
| |
| if (size > 0) { |
| uni_code<<=size; uni_code|=l; |
| uni_len+=size; |
| if (size > 8){ |
| uni_code<<=1; uni_code|=1; |
| uni_len++; |
| } |
| } |
| uni_DCtab_chrom_bits[level+256]= uni_code; |
| uni_DCtab_chrom_len [level+256]= uni_len; |
| |
| } |
| } |
| |
| static void init_uni_mpeg4_rl_tab(RLTable *rl, uint32_t *bits_tab, uint8_t *len_tab){ |
| int slevel, run, last; |
| |
| assert(MAX_LEVEL >= 64); |
| assert(MAX_RUN >= 63); |
| |
| for(slevel=-64; slevel<64; slevel++){ |
| if(slevel==0) continue; |
| for(run=0; run<64; run++){ |
| for(last=0; last<=1; last++){ |
| const int index= UNI_MPEG4_ENC_INDEX(last, run, slevel+64); |
| int level= slevel < 0 ? -slevel : slevel; |
| int sign= slevel < 0 ? 1 : 0; |
| int bits, len, code; |
| int level1, run1; |
| |
| len_tab[index]= 100; |
| |
| /* ESC0 */ |
| code= get_rl_index(rl, last, run, level); |
| bits= rl->table_vlc[code][0]; |
| len= rl->table_vlc[code][1]; |
| bits=bits*2+sign; len++; |
| |
| if(code!=rl->n && len < len_tab[index]){ |
| bits_tab[index]= bits; |
| len_tab [index]= len; |
| } |
| #if 1 |
| /* ESC1 */ |
| bits= rl->table_vlc[rl->n][0]; |
| len= rl->table_vlc[rl->n][1]; |
| bits=bits*2; len++; //esc1 |
| level1= level - rl->max_level[last][run]; |
| if(level1>0){ |
| code= get_rl_index(rl, last, run, level1); |
| bits<<= rl->table_vlc[code][1]; |
| len += rl->table_vlc[code][1]; |
| bits += rl->table_vlc[code][0]; |
| bits=bits*2+sign; len++; |
| |
| if(code!=rl->n && len < len_tab[index]){ |
| bits_tab[index]= bits; |
| len_tab [index]= len; |
| } |
| } |
| #endif |
| #if 1 |
| /* ESC2 */ |
| bits= rl->table_vlc[rl->n][0]; |
| len= rl->table_vlc[rl->n][1]; |
| bits=bits*4+2; len+=2; //esc2 |
| run1 = run - rl->max_run[last][level] - 1; |
| if(run1>=0){ |
| code= get_rl_index(rl, last, run1, level); |
| bits<<= rl->table_vlc[code][1]; |
| len += rl->table_vlc[code][1]; |
| bits += rl->table_vlc[code][0]; |
| bits=bits*2+sign; len++; |
| |
| if(code!=rl->n && len < len_tab[index]){ |
| bits_tab[index]= bits; |
| len_tab [index]= len; |
| } |
| } |
| #endif |
| /* ESC3 */ |
| bits= rl->table_vlc[rl->n][0]; |
| len = rl->table_vlc[rl->n][1]; |
| bits=bits*4+3; len+=2; //esc3 |
| bits=bits*2+last; len++; |
| bits=bits*64+run; len+=6; |
| bits=bits*2+1; len++; //marker |
| bits=bits*4096+(slevel&0xfff); len+=12; |
| bits=bits*2+1; len++; //marker |
| |
| if(len < len_tab[index]){ |
| bits_tab[index]= bits; |
| len_tab [index]= len; |
| } |
| } |
| } |
| } |
| } |
| |
| static void init_uni_h263_rl_tab(RLTable *rl, uint32_t *bits_tab, uint8_t *len_tab){ |
| int slevel, run, last; |
| |
| assert(MAX_LEVEL >= 64); |
| assert(MAX_RUN >= 63); |
| |
| for(slevel=-64; slevel<64; slevel++){ |
| if(slevel==0) continue; |
| for(run=0; run<64; run++){ |
| for(last=0; last<=1; last++){ |
| const int index= UNI_MPEG4_ENC_INDEX(last, run, slevel+64); |
| int level= slevel < 0 ? -slevel : slevel; |
| int sign= slevel < 0 ? 1 : 0; |
| int bits, len, code; |
| |
| len_tab[index]= 100; |
| |
| /* ESC0 */ |
| code= get_rl_index(rl, last, run, level); |
| bits= rl->table_vlc[code][0]; |
| len= rl->table_vlc[code][1]; |
| bits=bits*2+sign; len++; |
| |
| if(code!=rl->n && len < len_tab[index]){ |
| if(bits_tab) bits_tab[index]= bits; |
| len_tab [index]= len; |
| } |
| /* ESC */ |
| bits= rl->table_vlc[rl->n][0]; |
| len = rl->table_vlc[rl->n][1]; |
| bits=bits*2+last; len++; |
| bits=bits*64+run; len+=6; |
| bits=bits*256+(level&0xff); len+=8; |
| |
| if(len < len_tab[index]){ |
| if(bits_tab) bits_tab[index]= bits; |
| len_tab [index]= len; |
| } |
| } |
| } |
| } |
| } |
| |
| void h263_encode_init(MpegEncContext *s) |
| { |
| static int done = 0; |
| |
| if (!done) { |
| done = 1; |
| |
| init_uni_dc_tab(); |
| |
| init_rl(&rl_inter, static_rl_table_store[0]); |
| init_rl(&rl_intra, static_rl_table_store[1]); |
| init_rl(&rl_intra_aic, static_rl_table_store[2]); |
| |
| init_uni_mpeg4_rl_tab(&rl_intra, uni_mpeg4_intra_rl_bits, uni_mpeg4_intra_rl_len); |
| init_uni_mpeg4_rl_tab(&rl_inter, uni_mpeg4_inter_rl_bits, uni_mpeg4_inter_rl_len); |
| |
| init_uni_h263_rl_tab(&rl_intra_aic, NULL, uni_h263_intra_aic_rl_len); |
| init_uni_h263_rl_tab(&rl_inter , NULL, uni_h263_inter_rl_len); |
| |
| init_mv_penalty_and_fcode(s); |
| } |
| s->me.mv_penalty= mv_penalty; //FIXME exact table for msmpeg4 & h263p |
| |
| s->intra_ac_vlc_length =s->inter_ac_vlc_length = uni_h263_inter_rl_len; |
| s->intra_ac_vlc_last_length=s->inter_ac_vlc_last_length= uni_h263_inter_rl_len + 128*64; |
| if(s->h263_aic){ |
| s->intra_ac_vlc_length = uni_h263_intra_aic_rl_len; |
| s->intra_ac_vlc_last_length= uni_h263_intra_aic_rl_len + 128*64; |
| } |
| s->ac_esc_length= 7+1+6+8; |
| |
| // use fcodes >1 only for mpeg4 & h263 & h263p FIXME |
| switch(s->codec_id){ |
| case CODEC_ID_MPEG4: |
| s->fcode_tab= fcode_tab; |
| s->min_qcoeff= -2048; |
| s->max_qcoeff= 2047; |
| s->intra_ac_vlc_length = uni_mpeg4_intra_rl_len; |
| s->intra_ac_vlc_last_length= uni_mpeg4_intra_rl_len + 128*64; |
| s->inter_ac_vlc_length = uni_mpeg4_inter_rl_len; |
| s->inter_ac_vlc_last_length= uni_mpeg4_inter_rl_len + 128*64; |
| s->luma_dc_vlc_length= uni_DCtab_lum_len; |
| s->chroma_dc_vlc_length= uni_DCtab_chrom_len; |
| s->ac_esc_length= 7+2+1+6+1+12+1; |
| s->y_dc_scale_table= ff_mpeg4_y_dc_scale_table; |
| s->c_dc_scale_table= ff_mpeg4_c_dc_scale_table; |
| |
| if(s->flags & CODEC_FLAG_GLOBAL_HEADER){ |
| |
| s->avctx->extradata= av_malloc(1024); |
| init_put_bits(&s->pb, s->avctx->extradata, 1024); |
| |
| if(!(s->workaround_bugs & FF_BUG_MS)) |
| mpeg4_encode_visual_object_header(s); |
| mpeg4_encode_vol_header(s, 0, 0); |
| |
| // ff_mpeg4_stuffing(&s->pb); ? |
| flush_put_bits(&s->pb); |
| s->avctx->extradata_size= (put_bits_count(&s->pb)+7)>>3; |
| } |
| |
| break; |
| case CODEC_ID_H263P: |
| if(s->umvplus) |
| s->fcode_tab= umv_fcode_tab; |
| if(s->modified_quant){ |
| s->min_qcoeff= -2047; |
| s->max_qcoeff= 2047; |
| }else{ |
| s->min_qcoeff= -127; |
| s->max_qcoeff= 127; |
| } |
| break; |
| //Note for mpeg4 & h263 the dc-scale table will be set per frame as needed later |
| case CODEC_ID_FLV1: |
| if (s->h263_flv > 1) { |
| s->min_qcoeff= -1023; |
| s->max_qcoeff= 1023; |
| } else { |
| s->min_qcoeff= -127; |
| s->max_qcoeff= 127; |
| } |
| s->y_dc_scale_table= |
| s->c_dc_scale_table= ff_mpeg1_dc_scale_table; |
| break; |
| default: //nothing needed - default table already set in mpegvideo.c |
| s->min_qcoeff= -127; |
| s->max_qcoeff= 127; |
| s->y_dc_scale_table= |
| s->c_dc_scale_table= ff_mpeg1_dc_scale_table; |
| } |
| } |
| |
| /** |
| * encodes a 8x8 block. |
| * @param block the 8x8 block |
| * @param n block index (0-3 are luma, 4-5 are chroma) |
| */ |
| static void h263_encode_block(MpegEncContext * s, DCTELEM * block, int n) |
| { |
| int level, run, last, i, j, last_index, last_non_zero, sign, slevel, code; |
| RLTable *rl; |
| |
| rl = &rl_inter; |
| if (s->mb_intra && !s->h263_aic) { |
| /* DC coef */ |
| level = block[0]; |
| /* 255 cannot be represented, so we clamp */ |
| if (level > 254) { |
| level = 254; |
| block[0] = 254; |
| } |
| /* 0 cannot be represented also */ |
| else if (level < 1) { |
| level = 1; |
| block[0] = 1; |
| } |
| if (level == 128) //FIXME check rv10 |
| put_bits(&s->pb, 8, 0xff); |
| else |
| put_bits(&s->pb, 8, level); |
| i = 1; |
| } else { |
| i = 0; |
| if (s->h263_aic && s->mb_intra) |
| rl = &rl_intra_aic; |
| |
| if(s->alt_inter_vlc && !s->mb_intra){ |
| int aic_vlc_bits=0; |
| int inter_vlc_bits=0; |
| int wrong_pos=-1; |
| int aic_code; |
| |
| last_index = s->block_last_index[n]; |
| last_non_zero = i - 1; |
| for (; i <= last_index; i++) { |
| j = s->intra_scantable.permutated[i]; |
| level = block[j]; |
| if (level) { |
| run = i - last_non_zero - 1; |
| last = (i == last_index); |
| |
| if(level<0) level= -level; |
| |
| code = get_rl_index(rl, last, run, level); |
| aic_code = get_rl_index(&rl_intra_aic, last, run, level); |
| inter_vlc_bits += rl->table_vlc[code][1]+1; |
| aic_vlc_bits += rl_intra_aic.table_vlc[aic_code][1]+1; |
| |
| if (code == rl->n) { |
| inter_vlc_bits += 1+6+8-1; |
| } |
| if (aic_code == rl_intra_aic.n) { |
| aic_vlc_bits += 1+6+8-1; |
| wrong_pos += run + 1; |
| }else |
| wrong_pos += wrong_run[aic_code]; |
| last_non_zero = i; |
| } |
| } |
| i = 0; |
| if(aic_vlc_bits < inter_vlc_bits && wrong_pos > 63) |
| rl = &rl_intra_aic; |
| } |
| } |
| |
| /* AC coefs */ |
| last_index = s->block_last_index[n]; |
| last_non_zero = i - 1; |
| for (; i <= last_index; i++) { |
| j = s->intra_scantable.permutated[i]; |
| level = block[j]; |
| if (level) { |
| run = i - last_non_zero - 1; |
| last = (i == last_index); |
| sign = 0; |
| slevel = level; |
| if (level < 0) { |
| sign = 1; |
| level = -level; |
| } |
| code = get_rl_index(rl, last, run, level); |
| put_bits(&s->pb, rl->table_vlc[code][1], rl->table_vlc[code][0]); |
| if (code == rl->n) { |
| if(s->h263_flv <= 1){ |
| put_bits(&s->pb, 1, last); |
| put_bits(&s->pb, 6, run); |
| |
| assert(slevel != 0); |
| |
| if(level < 128) |
| put_sbits(&s->pb, 8, slevel); |
| else{ |
| put_bits(&s->pb, 8, 128); |
| put_sbits(&s->pb, 5, slevel); |
| put_sbits(&s->pb, 6, slevel>>5); |
| } |
| }else{ |
| if(level < 64) { // 7-bit level |
| put_bits(&s->pb, 1, 0); |
| put_bits(&s->pb, 1, last); |
| put_bits(&s->pb, 6, run); |
| |
| put_sbits(&s->pb, 7, slevel); |
| } else { |
| /* 11-bit level */ |
| put_bits(&s->pb, 1, 1); |
| put_bits(&s->pb, 1, last); |
| put_bits(&s->pb, 6, run); |
| |
| put_sbits(&s->pb, 11, slevel); |
| } |
| } |
| } else { |
| put_bits(&s->pb, 1, sign); |
| } |
| last_non_zero = i; |
| } |
| } |
| } |
| |
| /***************************************************/ |
| /** |
| * add mpeg4 stuffing bits (01...1) |
| */ |
| void ff_mpeg4_stuffing(PutBitContext * pbc) |
| { |
| int length; |
| put_bits(pbc, 1, 0); |
| length= (-put_bits_count(pbc))&7; |
| if(length) put_bits(pbc, length, (1<<length)-1); |
| } |
| |
| /* must be called before writing the header */ |
| void ff_set_mpeg4_time(MpegEncContext * s){ |
| if(s->pict_type==FF_B_TYPE){ |
| ff_mpeg4_init_direct_mv(s); |
| }else{ |
| s->last_time_base= s->time_base; |
| s->time_base= s->time/s->avctx->time_base.den; |
| } |
| } |
| |
| static void mpeg4_encode_gop_header(MpegEncContext * s){ |
| int hours, minutes, seconds; |
| int64_t time; |
| |
| put_bits(&s->pb, 16, 0); |
| put_bits(&s->pb, 16, GOP_STARTCODE); |
| |
| time= s->current_picture_ptr->pts; |
| if(s->reordered_input_picture[1]) |
| time= FFMIN(time, s->reordered_input_picture[1]->pts); |
| time= time*s->avctx->time_base.num; |
| |
| seconds= time/s->avctx->time_base.den; |
| minutes= seconds/60; seconds %= 60; |
| hours= minutes/60; minutes %= 60; |
| hours%=24; |
| |
| put_bits(&s->pb, 5, hours); |
| put_bits(&s->pb, 6, minutes); |
| put_bits(&s->pb, 1, 1); |
| put_bits(&s->pb, 6, seconds); |
| |
| put_bits(&s->pb, 1, !!(s->flags&CODEC_FLAG_CLOSED_GOP)); |
| put_bits(&s->pb, 1, 0); //broken link == NO |
| |
| s->last_time_base= time / s->avctx->time_base.den; |
| |
| ff_mpeg4_stuffing(&s->pb); |
| } |
| |
| static void mpeg4_encode_visual_object_header(MpegEncContext * s){ |
| int profile_and_level_indication; |
| int vo_ver_id; |
| |
| if(s->avctx->profile != FF_PROFILE_UNKNOWN){ |
| profile_and_level_indication = s->avctx->profile << 4; |
| }else if(s->max_b_frames || s->quarter_sample){ |
| profile_and_level_indication= 0xF0; // adv simple |
| }else{ |
| profile_and_level_indication= 0x00; // simple |
| } |
| |
| if(s->avctx->level != FF_LEVEL_UNKNOWN){ |
| profile_and_level_indication |= s->avctx->level; |
| }else{ |
| profile_and_level_indication |= 1; //level 1 |
| } |
| |
| if(profile_and_level_indication>>4 == 0xF){ |
| vo_ver_id= 5; |
| }else{ |
| vo_ver_id= 1; |
| } |
| |
| //FIXME levels |
| |
| put_bits(&s->pb, 16, 0); |
| put_bits(&s->pb, 16, VOS_STARTCODE); |
| |
| put_bits(&s->pb, 8, profile_and_level_indication); |
| |
| put_bits(&s->pb, 16, 0); |
| put_bits(&s->pb, 16, VISUAL_OBJ_STARTCODE); |
| |
| put_bits(&s->pb, 1, 1); |
| put_bits(&s->pb, 4, vo_ver_id); |
| put_bits(&s->pb, 3, 1); //priority |
| |
| put_bits(&s->pb, 4, 1); //visual obj type== video obj |
| |
| put_bits(&s->pb, 1, 0); //video signal type == no clue //FIXME |
| |
| ff_mpeg4_stuffing(&s->pb); |
| } |
| |
| static void mpeg4_encode_vol_header(MpegEncContext * s, int vo_number, int vol_number) |
| { |
| int vo_ver_id; |
| |
| if (!CONFIG_MPEG4_ENCODER) return; |
| |
| if(s->max_b_frames || s->quarter_sample){ |
| vo_ver_id= 5; |
| s->vo_type= ADV_SIMPLE_VO_TYPE; |
| }else{ |
| vo_ver_id= 1; |
| s->vo_type= SIMPLE_VO_TYPE; |
| } |
| |
| put_bits(&s->pb, 16, 0); |
| put_bits(&s->pb, 16, 0x100 + vo_number); /* video obj */ |
| put_bits(&s->pb, 16, 0); |
| put_bits(&s->pb, 16, 0x120 + vol_number); /* video obj layer */ |
| |
| put_bits(&s->pb, 1, 0); /* random access vol */ |
| put_bits(&s->pb, 8, s->vo_type); /* video obj type indication */ |
| if(s->workaround_bugs & FF_BUG_MS) { |
| put_bits(&s->pb, 1, 0); /* is obj layer id= no */ |
| } else { |
| put_bits(&s->pb, 1, 1); /* is obj layer id= yes */ |
| put_bits(&s->pb, 4, vo_ver_id); /* is obj layer ver id */ |
| put_bits(&s->pb, 3, 1); /* is obj layer priority */ |
| } |
| |
| aspect_to_info(s, s->avctx->sample_aspect_ratio); |
| |
| put_bits(&s->pb, 4, s->aspect_ratio_info);/* aspect ratio info */ |
| if (s->aspect_ratio_info == FF_ASPECT_EXTENDED){ |
| put_bits(&s->pb, 8, s->avctx->sample_aspect_ratio.num); |
| put_bits(&s->pb, 8, s->avctx->sample_aspect_ratio.den); |
| } |
| |
| if(s->workaround_bugs & FF_BUG_MS) { // |
| put_bits(&s->pb, 1, 0); /* vol control parameters= no @@@ */ |
| } else { |
| put_bits(&s->pb, 1, 1); /* vol control parameters= yes */ |
| put_bits(&s->pb, 2, 1); /* chroma format YUV 420/YV12 */ |
| put_bits(&s->pb, 1, s->low_delay); |
| put_bits(&s->pb, 1, 0); /* vbv parameters= no */ |
| } |
| |
| put_bits(&s->pb, 2, RECT_SHAPE); /* vol shape= rectangle */ |
| put_bits(&s->pb, 1, 1); /* marker bit */ |
| |
| put_bits(&s->pb, 16, s->avctx->time_base.den); |
| if (s->time_increment_bits < 1) |
| s->time_increment_bits = 1; |
| put_bits(&s->pb, 1, 1); /* marker bit */ |
| put_bits(&s->pb, 1, 0); /* fixed vop rate=no */ |
| put_bits(&s->pb, 1, 1); /* marker bit */ |
| put_bits(&s->pb, 13, s->width); /* vol width */ |
| put_bits(&s->pb, 1, 1); /* marker bit */ |
| put_bits(&s->pb, 13, s->height); /* vol height */ |
| put_bits(&s->pb, 1, 1); /* marker bit */ |
| put_bits(&s->pb, 1, s->progressive_sequence ? 0 : 1); |
| put_bits(&s->pb, 1, 1); /* obmc disable */ |
| if (vo_ver_id == 1) { |
| put_bits(&s->pb, 1, s->vol_sprite_usage); /* sprite enable */ |
| }else{ |
| put_bits(&s->pb, 2, s->vol_sprite_usage); /* sprite enable */ |
| } |
| |
| put_bits(&s->pb, 1, 0); /* not 8 bit == false */ |
| put_bits(&s->pb, 1, s->mpeg_quant); /* quant type= (0=h263 style)*/ |
| |
| if(s->mpeg_quant){ |
| ff_write_quant_matrix(&s->pb, s->avctx->intra_matrix); |
| ff_write_quant_matrix(&s->pb, s->avctx->inter_matrix); |
| } |
| |
| if (vo_ver_id != 1) |
| put_bits(&s->pb, 1, s->quarter_sample); |
| put_bits(&s->pb, 1, 1); /* complexity estimation disable */ |
| s->resync_marker= s->rtp_mode; |
| put_bits(&s->pb, 1, s->resync_marker ? 0 : 1);/* resync marker disable */ |
| put_bits(&s->pb, 1, s->data_partitioning ? 1 : 0); |
| if(s->data_partitioning){ |
| put_bits(&s->pb, 1, 0); /* no rvlc */ |
| } |
| |
| if (vo_ver_id != 1){ |
| put_bits(&s->pb, 1, 0); /* newpred */ |
| put_bits(&s->pb, 1, 0); /* reduced res vop */ |
| } |
| put_bits(&s->pb, 1, 0); /* scalability */ |
| |
| ff_mpeg4_stuffing(&s->pb); |
| |
| /* user data */ |
| if(!(s->flags & CODEC_FLAG_BITEXACT)){ |
| put_bits(&s->pb, 16, 0); |
| put_bits(&s->pb, 16, 0x1B2); /* user_data */ |
| ff_put_string(&s->pb, LIBAVCODEC_IDENT, 0); |
| } |
| } |
| |
| /* write mpeg4 VOP header */ |
| void mpeg4_encode_picture_header(MpegEncContext * s, int picture_number) |
| { |
| int time_incr; |
| int time_div, time_mod; |
| |
| if(s->pict_type==FF_I_TYPE){ |
| if(!(s->flags&CODEC_FLAG_GLOBAL_HEADER)){ |
| if(s->strict_std_compliance < FF_COMPLIANCE_VERY_STRICT) //HACK, the reference sw is buggy |
| mpeg4_encode_visual_object_header(s); |
| if(s->strict_std_compliance < FF_COMPLIANCE_VERY_STRICT || picture_number==0) //HACK, the reference sw is buggy |
| mpeg4_encode_vol_header(s, 0, 0); |
| } |
| if(!(s->workaround_bugs & FF_BUG_MS)) |
| mpeg4_encode_gop_header(s); |
| } |
| |
| s->partitioned_frame= s->data_partitioning && s->pict_type!=FF_B_TYPE; |
| |
| //printf("num:%d rate:%d base:%d\n", s->picture_number, s->time_base.den, FRAME_RATE_BASE); |
| |
| put_bits(&s->pb, 16, 0); /* vop header */ |
| put_bits(&s->pb, 16, VOP_STARTCODE); /* vop header */ |
| put_bits(&s->pb, 2, s->pict_type - 1); /* pict type: I = 0 , P = 1 */ |
| |
| assert(s->time>=0); |
| time_div= s->time/s->avctx->time_base.den; |
| time_mod= s->time%s->avctx->time_base.den; |
| time_incr= time_div - s->last_time_base; |
| assert(time_incr >= 0); |
| while(time_incr--) |
| put_bits(&s->pb, 1, 1); |
| |
| put_bits(&s->pb, 1, 0); |
| |
| put_bits(&s->pb, 1, 1); /* marker */ |
| put_bits(&s->pb, s->time_increment_bits, time_mod); /* time increment */ |
| put_bits(&s->pb, 1, 1); /* marker */ |
| put_bits(&s->pb, 1, 1); /* vop coded */ |
| if ( s->pict_type == FF_P_TYPE |
| || (s->pict_type == FF_S_TYPE && s->vol_sprite_usage==GMC_SPRITE)) { |
| put_bits(&s->pb, 1, s->no_rounding); /* rounding type */ |
| } |
| put_bits(&s->pb, 3, 0); /* intra dc VLC threshold */ |
| if(!s->progressive_sequence){ |
| put_bits(&s->pb, 1, s->current_picture_ptr->top_field_first); |
| put_bits(&s->pb, 1, s->alternate_scan); |
| } |
| //FIXME sprite stuff |
| |
| put_bits(&s->pb, 5, s->qscale); |
| |
| if (s->pict_type != FF_I_TYPE) |
| put_bits(&s->pb, 3, s->f_code); /* fcode_for */ |
| if (s->pict_type == FF_B_TYPE) |
| put_bits(&s->pb, 3, s-> |