/*
* H263/MPEG4 backend for ffmpeg encoder and decoder
- * Copyright (c) 2000,2001 Fabrice Bellard.
+ * Copyright (c) 2000,2001 Fabrice Bellard
* H263+ support.
- * Copyright (c) 2001 Juan J. Sierralta P.
+ * 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,
*/
/**
- * @file h263.c
+ * @file libavcodec/h263.c
* h263/mpeg4 codec.
*/
#include "mpegvideo.h"
#include "h263data.h"
#include "mpeg4data.h"
+#include "mathops.h"
+#include "unary.h"
//#undef NDEBUG
//#include <assert.h>
#define H263_MBTYPE_B_VLC_BITS 6
#define CBPC_B_VLC_BITS 3
-#ifdef CONFIG_ENCODERS
static void h263_encode_block(MpegEncContext * s, DCTELEM * block,
int n);
static void h263p_encode_umotion(MpegEncContext * s, int val);
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);
-#endif
static int h263_decode_motion(MpegEncContext * s, int pred, int fcode);
static int h263p_decode_umotion(MpegEncContext * s, int pred);
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);
-#ifdef CONFIG_ENCODERS
+
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);
-#endif //CONFIG_ENCODERS
+
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);
-#ifdef CONFIG_ENCODERS
+#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 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 == ff_get_fourcc("3IV1")
+#define IS_3IV1 s->codec_tag == AV_RL32("3IV1")
#else
#define IS_3IV1 0
#endif
);
}
-#ifdef CONFIG_ENCODERS
+#if CONFIG_ENCODERS
static void aspect_to_info(MpegEncContext * s, AVRational aspect){
int i;
align_put_bits(&s->pb);
/* Update the pointer to last GOB */
- s->ptr_lastgob = pbBufPtr(&s->pb);
+ s->ptr_lastgob = put_bits_ptr(&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_bits(&s->pb, 8, temp_ref & 0xff); /* TemporalReference */
+ 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, best_clock_code);
put_bits(&s->pb, 7, best_divisor);
}
- put_bits(&s->pb, 2, (temp_ref>>8)&3);
+ put_sbits(&s->pb, 2, temp_ref>>8);
}
/* Unlimited Unrestricted Motion Vectors Indicator (UUI) */
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;
}
#endif //CONFIG_ENCODERS
-#define tab_size ((signed)(sizeof(s->direct_scale_mv[0])/sizeof(int16_t)))
+#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 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;
+ uint16_t time_pp;
+ uint16_t time_pb;
int i;
//FIXME avoid divides
}
}
-#ifdef CONFIG_ENCODERS
+#if CONFIG_ENCODERS
static inline int h263_get_motion_length(MpegEncContext * s, int val, int f_code){
int l, bit_size, code;
for (i = 0; i < 6; i++) {
if (s->block_last_index[i] >= 0 && ((cbp >> (5 - i))&1)==0 ){
s->block_last_index[i]= -1;
- memset(s->block[i], 0, sizeof(DCTELEM)*64);
+ s->dsp.clear_block(s->block[i]);
}
}
}else{
for (i = 0; i < 6; i++) {
if (s->block_last_index[i] >= 0 && ((cbp >> (5 - i))&1)==0 ){
s->block_last_index[i]= -1;
- memset(s->block[i], 0, sizeof(DCTELEM)*64);
+ s->dsp.clear_block(s->block[i]);
}
}
}else{
}
}
+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)
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;
- const int dquant_code[5]= {1,0,9,2,3};
// printf("**mb x=%d y=%d\n", s->mb_x, s->mb_y);
if (!s->mb_intra) {
int16_t rec_intradc[6];
int16_t *dc_ptr[6];
const int interleaved_stats= (s->flags&CODEC_FLAG_PASS1);
- const int dquant_code[5]= {1,0,9,2,3};
//printf("**mb x=%d y=%d\n", s->mb_x, s->mb_y);
if (!s->mb_intra) {
qp_c= 0;
if(s->mb_y){
- int qp_dt, qp_t, qp_tc;
+ int qp_dt, qp_tt, qp_tc;
if(IS_SKIP(s->current_picture.mb_type[xy-s->mb_stride]))
- qp_t=0;
+ qp_tt=0;
else
- qp_t= s->current_picture.qscale_table[xy-s->mb_stride];
+ qp_tt= s->current_picture.qscale_table[xy-s->mb_stride];
if(qp_c)
qp_tc= qp_c;
else
- qp_tc= qp_t;
+ qp_tc= qp_tt;
if(qp_tc){
const int chroma_qp= s->chroma_qscale_table[qp_tc];
s->dsp.h263_v_loop_filter(dest_cr , uvlinesize, chroma_qp);
}
- if(qp_t)
- s->dsp.h263_h_loop_filter(dest_y-8*linesize+8 , linesize, qp_t);
+ if(qp_tt)
+ s->dsp.h263_h_loop_filter(dest_y-8*linesize+8 , linesize, qp_tt);
if(s->mb_x){
- if(qp_t || IS_SKIP(s->current_picture.mb_type[xy-1-s->mb_stride]))
- qp_dt= qp_t;
+ 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];
}
}
-#ifdef CONFIG_ENCODERS
+#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;
+ int x, y, wrap, a, c, pred_dc;
int16_t *dc_val;
/* find prediction */
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
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;
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;
}
return *mot_val;
}
-#ifdef CONFIG_ENCODERS
+#if CONFIG_ENCODERS
void ff_h263_encode_motion(MpegEncContext * s, int val, int f_code)
{
int range, l, bit_size, sign, code, bits;
if(mv==0) len= mvtab[0][1];
else{
- int val, bit_size, range, code;
+ int val, bit_size, code;
bit_size = f_code - 1;
- range = 1 << bit_size;
val=mv;
if (val < 0)
assert(slevel != 0);
if(level < 128)
- put_bits(&s->pb, 8, slevel & 0xff);
+ put_sbits(&s->pb, 8, slevel);
else{
put_bits(&s->pb, 8, 128);
- put_bits(&s->pb, 5, slevel & 0x1f);
- put_bits(&s->pb, 6, (slevel>>5)&0x3f);
+ 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, last);
put_bits(&s->pb, 6, run);
- put_bits(&s->pb, 7, slevel & 0x7f);
+ 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_bits(&s->pb, 11, slevel & 0x7ff);
+ put_sbits(&s->pb, 11, slevel);
}
}
} else {
{
int vo_ver_id;
- if (!ENABLE_MPEG4_ENCODER) return;
+ if (!CONFIG_MPEG4_ENCODER) return;
if(s->max_b_frames || s->quarter_sample){
vo_ver_id= 5;
}else{
level += pred;
ret= level;
- if(s->error_resilience>=3){
+ if(s->error_recognition>=3){
if(level<0){
av_log(s->avctx, AV_LOG_ERROR, "dc<0 at %dx%d\n", s->mb_x, s->mb_y);
return -1;
}
-#ifdef CONFIG_ENCODERS
+#if CONFIG_ENCODERS
/**
* encodes the dc value.
put_bits(ac_pb, 1, last);
put_bits(ac_pb, 6, run);
put_bits(ac_pb, 1, 1);
- put_bits(ac_pb, 12, slevel & 0xfff);
+ put_sbits(ac_pb, 12, slevel);
put_bits(ac_pb, 1, 1);
} else {
/* second escape */
uint8_t *scan_table)
{
int i, last_non_zero;
- const RLTable *rl;
uint8_t *len_tab;
const int last_index = s->block_last_index[n];
int len=0;
len += mpeg4_get_dc_length(intra_dc, n);
if(last_index<1) return len;
i = 1;
- rl = &rl_intra;
len_tab = uni_mpeg4_intra_rl_len;
} else {
if(last_index<0) return 0;
i = 0;
- rl = &rl_inter;
len_tab = uni_mpeg4_inter_rl_len;
}
tab[i] = val;
}
-#ifdef CONFIG_ENCODERS
+#if CONFIG_ENCODERS
void ff_mpeg4_init_partitions(MpegEncContext *s)
{
- uint8_t *start= pbBufPtr(&s->pb);
+ uint8_t *start= put_bits_ptr(&s->pb);
uint8_t *end= s->pb.buf_end;
int size= end - start;
- int pb_size = (((long)start + size/3)&(~3)) - (long)start;
+ int pb_size = (((intptr_t)start + size/3)&(~3)) - (intptr_t)start;
int tex_size= (size - 2*pb_size)&(~3);
set_put_bits_buffer_size(&s->pb, pb_size);
}
}
-#ifdef CONFIG_ENCODERS
+#if CONFIG_ENCODERS
void ff_mpeg4_encode_video_packet_header(MpegEncContext *s)
{
s->last_mv[1][0][1]= 0;
}
+/**
+ * finds the next resync_marker
+ * @param p pointer to buffer to scan
+ * @param end pointer to the end of the buffer
+ * @return pointer to the next resync_marker, or \p end if none was found
+ */
+const uint8_t *ff_h263_find_resync_marker(const uint8_t *restrict p, const uint8_t * restrict end)
+{
+ assert(p < end);
+
+ end-=2;
+ p++;
+ for(;p<end; p+=2){
+ if(!*p){
+ if (!p[-1] && p[1]) return p - 1;
+ else if(!p[ 1] && p[2]) return p;
+ }
+ }
+ return end+2;
+}
+
/**
* decodes the group of blocks / video packet header.
- * @return <0 if no resync found
+ * @return bit position of the resync_marker, or <0 if none was found
*/
int ff_h263_resync(MpegEncContext *s){
- int left, ret;
+ int left, pos, ret;
if(s->codec_id==CODEC_ID_MPEG4){
skip_bits1(&s->gb);
}
if(show_bits(&s->gb, 16)==0){
+ pos= get_bits_count(&s->gb);
if(s->codec_id==CODEC_ID_MPEG4)
ret= mpeg4_decode_video_packet_header(s);
else
ret= h263_decode_gob_header(s);
if(ret>=0)
- return 0;
+ return pos;
}
//OK, it's not where it is supposed to be ...
s->gb= s->last_resync_gb;
if(show_bits(&s->gb, 16)==0){
GetBitContext bak= s->gb;
+ pos= get_bits_count(&s->gb);
if(s->codec_id==CODEC_ID_MPEG4)
ret= mpeg4_decode_video_packet_header(s);
else
ret= h263_decode_gob_header(s);
if(ret>=0)
- return 0;
+ return pos;
s->gb= bak;
}
ff_set_qscale(s, s->qscale);
}
+static int h263_skip_b_part(MpegEncContext *s, int cbp)
+{
+ DECLARE_ALIGNED(16, DCTELEM, dblock[64]);
+ int i, mbi;
+
+ /* we have to set s->mb_intra to zero to decode B-part of PB-frame correctly
+ * but real value should be restored in order to be used later (in OBMC condition)
+ */
+ mbi = s->mb_intra;
+ s->mb_intra = 0;
+ for (i = 0; i < 6; i++) {
+ if (h263_decode_block(s, dblock, i, cbp&32) < 0)
+ return -1;
+ cbp+=cbp;
+ }
+ s->mb_intra = mbi;
+ return 0;
+}
+
+static int h263_get_modb(GetBitContext *gb, int pb_frame, int *cbpb)
+{
+ int c, mv = 1;
+
+ if (pb_frame < 3) { // h.263 Annex G and i263 PB-frame
+ c = get_bits1(gb);
+ if (pb_frame == 2 && c)
+ mv = !get_bits1(gb);
+ } else { // h.263 Annex M improved PB-frame
+ mv = get_unary(gb, 0, 4) + 1;
+ c = mv & 1;
+ mv = !!(mv & 2);
+ }
+ if(c)
+ *cbpb = get_bits(gb, 6);
+ return mv;
+}
+
int ff_h263_decode_mb(MpegEncContext *s,
DCTELEM block[6][64])
{
int cbpc, cbpy, i, cbp, pred_x, pred_y, mx, my, dquant;
int16_t *mot_val;
const int xy= s->mb_x + s->mb_y * s->mb_stride;
+ int cbpb = 0, pb_mv_count = 0;
assert(!s->h263_pred);
s->mb_intra = ((cbpc & 4) != 0);
if (s->mb_intra) goto intra;
+ if(s->pb_frame && get_bits1(&s->gb))
+ pb_mv_count = h263_get_modb(&s->gb, s->pb_frame, &cbpb);
cbpy = get_vlc2(&s->gb, cbpy_vlc.table, CBPY_VLC_BITS, 1);
if(s->alt_inter_vlc==0 || (cbpc & 3)!=3)
mot_val[1] = my;
}
}
-
- /* decode each block */
- for (i = 0; i < 6; i++) {
- if (h263_decode_block(s, block[i], i, cbp&32) < 0)
- return -1;
- cbp+=cbp;
- }
-
- if(s->obmc){
- if(s->pict_type == FF_P_TYPE && s->mb_x+1<s->mb_width && s->mb_num_left != 1)
- preview_obmc(s);
- }
} else if(s->pict_type==FF_B_TYPE) {
int mb_type;
const int stride= s->b8_stride;
}
s->current_picture.mb_type[xy]= mb_type;
-
- /* decode each block */
- for (i = 0; i < 6; i++) {
- if (h263_decode_block(s, block[i], i, cbp&32) < 0)
- return -1;
- cbp+=cbp;
- }
} else { /* I-Frame */
do{
cbpc = get_vlc2(&s->gb, intra_MCBPC_vlc.table, INTRA_MCBPC_VLC_BITS, 2);
}else
s->ac_pred = 0;
+ if(s->pb_frame && get_bits1(&s->gb))
+ pb_mv_count = h263_get_modb(&s->gb, s->pb_frame, &cbpb);
cbpy = get_vlc2(&s->gb, cbpy_vlc.table, CBPY_VLC_BITS, 1);
if(cbpy<0){
av_log(s->avctx, AV_LOG_ERROR, "I cbpy damaged at %d %d\n", s->mb_x, s->mb_y);
h263_decode_dquant(s);
}
- /* decode each block */
- for (i = 0; i < 6; i++) {
- if (h263_decode_block(s, block[i], i, cbp&32) < 0)
- return -1;
- cbp+=cbp;
- }
+ pb_mv_count += !!s->pb_frame;
+ }
+
+ while(pb_mv_count--){
+ h263_decode_motion(s, 0, 1);
+ h263_decode_motion(s, 0, 1);
+ }
+
+ /* decode each block */
+ for (i = 0; i < 6; i++) {
+ if (h263_decode_block(s, block[i], i, cbp&32) < 0)
+ return -1;
+ cbp+=cbp;
+ }
+
+ if(s->pb_frame && h263_skip_b_part(s, cbpb) < 0)
+ return -1;
+ if(s->obmc && !s->mb_intra){
+ if(s->pict_type == FF_P_TYPE && s->mb_x+1<s->mb_width && s->mb_num_left != 1)
+ preview_obmc(s);
}
end:
} else if (s->mb_intra) {
/* DC coef */
if(s->codec_id == CODEC_ID_RV10){
-#ifdef CONFIG_RV10_DECODER
+#if CONFIG_RV10_DECODER
if (s->rv10_version == 3 && s->pict_type == FF_I_TYPE) {
int component, diff;
component = (n <= 3 ? 0 : n - 4 + 1);
level = get_bits(&s->gb, 8);
if((level&0x7F) == 0){
av_log(s->avctx, AV_LOG_ERROR, "illegal dc %d at %d %d\n", level, s->mb_x, s->mb_y);
- if(s->error_resilience >= FF_ER_COMPLIANT)
+ if(s->error_recognition >= FF_ER_COMPLIANT)
return -1;
}
if (level == 255)
rl = &rl_intra_aic;
i = 0;
s->gb= gb;
- memset(block, 0, sizeof(DCTELEM)*64);
+ s->dsp.clear_block(block);
goto retry;
}
av_log(s->avctx, AV_LOG_ERROR, "run overflow at %dx%d i:%d\n", s->mb_x, s->mb_y, s->mb_intra);
if (code > 8){
if(get_bits1(&s->gb)==0){ /* marker */
- if(s->error_resilience>=2){
+ if(s->error_recognition>=2){
av_log(s->avctx, AV_LOG_ERROR, "dc marker bit missing\n");
return -1;
}
}
#if 0
- if(s->error_resilience >= FF_ER_COMPLIANT){
+ if(s->error_recognition >= FF_ER_COMPLIANT){
const int abs_level= FFABS(level);
if(abs_level<=MAX_LEVEL && run<=MAX_RUN){
const int run1= run - rl->max_run[last][abs_level] - 1;
av_log(s->avctx, AV_LOG_ERROR, "illegal 3. esc, vlc encoding possible\n");
return -1;
}
- if(s->error_resilience > FF_ER_COMPLIANT){
+ if(s->error_recognition > FF_ER_COMPLIANT){
if(abs_level <= rl->max_level[last][run]*2){
av_log(s->avctx, AV_LOG_ERROR, "illegal 3. esc, esc 1 encoding possible\n");
return -1;
else level= level * qmul - qadd;
if((unsigned)(level + 2048) > 4095){
- if(s->error_resilience > FF_ER_COMPLIANT){
+ if(s->error_recognition > FF_ER_COMPLIANT){
if(level > 2560 || level<-2560){
av_log(s->avctx, AV_LOG_ERROR, "|level| overflow in 3. esc, qp=%d\n", s->qscale);
return -1;
s->obmc= get_bits1(&s->gb); /* Advanced prediction mode */
s->unrestricted_mv = s->h263_long_vectors || s->obmc;
- if (get_bits1(&s->gb) != 0) {
- av_log(s->avctx, AV_LOG_ERROR, "H263 PB frame not supported\n");
- return -1; /* not PB frame */
- }
+ s->pb_frame = get_bits1(&s->gb);
s->chroma_qscale= s->qscale = get_bits(&s->gb, 5);
skip_bits1(&s->gb); /* Continuous Presence Multipoint mode: off */
switch(s->pict_type){
case 0: s->pict_type= FF_I_TYPE;break;
case 1: s->pict_type= FF_P_TYPE;break;
+ case 2: s->pict_type= FF_P_TYPE;s->pb_frame = 3;break;
case 3: s->pict_type= FF_B_TYPE;break;
case 7: s->pict_type= FF_I_TYPE;break; //ZYGO
default:
av_log(s, AV_LOG_ERROR, "zero framerate\n");
return -1;
}
- gcd= ff_gcd(s->avctx->time_base.den, s->avctx->time_base.num);
+ gcd= av_gcd(s->avctx->time_base.den, s->avctx->time_base.num);
s->avctx->time_base.den /= gcd;
s->avctx->time_base.num /= gcd;
// av_log(s->avctx, AV_LOG_DEBUG, "%d/%d\n", s->avctx->time_base.den, s->avctx->time_base.num);
s->mb_height = (s->height + 15) / 16;
s->mb_num = s->mb_width * s->mb_height;
+ if (s->pb_frame) {
+ skip_bits(&s->gb, 3); /* Temporal reference for B-pictures */
+ if (s->custom_pcf)
+ skip_bits(&s->gb, 2); //extended Temporal reference
+ skip_bits(&s->gb, 2); /* Quantization information for B-pictures */
+ }
+
/* PEI */
while (get_bits1(&s->gb) != 0) {
skip_bits(&s->gb, 8);
show_pict_info(s);
}
#if 1
- if (s->pict_type == FF_I_TYPE && s->codec_tag == ff_get_fourcc("ZYGO")){
+ if (s->pict_type == FF_I_TYPE && s->codec_tag == AV_RL32("ZYGO")){
int i,j;
for(i=0; i<85; i++) av_log(s->avctx, AV_LOG_DEBUG, "%d", get_bits1(&s->gb));
av_log(s->avctx, AV_LOG_DEBUG, "\n");
}
skip_bits1(gb); /* marker bit */
//printf("%d %d %d %d\n", x, y, i, s->sprite_warping_accuracy);
- d[i][0]= x;
- d[i][1]= y;
+ s->sprite_traj[i][0]= d[i][0]= x;
+ s->sprite_traj[i][1]= d[i][1]= y;
}
+ for(; i<4; i++)
+ s->sprite_traj[i][0]= s->sprite_traj[i][1]= 0;
while((1<<alpha)<w) alpha++;
while((1<<beta )<h) beta++; // there seems to be a typo in the mpeg4 std for the definition of w' and h'
if ((s->vol_control_parameters=get_bits1(gb))) { /* vol control parameter */
int chroma_format= get_bits(gb, 2);
- if(chroma_format!=1){
+ if(chroma_format!=CHROMA_420){
av_log(s->avctx, AV_LOG_ERROR, "illegal chroma format\n");
}
s->low_delay= get_bits1(gb);
skip_bits1(gb); /* marker */
height = get_bits(gb, 13);
skip_bits1(gb); /* marker */
- if(width && height && !(s->width && s->codec_tag == ff_get_fourcc("MP4S"))){ /* they should be non zero but who knows ... */
+ if(width && height && !(s->width && s->codec_tag == AV_RL32("MP4S"))){ /* they should be non zero but who knows ... */
s->width = width;
s->height = height;
// printf("width/height: %d %d\n", width, height);
s->quarter_sample= get_bits1(gb);
else s->quarter_sample=0;
- if(!get_bits1(gb)) av_log(s->avctx, AV_LOG_ERROR, "Complexity estimation not supported\n");
+ if(!get_bits1(gb)){
+ int pos= get_bits_count(gb);
+ int estimation_method= get_bits(gb, 2);
+ if(estimation_method<2){
+ if(!get_bits1(gb)){
+ s->cplx_estimation_trash_i += 8*get_bits1(gb); //opaque
+ s->cplx_estimation_trash_i += 8*get_bits1(gb); //transparent
+ s->cplx_estimation_trash_i += 8*get_bits1(gb); //intra_cae
+ s->cplx_estimation_trash_i += 8*get_bits1(gb); //inter_cae
+ s->cplx_estimation_trash_i += 8*get_bits1(gb); //no_update
+ s->cplx_estimation_trash_i += 8*get_bits1(gb); //upampling
+ }
+ if(!get_bits1(gb)){
+ s->cplx_estimation_trash_i += 8*get_bits1(gb); //intra_blocks
+ s->cplx_estimation_trash_p += 8*get_bits1(gb); //inter_blocks
+ s->cplx_estimation_trash_p += 8*get_bits1(gb); //inter4v_blocks
+ s->cplx_estimation_trash_i += 8*get_bits1(gb); //not coded blocks
+ }
+ if(!check_marker(gb, "in complexity estimation part 1")){
+ skip_bits_long(gb, pos - get_bits_count(gb));
+ goto no_cplx_est;
+ }
+ if(!get_bits1(gb)){
+ s->cplx_estimation_trash_i += 8*get_bits1(gb); //dct_coeffs
+ s->cplx_estimation_trash_i += 8*get_bits1(gb); //dct_lines
+ s->cplx_estimation_trash_i += 8*get_bits1(gb); //vlc_syms
+ s->cplx_estimation_trash_i += 4*get_bits1(gb); //vlc_bits
+ }
+ if(!get_bits1(gb)){
+ s->cplx_estimation_trash_p += 8*get_bits1(gb); //apm
+ s->cplx_estimation_trash_p += 8*get_bits1(gb); //npm
+ s->cplx_estimation_trash_b += 8*get_bits1(gb); //interpolate_mc_q
+ s->cplx_estimation_trash_p += 8*get_bits1(gb); //forwback_mc_q
+ s->cplx_estimation_trash_p += 8*get_bits1(gb); //halfpel2
+ s->cplx_estimation_trash_p += 8*get_bits1(gb); //halfpel4
+ }
+ if(!check_marker(gb, "in complexity estimation part 2")){
+ skip_bits_long(gb, pos - get_bits_count(gb));
+ goto no_cplx_est;
+ }
+ if(estimation_method==1){
+ s->cplx_estimation_trash_i += 8*get_bits1(gb); //sadct
+ s->cplx_estimation_trash_p += 8*get_bits1(gb); //qpel
+ }
+ }else
+ av_log(s->avctx, AV_LOG_ERROR, "Invalid Complexity estimation method %d\n", estimation_method);
+ }else{
+no_cplx_est:
+ s->cplx_estimation_trash_i=
+ s->cplx_estimation_trash_p=
+ s->cplx_estimation_trash_b= 0;
+ }
s->resync_marker= !get_bits1(gb); /* resync_marker_disabled */
s->divx_version= ver;
s->divx_build= build;
s->divx_packed= e==3 && last=='p';
- if(s->divx_packed)
+ if(s->divx_packed && !s->showed_packed_warning) {
av_log(s->avctx, AV_LOG_WARNING, "Invalid and inefficient vfw-avi packed B frames detected\n");
+ s->showed_packed_warning=1;
+ }
}
/* ffmpeg detection */
//FIXME complexity estimation stuff
if (s->shape != BIN_ONLY_SHAPE) {
+ skip_bits_long(gb, s->cplx_estimation_trash_i);
+ if(s->pict_type != FF_I_TYPE)
+ skip_bits_long(gb, s->cplx_estimation_trash_p);
+ if(s->pict_type == FF_B_TYPE)
+ skip_bits_long(gb, s->cplx_estimation_trash_b);
+
s->intra_dc_threshold= mpeg4_dc_threshold[ get_bits(gb, 3) ];
if(!s->progressive_sequence){
s->top_field_first= get_bits1(gb);
s->b_code=1;
if(s->avctx->debug&FF_DEBUG_PICT_INFO){
- av_log(s->avctx, AV_LOG_DEBUG, "qp:%d fc:%d,%d %s size:%d pro:%d alt:%d top:%d %spel part:%d resync:%d w:%d a:%d rnd:%d vot:%d%s dc:%d\n",
+ av_log(s->avctx, AV_LOG_DEBUG, "qp:%d fc:%d,%d %s size:%d pro:%d alt:%d top:%d %spel part:%d resync:%d w:%d a:%d rnd:%d vot:%d%s dc:%d ce:%d/%d/%d\n",
s->qscale, s->f_code, s->b_code,
s->pict_type == FF_I_TYPE ? "I" : (s->pict_type == FF_P_TYPE ? "P" : (s->pict_type == FF_B_TYPE ? "B" : "S")),
gb->size_in_bits,s->progressive_sequence, s->alternate_scan, s->top_field_first,
s->quarter_sample ? "q" : "h", s->data_partitioning, s->resync_marker, s->num_sprite_warping_points,
- s->sprite_warping_accuracy, 1-s->no_rounding, s->vo_type, s->vol_control_parameters ? " VOLC" : " ", s->intra_dc_threshold);
+ s->sprite_warping_accuracy, 1-s->no_rounding, s->vo_type, s->vol_control_parameters ? " VOLC" : " ", s->intra_dc_threshold, s->cplx_estimation_trash_i, s->cplx_estimation_trash_p, s->cplx_estimation_trash_b);
}
if(!s->scalability){
/* search next start code */
align_get_bits(gb);
- if(s->codec_tag == ff_get_fourcc("WV1F") && show_bits(gb, 24) == 0x575630){
+ if(s->codec_tag == AV_RL32("WV1F") && show_bits(gb, 24) == 0x575630){
skip_bits(gb, 24);
if(get_bits(gb, 8) == 0xF0)
- return decode_vop_header(s, gb);
+ goto end;
}
startcode = 0xff;
mpeg4_decode_gop_header(s, gb);
}
else if(startcode == VOP_STARTCODE){
- return decode_vop_header(s, gb);
+ break;
}
align_get_bits(gb);
startcode = 0xff;
}
+end:
+ if(s->flags& CODEC_FLAG_LOW_DELAY)
+ s->low_delay=1;
+ s->avctx->has_b_frames= !s->low_delay;
+ return decode_vop_header(s, gb);
}
/* don't understand why they choose a different header ! */
return -1; /* SAC: off */
}
s->obmc= get_bits1(&s->gb);
- if (get_bits1(&s->gb) != 0) {
- av_log(s->avctx, AV_LOG_ERROR, "PB frame mode no supported\n");
- return -1; /* PB frame mode */
- }
+ s->pb_frame = get_bits1(&s->gb);
- /* skip unknown header garbage */
- skip_bits(&s->gb, 41);
+ if(format == 7){
+ format = get_bits(&s->gb, 3);
+ if(format == 0 || format == 7){
+ av_log(s->avctx, AV_LOG_ERROR, "Wrong Intel H263 format\n");
+ return -1;
+ }
+ if(get_bits(&s->gb, 2))
+ av_log(s->avctx, AV_LOG_ERROR, "Bad value for reserved field\n");
+ s->loop_filter = get_bits1(&s->gb);
+ if(get_bits1(&s->gb))
+ av_log(s->avctx, AV_LOG_ERROR, "Bad value for reserved field\n");
+ if(get_bits1(&s->gb))
+ s->pb_frame = 2;
+ if(get_bits(&s->gb, 5))
+ av_log(s->avctx, AV_LOG_ERROR, "Bad value for reserved field\n");
+ if(get_bits(&s->gb, 5) != 1)
+ av_log(s->avctx, AV_LOG_ERROR, "Invalid marker\n");
+ }
+ if(format == 6){
+ int ar = get_bits(&s->gb, 4);
+ skip_bits(&s->gb, 9); // display width
+ skip_bits1(&s->gb);
+ skip_bits(&s->gb, 9); // display height
+ if(ar == 15){
+ skip_bits(&s->gb, 8); // aspect ratio - width
+ skip_bits(&s->gb, 8); // aspect ratio - height
+ }
+ }
s->chroma_qscale= s->qscale = get_bits(&s->gb, 5);
skip_bits1(&s->gb); /* Continuous Presence Multipoint mode: off */
+ if(s->pb_frame){
+ skip_bits(&s->gb, 3); //temporal reference for B-frame
+ skip_bits(&s->gb, 2); //dbquant
+ }
+
/* PEI */
while (get_bits1(&s->gb) != 0) {
skip_bits(&s->gb, 8);