*
* 4MV & hq & b-frame encoding stuff by Michael Niedermayer <michaelni@gmx.at>
*/
+
+#include <ctype.h>
#include "avcodec.h"
#include "dsputil.h"
#include "mpegvideo.h"
+#include "simple_idct.h"
#ifdef USE_FASTMEMCPY
#include "fastmemcpy.h"
#endif
+//#undef NDEBUG
+//#include <assert.h>
+
static void encode_picture(MpegEncContext *s, int picture_number);
static void dct_unquantize_mpeg1_c(MpegEncContext *s,
DCTELEM *block, int n, int qscale);
static UINT16 default_mv_penalty[MAX_FCODE+1][MAX_MV*2+1];
static UINT8 default_fcode_tab[MAX_MV*2+1];
-extern UINT8 zigzag_end[64];
-
/* default motion estimation */
int motion_estimation_method = ME_EPZS;
static void convert_matrix(MpegEncContext *s, int (*qmat)[64], uint16_t (*qmat16)[64], uint16_t (*qmat16_bias)[64],
- const UINT16 *quant_matrix, int bias)
+ const UINT16 *quant_matrix, int bias, int qmin, int qmax)
{
int qscale;
- for(qscale=1; qscale<32; qscale++){
+ for(qscale=qmin; qscale<=qmax; qscale++){
int i;
if (s->fdct == ff_jpeg_fdct_islow) {
for(i=0;i<64;i++) {
- const int j= block_permute_op(i);
+ const int j= s->idct_permutation[i];
/* 16 <= qscale * quant_matrix[i] <= 7905 */
/* 19952 <= aanscales[i] * qscale * quant_matrix[i] <= 249205026 */
/* (1<<36)/19952 >= (1<<36)/(aanscales[i] * qscale * quant_matrix[i]) >= (1<<36)/249205026 */
/* 3444240 >= (1<<36)/(aanscales[i] * qscale * quant_matrix[i]) >= 275 */
- qmat[qscale][j] = (int)((UINT64_C(1) << (QMAT_SHIFT-3)) /
+ qmat[qscale][j] = (int)((UINT64_C(1) << QMAT_SHIFT) /
(qscale * quant_matrix[j]));
}
} else if (s->fdct == fdct_ifast) {
for(i=0;i<64;i++) {
- const int j= block_permute_op(i);
+ const int j= s->idct_permutation[i];
/* 16 <= qscale * quant_matrix[i] <= 7905 */
/* 19952 <= aanscales[i] * qscale * quant_matrix[i] <= 249205026 */
/* (1<<36)/19952 >= (1<<36)/(aanscales[i] * qscale * quant_matrix[i]) >= (1<<36)/249205026 */
/* 3444240 >= (1<<36)/(aanscales[i] * qscale * quant_matrix[i]) >= 275 */
- qmat[qscale][j] = (int)((UINT64_C(1) << (QMAT_SHIFT + 11)) /
+ qmat[qscale][j] = (int)((UINT64_C(1) << (QMAT_SHIFT + 14)) /
(aanscales[i] * qscale * quant_matrix[j]));
}
} else {
for(i=0;i<64;i++) {
+ const int j= s->idct_permutation[i];
/* We can safely suppose that 16 <= quant_matrix[i] <= 255
So 16 <= qscale * quant_matrix[i] <= 7905
so (1<<19) / 16 >= (1<<19) / (qscale * quant_matrix[i]) >= (1<<19) / 7905
so 32768 >= (1<<19) / (qscale * quant_matrix[i]) >= 67
*/
qmat [qscale][i] = (1 << QMAT_SHIFT_MMX) / (qscale * quant_matrix[i]);
- qmat16[qscale][i] = (1 << QMAT_SHIFT_MMX) / (qscale * quant_matrix[block_permute_op(i)]);
+ qmat16[qscale][i] = (1 << QMAT_SHIFT_MMX) / (qscale * quant_matrix[j]);
if(qmat16[qscale][i]==0 || qmat16[qscale][i]==128*256) qmat16[qscale][i]=128*256-1;
-
qmat16_bias[qscale][i]= ROUNDED_DIV(bias<<(16-QUANT_BIAS_SHIFT), qmat16[qscale][i]);
}
}
goto fail;\
}\
}
+/*
+static void build_end(void)
+{
+ int lastIndex;
+ int lastIndexAfterPerm=0;
+ for(lastIndex=0; lastIndex<64; lastIndex++)
+ {
+ if(ff_zigzag_direct[lastIndex] > lastIndexAfterPerm)
+ lastIndexAfterPerm= ff_zigzag_direct[lastIndex];
+ zigzag_end[lastIndex]= lastIndexAfterPerm + 1;
+ }
+}
+*/
+void ff_init_scantable(MpegEncContext *s, ScanTable *st, const UINT8 *src_scantable){
+ int i;
+ int end;
+
+ for(i=0; i<64; i++){
+ int j;
+ j = src_scantable[i];
+ st->permutated[i] = s->idct_permutation[j];
+ }
+
+ end=-1;
+ for(i=0; i<64; i++){
+ int j;
+ j = st->permutated[i];
+ if(j>end) end=j;
+ st->raster_end[i]= end;
+ }
+}
+
+/* XXX: those functions should be suppressed ASAP when all IDCTs are
+ converted */
+static void ff_jref_idct_put(UINT8 *dest, int line_size, DCTELEM *block)
+{
+ j_rev_dct (block);
+ put_pixels_clamped(block, dest, line_size);
+}
+static void ff_jref_idct_add(UINT8 *dest, int line_size, DCTELEM *block)
+{
+ j_rev_dct (block);
+ add_pixels_clamped(block, dest, line_size);
+}
/* init common structure for both encoder and decoder */
int MPV_common_init(MpegEncContext *s)
if(s->avctx->dct_algo==FF_DCT_FASTINT)
s->fdct = fdct_ifast;
else
- s->fdct = ff_jpeg_fdct_islow;
+ s->fdct = ff_jpeg_fdct_islow; //slow/accurate/default
+
+ if(s->avctx->idct_algo==FF_IDCT_INT){
+ s->idct_put= ff_jref_idct_put;
+ s->idct_add= ff_jref_idct_add;
+ for(i=0; i<64; i++)
+ s->idct_permutation[i]= (i & 0x38) | ((i & 6) >> 1) | ((i & 1) << 2);
+ }else{ //accurate/default
+ s->idct_put= simple_idct_put;
+ s->idct_add= simple_idct_add;
+ for(i=0; i<64; i++)
+ s->idct_permutation[i]= i;
+ }
#ifdef HAVE_MMX
MPV_common_init_mmx(s);
#ifdef ARCH_ALPHA
MPV_common_init_axp(s);
#endif
+#ifdef HAVE_MLIB
+ MPV_common_init_mlib(s);
+#endif
+
+
+ /* load & permutate scantables
+ note: only wmv uses differnt ones
+ */
+ ff_init_scantable(s, &s->inter_scantable , ff_zigzag_direct);
+ ff_init_scantable(s, &s->intra_scantable , ff_zigzag_direct);
+ ff_init_scantable(s, &s->intra_h_scantable, ff_alternate_horizontal_scan);
+ ff_init_scantable(s, &s->intra_v_scantable, ff_alternate_vertical_scan);
s->mb_width = (s->width + 15) / 16;
s->mb_height = (s->height + 15) / 16;
/* set default edge pos, will be overriden in decode_header if needed */
s->h_edge_pos= s->mb_width*16;
s->v_edge_pos= s->mb_height*16;
+
+ /* convert fourcc to upper case */
+ s->avctx->fourcc= toupper( s->avctx->fourcc &0xFF)
+ + (toupper((s->avctx->fourcc>>8 )&0xFF)<<8 )
+ + (toupper((s->avctx->fourcc>>16)&0xFF)<<16)
+ + (toupper((s->avctx->fourcc>>24)&0xFF)<<24);
s->mb_num = s->mb_width * s->mb_height;
if(!(s->flags&CODEC_FLAG_DR1)){
CHECKED_ALLOCZ(s->mb_var , s->mb_num * sizeof(INT16))
CHECKED_ALLOCZ(s->mc_mb_var, s->mb_num * sizeof(INT16))
+ CHECKED_ALLOCZ(s->mb_mean , s->mb_num * sizeof(INT8))
/* Allocate MV tables */
CHECKED_ALLOCZ(s->p_mv_table , mv_table_size * 2 * sizeof(INT16))
CHECKED_ALLOCZ( s->pb2_buffer, PB_BUFFER_SIZE);
}
+ if(s->msmpeg4_version){
+ CHECKED_ALLOCZ(s->ac_stats, 2*2*(MAX_LEVEL+1)*(MAX_RUN+1)*2*sizeof(int));
+ }
CHECKED_ALLOCZ(s->avctx->stats_out, 256);
}
/* MV prediction */
size = (2 * s->mb_width + 2) * (2 * s->mb_height + 2);
CHECKED_ALLOCZ(s->motion_val, size * 2 * sizeof(INT16));
-
- /* 4mv direct mode decoding table */
- CHECKED_ALLOCZ(s->non_b_mv4_table, size * sizeof(UINT8))
+ }
+
+ if(s->codec_id==CODEC_ID_MPEG4){
+ /* 4mv and interlaced direct mode decoding tables */
+ CHECKED_ALLOCZ(s->co_located_type_table, s->mb_num * sizeof(UINT8))
+ CHECKED_ALLOCZ(s->field_mv_table, s->mb_num*2*2 * sizeof(INT16))
+ CHECKED_ALLOCZ(s->field_select_table, s->mb_num*2* sizeof(INT8))
}
if (s->h263_pred || s->h263_plus) {
av_freep(&s->mb_type);
av_freep(&s->mb_var);
av_freep(&s->mc_mb_var);
+ av_freep(&s->mb_mean);
av_freep(&s->p_mv_table);
av_freep(&s->b_forw_mv_table);
av_freep(&s->b_back_mv_table);
av_freep(&s->tex_pb_buffer);
av_freep(&s->pb2_buffer);
av_freep(&s->edge_emu_buffer);
- av_freep(&s->non_b_mv4_table);
+ av_freep(&s->co_located_type_table);
+ av_freep(&s->field_mv_table);
+ av_freep(&s->field_select_table);
av_freep(&s->avctx->stats_out);
+ av_freep(&s->ac_stats);
for(i=0;i<3;i++) {
int j;
} else {
s->intra_only = 0;
}
-
+
/* ME algorithm */
if (avctx->me_method == 0)
/* For compatibility */
s->me_method = motion_estimation_method;
else
s->me_method = avctx->me_method;
-
+
/* Fixed QSCALE */
s->fixed_qscale = (avctx->flags & CODEC_FLAG_QSCALE);
+ s->adaptive_quant= ( s->avctx->lumi_masking
+ || s->avctx->dark_masking
+ || s->avctx->temporal_cplx_masking
+ || s->avctx->spatial_cplx_masking
+ || s->avctx->p_masking)
+ && !s->fixed_qscale;
+
+ s->progressive_sequence= !(avctx->flags & CODEC_FLAG_INTERLACED_DCT);
+
switch(avctx->codec->id) {
case CODEC_ID_MPEG1VIDEO:
s->out_format = FMT_MPEG1;
s->y_dc_scale_table=
s->c_dc_scale_table= ff_mpeg1_dc_scale_table;
- if (s->out_format == FMT_H263)
- h263_encode_init(s);
- else if (s->out_format == FMT_MPEG1)
- ff_mpeg1_encode_init(s);
- if(s->msmpeg4_version)
- ff_msmpeg4_encode_init(s);
-
/* dont use mv_penalty table for crap MV as it would be confused */
if (s->me_method < ME_EPZS) s->mv_penalty = default_mv_penalty;
if (MPV_common_init(s) < 0)
return -1;
+ if (s->out_format == FMT_H263)
+ h263_encode_init(s);
+ else if (s->out_format == FMT_MPEG1)
+ ff_mpeg1_encode_init(s);
+ if(s->msmpeg4_version)
+ ff_msmpeg4_encode_init(s);
+
/* init default q matrix */
for(i=0;i<64;i++) {
+ int j= s->idct_permutation[i];
if(s->codec_id==CODEC_ID_MPEG4 && s->mpeg_quant){
- s->intra_matrix[i] = ff_mpeg4_default_intra_matrix[i];
- s->inter_matrix[i] = ff_mpeg4_default_non_intra_matrix[i];
+ s->intra_matrix[j] = ff_mpeg4_default_intra_matrix[i];
+ s->inter_matrix[j] = ff_mpeg4_default_non_intra_matrix[i];
}else if(s->out_format == FMT_H263){
- s->intra_matrix[i] =
- s->inter_matrix[i] = ff_mpeg1_default_non_intra_matrix[i];
+ s->intra_matrix[j] =
+ s->inter_matrix[j] = ff_mpeg1_default_non_intra_matrix[i];
}else{ /* mpeg1 */
- s->intra_matrix[i] = ff_mpeg1_default_intra_matrix[i];
- s->inter_matrix[i] = ff_mpeg1_default_non_intra_matrix[i];
+ s->intra_matrix[j] = ff_mpeg1_default_intra_matrix[i];
+ s->inter_matrix[j] = ff_mpeg1_default_non_intra_matrix[i];
}
}
/* for mjpeg, we do include qscale in the matrix */
if (s->out_format != FMT_MJPEG) {
convert_matrix(s, s->q_intra_matrix, s->q_intra_matrix16, s->q_intra_matrix16_bias,
- s->intra_matrix, s->intra_quant_bias);
+ s->intra_matrix, s->intra_quant_bias, 1, 31);
convert_matrix(s, s->q_inter_matrix, s->q_inter_matrix16, s->q_inter_matrix16_bias,
- s->inter_matrix, s->inter_quant_bias);
+ s->inter_matrix, s->inter_quant_bias, 1, 31);
}
if(ff_rate_control_init(s) < 0)
/* generic function for encode/decode called after a frame has been coded/decoded */
void MPV_frame_end(MpegEncContext *s)
{
-// if((s->picture_number%100)==0 && s->encoding) printf("sads:%d //\n", sads);
+ s->avctx->key_frame = (s->pict_type == I_TYPE);
+ s->avctx->pict_type = s->pict_type;
/* draw edge for correct motion prediction if outside */
if (s->pict_type != B_TYPE && !s->intra_only && !(s->flags&CODEC_FLAG_EMU_EDGE)) {
MPV_frame_start(s, avctx);
encode_picture(s, s->picture_number);
- avctx->key_frame = (s->pict_type == I_TYPE);
- avctx->pict_type = s->pict_type;
+
avctx->real_pict_num = s->picture_number;
avctx->header_bits = s->header_bits;
avctx->mv_bits = s->mv_bits;
avctx->i_tex_bits = s->i_tex_bits;
avctx->p_tex_bits = s->p_tex_bits;
avctx->i_count = s->i_count;
- avctx->p_count = s->p_count;
+ avctx->p_count = s->mb_num - s->i_count - s->skip_count; //FIXME f/b_count in avctx
avctx->skip_count = s->skip_count;
MPV_frame_end(s);
if (s->out_format == FMT_MJPEG)
mjpeg_picture_trailer(s);
- avctx->quality = s->qscale;
+ if(!s->fixed_qscale)
+ avctx->quality = s->qscale;
if(s->flags&CODEC_FLAG_PASS1)
ff_write_pass1_stats(s);
UINT8 *dest_y, UINT8 *dest_cb, UINT8 *dest_cr,
int dest_offset,
UINT8 **ref_picture, int src_offset,
- int field_based, op_pixels_func *pix_op,
+ int field_based, op_pixels_func (*pix_op)[4],
int motion_x, int motion_y, int h)
{
UINT8 *ptr;
int dxy, offset, mx, my, src_x, src_y, height, v_edge_pos, linesize, uvlinesize;
int emu=0;
-
+#if 0
if(s->quarter_sample)
{
motion_x>>=1;
motion_y>>=1;
}
+#endif
dxy = ((motion_y & 1) << 1) | (motion_x & 1);
src_x = s->mb_x * 16 + (motion_x >> 1);
src_y = s->mb_y * (16 >> field_based) + (motion_y >> 1);
emu=1;
}
}
- pix_op[dxy](dest_y, ptr, linesize, h);
- pix_op[dxy](dest_y + 8, ptr + 8, linesize, h);
+ pix_op[0][dxy](dest_y, ptr, linesize, h);
if(s->flags&CODEC_FLAG_GRAY) return;
emulated_edge_mc(s, ptr, uvlinesize, 9, (h>>1)+1, src_x, src_y, s->h_edge_pos>>1, v_edge_pos>>1);
ptr= s->edge_emu_buffer;
}
- pix_op[dxy](dest_cb + (dest_offset >> 1), ptr, uvlinesize, h >> 1);
+ pix_op[1][dxy](dest_cb + (dest_offset >> 1), ptr, uvlinesize, h >> 1);
ptr = ref_picture[2] + offset;
if(emu){
emulated_edge_mc(s, ptr, uvlinesize, 9, (h>>1)+1, src_x, src_y, s->h_edge_pos>>1, v_edge_pos>>1);
ptr= s->edge_emu_buffer;
}
- pix_op[dxy](dest_cr + (dest_offset >> 1), ptr, uvlinesize, h >> 1);
+ pix_op[1][dxy](dest_cr + (dest_offset >> 1), ptr, uvlinesize, h >> 1);
}
static inline void qpel_motion(MpegEncContext *s,
UINT8 *dest_y, UINT8 *dest_cb, UINT8 *dest_cr,
int dest_offset,
UINT8 **ref_picture, int src_offset,
- int field_based, op_pixels_func *pix_op,
- qpel_mc_func *qpix_op,
+ int field_based, op_pixels_func (*pix_op)[4],
+ qpel_mc_func (*qpix_op)[16],
int motion_x, int motion_y, int h)
{
UINT8 *ptr;
- int dxy, offset, mx, my, src_x, src_y, height, v_edge_pos, linesize;
+ int dxy, offset, mx, my, src_x, src_y, height, v_edge_pos, linesize, uvlinesize;
int emu=0;
dxy = ((motion_y & 3) << 2) | (motion_x & 3);
if (src_y == height)
dxy &= ~12;
linesize = s->linesize << field_based;
+ uvlinesize = s->uvlinesize << field_based;
ptr = ref_picture[0] + (src_y * linesize) + src_x + src_offset;
dest_y += dest_offset;
//printf("%d %d %d\n", src_x, src_y, dxy);
emu=1;
}
}
- qpix_op[dxy](dest_y , ptr , linesize, linesize, motion_x&3, motion_y&3);
- qpix_op[dxy](dest_y + 8, ptr + 8, linesize, linesize, motion_x&3, motion_y&3);
- qpix_op[dxy](dest_y + linesize*8 , ptr + linesize*8 , linesize, linesize, motion_x&3, motion_y&3);
- qpix_op[dxy](dest_y + linesize*8 + 8, ptr + linesize*8 + 8, linesize, linesize, motion_x&3, motion_y&3);
-
+ if(!field_based)
+ qpix_op[0][dxy](dest_y, ptr, linesize);
+ else{
+ //damn interlaced mode
+ //FIXME boundary mirroring is not exactly correct here
+ qpix_op[1][dxy](dest_y , ptr , linesize);
+ qpix_op[1][dxy](dest_y+8, ptr+8, linesize);
+ }
+
if(s->flags&CODEC_FLAG_GRAY) return;
- mx= (motion_x>>1) | (motion_x&1);
- my= (motion_y>>1) | (motion_y&1);
+ if(field_based){
+ mx= motion_x/2;
+ my= motion_y>>1;
+ }else if(s->divx_version){
+ mx= (motion_x>>1)|(motion_x&1);
+ my= (motion_y>>1)|(motion_y&1);
+ }else{
+ mx= motion_x/2;
+ my= motion_y/2;
+ }
+ mx= (mx>>1)|(mx&1);
+ my= (my>>1)|(my&1);
+ dxy= (mx&1) | ((my&1)<<1);
+ mx>>=1;
+ my>>=1;
- dxy = 0;
- if ((mx & 3) != 0)
- dxy |= 1;
- if ((my & 3) != 0)
- dxy |= 2;
- mx = mx >> 2;
- my = my >> 2;
-
src_x = s->mb_x * 8 + mx;
src_y = s->mb_y * (8 >> field_based) + my;
src_x = clip(src_x, -8, s->width >> 1);
if (src_y == (height >> 1))
dxy &= ~2;
- offset = (src_y * s->uvlinesize) + src_x + (src_offset >> 1);
+ offset = (src_y * uvlinesize) + src_x + (src_offset >> 1);
ptr = ref_picture[1] + offset;
if(emu){
- emulated_edge_mc(s, ptr, s->uvlinesize, 9, (h>>1)+1, src_x, src_y, s->h_edge_pos>>1, v_edge_pos>>1);
+ emulated_edge_mc(s, ptr, uvlinesize, 9, (h>>1)+1, src_x, src_y, s->h_edge_pos>>1, v_edge_pos>>1);
ptr= s->edge_emu_buffer;
}
- pix_op[dxy](dest_cb + (dest_offset >> 1), ptr, s->uvlinesize, h >> 1);
+ pix_op[1][dxy](dest_cb + (dest_offset >> 1), ptr, uvlinesize, h >> 1);
ptr = ref_picture[2] + offset;
if(emu){
- emulated_edge_mc(s, ptr, s->uvlinesize, 9, (h>>1)+1, src_x, src_y, s->h_edge_pos>>1, v_edge_pos>>1);
+ emulated_edge_mc(s, ptr, uvlinesize, 9, (h>>1)+1, src_x, src_y, s->h_edge_pos>>1, v_edge_pos>>1);
ptr= s->edge_emu_buffer;
}
- pix_op[dxy](dest_cr + (dest_offset >> 1), ptr, s->uvlinesize, h >> 1);
+ pix_op[1][dxy](dest_cr + (dest_offset >> 1), ptr, uvlinesize, h >> 1);
}
static inline void MPV_motion(MpegEncContext *s,
UINT8 *dest_y, UINT8 *dest_cb, UINT8 *dest_cr,
int dir, UINT8 **ref_picture,
- op_pixels_func *pix_op, qpel_mc_func *qpix_op)
+ op_pixels_func (*pix_op)[4], qpel_mc_func (*qpix_op)[16])
{
int dxy, offset, mx, my, src_x, src_y, motion_x, motion_y;
int mb_x, mb_y, i;
switch(s->mv_type) {
case MV_TYPE_16X16:
if(s->mcsel){
-#if 0
- mpeg_motion(s, dest_y, dest_cb, dest_cr, 0,
- ref_picture, 0,
- 0, pix_op,
- s->sprite_offset[0][0]>>3,
- s->sprite_offset[0][1]>>3,
- 16);
-#else
gmc1_motion(s, dest_y, dest_cb, dest_cr, 0,
ref_picture, 0,
16);
-#endif
- }else if(s->quarter_sample && dir==0){ //FIXME
+ }else if(s->quarter_sample){
qpel_motion(s, dest_y, dest_cb, dest_cr, 0,
ref_picture, 0,
0, pix_op, qpix_op,
}
break;
case MV_TYPE_8X8:
- for(i=0;i<4;i++) {
- motion_x = s->mv[dir][i][0];
- motion_y = s->mv[dir][i][1];
+ mx = 0;
+ my = 0;
+ if(s->quarter_sample){
+ for(i=0;i<4;i++) {
+ motion_x = s->mv[dir][i][0];
+ motion_y = s->mv[dir][i][1];
+
+ dxy = ((motion_y & 3) << 2) | (motion_x & 3);
+ src_x = mb_x * 16 + (motion_x >> 2) + (i & 1) * 8;
+ src_y = mb_y * 16 + (motion_y >> 2) + (i >>1) * 8;
+
+ /* WARNING: do no forget half pels */
+ src_x = clip(src_x, -16, s->width);
+ if (src_x == s->width)
+ dxy &= ~3;
+ src_y = clip(src_y, -16, s->height);
+ if (src_y == s->height)
+ dxy &= ~12;
+
+ ptr = ref_picture[0] + (src_y * s->linesize) + (src_x);
+ if(s->flags&CODEC_FLAG_EMU_EDGE){
+ if(src_x<0 || src_y<0 || src_x + (motion_x&3) + 8 > s->h_edge_pos
+ || src_y + (motion_y&3) + 8 > s->v_edge_pos){
+ emulated_edge_mc(s, ptr, s->linesize, 9, 9, src_x, src_y, s->h_edge_pos, s->v_edge_pos);
+ ptr= s->edge_emu_buffer;
+ }
+ }
+ dest = dest_y + ((i & 1) * 8) + (i >> 1) * 8 * s->linesize;
+ qpix_op[1][dxy](dest, ptr, s->linesize);
- dxy = ((motion_y & 1) << 1) | (motion_x & 1);
- src_x = mb_x * 16 + (motion_x >> 1) + (i & 1) * 8;
- src_y = mb_y * 16 + (motion_y >> 1) + (i >>1) * 8;
+ mx += s->mv[dir][i][0]/2;
+ my += s->mv[dir][i][1]/2;
+ }
+ }else{
+ for(i=0;i<4;i++) {
+ motion_x = s->mv[dir][i][0];
+ motion_y = s->mv[dir][i][1];
+
+ dxy = ((motion_y & 1) << 1) | (motion_x & 1);
+ src_x = mb_x * 16 + (motion_x >> 1) + (i & 1) * 8;
+ src_y = mb_y * 16 + (motion_y >> 1) + (i >>1) * 8;
- /* WARNING: do no forget half pels */
- src_x = clip(src_x, -16, s->width);
- if (src_x == s->width)
- dxy &= ~1;
- src_y = clip(src_y, -16, s->height);
- if (src_y == s->height)
- dxy &= ~2;
+ /* WARNING: do no forget half pels */
+ src_x = clip(src_x, -16, s->width);
+ if (src_x == s->width)
+ dxy &= ~1;
+ src_y = clip(src_y, -16, s->height);
+ if (src_y == s->height)
+ dxy &= ~2;
- ptr = ref_picture[0] + (src_y * s->linesize) + (src_x);
- if(s->flags&CODEC_FLAG_EMU_EDGE){
- if(src_x<0 || src_y<0 || src_x + (motion_x&1) + 8 > s->h_edge_pos
- || src_y + (motion_y&1) + 8 > s->v_edge_pos){
- emulated_edge_mc(s, ptr, s->linesize, 9, 9, src_x, src_y, s->h_edge_pos, s->v_edge_pos);
- ptr= s->edge_emu_buffer;
+ ptr = ref_picture[0] + (src_y * s->linesize) + (src_x);
+ if(s->flags&CODEC_FLAG_EMU_EDGE){
+ if(src_x<0 || src_y<0 || src_x + (motion_x&1) + 8 > s->h_edge_pos
+ || src_y + (motion_y&1) + 8 > s->v_edge_pos){
+ emulated_edge_mc(s, ptr, s->linesize, 9, 9, src_x, src_y, s->h_edge_pos, s->v_edge_pos);
+ ptr= s->edge_emu_buffer;
+ }
}
+ dest = dest_y + ((i & 1) * 8) + (i >> 1) * 8 * s->linesize;
+ pix_op[1][dxy](dest, ptr, s->linesize, 8);
+
+ mx += s->mv[dir][i][0];
+ my += s->mv[dir][i][1];
}
- dest = dest_y + ((i & 1) * 8) + (i >> 1) * 8 * s->linesize;
- pix_op[dxy](dest, ptr, s->linesize, 8);
}
-
+
if(s->flags&CODEC_FLAG_GRAY) break;
/* In case of 8X8, we construct a single chroma motion vector
with a special rounding */
- mx = 0;
- my = 0;
for(i=0;i<4;i++) {
- mx += s->mv[dir][i][0];
- my += s->mv[dir][i][1];
}
if (mx >= 0)
mx = (h263_chroma_roundtab[mx & 0xf] + ((mx >> 3) & ~1));
emu=1;
}
}
- pix_op[dxy](dest_cb, ptr, s->uvlinesize, 8);
+ pix_op[1][dxy](dest_cb, ptr, s->uvlinesize, 8);
ptr = ref_picture[2] + offset;
if(emu){
emulated_edge_mc(s, ptr, s->uvlinesize, 9, 9, src_x, src_y, s->h_edge_pos>>1, s->v_edge_pos>>1);
ptr= s->edge_emu_buffer;
}
- pix_op[dxy](dest_cr, ptr, s->uvlinesize, 8);
+ pix_op[1][dxy](dest_cr, ptr, s->uvlinesize, 8);
break;
case MV_TYPE_FIELD:
if (s->picture_structure == PICT_FRAME) {
- /* top field */
- mpeg_motion(s, dest_y, dest_cb, dest_cr, 0,
- ref_picture, s->field_select[dir][0] ? s->linesize : 0,
- 1, pix_op,
- s->mv[dir][0][0], s->mv[dir][0][1], 8);
- /* bottom field */
- mpeg_motion(s, dest_y, dest_cb, dest_cr, s->linesize,
- ref_picture, s->field_select[dir][1] ? s->linesize : 0,
- 1, pix_op,
- s->mv[dir][1][0], s->mv[dir][1][1], 8);
+ if(s->quarter_sample){
+ /* top field */
+ qpel_motion(s, dest_y, dest_cb, dest_cr, 0,
+ ref_picture, s->field_select[dir][0] ? s->linesize : 0,
+ 1, pix_op, qpix_op,
+ s->mv[dir][0][0], s->mv[dir][0][1], 8);
+ /* bottom field */
+ qpel_motion(s, dest_y, dest_cb, dest_cr, s->linesize,
+ ref_picture, s->field_select[dir][1] ? s->linesize : 0,
+ 1, pix_op, qpix_op,
+ s->mv[dir][1][0], s->mv[dir][1][1], 8);
+ }else{
+ /* top field */
+ mpeg_motion(s, dest_y, dest_cb, dest_cr, 0,
+ ref_picture, s->field_select[dir][0] ? s->linesize : 0,
+ 1, pix_op,
+ s->mv[dir][0][0], s->mv[dir][0][1], 8);
+ /* bottom field */
+ mpeg_motion(s, dest_y, dest_cb, dest_cr, s->linesize,
+ ref_picture, s->field_select[dir][1] ? s->linesize : 0,
+ 1, pix_op,
+ s->mv[dir][1][0], s->mv[dir][1][1], 8);
+ }
} else {
{
if (!s->mpeg2)
s->dct_unquantize(s, block, i, s->qscale);
- ff_idct_put (dest, line_size, block);
+ s->idct_put (dest, line_size, block);
}
/* add block[] to dest[] */
DCTELEM *block, int i, UINT8 *dest, int line_size)
{
if (s->block_last_index[i] >= 0) {
- ff_idct_add (dest, line_size, block);
+ s->idct_add (dest, line_size, block);
}
}
if (s->block_last_index[i] >= 0) {
s->dct_unquantize(s, block, i, s->qscale);
- ff_idct_add (dest, line_size, block);
+ s->idct_add (dest, line_size, block);
}
}
const int wrap = s->block_wrap[0];
const int xy = s->block_index[0];
+ const int mb_index= s->mb_x + s->mb_y*s->mb_width;
if(s->mv_type == MV_TYPE_8X8){
- s->non_b_mv4_table[xy]=1;
+ s->co_located_type_table[mb_index]= CO_LOCATED_TYPE_4MV;
} else {
int motion_x, motion_y;
if (s->mb_intra) {
motion_x = 0;
motion_y = 0;
+ if(s->co_located_type_table)
+ s->co_located_type_table[mb_index]= 0;
} else if (s->mv_type == MV_TYPE_16X16) {
motion_x = s->mv[0][0][0];
motion_y = s->mv[0][0][1];
+ if(s->co_located_type_table)
+ s->co_located_type_table[mb_index]= 0;
} 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);
- motion_y = (motion_y>>1) | (motion_y&1);
+ for(i=0; i<2; i++){
+ s->field_mv_table[mb_index][i][0]= s->mv[0][i][0];
+ s->field_mv_table[mb_index][i][1]= s->mv[0][i][1];
+ s->field_select_table[mb_index][i]= s->field_select[0][i];
+ }
+ s->co_located_type_table[mb_index]= CO_LOCATED_TYPE_FIELDMV;
}
/* no update if 8X8 because it has been done during parsing */
s->motion_val[xy][0] = motion_x;
s->motion_val[xy + wrap][1] = motion_y;
s->motion_val[xy + 1 + wrap][0] = motion_x;
s->motion_val[xy + 1 + wrap][1] = motion_y;
- s->non_b_mv4_table[xy]=0;
}
}
if (!(s->encoding && (s->intra_only || s->pict_type==B_TYPE))) {
UINT8 *dest_y, *dest_cb, *dest_cr;
int dct_linesize, dct_offset;
- op_pixels_func *op_pix;
- qpel_mc_func *op_qpix;
+ op_pixels_func (*op_pix)[4];
+ qpel_mc_func (*op_qpix)[16];
/* avoid copy if macroblock skipped in last frame too
dont touch it for B-frames as they need the skip info from the next p-frame */
if((!s->encoding) || (s->mb_type[mb_xy]&(s->mb_type[mb_xy]-1))){
if ((!s->no_rounding) || s->pict_type==B_TYPE){
op_pix = put_pixels_tab;
- op_qpix= qpel_mc_rnd_tab;
+ op_qpix= put_qpel_pixels_tab;
}else{
op_pix = put_no_rnd_pixels_tab;
- op_qpix= qpel_mc_no_rnd_tab;
+ op_qpix= put_no_rnd_qpel_pixels_tab;
}
if (s->mv_dir & MV_DIR_FORWARD) {
MPV_motion(s, dest_y, dest_cb, dest_cr, 0, s->last_picture, op_pix, op_qpix);
- if ((!s->no_rounding) || s->pict_type==B_TYPE)
- op_pix = avg_pixels_tab;
- else
- op_pix = avg_no_rnd_pixels_tab;
+ op_pix = avg_pixels_tab;
+ op_qpix= avg_qpel_pixels_tab;
}
if (s->mv_dir & MV_DIR_BACKWARD) {
MPV_motion(s, dest_y, dest_cb, dest_cr, 1, s->next_picture, op_pix, op_qpix);
if(last_index<=skip_dc - 1) return;
for(i=0; i<=last_index; i++){
- const int j = zigzag_direct[i];
+ const int j = s->intra_scantable.permutated[i];
const int level = ABS(block[j]);
if(level==1){
if(skip_dc && i==0) continue;
}
if(score >= threshold) return;
for(i=skip_dc; i<=last_index; i++){
- const int j = zigzag_direct[i];
+ const int j = s->intra_scantable.permutated[i];
block[j]=0;
}
if(block[0]) s->block_last_index[n]= 0;
int i;
const int maxlevel= s->max_qcoeff;
const int minlevel= s->min_qcoeff;
-
- for(i=0;i<=last_index; i++){
- const int j = zigzag_direct[i];
+
+ if(s->mb_intra){
+ i=1; //skip clipping of intra dc
+ }else
+ i=0;
+
+ for(;i<=last_index; i++){
+ const int j= s->intra_scantable.permutated[i];
int level = block[j];
if (level>maxlevel) level=maxlevel;
}
}
+static inline void requantize_coeffs(MpegEncContext *s, DCTELEM block[64], int oldq, int newq, int n)
+{
+ int i;
+
+ if(s->mb_intra){
+ i=1; //skip clipping of intra dc
+ //FIXME requantize, note (mpeg1/h263/h263p-aic dont need it,...)
+ }else
+ i=0;
+
+ for(;i<=s->block_last_index[n]; i++){
+ const int j = s->intra_scantable.permutated[i];
+ int level = block[j];
+
+ block[j]= ROUNDED_DIV(level*oldq, newq);
+ }
+
+ for(i=s->block_last_index[n]; i>=0; i--){
+ const int j = s->intra_scantable.permutated[i];
+ if(block[j]) break;
+ }
+ s->block_last_index[n]= i;
+}
+
+static inline void auto_requantize_coeffs(MpegEncContext *s, DCTELEM block[6][64])
+{
+ int i,n, newq;
+ const int maxlevel= s->max_qcoeff;
+ const int minlevel= s->min_qcoeff;
+ int largest=0, smallest=0;
+
+ assert(s->adaptive_quant);
+
+ for(n=0; n<6; n++){
+ if(s->mb_intra){
+ i=1; //skip clipping of intra dc
+ //FIXME requantize, note (mpeg1/h263/h263p-aic dont need it,...)
+ }else
+ i=0;
+
+ for(;i<=s->block_last_index[n]; i++){
+ const int j = s->intra_scantable.permutated[i];
+ int level = block[n][j];
+ if(largest < level) largest = level;
+ if(smallest > level) smallest= level;
+ }
+ }
+
+ for(newq=s->qscale+1; newq<32; newq++){
+ if( ROUNDED_DIV(smallest*s->qscale, newq) >= minlevel
+ && ROUNDED_DIV(largest *s->qscale, newq) <= maxlevel)
+ break;
+ }
+
+ if(s->out_format==FMT_H263){
+ /* h263 like formats cannot change qscale by more than 2 easiely */
+ if(s->avctx->qmin + 2 < newq)
+ newq= s->avctx->qmin + 2;
+ }
+
+ for(n=0; n<6; n++){
+ requantize_coeffs(s, block[n], s->qscale, newq, n);
+ clip_coeffs(s, block[n], s->block_last_index[n]);
+ }
+
+ s->dquant+= newq - s->qscale;
+ s->qscale= newq;
+}
+#if 0
+static int pix_vcmp16x8(UINT8 *s, int stride){ //FIXME move to dsputil & optimize
+ int score=0;
+ int x,y;
+
+ for(y=0; y<7; y++){
+ for(x=0; x<16; x+=4){
+ score+= ABS(s[x ] - s[x +stride]) + ABS(s[x+1] - s[x+1+stride])
+ +ABS(s[x+2] - s[x+2+stride]) + ABS(s[x+3] - s[x+3+stride]);
+ }
+ s+= stride;
+ }
+
+ return score;
+}
+
+static int pix_diff_vcmp16x8(UINT8 *s1, UINT8*s2, int stride){ //FIXME move to dsputil & optimize
+ int score=0;
+ int x,y;
+
+ for(y=0; y<7; y++){
+ for(x=0; x<16; x++){
+ score+= ABS(s1[x ] - s2[x ] - s1[x +stride] + s2[x +stride]);
+ }
+ s1+= stride;
+ s2+= stride;
+ }
+
+ return score;
+}
+#else
+#define SQ(a) ((a)*(a))
+
+static int pix_vcmp16x8(UINT8 *s, int stride){ //FIXME move to dsputil & optimize
+ int score=0;
+ int x,y;
+
+ for(y=0; y<7; y++){
+ for(x=0; x<16; x+=4){
+ score+= SQ(s[x ] - s[x +stride]) + SQ(s[x+1] - s[x+1+stride])
+ +SQ(s[x+2] - s[x+2+stride]) + SQ(s[x+3] - s[x+3+stride]);
+ }
+ s+= stride;
+ }
+
+ return score;
+}
+
+static int pix_diff_vcmp16x8(UINT8 *s1, UINT8*s2, int stride){ //FIXME move to dsputil & optimize
+ int score=0;
+ int x,y;
+
+ for(y=0; y<7; y++){
+ for(x=0; x<16; x++){
+ score+= SQ(s1[x ] - s2[x ] - s1[x +stride] + s2[x +stride]);
+ }
+ s1+= stride;
+ s2+= stride;
+ }
+
+ return score;
+}
+
+#endif
static void encode_mb(MpegEncContext *s, int motion_x, int motion_y)
{
const int mb_x= s->mb_x;
const int mb_y= s->mb_y;
int i;
int skip_dct[6];
-#if 0
- if (s->interlaced_dct) {
- dct_linesize = s->linesize * 2;
- dct_offset = s->linesize;
- } else {
- dct_linesize = s->linesize;
- dct_offset = s->linesize * 8;
- }
-#endif
+ int dct_offset = s->linesize*8; //default for progressive frames
+
for(i=0; i<6; i++) skip_dct[i]=0;
+
+ if(s->adaptive_quant){
+ s->dquant= s->qscale_table[mb_x + mb_y*s->mb_width] - s->qscale;
+
+ if(s->out_format==FMT_H263){
+ if (s->dquant> 2) s->dquant= 2;
+ else if(s->dquant<-2) s->dquant=-2;
+ }
+
+ if(s->codec_id==CODEC_ID_MPEG4){
+ if(!s->mb_intra){
+ assert(s->dquant==0 || s->mv_type!=MV_TYPE_8X8);
+
+ if(s->mv_dir&MV_DIRECT)
+ s->dquant=0;
+ }
+ }
+ s->qscale+= s->dquant;
+ s->y_dc_scale= s->y_dc_scale_table[ s->qscale ];
+ s->c_dc_scale= s->c_dc_scale_table[ s->qscale ];
+ }
if (s->mb_intra) {
UINT8 *ptr;
- int wrap;
+ int wrap_y;
int emu=0;
- wrap = s->linesize;
- ptr = s->new_picture[0] + (mb_y * 16 * wrap) + mb_x * 16;
+ wrap_y = s->linesize;
+ ptr = s->new_picture[0] + (mb_y * 16 * wrap_y) + mb_x * 16;
+
if(mb_x*16+16 > s->width || mb_y*16+16 > s->height){
- emulated_edge_mc(s, ptr, wrap, 16, 16, mb_x*16, mb_y*16, s->width, s->height);
+ emulated_edge_mc(s, ptr, wrap_y, 16, 16, mb_x*16, mb_y*16, s->width, s->height);
ptr= s->edge_emu_buffer;
emu=1;
}
- get_pixels(s->block[0], ptr , wrap);
- get_pixels(s->block[1], ptr + 8, wrap);
- get_pixels(s->block[2], ptr + 8 * wrap , wrap);
- get_pixels(s->block[3], ptr + 8 * wrap + 8, wrap);
+
+ if(s->flags&CODEC_FLAG_INTERLACED_DCT){
+ int progressive_score, interlaced_score;
+
+ progressive_score= pix_vcmp16x8(ptr, wrap_y ) + pix_vcmp16x8(ptr + wrap_y*8, wrap_y );
+ interlaced_score = pix_vcmp16x8(ptr, wrap_y*2) + pix_vcmp16x8(ptr + wrap_y , wrap_y*2);
+
+ if(progressive_score > interlaced_score + 100){
+ s->interlaced_dct=1;
+
+ dct_offset= wrap_y;
+ wrap_y<<=1;
+ }else
+ s->interlaced_dct=0;
+ }
+
+ get_pixels(s->block[0], ptr , wrap_y);
+ get_pixels(s->block[1], ptr + 8, wrap_y);
+ get_pixels(s->block[2], ptr + dct_offset , wrap_y);
+ get_pixels(s->block[3], ptr + dct_offset + 8, wrap_y);
if(s->flags&CODEC_FLAG_GRAY){
skip_dct[4]= 1;
skip_dct[5]= 1;
}else{
- wrap >>=1;
- ptr = s->new_picture[1] + (mb_y * 8 * wrap) + mb_x * 8;
+ int wrap_c = s->uvlinesize;
+ ptr = s->new_picture[1] + (mb_y * 8 * wrap_c) + mb_x * 8;
if(emu){
- emulated_edge_mc(s, ptr, wrap, 8, 8, mb_x*8, mb_y*8, s->width>>1, s->height>>1);
+ emulated_edge_mc(s, ptr, wrap_c, 8, 8, mb_x*8, mb_y*8, s->width>>1, s->height>>1);
ptr= s->edge_emu_buffer;
}
- get_pixels(s->block[4], ptr, wrap);
+ get_pixels(s->block[4], ptr, wrap_c);
- ptr = s->new_picture[2] + (mb_y * 8 * wrap) + mb_x * 8;
+ ptr = s->new_picture[2] + (mb_y * 8 * wrap_c) + mb_x * 8;
if(emu){
- emulated_edge_mc(s, ptr, wrap, 8, 8, mb_x*8, mb_y*8, s->width>>1, s->height>>1);
+ emulated_edge_mc(s, ptr, wrap_c, 8, 8, mb_x*8, mb_y*8, s->width>>1, s->height>>1);
ptr= s->edge_emu_buffer;
}
- get_pixels(s->block[5], ptr, wrap);
+ get_pixels(s->block[5], ptr, wrap_c);
}
}else{
- op_pixels_func *op_pix;
- qpel_mc_func *op_qpix;
+ op_pixels_func (*op_pix)[4];
+ qpel_mc_func (*op_qpix)[16];
UINT8 *dest_y, *dest_cb, *dest_cr;
UINT8 *ptr_y, *ptr_cb, *ptr_cr;
int wrap_y, wrap_c;
dest_cb = s->current_picture[1] + (mb_y * 8 * (s->uvlinesize)) + mb_x * 8;
dest_cr = s->current_picture[2] + (mb_y * 8 * (s->uvlinesize)) + mb_x * 8;
wrap_y = s->linesize;
- wrap_c = wrap_y>>1;
+ wrap_c = s->uvlinesize;
ptr_y = s->new_picture[0] + (mb_y * 16 * wrap_y) + mb_x * 16;
ptr_cb = s->new_picture[1] + (mb_y * 8 * wrap_c) + mb_x * 8;
ptr_cr = s->new_picture[2] + (mb_y * 8 * wrap_c) + mb_x * 8;
if ((!s->no_rounding) || s->pict_type==B_TYPE){
op_pix = put_pixels_tab;
- op_qpix= qpel_mc_rnd_tab;
+ op_qpix= put_qpel_pixels_tab;
}else{
op_pix = put_no_rnd_pixels_tab;
- op_qpix= qpel_mc_no_rnd_tab;
+ op_qpix= put_no_rnd_qpel_pixels_tab;
}
if (s->mv_dir & MV_DIR_FORWARD) {
MPV_motion(s, dest_y, dest_cb, dest_cr, 0, s->last_picture, op_pix, op_qpix);
- if ((!s->no_rounding) || s->pict_type==B_TYPE)
- op_pix = avg_pixels_tab;
- else
- op_pix = avg_no_rnd_pixels_tab;
+ op_pix = avg_pixels_tab;
+ op_qpix= avg_qpel_pixels_tab;
}
if (s->mv_dir & MV_DIR_BACKWARD) {
MPV_motion(s, dest_y, dest_cb, dest_cr, 1, s->next_picture, op_pix, op_qpix);
ptr_y= s->edge_emu_buffer;
emu=1;
}
+
+ if(s->flags&CODEC_FLAG_INTERLACED_DCT){
+ int progressive_score, interlaced_score;
+
+ progressive_score= pix_diff_vcmp16x8(ptr_y , dest_y , wrap_y )
+ + pix_diff_vcmp16x8(ptr_y + wrap_y*8, dest_y + wrap_y*8, wrap_y );
+ interlaced_score = pix_diff_vcmp16x8(ptr_y , dest_y , wrap_y*2)
+ + pix_diff_vcmp16x8(ptr_y + wrap_y , dest_y + wrap_y , wrap_y*2);
+
+ if(progressive_score > interlaced_score + 600){
+ s->interlaced_dct=1;
+
+ dct_offset= wrap_y;
+ wrap_y<<=1;
+ }else
+ s->interlaced_dct=0;
+ }
+
diff_pixels(s->block[0], ptr_y , dest_y , wrap_y);
diff_pixels(s->block[1], ptr_y + 8, dest_y + 8, wrap_y);
- diff_pixels(s->block[2], ptr_y + 8 * wrap_y , dest_y + 8 * wrap_y , wrap_y);
- diff_pixels(s->block[3], ptr_y + 8 * wrap_y + 8, dest_y + 8 * wrap_y + 8, wrap_y);
+ diff_pixels(s->block[2], ptr_y + dct_offset , dest_y + dct_offset , wrap_y);
+ diff_pixels(s->block[3], ptr_y + dct_offset + 8, dest_y + dct_offset + 8, wrap_y);
if(s->flags&CODEC_FLAG_GRAY){
skip_dct[4]= 1;
/* pre quantization */
if(s->mc_mb_var[s->mb_width*mb_y+ mb_x]<2*s->qscale*s->qscale){
+ //FIXME optimize
if(pix_abs8x8(ptr_y , dest_y , wrap_y) < 20*s->qscale) skip_dct[0]= 1;
if(pix_abs8x8(ptr_y + 8, dest_y + 8, wrap_y) < 20*s->qscale) skip_dct[1]= 1;
- if(pix_abs8x8(ptr_y + 8*wrap_y , dest_y + 8*wrap_y , wrap_y) < 20*s->qscale) skip_dct[2]= 1;
- if(pix_abs8x8(ptr_y + 8*wrap_y + 8, dest_y + 8*wrap_y + 8, wrap_y) < 20*s->qscale) skip_dct[3]= 1;
+ if(pix_abs8x8(ptr_y +dct_offset , dest_y +dct_offset , wrap_y) < 20*s->qscale) skip_dct[2]= 1;
+ if(pix_abs8x8(ptr_y +dct_offset+ 8, dest_y +dct_offset+ 8, wrap_y) < 20*s->qscale) skip_dct[3]= 1;
if(pix_abs8x8(ptr_cb , dest_cb , wrap_y) < 20*s->qscale) skip_dct[4]= 1;
if(pix_abs8x8(ptr_cr , dest_cr , wrap_y) < 20*s->qscale) skip_dct[5]= 1;
#if 0
d->i_tex_bits= s->i_tex_bits;
d->p_tex_bits= s->p_tex_bits;
d->i_count= s->i_count;
- d->p_count= s->p_count;
+ d->f_count= s->f_count;
+ d->b_count= s->b_count;
d->skip_count= s->skip_count;
d->misc_bits= s->misc_bits;
d->last_bits= 0;
d->i_tex_bits= s->i_tex_bits;
d->p_tex_bits= s->p_tex_bits;
d->i_count= s->i_count;
- d->p_count= s->p_count;
+ d->f_count= s->f_count;
+ d->b_count= s->b_count;
d->skip_count= s->skip_count;
d->misc_bits= s->misc_bits;
ff_set_mpeg4_time(s, s->picture_number);
s->scene_change_score=0;
+
+ s->qscale= (int)(s->frame_qscale + 0.5); //FIXME qscale / ... stuff for ME ratedistoration
/* Estimate motion for every MB */
if(s->pict_type != I_TYPE){
sum= (sum+8)>>4;
varc = (pix_norm1(pix, s->linesize) - sum*sum + 500 + 128)>>8;
- s->mb_var[s->mb_width * mb_y + mb_x] = varc;
+ s->mb_var [s->mb_width * mb_y + mb_x] = varc;
+ s->mb_mean[s->mb_width * mb_y + mb_x] = (sum+7)>>4;
s->mb_var_sum += varc;
}
}
ff_fix_long_b_mvs(s, s->b_bidir_back_mv_table, s->b_code, MB_TYPE_BIDIR);
}
-//printf("f_code %d ///\n", s->f_code);
-
-// printf("%d %d\n", s->avg_mb_var, s->mc_mb_var);
- if (!s->fixed_qscale)
- s->qscale = ff_rate_estimate_qscale(s);
+ if (s->fixed_qscale)
+ s->frame_qscale = s->avctx->quality;
+ else
+ s->frame_qscale = ff_rate_estimate_qscale(s);
+
+ if(s->adaptive_quant){
+ switch(s->codec_id){
+ case CODEC_ID_MPEG4:
+ ff_clean_mpeg4_qscales(s);
+ break;
+ case CODEC_ID_H263:
+ case CODEC_ID_H263P:
+ ff_clean_h263_qscales(s);
+ break;
+ }
+ s->qscale= s->qscale_table[0];
+ }else
+ s->qscale= (int)(s->frame_qscale + 0.5);
+
if (s->out_format == FMT_MJPEG) {
/* for mjpeg, we do include qscale in the matrix */
s->intra_matrix[0] = ff_mpeg1_default_intra_matrix[0];
- for(i=1;i<64;i++)
- s->intra_matrix[i] = CLAMP_TO_8BIT((ff_mpeg1_default_intra_matrix[i] * s->qscale) >> 3);
+ for(i=1;i<64;i++){
+ int j= s->idct_permutation[i];
+
+ s->intra_matrix[j] = CLAMP_TO_8BIT((ff_mpeg1_default_intra_matrix[i] * s->qscale) >> 3);
+ }
convert_matrix(s, s->q_intra_matrix, s->q_intra_matrix16,
- s->q_intra_matrix16_bias, s->intra_matrix, s->intra_quant_bias);
+ s->q_intra_matrix16_bias, s->intra_matrix, s->intra_quant_bias, 8, 8);
}
s->last_bits= get_bit_count(&s->pb);
s->i_tex_bits=0;
s->p_tex_bits=0;
s->i_count=0;
- s->p_count=0;
+ s->f_count=0;
+ s->b_count=0;
s->skip_count=0;
/* init last dc values */
s->fdct (block);
+#ifndef ARCH_ALPHA /* Alpha uses unpermuted matrix */
/* we need this permutation so that we correct the IDCT
permutation. will be moved into DCT code */
- block_permute(block);
+ block_permute(block, s->idct_permutation); //FIXME remove
+#endif
if (s->mb_intra) {
if (!s->h263_aic) {
i = 1;
last_non_zero = 0;
qmat = s->q_intra_matrix[qscale];
- bias= s->intra_quant_bias<<(QMAT_SHIFT - 3 - QUANT_BIAS_SHIFT);
+ bias= s->intra_quant_bias<<(QMAT_SHIFT - QUANT_BIAS_SHIFT);
} else {
i = 0;
last_non_zero = -1;
qmat = s->q_inter_matrix[qscale];
- bias= s->inter_quant_bias<<(QMAT_SHIFT - 3 - QUANT_BIAS_SHIFT);
+ bias= s->inter_quant_bias<<(QMAT_SHIFT - QUANT_BIAS_SHIFT);
}
- threshold1= (1<<(QMAT_SHIFT - 3)) - bias - 1;
- threshold2= threshold1<<1;
+ threshold1= (1<<QMAT_SHIFT) - bias - 1;
+ threshold2= (threshold1<<1);
for(;i<64;i++) {
- j = zigzag_direct[i];
+ j = s->intra_scantable.permutated[i];
level = block[j];
level = level * qmat[j];
// || bias-level >= (1<<(QMAT_SHIFT - 3))){
if(((unsigned)(level+threshold1))>threshold2){
if(level>0){
- level= (bias + level)>>(QMAT_SHIFT - 3);
+ level= (bias + level)>>QMAT_SHIFT;
block[j]= level;
}else{
- level= (bias - level)>>(QMAT_SHIFT - 3);
+ level= (bias - level)>>QMAT_SHIFT;
block[j]= -level;
}
max |=level;
int i, level, nCoeffs;
const UINT16 *quant_matrix;
- if(s->alternate_scan) nCoeffs= 64;
- else nCoeffs= s->block_last_index[n]+1;
+ nCoeffs= s->block_last_index[n];
if (s->mb_intra) {
if (n < 4)
block[0] = block[0] * s->c_dc_scale;
/* XXX: only mpeg1 */
quant_matrix = s->intra_matrix;
- for(i=1;i<nCoeffs;i++) {
- int j= zigzag_direct[i];
+ for(i=1;i<=nCoeffs;i++) {
+ int j= s->intra_scantable.permutated[i];
level = block[j];
if (level) {
if (level < 0) {
} else {
i = 0;
quant_matrix = s->inter_matrix;
- for(;i<nCoeffs;i++) {
- int j= zigzag_direct[i];
+ for(;i<=nCoeffs;i++) {
+ int j= s->intra_scantable.permutated[i];
level = block[j];
if (level) {
if (level < 0) {
int i, level, nCoeffs;
const UINT16 *quant_matrix;
- if(s->alternate_scan) nCoeffs= 64;
- else nCoeffs= s->block_last_index[n]+1;
+ if(s->alternate_scan) nCoeffs= 63;
+ else nCoeffs= s->block_last_index[n];
if (s->mb_intra) {
if (n < 4)
else
block[0] = block[0] * s->c_dc_scale;
quant_matrix = s->intra_matrix;
- for(i=1;i<nCoeffs;i++) {
- int j= zigzag_direct[i];
+ for(i=1;i<=nCoeffs;i++) {
+ int j= s->intra_scantable.permutated[i];
level = block[j];
if (level) {
if (level < 0) {
int sum=-1;
i = 0;
quant_matrix = s->inter_matrix;
- for(;i<nCoeffs;i++) {
- int j= zigzag_direct[i];
+ for(;i<=nCoeffs;i++) {
+ int j= s->intra_scantable.permutated[i];
level = block[j];
if (level) {
if (level < 0) {
int i, level, qmul, qadd;
int nCoeffs;
+ assert(s->block_last_index[n]>=0);
+
+ qadd = (qscale - 1) | 1;
+ qmul = qscale << 1;
+
if (s->mb_intra) {
if (!s->h263_aic) {
if (n < 4)
block[0] = block[0] * s->y_dc_scale;
else
block[0] = block[0] * s->c_dc_scale;
- }
+ }else
+ qadd = 0;
i = 1;
- nCoeffs= 64; //does not allways use zigzag table
+ nCoeffs= 63; //does not allways use zigzag table
} else {
i = 0;
- nCoeffs= zigzag_end[ s->block_last_index[n] ];
+ nCoeffs= s->intra_scantable.raster_end[ s->block_last_index[n] ];
}
- qmul = s->qscale << 1;
- if (s->h263_aic && s->mb_intra)
- qadd = 0;
- else
- qadd = (s->qscale - 1) | 1;
-
- for(;i<nCoeffs;i++) {
+ for(;i<=nCoeffs;i++) {
level = block[i];
if (level) {
if (level < 0) {