blob: 2a25cdae671645e34d1e5dfc1ef8dd274b943331 [file] [log] [blame]
/*
* 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"
//#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;
}
s->mv[0][i][0] = s->p_field_mv_table[i][0][mb_index][0]*time_pb/time_pp + mx;
s->mv[0][i][1] = 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]
: 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]
: 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);
}