Commit 45870f57 authored by Michael Niedermayer's avatar Michael Niedermayer

new motion estimation (epzs) not complete yet but allready pretty good :)

unlimited mv search range
minor bugfix in the mpeg4 header parser
reset picture in gop counter if scene change is detected

Originally committed as revision 344 to svn://svn.ffmpeg.org/ffmpeg/trunk
parent daa57641
......@@ -57,6 +57,8 @@ extern int motion_estimation_method;
#define ME_FULL 1
#define ME_LOG 2
#define ME_PHODS 3
#define ME_EPZS 4
#define ME_X1 5
/* encoding support */
......
......@@ -128,6 +128,7 @@ void init_get_bits(GetBitContext *s,
s->bit_cnt += 8;
}
#endif
s->size= buffer_size;
}
#ifndef ALT_BITSTREAM_READER
......
......@@ -197,6 +197,7 @@ typedef struct GetBitContext {
int bit_cnt;
UINT8 *buf, *buf_ptr, *buf_end;
#endif
int size;
} GetBitContext;
typedef struct VLC {
......@@ -787,6 +788,24 @@ static inline int av_log2(unsigned int v)
return n;
}
/* median of 3 */
static inline int mid_pred(int a, int b, int c)
{
int vmin, vmax;
vmax = vmin = a;
if (b < vmin)
vmin = b;
else
vmax = b;
if (c < vmin)
vmin = c;
else if (c > vmax)
vmax = c;
return a + b + c - vmin - vmax;
}
/* memory */
void *av_mallocz(int size);
......
......@@ -17,6 +17,8 @@
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* ac prediction encoding by Michael Niedermayer <michaelni@gmx.at>
*/
#include "common.h"
#include "dsputil.h"
......@@ -45,9 +47,11 @@ static int mpeg4_decode_block(MpegEncContext * s, DCTELEM * block,
static inline int mpeg4_pred_dc(MpegEncContext * s, int n, UINT16 **dc_val_ptr, int *dir_ptr);
static void mpeg4_inv_pred_ac(MpegEncContext * s, INT16 *block, int n,
int dir);
extern UINT32 inverse[256];
static UINT16 mv_penalty[MAX_FCODE][MAX_MV*2+1];
static UINT8 fcode_tab[MAX_MV*2+1];
int h263_get_picture_format(int width, int height)
{
int format;
......@@ -524,24 +528,6 @@ void h263_pred_acdc(MpegEncContext * s, INT16 *block, int n)
ac_val1[8 + i] = block[block_permute_op(i)];
}
static inline int mid_pred(int a, int b, int c)
{
int vmin, vmax;
vmax = vmin = a;
if (b < vmin)
vmin = b;
else
vmax = b;
if (c < vmin)
vmin = c;
else if (c > vmax)
vmax = c;
return a + b + c - vmin - vmax;
}
INT16 *h263_pred_motion(MpegEncContext * s, int block,
int *px, int *py)
{
......@@ -648,7 +634,46 @@ static void h263p_encode_umotion(MpegEncContext * s, int val)
}
}
void h263_encode_init_vlc(MpegEncContext *s)
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 = s->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] + 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;
}
}
}
void h263_encode_init(MpegEncContext *s)
{
static int done = 0;
......@@ -656,7 +681,13 @@ void h263_encode_init_vlc(MpegEncContext *s)
done = 1;
init_rl(&rl_inter);
init_rl(&rl_intra);
init_mv_penalty_and_fcode(s);
}
s->mv_penalty= mv_penalty;
// use fcodes >1 only for mpeg4 FIXME
if(!s->h263_msmpeg4 && s->h263_pred) s->fcode_tab= fcode_tab;
}
static void h263_encode_block(MpegEncContext * s, DCTELEM * block, int n)
......@@ -2094,9 +2125,8 @@ int mpeg4_decode_picture_header(MpegEncContext * s)
break;
}
state = ((state << 8) | v) & 0xffffff;
/* XXX: really detect end of frame */
if (state == 0){
printf("illegal zero code found\n");
if( get_bits_count(&s->gb) > s->gb.size*8){
printf("no VOP startcode found\n");
return -1;
}
}
......@@ -2152,6 +2182,7 @@ int mpeg4_decode_picture_header(MpegEncContext * s)
if(width && height){ /* they should be non zero but who knows ... */
s->width = width;
s->height = height;
// printf("%d %d\n", width, height);
}
}
......
This diff is collapsed.
......@@ -66,7 +66,7 @@ static void mpeg1_encode_sequence_header(MpegEncContext *s)
int n;
UINT64 time_code;
if ((s->picture_number % s->gop_size) == 0) {
if (s->picture_in_gop_number == 0) {
/* mpeg1 header repeated every gop */
put_header(s, SEQ_START_CODE);
......
......@@ -67,6 +67,9 @@ static UINT8 h263_chroma_roundtab[16] = {
0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2,
};
static UINT16 default_mv_penalty[MAX_FCODE][MAX_MV*2+1];
static UINT8 default_fcode_tab[MAX_MV*2+1];
/* default motion estimation */
int motion_estimation_method = ME_LOG;
......@@ -356,8 +359,24 @@ int MPV_encode_init(AVCodecContext *avctx)
return -1;
}
{ /* set up some save defaults, some codecs might override them later */
static int done=0;
if(!done){
int i;
done=1;
memset(default_mv_penalty, 0, sizeof(UINT16)*MAX_FCODE*(2*MAX_MV+1));
memset(default_fcode_tab , 0, sizeof(UINT8)*(2*MAX_MV+1));
for(i=-16; i<16; i++){
default_fcode_tab[i + MAX_MV]= 1;
}
}
}
s->mv_penalty= default_mv_penalty;
s->fcode_tab= default_fcode_tab;
if (s->out_format == FMT_H263)
h263_encode_init_vlc(s);
h263_encode_init(s);
s->encoding = 1;
......@@ -375,6 +394,7 @@ int MPV_encode_init(AVCodecContext *avctx)
rate_control_init(s);
s->picture_number = 0;
s->picture_in_gop_number = 0;
s->fake_picture_number = 0;
/* motion detector init */
s->f_code = 1;
......@@ -480,9 +500,10 @@ int MPV_encode_picture(AVCodecContext *avctx,
if (!s->intra_only) {
/* first picture of GOP is intra */
if ((s->picture_number % s->gop_size) == 0)
if (s->picture_in_gop_number >= s->gop_size){
s->picture_in_gop_number=0;
s->pict_type = I_TYPE;
else
}else
s->pict_type = P_TYPE;
} else {
s->pict_type = I_TYPE;
......@@ -521,6 +542,7 @@ int MPV_encode_picture(AVCodecContext *avctx,
MPV_frame_end(s);
s->picture_number++;
s->picture_in_gop_number++;
if (s->out_format == FMT_MJPEG)
mjpeg_picture_trailer(s);
......@@ -1077,16 +1099,65 @@ static void encode_picture(MpegEncContext *s, int picture_number)
s->mv_table[1][xy] = motion_y;
}
}
emms_c();
if(s->avg_mb_var < s->mc_mb_var && s->pict_type != B_TYPE){ //FIXME subtract MV bits
int i;
s->pict_type= I_TYPE;
for(i=0; i<s->mb_height*s->mb_width; i++){
s->mb_type[i] = I_TYPE;
s->picture_in_gop_number=0;
for(i=0; i<s->mb_num; i++){
s->mb_type[i] = 1;
s->mv_table[0][i] = 0;
s->mv_table[1][i] = 0;
}
}
/* find best f_code */
if(s->pict_type==P_TYPE){
int mv_num[8];
int i;
int loose=0;
UINT8 * fcode_tab= s->fcode_tab;
for(i=0; i<8; i++) mv_num[i]=0;
for(i=0; i<s->mb_num; i++){
if(s->mb_type[i] == 0){
mv_num[ fcode_tab[s->mv_table[0][i] + MAX_MV] ]++;
mv_num[ fcode_tab[s->mv_table[1][i] + MAX_MV] ]++;
//printf("%d %d %d\n", s->mv_table[0][i], fcode_tab[s->mv_table[0][i] + MAX_MV], i);
}
//else printf("I");
}
for(i=MAX_FCODE; i>1; i--){
loose+= mv_num[i];
if(loose > 4) break;
}
s->f_code= i;
}else{
s->f_code= 1;
}
//printf("f_code %d ///\n", s->f_code);
/* convert MBs with too long MVs to I-Blocks */
if(s->pict_type==P_TYPE){
int i;
const int f_code= s->f_code;
UINT8 * fcode_tab= s->fcode_tab;
for(i=0; i<s->mb_num; i++){
if(s->mb_type[i] == 0){
if( fcode_tab[s->mv_table[0][i] + MAX_MV] > f_code
|| fcode_tab[s->mv_table[0][i] + MAX_MV] == 0
|| fcode_tab[s->mv_table[1][i] + MAX_MV] > f_code
|| fcode_tab[s->mv_table[1][i] + MAX_MV] == 0 ){
s->mb_type[i] = 1;
s->mv_table[0][i] = 0;
s->mv_table[1][i] = 0;
}
}
}
}
// printf("%d %d\n", s->avg_mb_var, s->mc_mb_var);
......
......@@ -34,6 +34,9 @@ enum OutputFormat {
#define QMAT_SHIFT_MMX 19
#define QMAT_SHIFT 25
#define MAX_FCODE 7
#define MAX_MV 2048
typedef struct Predictor{
double coeff;
double count;
......@@ -71,7 +74,8 @@ typedef struct MpegEncContext {
int context_initialized;
int picture_number;
int fake_picture_number; /* picture number at the bitstream frame rate */
int gop_picture_number; /* index of the first picture of a GOP */
int gop_picture_number; /* index of the first picture of a GOP based on fake_pic_num & mpeg1 specific */
int picture_in_gop_number; /* 0-> first pic in gop, ... */
int mb_width, mb_height;
int mb_num; /* number of MBs of a picture */
int linesize; /* line size, in bytes, may be different from width */
......@@ -114,7 +118,7 @@ typedef struct MpegEncContext {
#define MV_DIRECT 4 // bidirectional mode where the difference equals the MV of the last P/S/I-Frame (mpeg4)
int mv_type;
#define MV_TYPE_16X16 0 /* 1 vector for the whole mb */
#define MV_TYPE_8X8 1 /* 4 vectors (h263) */
#define MV_TYPE_8X8 1 /* 4 vectors (h263, mpeg4 4MV) */
#define MV_TYPE_16X8 2 /* 2 vectors, one per 16x8 block */
#define MV_TYPE_FIELD 3 /* 2 vectors, one per field */
#define MV_TYPE_DMV 4 /* 2 vectors, special mpeg2 Dual Prime Vectors */
......@@ -126,6 +130,8 @@ typedef struct MpegEncContext {
int mv[2][4][2];
int field_select[2][2];
int last_mv[2][2][2];
UINT16 (*mv_penalty)[MAX_MV*2+1]; /* amount of bits needed to encode a MV, used for ME */
UINT8 *fcode_tab; /* smallest fcode needed for each MV */
int has_b_frames;
int no_rounding; /* apply no rounding to motion estimation (MPEG4) */
......@@ -350,7 +356,7 @@ INT16 *h263_pred_motion(MpegEncContext * s, int block,
void mpeg4_pred_ac(MpegEncContext * s, INT16 *block, int n,
int dir);
void mpeg4_encode_picture_header(MpegEncContext *s, int picture_number);
void h263_encode_init_vlc(MpegEncContext *s);
void h263_encode_init(MpegEncContext *s);
void h263_decode_init_vlc(MpegEncContext *s);
int h263_decode_picture_header(MpegEncContext *s);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment