mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2025-01-24 13:56:33 +02:00
complete mpeg4 GMC decoding support
Originally committed as revision 1046 to svn://svn.ffmpeg.org/ffmpeg/trunk
This commit is contained in:
parent
46fd0de8a7
commit
073b013d00
@ -157,6 +157,8 @@ inline void dprintf(const char* fmt,...) {}
|
|||||||
|
|
||||||
# define av_abort() do { fprintf(stderr, "Abort at %s:%d\n", __FILE__, __LINE__); abort(); } while (0)
|
# define av_abort() do { fprintf(stderr, "Abort at %s:%d\n", __FILE__, __LINE__); abort(); } while (0)
|
||||||
|
|
||||||
|
//rounded divison & shift
|
||||||
|
#define RSHIFT(a,b) ((a) > 0 ? ((a) + (1<<((b)-1)))>>(b) : ((a) + (1<<((b)-1))-1)>>(b))
|
||||||
/* assume b>0 */
|
/* assume b>0 */
|
||||||
#define ROUNDED_DIV(a,b) (((a)>0 ? (a) + ((b)>>1) : (a) - ((b)>>1))/(b))
|
#define ROUNDED_DIV(a,b) (((a)>0 ? (a) + ((b)>>1) : (a) - ((b)>>1))/(b))
|
||||||
#define ABS(a) ((a) >= 0 ? (a) : (-(a)))
|
#define ABS(a) ((a) >= 0 ? (a) : (-(a)))
|
||||||
|
@ -25,7 +25,9 @@ void (*get_pixels)(DCTELEM *block, const UINT8 *pixels, int line_size);
|
|||||||
void (*diff_pixels)(DCTELEM *block, const UINT8 *s1, const UINT8 *s2, int stride);
|
void (*diff_pixels)(DCTELEM *block, const UINT8 *s1, const UINT8 *s2, int stride);
|
||||||
void (*put_pixels_clamped)(const DCTELEM *block, UINT8 *pixels, int line_size);
|
void (*put_pixels_clamped)(const DCTELEM *block, UINT8 *pixels, int line_size);
|
||||||
void (*add_pixels_clamped)(const DCTELEM *block, UINT8 *pixels, int line_size);
|
void (*add_pixels_clamped)(const DCTELEM *block, UINT8 *pixels, int line_size);
|
||||||
void (*gmc1)(UINT8 *dst, UINT8 *src, int srcStride, int h, int x16, int y16, int rounder);
|
void (*ff_gmc1)(UINT8 *dst, UINT8 *src, int srcStride, int h, int x16, int y16, int rounder);
|
||||||
|
void (*ff_gmc )(UINT8 *dst, UINT8 *src, int stride, int h, int ox, int oy,
|
||||||
|
int dxx, int dxy, int dyx, int dyy, int shift, int r, int width, int height);
|
||||||
void (*clear_blocks)(DCTELEM *blocks);
|
void (*clear_blocks)(DCTELEM *blocks);
|
||||||
int (*pix_sum)(UINT8 * pix, int line_size);
|
int (*pix_sum)(UINT8 * pix, int line_size);
|
||||||
int (*pix_norm1)(UINT8 * pix, int line_size);
|
int (*pix_norm1)(UINT8 * pix, int line_size);
|
||||||
@ -822,6 +824,7 @@ PIXOP(uint8_t, put_no_rnd, op_put, line_size)
|
|||||||
#define avg2(a,b) ((a+b+1)>>1)
|
#define avg2(a,b) ((a+b+1)>>1)
|
||||||
#define avg4(a,b,c,d) ((a+b+c+d+2)>>2)
|
#define avg4(a,b,c,d) ((a+b+c+d+2)>>2)
|
||||||
|
|
||||||
|
|
||||||
static void gmc1_c(UINT8 *dst, UINT8 *src, int stride, int h, int x16, int y16, int rounder)
|
static void gmc1_c(UINT8 *dst, UINT8 *src, int stride, int h, int x16, int y16, int rounder)
|
||||||
{
|
{
|
||||||
const int A=(16-x16)*(16-y16);
|
const int A=(16-x16)*(16-y16);
|
||||||
@ -829,7 +832,6 @@ static void gmc1_c(UINT8 *dst, UINT8 *src, int stride, int h, int x16, int y16,
|
|||||||
const int C=(16-x16)*( y16);
|
const int C=(16-x16)*( y16);
|
||||||
const int D=( x16)*( y16);
|
const int D=( x16)*( y16);
|
||||||
int i;
|
int i;
|
||||||
rounder= 128 - rounder;
|
|
||||||
|
|
||||||
for(i=0; i<h; i++)
|
for(i=0; i<h; i++)
|
||||||
{
|
{
|
||||||
@ -846,6 +848,64 @@ static void gmc1_c(UINT8 *dst, UINT8 *src, int stride, int h, int x16, int y16,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void gmc_c(UINT8 *dst, UINT8 *src, int stride, int h, int ox, int oy,
|
||||||
|
int dxx, int dxy, int dyx, int dyy, int shift, int r, int width, int height)
|
||||||
|
{
|
||||||
|
int y, vx, vy;
|
||||||
|
const int s= 1<<shift;
|
||||||
|
|
||||||
|
width--;
|
||||||
|
height--;
|
||||||
|
|
||||||
|
for(y=0; y<h; y++){
|
||||||
|
int x;
|
||||||
|
|
||||||
|
vx= ox;
|
||||||
|
vy= oy;
|
||||||
|
for(x=0; x<8; x++){ //XXX FIXME optimize
|
||||||
|
int src_x, src_y, frac_x, frac_y, index;
|
||||||
|
|
||||||
|
src_x= vx>>16;
|
||||||
|
src_y= vy>>16;
|
||||||
|
frac_x= src_x&(s-1);
|
||||||
|
frac_y= src_y&(s-1);
|
||||||
|
src_x>>=shift;
|
||||||
|
src_y>>=shift;
|
||||||
|
|
||||||
|
if((unsigned)src_x < width){
|
||||||
|
if((unsigned)src_y < height){
|
||||||
|
index= src_x + src_y*stride;
|
||||||
|
dst[y*stride + x]= ( ( src[index ]*(s-frac_x)
|
||||||
|
+ src[index +1]* frac_x )*(s-frac_y)
|
||||||
|
+ ( src[index+stride ]*(s-frac_x)
|
||||||
|
+ src[index+stride+1]* frac_x )* frac_y
|
||||||
|
+ r)>>(shift*2);
|
||||||
|
}else{
|
||||||
|
index= src_x + clip(src_y, 0, height)*stride;
|
||||||
|
dst[y*stride + x]= ( ( src[index ]*(s-frac_x)
|
||||||
|
+ src[index +1]* frac_x )*s
|
||||||
|
+ r)>>(shift*2);
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
if((unsigned)src_y < height){
|
||||||
|
index= clip(src_x, 0, width) + src_y*stride;
|
||||||
|
dst[y*stride + x]= ( ( src[index ]*(s-frac_y)
|
||||||
|
+ src[index+stride ]* frac_y )*s
|
||||||
|
+ r)>>(shift*2);
|
||||||
|
}else{
|
||||||
|
index= clip(src_x, 0, width) + clip(src_y, 0, height)*stride;
|
||||||
|
dst[y*stride + x]= src[index ];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
vx+= dxx;
|
||||||
|
vy+= dyx;
|
||||||
|
}
|
||||||
|
ox += dxy;
|
||||||
|
oy += dyy;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static inline void copy_block17(UINT8 *dst, UINT8 *src, int dstStride, int srcStride, int h)
|
static inline void copy_block17(UINT8 *dst, UINT8 *src, int dstStride, int srcStride, int h)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
@ -1528,7 +1588,8 @@ void dsputil_init(void)
|
|||||||
diff_pixels = diff_pixels_c;
|
diff_pixels = diff_pixels_c;
|
||||||
put_pixels_clamped = put_pixels_clamped_c;
|
put_pixels_clamped = put_pixels_clamped_c;
|
||||||
add_pixels_clamped = add_pixels_clamped_c;
|
add_pixels_clamped = add_pixels_clamped_c;
|
||||||
gmc1= gmc1_c;
|
ff_gmc1= gmc1_c;
|
||||||
|
ff_gmc= gmc_c;
|
||||||
clear_blocks= clear_blocks_c;
|
clear_blocks= clear_blocks_c;
|
||||||
pix_sum= pix_sum_c;
|
pix_sum= pix_sum_c;
|
||||||
pix_norm1= pix_norm1_c;
|
pix_norm1= pix_norm1_c;
|
||||||
|
@ -62,7 +62,9 @@ extern void (*get_pixels)(DCTELEM *block/*align 16*/, const UINT8 *pixels/*align
|
|||||||
extern void (*diff_pixels)(DCTELEM *block/*align 16*/, const UINT8 *s1/*align 8*/, const UINT8 *s2/*align 8*/, int stride);
|
extern void (*diff_pixels)(DCTELEM *block/*align 16*/, const UINT8 *s1/*align 8*/, const UINT8 *s2/*align 8*/, int stride);
|
||||||
extern void (*put_pixels_clamped)(const DCTELEM *block/*align 16*/, UINT8 *pixels/*align 8*/, int line_size);
|
extern void (*put_pixels_clamped)(const DCTELEM *block/*align 16*/, UINT8 *pixels/*align 8*/, int line_size);
|
||||||
extern void (*add_pixels_clamped)(const DCTELEM *block/*align 16*/, UINT8 *pixels/*align 8*/, int line_size);
|
extern void (*add_pixels_clamped)(const DCTELEM *block/*align 16*/, UINT8 *pixels/*align 8*/, int line_size);
|
||||||
extern void (*gmc1)(UINT8 *dst/*align 8*/, UINT8 *src/*align 1*/, int srcStride, int h, int x16, int y16, int rounder);
|
extern void (*ff_gmc1)(UINT8 *dst/*align 8*/, UINT8 *src/*align 1*/, int srcStride, int h, int x16, int y16, int rounder);
|
||||||
|
extern void (*ff_gmc )(UINT8 *dst/*align 8*/, UINT8 *src/*align 1*/, int stride, int h, int ox, int oy,
|
||||||
|
int dxx, int dxy, int dyx, int dyy, int shift, int r, int width, int height);
|
||||||
extern void (*clear_blocks)(DCTELEM *blocks/*align 16*/);
|
extern void (*clear_blocks)(DCTELEM *blocks/*align 16*/);
|
||||||
extern int (*pix_sum)(UINT8 * pix, int line_size);
|
extern int (*pix_sum)(UINT8 * pix, int line_size);
|
||||||
extern int (*pix_norm1)(UINT8 * pix, int line_size);
|
extern int (*pix_norm1)(UINT8 * pix, int line_size);
|
||||||
|
@ -34,9 +34,6 @@
|
|||||||
//#undef NDEBUG
|
//#undef NDEBUG
|
||||||
//#include <assert.h>
|
//#include <assert.h>
|
||||||
|
|
||||||
//rounded divison & shift
|
|
||||||
#define RSHIFT(a,b) ((a) > 0 ? ((a) + (1<<((b)-1)))>>(b) : ((a) + (1<<((b)-1))-1)>>(b))
|
|
||||||
|
|
||||||
#if 1
|
#if 1
|
||||||
#define PRINT_MB_TYPE(a) {}
|
#define PRINT_MB_TYPE(a) {}
|
||||||
#else
|
#else
|
||||||
@ -2432,6 +2429,49 @@ int ff_h263_resync(MpegEncContext *s){
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param n either 0 for the x component or 1 for y
|
||||||
|
* @returns the average MV for a GMC MB
|
||||||
|
*/
|
||||||
|
static inline int get_amv(MpegEncContext *s, int n){
|
||||||
|
int x, y, mb_v, sum, dx, dy, shift;
|
||||||
|
int len = 1 << (s->f_code + 4);
|
||||||
|
const int a= s->sprite_warping_accuracy;
|
||||||
|
|
||||||
|
if(s->real_sprite_warping_points==1){
|
||||||
|
if(s->divx_version==500 && s->divx_build==413)
|
||||||
|
sum= s->sprite_offset[0][n] / (1<<(a - s->quarter_sample));
|
||||||
|
else
|
||||||
|
sum= RSHIFT(s->sprite_offset[0][n]<<s->quarter_sample, a);
|
||||||
|
}else{
|
||||||
|
dx= s->sprite_delta[n][0];
|
||||||
|
dy= s->sprite_delta[n][1];
|
||||||
|
shift= s->sprite_shift[0];
|
||||||
|
if(n) dy -= 1<<(shift + a + 1);
|
||||||
|
else dx -= 1<<(shift + a + 1);
|
||||||
|
mb_v= s->sprite_offset[0][n] + dx*s->mb_x*16 + dy*s->mb_y*16;
|
||||||
|
|
||||||
|
sum=0;
|
||||||
|
for(y=0; y<16; y++){
|
||||||
|
int v;
|
||||||
|
|
||||||
|
v= mb_v + dy*y;
|
||||||
|
//XXX FIXME optimize
|
||||||
|
for(x=0; x<16; x++){
|
||||||
|
sum+= v>>shift;
|
||||||
|
v+= dx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sum /= 256;
|
||||||
|
sum= RSHIFT(sum<<s->quarter_sample, a);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sum < -len) sum= -len;
|
||||||
|
else if (sum >= len) sum= len-1;
|
||||||
|
|
||||||
|
return sum;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* decodes first partition.
|
* decodes first partition.
|
||||||
* @return number of MBs decoded or <0 if an error occured
|
* @return number of MBs decoded or <0 if an error occured
|
||||||
@ -2508,20 +2548,12 @@ static int mpeg4_decode_partition_a(MpegEncContext *s){
|
|||||||
/* skip mb */
|
/* skip mb */
|
||||||
s->mb_type[xy]= MB_TYPE_SKIPED;
|
s->mb_type[xy]= MB_TYPE_SKIPED;
|
||||||
if(s->pict_type==S_TYPE && s->vol_sprite_usage==GMC_SPRITE){
|
if(s->pict_type==S_TYPE && s->vol_sprite_usage==GMC_SPRITE){
|
||||||
const int a= s->sprite_warping_accuracy;
|
|
||||||
PRINT_MB_TYPE("G");
|
PRINT_MB_TYPE("G");
|
||||||
if(s->divx_version==500 && s->divx_build==413){
|
mx= get_amv(s, 0);
|
||||||
mx = s->sprite_offset[0][0] / (1<<(a-s->quarter_sample));
|
my= get_amv(s, 1);
|
||||||
my = s->sprite_offset[0][1] / (1<<(a-s->quarter_sample));
|
|
||||||
}else{
|
|
||||||
mx = RSHIFT(s->sprite_offset[0][0], a-s->quarter_sample);
|
|
||||||
my = RSHIFT(s->sprite_offset[0][1], a-s->quarter_sample);
|
|
||||||
s->mb_type[xy]= MB_TYPE_GMC | MB_TYPE_SKIPED;
|
|
||||||
}
|
|
||||||
}else{
|
}else{
|
||||||
PRINT_MB_TYPE("S");
|
PRINT_MB_TYPE("S");
|
||||||
mx = 0;
|
mx=my=0;
|
||||||
my = 0;
|
|
||||||
}
|
}
|
||||||
mot_val[0 ]= mot_val[2 ]=
|
mot_val[0 ]= mot_val[2 ]=
|
||||||
mot_val[0+stride]= mot_val[2+stride]= mx;
|
mot_val[0+stride]= mot_val[2+stride]= mx;
|
||||||
@ -2570,31 +2602,19 @@ static int mpeg4_decode_partition_a(MpegEncContext *s){
|
|||||||
s->mb_type[xy]= MB_TYPE_INTER;
|
s->mb_type[xy]= MB_TYPE_INTER;
|
||||||
|
|
||||||
h263_pred_motion(s, 0, &pred_x, &pred_y);
|
h263_pred_motion(s, 0, &pred_x, &pred_y);
|
||||||
if(!s->mcsel)
|
if(!s->mcsel){
|
||||||
mx = h263_decode_motion(s, pred_x, s->f_code);
|
mx = h263_decode_motion(s, pred_x, s->f_code);
|
||||||
else {
|
if (mx >= 0xffff)
|
||||||
const int a= s->sprite_warping_accuracy;
|
return -1;
|
||||||
if(s->divx_version==500 && s->divx_build==413){
|
|
||||||
mx = s->sprite_offset[0][0] / (1<<(a-s->quarter_sample));
|
my = h263_decode_motion(s, pred_y, s->f_code);
|
||||||
}else{
|
if (my >= 0xffff)
|
||||||
mx = RSHIFT(s->sprite_offset[0][0], a-s->quarter_sample);
|
return -1;
|
||||||
}
|
} else {
|
||||||
|
mx = get_amv(s, 0);
|
||||||
|
my = get_amv(s, 1);
|
||||||
}
|
}
|
||||||
if (mx >= 0xffff)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
if(!s->mcsel)
|
|
||||||
my = h263_decode_motion(s, pred_y, s->f_code);
|
|
||||||
else{
|
|
||||||
const int a= s->sprite_warping_accuracy;
|
|
||||||
if(s->divx_version==500 && s->divx_build==413){
|
|
||||||
my = s->sprite_offset[0][1] / (1<<(a-s->quarter_sample));
|
|
||||||
}else{
|
|
||||||
my = RSHIFT(s->sprite_offset[0][1], a-s->quarter_sample);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (my >= 0xffff)
|
|
||||||
return -1;
|
|
||||||
mot_val[0 ]= mot_val[2 ] =
|
mot_val[0 ]= mot_val[2 ] =
|
||||||
mot_val[0+stride]= mot_val[2+stride]= mx;
|
mot_val[0+stride]= mot_val[2+stride]= mx;
|
||||||
mot_val[1 ]= mot_val[3 ]=
|
mot_val[1 ]= mot_val[3 ]=
|
||||||
@ -2876,21 +2896,10 @@ int ff_h263_decode_mb(MpegEncContext *s,
|
|||||||
s->mv_dir = MV_DIR_FORWARD;
|
s->mv_dir = MV_DIR_FORWARD;
|
||||||
s->mv_type = MV_TYPE_16X16;
|
s->mv_type = MV_TYPE_16X16;
|
||||||
if(s->pict_type==S_TYPE && s->vol_sprite_usage==GMC_SPRITE){
|
if(s->pict_type==S_TYPE && s->vol_sprite_usage==GMC_SPRITE){
|
||||||
const int a= s->sprite_warping_accuracy;
|
|
||||||
// int l = (1 << (s->f_code - 1)) * 32;
|
|
||||||
PRINT_MB_TYPE("G");
|
PRINT_MB_TYPE("G");
|
||||||
s->mcsel=1;
|
s->mcsel=1;
|
||||||
if(s->divx_version==500 && s->divx_build==413){
|
s->mv[0][0][0]= get_amv(s, 0);
|
||||||
s->mv[0][0][0] = s->sprite_offset[0][0] / (1<<(a-s->quarter_sample));
|
s->mv[0][0][1]= get_amv(s, 1);
|
||||||
s->mv[0][0][1] = s->sprite_offset[0][1] / (1<<(a-s->quarter_sample));
|
|
||||||
}else{
|
|
||||||
s->mv[0][0][0] = RSHIFT(s->sprite_offset[0][0], a-s->quarter_sample);
|
|
||||||
s->mv[0][0][1] = RSHIFT(s->sprite_offset[0][1], a-s->quarter_sample);
|
|
||||||
}
|
|
||||||
/* if (s->mv[0][0][0] < -l) s->mv[0][0][0]= -l;
|
|
||||||
else if (s->mv[0][0][0] >= l) s->mv[0][0][0]= l-1;
|
|
||||||
if (s->mv[0][0][1] < -l) s->mv[0][0][1]= -l;
|
|
||||||
else if (s->mv[0][0][1] >= l) s->mv[0][0][1]= l-1;*/
|
|
||||||
|
|
||||||
s->mb_skiped = 0;
|
s->mb_skiped = 0;
|
||||||
}else{
|
}else{
|
||||||
@ -2929,19 +2938,11 @@ int ff_h263_decode_mb(MpegEncContext *s,
|
|||||||
s->mv_dir = MV_DIR_FORWARD;
|
s->mv_dir = MV_DIR_FORWARD;
|
||||||
if ((cbpc & 16) == 0) {
|
if ((cbpc & 16) == 0) {
|
||||||
if(s->mcsel){
|
if(s->mcsel){
|
||||||
const int a= s->sprite_warping_accuracy;
|
|
||||||
PRINT_MB_TYPE("G");
|
PRINT_MB_TYPE("G");
|
||||||
/* 16x16 global motion prediction */
|
/* 16x16 global motion prediction */
|
||||||
s->mv_type = MV_TYPE_16X16;
|
s->mv_type = MV_TYPE_16X16;
|
||||||
// int l = (1 << (s->f_code - 1)) * 32;
|
mx= get_amv(s, 0);
|
||||||
if(s->divx_version==500 && s->divx_build==413){
|
my= get_amv(s, 1);
|
||||||
mx = s->sprite_offset[0][0] / (1<<(a-s->quarter_sample));
|
|
||||||
my = s->sprite_offset[0][1] / (1<<(a-s->quarter_sample));
|
|
||||||
}else{
|
|
||||||
mx = RSHIFT(s->sprite_offset[0][0], a-s->quarter_sample);
|
|
||||||
my = RSHIFT(s->sprite_offset[0][1], a-s->quarter_sample);
|
|
||||||
}
|
|
||||||
// int l = (1 << (s->f_code - 1)) * 32;
|
|
||||||
s->mv[0][0][0] = mx;
|
s->mv[0][0][0] = mx;
|
||||||
s->mv[0][0][1] = my;
|
s->mv[0][0][1] = my;
|
||||||
}else if((!s->progressive_sequence) && get_bits1(&s->gb)){
|
}else if((!s->progressive_sequence) && get_bits1(&s->gb)){
|
||||||
@ -3862,11 +3863,12 @@ static void mpeg4_decode_sprite_trajectory(MpegEncContext * s)
|
|||||||
int d[4][2]={{0,0}, {0,0}, {0,0}, {0,0}};
|
int d[4][2]={{0,0}, {0,0}, {0,0}, {0,0}};
|
||||||
int sprite_ref[4][2];
|
int sprite_ref[4][2];
|
||||||
int virtual_ref[2][2];
|
int virtual_ref[2][2];
|
||||||
int w2, h2;
|
int w2, h2, w3, h3;
|
||||||
int alpha=0, beta=0;
|
int alpha=0, beta=0;
|
||||||
int w= s->width;
|
int w= s->width;
|
||||||
int h= s->height;
|
int h= s->height;
|
||||||
//printf("SP %d\n", s->sprite_warping_accuracy);
|
int min_ab;
|
||||||
|
|
||||||
for(i=0; i<s->num_sprite_warping_points; i++){
|
for(i=0; i<s->num_sprite_warping_points; i++){
|
||||||
int length;
|
int length;
|
||||||
int x=0, y=0;
|
int x=0, y=0;
|
||||||
@ -3874,7 +3876,7 @@ static void mpeg4_decode_sprite_trajectory(MpegEncContext * s)
|
|||||||
length= get_vlc(&s->gb, &sprite_trajectory);
|
length= get_vlc(&s->gb, &sprite_trajectory);
|
||||||
if(length){
|
if(length){
|
||||||
x= get_bits(&s->gb, length);
|
x= get_bits(&s->gb, length);
|
||||||
//printf("lx %d %d\n", length, x);
|
|
||||||
if ((x >> (length - 1)) == 0) /* if MSB not set it is negative*/
|
if ((x >> (length - 1)) == 0) /* if MSB not set it is negative*/
|
||||||
x = - (x ^ ((1 << length) - 1));
|
x = - (x ^ ((1 << length) - 1));
|
||||||
}
|
}
|
||||||
@ -3883,14 +3885,12 @@ static void mpeg4_decode_sprite_trajectory(MpegEncContext * s)
|
|||||||
length= get_vlc(&s->gb, &sprite_trajectory);
|
length= get_vlc(&s->gb, &sprite_trajectory);
|
||||||
if(length){
|
if(length){
|
||||||
y=get_bits(&s->gb, length);
|
y=get_bits(&s->gb, length);
|
||||||
//printf("ly %d %d\n", length, y);
|
|
||||||
if ((y >> (length - 1)) == 0) /* if MSB not set it is negative*/
|
if ((y >> (length - 1)) == 0) /* if MSB not set it is negative*/
|
||||||
y = - (y ^ ((1 << length) - 1));
|
y = - (y ^ ((1 << length) - 1));
|
||||||
}
|
}
|
||||||
skip_bits1(&s->gb); /* marker bit */
|
skip_bits1(&s->gb); /* marker bit */
|
||||||
//printf("%d %d %d %d\n", x, y, i, s->sprite_warping_accuracy);
|
//printf("%d %d %d %d\n", x, y, i, s->sprite_warping_accuracy);
|
||||||
//if(i>0 && (x!=0 || y!=0)) printf("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n");
|
|
||||||
//x=y=0;
|
|
||||||
d[i][0]= x;
|
d[i][0]= x;
|
||||||
d[i][1]= y;
|
d[i][1]= y;
|
||||||
}
|
}
|
||||||
@ -3931,7 +3931,7 @@ static void mpeg4_decode_sprite_trajectory(MpegEncContext * s)
|
|||||||
+ ROUNDED_DIV(((h - h2)*(r*sprite_ref[0][0] - 16*vop_ref[0][0]) + h2*(r*sprite_ref[2][0] - 16*vop_ref[2][0])),h);
|
+ ROUNDED_DIV(((h - h2)*(r*sprite_ref[0][0] - 16*vop_ref[0][0]) + h2*(r*sprite_ref[2][0] - 16*vop_ref[2][0])),h);
|
||||||
virtual_ref[1][1]= 16*(vop_ref[0][1] + h2)
|
virtual_ref[1][1]= 16*(vop_ref[0][1] + h2)
|
||||||
+ ROUNDED_DIV(((h - h2)*(r*sprite_ref[0][1] - 16*vop_ref[0][1]) + h2*(r*sprite_ref[2][1] - 16*vop_ref[2][1])),h);
|
+ ROUNDED_DIV(((h - h2)*(r*sprite_ref[0][1] - 16*vop_ref[0][1]) + h2*(r*sprite_ref[2][1] - 16*vop_ref[2][1])),h);
|
||||||
|
|
||||||
switch(s->num_sprite_warping_points)
|
switch(s->num_sprite_warping_points)
|
||||||
{
|
{
|
||||||
case 0:
|
case 0:
|
||||||
@ -3939,107 +3939,133 @@ static void mpeg4_decode_sprite_trajectory(MpegEncContext * s)
|
|||||||
s->sprite_offset[0][1]= 0;
|
s->sprite_offset[0][1]= 0;
|
||||||
s->sprite_offset[1][0]= 0;
|
s->sprite_offset[1][0]= 0;
|
||||||
s->sprite_offset[1][1]= 0;
|
s->sprite_offset[1][1]= 0;
|
||||||
s->sprite_delta[0][0][0]= a;
|
s->sprite_delta[0][0]= a;
|
||||||
s->sprite_delta[0][0][1]= 0;
|
s->sprite_delta[0][1]= 0;
|
||||||
s->sprite_delta[0][1][0]= 0;
|
s->sprite_delta[1][0]= 0;
|
||||||
s->sprite_delta[0][1][1]= a;
|
s->sprite_delta[1][1]= a;
|
||||||
s->sprite_delta[1][0][0]= a;
|
s->sprite_shift[0]= 0;
|
||||||
s->sprite_delta[1][0][1]= 0;
|
s->sprite_shift[1]= 0;
|
||||||
s->sprite_delta[1][1][0]= 0;
|
|
||||||
s->sprite_delta[1][1][1]= a;
|
|
||||||
s->sprite_shift[0][0]= 0;
|
|
||||||
s->sprite_shift[0][1]= 0;
|
|
||||||
s->sprite_shift[1][0]= 0;
|
|
||||||
s->sprite_shift[1][1]= 0;
|
|
||||||
break;
|
break;
|
||||||
case 1: //GMC only
|
case 1: //GMC only
|
||||||
s->sprite_offset[0][0]= sprite_ref[0][0] - a*vop_ref[0][0];
|
s->sprite_offset[0][0]= sprite_ref[0][0] - a*vop_ref[0][0];
|
||||||
s->sprite_offset[0][1]= sprite_ref[0][1] - a*vop_ref[0][1];
|
s->sprite_offset[0][1]= sprite_ref[0][1] - a*vop_ref[0][1];
|
||||||
s->sprite_offset[1][0]= ((sprite_ref[0][0]>>1)|(sprite_ref[0][0]&1)) - a*(vop_ref[0][0]/2);
|
s->sprite_offset[1][0]= ((sprite_ref[0][0]>>1)|(sprite_ref[0][0]&1)) - a*(vop_ref[0][0]/2);
|
||||||
s->sprite_offset[1][1]= ((sprite_ref[0][1]>>1)|(sprite_ref[0][1]&1)) - a*(vop_ref[0][1]/2);
|
s->sprite_offset[1][1]= ((sprite_ref[0][1]>>1)|(sprite_ref[0][1]&1)) - a*(vop_ref[0][1]/2);
|
||||||
s->sprite_delta[0][0][0]= a;
|
s->sprite_delta[0][0]= a;
|
||||||
s->sprite_delta[0][0][1]= 0;
|
s->sprite_delta[0][1]= 0;
|
||||||
s->sprite_delta[0][1][0]= 0;
|
s->sprite_delta[1][0]= 0;
|
||||||
s->sprite_delta[0][1][1]= a;
|
s->sprite_delta[1][1]= a;
|
||||||
s->sprite_delta[1][0][0]= a;
|
s->sprite_shift[0]= 0;
|
||||||
s->sprite_delta[1][0][1]= 0;
|
s->sprite_shift[1]= 0;
|
||||||
s->sprite_delta[1][1][0]= 0;
|
|
||||||
s->sprite_delta[1][1][1]= a;
|
|
||||||
s->sprite_shift[0][0]= 0;
|
|
||||||
s->sprite_shift[0][1]= 0;
|
|
||||||
s->sprite_shift[1][0]= 0;
|
|
||||||
s->sprite_shift[1][1]= 0;
|
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
case 3: //FIXME
|
|
||||||
s->sprite_offset[0][0]= (sprite_ref[0][0]<<(alpha+rho))
|
s->sprite_offset[0][0]= (sprite_ref[0][0]<<(alpha+rho))
|
||||||
+ ((-r*sprite_ref[0][0] + virtual_ref[0][0])*(-vop_ref[0][0])
|
+ (-r*sprite_ref[0][0] + virtual_ref[0][0])*(-vop_ref[0][0])
|
||||||
+( r*sprite_ref[0][1] - virtual_ref[0][1])*(-vop_ref[0][1]));
|
+ ( r*sprite_ref[0][1] - virtual_ref[0][1])*(-vop_ref[0][1])
|
||||||
|
+ (1<<(alpha+rho-1));
|
||||||
s->sprite_offset[0][1]= (sprite_ref[0][1]<<(alpha+rho))
|
s->sprite_offset[0][1]= (sprite_ref[0][1]<<(alpha+rho))
|
||||||
+ ((-r*sprite_ref[0][1] + virtual_ref[0][1])*(-vop_ref[0][0])
|
+ (-r*sprite_ref[0][1] + virtual_ref[0][1])*(-vop_ref[0][0])
|
||||||
+(-r*sprite_ref[0][0] + virtual_ref[0][0])*(-vop_ref[0][1]));
|
+ (-r*sprite_ref[0][0] + virtual_ref[0][0])*(-vop_ref[0][1])
|
||||||
s->sprite_offset[1][0]= ((-r*sprite_ref[0][0] + virtual_ref[0][0])*(-2*vop_ref[0][0] + 1)
|
+ (1<<(alpha+rho-1));
|
||||||
+( r*sprite_ref[0][1] - virtual_ref[0][1])*(-2*vop_ref[0][1] + 1)
|
s->sprite_offset[1][0]= ( (-r*sprite_ref[0][0] + virtual_ref[0][0])*(-2*vop_ref[0][0] + 1)
|
||||||
+2*w2*r*sprite_ref[0][0] - 16*w2);
|
+( r*sprite_ref[0][1] - virtual_ref[0][1])*(-2*vop_ref[0][1] + 1)
|
||||||
s->sprite_offset[1][1]= ((-r*sprite_ref[0][1] + virtual_ref[0][1])*(-2*vop_ref[0][0] + 1)
|
+2*w2*r*sprite_ref[0][0]
|
||||||
+(-r*sprite_ref[0][0] + virtual_ref[0][0])*(-2*vop_ref[0][1] + 1)
|
- 16*w2
|
||||||
+2*w2*r*sprite_ref[0][1] - 16*w2);
|
+ (1<<(alpha+rho+1)));
|
||||||
s->sprite_delta[0][0][0]= (-r*sprite_ref[0][0] + virtual_ref[0][0]);
|
s->sprite_offset[1][1]= ( (-r*sprite_ref[0][1] + virtual_ref[0][1])*(-2*vop_ref[0][0] + 1)
|
||||||
s->sprite_delta[0][0][1]= ( r*sprite_ref[0][1] - virtual_ref[0][1]);
|
+(-r*sprite_ref[0][0] + virtual_ref[0][0])*(-2*vop_ref[0][1] + 1)
|
||||||
s->sprite_delta[0][1][0]= (-r*sprite_ref[0][1] + virtual_ref[0][1]);
|
+2*w2*r*sprite_ref[0][1]
|
||||||
s->sprite_delta[0][1][1]= (-r*sprite_ref[0][0] + virtual_ref[0][0]);
|
- 16*w2
|
||||||
s->sprite_delta[1][0][0]= 4*(-r*sprite_ref[0][0] + virtual_ref[0][0]);
|
+ (1<<(alpha+rho+1)));
|
||||||
s->sprite_delta[1][0][1]= 4*( r*sprite_ref[0][1] - virtual_ref[0][1]);
|
s->sprite_delta[0][0]= (-r*sprite_ref[0][0] + virtual_ref[0][0]);
|
||||||
s->sprite_delta[1][1][0]= 4*(-r*sprite_ref[0][1] + virtual_ref[0][1]);
|
s->sprite_delta[0][1]= (+r*sprite_ref[0][1] - virtual_ref[0][1]);
|
||||||
s->sprite_delta[1][1][1]= 4*(-r*sprite_ref[0][0] + virtual_ref[0][0]);
|
s->sprite_delta[1][0]= (-r*sprite_ref[0][1] + virtual_ref[0][1]);
|
||||||
s->sprite_shift[0][0]= alpha+rho;
|
s->sprite_delta[1][1]= (-r*sprite_ref[0][0] + virtual_ref[0][0]);
|
||||||
s->sprite_shift[0][1]= alpha+rho;
|
|
||||||
s->sprite_shift[1][0]= alpha+rho+2;
|
s->sprite_shift[0]= alpha+rho;
|
||||||
s->sprite_shift[1][1]= alpha+rho+2;
|
s->sprite_shift[1]= alpha+rho+2;
|
||||||
break;
|
break;
|
||||||
// case 3:
|
case 3:
|
||||||
|
min_ab= MIN(alpha, beta);
|
||||||
|
w3= w2>>min_ab;
|
||||||
|
h3= h2>>min_ab;
|
||||||
|
s->sprite_offset[0][0]= (sprite_ref[0][0]<<(alpha+beta+rho-min_ab))
|
||||||
|
+ (-r*sprite_ref[0][0] + virtual_ref[0][0])*h3*(-vop_ref[0][0])
|
||||||
|
+ (-r*sprite_ref[0][0] + virtual_ref[1][0])*w3*(-vop_ref[0][1])
|
||||||
|
+ (1<<(alpha+beta+rho-min_ab-1));
|
||||||
|
s->sprite_offset[0][1]= (sprite_ref[0][1]<<(alpha+beta+rho-min_ab))
|
||||||
|
+ (-r*sprite_ref[0][1] + virtual_ref[0][1])*h3*(-vop_ref[0][0])
|
||||||
|
+ (-r*sprite_ref[0][1] + virtual_ref[1][1])*w3*(-vop_ref[0][1])
|
||||||
|
+ (1<<(alpha+beta+rho-min_ab-1));
|
||||||
|
s->sprite_offset[1][0]= (-r*sprite_ref[0][0] + virtual_ref[0][0])*h3*(-2*vop_ref[0][0] + 1)
|
||||||
|
+ (-r*sprite_ref[0][0] + virtual_ref[1][0])*w3*(-2*vop_ref[0][1] + 1)
|
||||||
|
+ 2*w2*h3*r*sprite_ref[0][0]
|
||||||
|
- 16*w2*h3
|
||||||
|
+ (1<<(alpha+beta+rho-min_ab+1));
|
||||||
|
s->sprite_offset[1][1]= (-r*sprite_ref[0][1] + virtual_ref[0][1])*h3*(-2*vop_ref[0][0] + 1)
|
||||||
|
+ (-r*sprite_ref[0][1] + virtual_ref[1][1])*w3*(-2*vop_ref[0][1] + 1)
|
||||||
|
+ 2*w2*h3*r*sprite_ref[0][1]
|
||||||
|
- 16*w2*h3
|
||||||
|
+ (1<<(alpha+beta+rho-min_ab+1));
|
||||||
|
s->sprite_delta[0][0]= (-r*sprite_ref[0][0] + virtual_ref[0][0])*h3;
|
||||||
|
s->sprite_delta[0][1]= (-r*sprite_ref[0][0] + virtual_ref[1][0])*w3;
|
||||||
|
s->sprite_delta[1][0]= (-r*sprite_ref[0][1] + virtual_ref[0][1])*h3;
|
||||||
|
s->sprite_delta[1][1]= (-r*sprite_ref[0][1] + virtual_ref[1][1])*w3;
|
||||||
|
|
||||||
|
s->sprite_shift[0]= alpha + beta + rho - min_ab;
|
||||||
|
s->sprite_shift[1]= alpha + beta + rho - min_ab + 2;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
/*printf("%d %d\n", s->sprite_delta[0][0][0], a<<s->sprite_shift[0][0]);
|
|
||||||
printf("%d %d\n", s->sprite_delta[0][0][1], 0);
|
|
||||||
printf("%d %d\n", s->sprite_delta[0][1][0], 0);
|
|
||||||
printf("%d %d\n", s->sprite_delta[0][1][1], a<<s->sprite_shift[0][1]);
|
|
||||||
printf("%d %d\n", s->sprite_delta[1][0][0], a<<s->sprite_shift[1][0]);
|
|
||||||
printf("%d %d\n", s->sprite_delta[1][0][1], 0);
|
|
||||||
printf("%d %d\n", s->sprite_delta[1][1][0], 0);
|
|
||||||
printf("%d %d\n", s->sprite_delta[1][1][1], a<<s->sprite_shift[1][1]);*/
|
|
||||||
/* try to simplify the situation */
|
/* try to simplify the situation */
|
||||||
if( s->sprite_delta[0][0][0] == a<<s->sprite_shift[0][0]
|
if( s->sprite_delta[0][0] == a<<s->sprite_shift[0]
|
||||||
&& s->sprite_delta[0][0][1] == 0
|
&& s->sprite_delta[0][1] == 0
|
||||||
&& s->sprite_delta[0][1][0] == 0
|
&& s->sprite_delta[1][0] == 0
|
||||||
&& s->sprite_delta[0][1][1] == a<<s->sprite_shift[0][1]
|
&& s->sprite_delta[1][1] == a<<s->sprite_shift[0])
|
||||||
&& s->sprite_delta[1][0][0] == a<<s->sprite_shift[1][0]
|
|
||||||
&& s->sprite_delta[1][0][1] == 0
|
|
||||||
&& s->sprite_delta[1][1][0] == 0
|
|
||||||
&& s->sprite_delta[1][1][1] == a<<s->sprite_shift[1][1])
|
|
||||||
{
|
{
|
||||||
s->sprite_offset[0][0]>>=s->sprite_shift[0][0];
|
s->sprite_offset[0][0]>>=s->sprite_shift[0];
|
||||||
s->sprite_offset[0][1]>>=s->sprite_shift[0][1];
|
s->sprite_offset[0][1]>>=s->sprite_shift[0];
|
||||||
s->sprite_offset[1][0]>>=s->sprite_shift[1][0];
|
s->sprite_offset[1][0]>>=s->sprite_shift[1];
|
||||||
s->sprite_offset[1][1]>>=s->sprite_shift[1][1];
|
s->sprite_offset[1][1]>>=s->sprite_shift[1];
|
||||||
s->sprite_delta[0][0][0]= a;
|
s->sprite_delta[0][0]= a;
|
||||||
s->sprite_delta[0][0][1]= 0;
|
s->sprite_delta[0][1]= 0;
|
||||||
s->sprite_delta[0][1][0]= 0;
|
s->sprite_delta[1][0]= 0;
|
||||||
s->sprite_delta[0][1][1]= a;
|
s->sprite_delta[1][1]= a;
|
||||||
s->sprite_delta[1][0][0]= a;
|
s->sprite_shift[0]= 0;
|
||||||
s->sprite_delta[1][0][1]= 0;
|
s->sprite_shift[1]= 0;
|
||||||
s->sprite_delta[1][1][0]= 0;
|
|
||||||
s->sprite_delta[1][1][1]= a;
|
|
||||||
s->sprite_shift[0][0]= 0;
|
|
||||||
s->sprite_shift[0][1]= 0;
|
|
||||||
s->sprite_shift[1][0]= 0;
|
|
||||||
s->sprite_shift[1][1]= 0;
|
|
||||||
s->real_sprite_warping_points=1;
|
s->real_sprite_warping_points=1;
|
||||||
}
|
}
|
||||||
else
|
else{
|
||||||
|
int shift_y= 16 - s->sprite_shift[0];
|
||||||
|
int shift_c= 16 - s->sprite_shift[1];
|
||||||
|
//printf("shifts %d %d\n", shift_y, shift_c);
|
||||||
|
for(i=0; i<2; i++){
|
||||||
|
s->sprite_offset[0][i]<<= shift_y;
|
||||||
|
s->sprite_offset[1][i]<<= shift_c;
|
||||||
|
s->sprite_delta[0][i]<<= shift_y;
|
||||||
|
s->sprite_delta[1][i]<<= shift_y;
|
||||||
|
s->sprite_shift[i]= 16;
|
||||||
|
}
|
||||||
s->real_sprite_warping_points= s->num_sprite_warping_points;
|
s->real_sprite_warping_points= s->num_sprite_warping_points;
|
||||||
|
}
|
||||||
//printf("%d %d %d %d\n", d[0][0], d[0][1], s->sprite_offset[0][0], s->sprite_offset[0][1]);
|
#if 0
|
||||||
|
printf("vop:%d:%d %d:%d %d:%d, sprite:%d:%d %d:%d %d:%d, virtual: %d:%d %d:%d\n",
|
||||||
|
vop_ref[0][0], vop_ref[0][1],
|
||||||
|
vop_ref[1][0], vop_ref[1][1],
|
||||||
|
vop_ref[2][0], vop_ref[2][1],
|
||||||
|
sprite_ref[0][0], sprite_ref[0][1],
|
||||||
|
sprite_ref[1][0], sprite_ref[1][1],
|
||||||
|
sprite_ref[2][0], sprite_ref[2][1],
|
||||||
|
virtual_ref[0][0], virtual_ref[0][1],
|
||||||
|
virtual_ref[1][0], virtual_ref[1][1]
|
||||||
|
);
|
||||||
|
|
||||||
|
printf("offset: %d:%d , delta: %d %d %d %d, shift %d\n",
|
||||||
|
s->sprite_offset[0][0], s->sprite_offset[0][1],
|
||||||
|
s->sprite_delta[0][0], s->sprite_delta[0][1],
|
||||||
|
s->sprite_delta[1][0], s->sprite_delta[1][1],
|
||||||
|
s->sprite_shift[0]
|
||||||
|
);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static int decode_vol_header(MpegEncContext *s, GetBitContext *gb){
|
static int decode_vol_header(MpegEncContext *s, GetBitContext *gb){
|
||||||
@ -4337,8 +4363,7 @@ static int decode_vop_header(MpegEncContext *s, GetBitContext *gb){
|
|||||||
printf("low_delay flag set, but shouldnt, clearing it\n");
|
printf("low_delay flag set, but shouldnt, clearing it\n");
|
||||||
s->low_delay=0;
|
s->low_delay=0;
|
||||||
}
|
}
|
||||||
// printf("pic: %d, qpel:%d part:%d resync:%d\n", s->pict_type, s->quarter_sample, s->data_partitioning, s->resync_marker);
|
|
||||||
|
|
||||||
s->partitioned_frame= s->data_partitioning && s->pict_type!=B_TYPE;
|
s->partitioned_frame= s->data_partitioning && s->pict_type!=B_TYPE;
|
||||||
if(s->partitioned_frame)
|
if(s->partitioned_frame)
|
||||||
s->decode_mb= mpeg4_decode_partitioned_mb;
|
s->decode_mb= mpeg4_decode_partitioned_mb;
|
||||||
@ -4483,11 +4508,12 @@ static int decode_vop_header(MpegEncContext *s, GetBitContext *gb){
|
|||||||
}else
|
}else
|
||||||
s->b_code=1;
|
s->b_code=1;
|
||||||
#if 0
|
#if 0
|
||||||
printf("qp:%d fc:%d bc:%d type:%s size:%d pro:%d alt:%d top:%d qpel:%d part:%d resync:%d\n",
|
printf("qp:%d fc:%d bc:%d type:%s size:%d pro:%d alt:%d top:%d qpel:%d part:%d resync:%d w:%d a:%d\n",
|
||||||
s->qscale, s->f_code, s->b_code,
|
s->qscale, s->f_code, s->b_code,
|
||||||
s->pict_type == I_TYPE ? "I" : (s->pict_type == P_TYPE ? "P" : (s->pict_type == B_TYPE ? "B" : "S")),
|
s->pict_type == I_TYPE ? "I" : (s->pict_type == P_TYPE ? "P" : (s->pict_type == B_TYPE ? "B" : "S")),
|
||||||
gb->size,s->progressive_sequence, s->alternate_scan, s->top_field_first,
|
gb->size,s->progressive_sequence, s->alternate_scan, s->top_field_first,
|
||||||
s->quarter_sample, s->data_partitioning, s->resync_marker);
|
s->quarter_sample, s->data_partitioning, s->resync_marker, s->num_sprite_warping_points,
|
||||||
|
s->sprite_warping_accuracy);
|
||||||
#endif
|
#endif
|
||||||
if(!s->scalability){
|
if(!s->scalability){
|
||||||
if (s->shape!=RECT_SHAPE && s->pict_type!=I_TYPE) {
|
if (s->shape!=RECT_SHAPE && s->pict_type!=I_TYPE) {
|
||||||
|
@ -1032,15 +1032,13 @@ if(s->max_b_frames==0)
|
|||||||
static inline void gmc1_motion(MpegEncContext *s,
|
static inline void gmc1_motion(MpegEncContext *s,
|
||||||
UINT8 *dest_y, UINT8 *dest_cb, UINT8 *dest_cr,
|
UINT8 *dest_y, UINT8 *dest_cb, UINT8 *dest_cr,
|
||||||
int dest_offset,
|
int dest_offset,
|
||||||
UINT8 **ref_picture, int src_offset,
|
UINT8 **ref_picture, int src_offset)
|
||||||
int h)
|
|
||||||
{
|
{
|
||||||
UINT8 *ptr;
|
UINT8 *ptr;
|
||||||
int offset, src_x, src_y, linesize, uvlinesize;
|
int offset, src_x, src_y, linesize, uvlinesize;
|
||||||
int motion_x, motion_y;
|
int motion_x, motion_y;
|
||||||
int emu=0;
|
int emu=0;
|
||||||
|
|
||||||
if(s->real_sprite_warping_points>1) printf("more than 1 warp point isnt supported\n");
|
|
||||||
motion_x= s->sprite_offset[0][0];
|
motion_x= s->sprite_offset[0][0];
|
||||||
motion_y= s->sprite_offset[0][1];
|
motion_y= s->sprite_offset[0][1];
|
||||||
src_x = s->mb_x * 16 + (motion_x >> (s->sprite_warping_accuracy+1));
|
src_x = s->mb_x * 16 + (motion_x >> (s->sprite_warping_accuracy+1));
|
||||||
@ -1053,22 +1051,37 @@ static inline void gmc1_motion(MpegEncContext *s,
|
|||||||
src_y = clip(src_y, -16, s->height);
|
src_y = clip(src_y, -16, s->height);
|
||||||
if (src_y == s->height)
|
if (src_y == s->height)
|
||||||
motion_y =0;
|
motion_y =0;
|
||||||
|
|
||||||
linesize = s->linesize;
|
linesize = s->linesize;
|
||||||
uvlinesize = s->uvlinesize;
|
uvlinesize = s->uvlinesize;
|
||||||
|
|
||||||
ptr = ref_picture[0] + (src_y * linesize) + src_x + src_offset;
|
ptr = ref_picture[0] + (src_y * linesize) + src_x + src_offset;
|
||||||
|
|
||||||
dest_y+=dest_offset;
|
dest_y+=dest_offset;
|
||||||
if(s->flags&CODEC_FLAG_EMU_EDGE){
|
if(s->flags&CODEC_FLAG_EMU_EDGE){
|
||||||
if(src_x<0 || src_y<0 || src_x + (motion_x&15) + 16 > s->h_edge_pos
|
if(src_x<0 || src_y<0 || src_x + (motion_x&15) + 16 > s->h_edge_pos
|
||||||
|| src_y + (motion_y&15) + h > s->v_edge_pos){
|
|| src_y + (motion_y&15) + 16 > s->v_edge_pos){
|
||||||
emulated_edge_mc(s, ptr, linesize, 17, h+1, src_x, src_y, s->h_edge_pos, s->v_edge_pos);
|
emulated_edge_mc(s, ptr, linesize, 17, 17, src_x, src_y, s->h_edge_pos, s->v_edge_pos);
|
||||||
ptr= s->edge_emu_buffer;
|
ptr= s->edge_emu_buffer;
|
||||||
emu=1;
|
emu=1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
gmc1(dest_y , ptr , linesize, h, motion_x&15, motion_y&15, s->no_rounding);
|
|
||||||
gmc1(dest_y+8, ptr+8, linesize, h, motion_x&15, motion_y&15, s->no_rounding);
|
if((motion_x|motion_y)&7){
|
||||||
|
ff_gmc1(dest_y , ptr , linesize, 16, motion_x&15, motion_y&15, 128 - s->no_rounding);
|
||||||
|
ff_gmc1(dest_y+8, ptr+8, linesize, 16, motion_x&15, motion_y&15, 128 - s->no_rounding);
|
||||||
|
}else{
|
||||||
|
int dxy;
|
||||||
|
|
||||||
|
dxy= ((motion_x>>3)&1) | ((motion_y>>2)&2);
|
||||||
|
if (s->no_rounding){
|
||||||
|
put_no_rnd_pixels_tab[0][dxy](dest_y, ptr, linesize, 16);
|
||||||
|
}else{
|
||||||
|
put_pixels_tab [0][dxy](dest_y, ptr, linesize, 16);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(s->flags&CODEC_FLAG_GRAY) return;
|
||||||
|
|
||||||
motion_x= s->sprite_offset[1][0];
|
motion_x= s->sprite_offset[1][0];
|
||||||
motion_y= s->sprite_offset[1][1];
|
motion_y= s->sprite_offset[1][1];
|
||||||
@ -1086,21 +1099,85 @@ static inline void gmc1_motion(MpegEncContext *s,
|
|||||||
offset = (src_y * uvlinesize) + src_x + (src_offset>>1);
|
offset = (src_y * uvlinesize) + src_x + (src_offset>>1);
|
||||||
ptr = ref_picture[1] + offset;
|
ptr = ref_picture[1] + offset;
|
||||||
if(emu){
|
if(emu){
|
||||||
emulated_edge_mc(s, ptr, uvlinesize, 9, (h>>1)+1, src_x, src_y, s->h_edge_pos>>1, s->v_edge_pos>>1);
|
emulated_edge_mc(s, ptr, uvlinesize, 9, 9, src_x, src_y, s->h_edge_pos>>1, s->v_edge_pos>>1);
|
||||||
ptr= s->edge_emu_buffer;
|
ptr= s->edge_emu_buffer;
|
||||||
}
|
}
|
||||||
gmc1(dest_cb + (dest_offset>>1), ptr, uvlinesize, h>>1, motion_x&15, motion_y&15, s->no_rounding);
|
ff_gmc1(dest_cb + (dest_offset>>1), ptr, uvlinesize, 8, motion_x&15, motion_y&15, 128 - s->no_rounding);
|
||||||
|
|
||||||
ptr = ref_picture[2] + offset;
|
ptr = ref_picture[2] + offset;
|
||||||
if(emu){
|
if(emu){
|
||||||
emulated_edge_mc(s, ptr, uvlinesize, 9, (h>>1)+1, src_x, src_y, s->h_edge_pos>>1, s->v_edge_pos>>1);
|
emulated_edge_mc(s, ptr, uvlinesize, 9, 9, src_x, src_y, s->h_edge_pos>>1, s->v_edge_pos>>1);
|
||||||
ptr= s->edge_emu_buffer;
|
ptr= s->edge_emu_buffer;
|
||||||
}
|
}
|
||||||
gmc1(dest_cr + (dest_offset>>1), ptr, uvlinesize, h>>1, motion_x&15, motion_y&15, s->no_rounding);
|
ff_gmc1(dest_cr + (dest_offset>>1), ptr, uvlinesize, 8, motion_x&15, motion_y&15, 128 - s->no_rounding);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline void gmc_motion(MpegEncContext *s,
|
||||||
|
UINT8 *dest_y, UINT8 *dest_cb, UINT8 *dest_cr,
|
||||||
|
int dest_offset,
|
||||||
|
UINT8 **ref_picture, int src_offset)
|
||||||
|
{
|
||||||
|
UINT8 *ptr;
|
||||||
|
int linesize, uvlinesize;
|
||||||
|
const int a= s->sprite_warping_accuracy;
|
||||||
|
int ox, oy;
|
||||||
|
|
||||||
|
linesize = s->linesize;
|
||||||
|
uvlinesize = s->uvlinesize;
|
||||||
|
|
||||||
|
ptr = ref_picture[0] + src_offset;
|
||||||
|
|
||||||
|
dest_y+=dest_offset;
|
||||||
|
|
||||||
|
ox= s->sprite_offset[0][0] + s->sprite_delta[0][0]*s->mb_x*16 + s->sprite_delta[0][1]*s->mb_y*16;
|
||||||
|
oy= s->sprite_offset[0][1] + s->sprite_delta[1][0]*s->mb_x*16 + s->sprite_delta[1][1]*s->mb_y*16;
|
||||||
|
|
||||||
|
ff_gmc(dest_y, ptr, linesize, 16,
|
||||||
|
ox,
|
||||||
|
oy,
|
||||||
|
s->sprite_delta[0][0], s->sprite_delta[0][1],
|
||||||
|
s->sprite_delta[1][0], s->sprite_delta[1][1],
|
||||||
|
a+1, (1<<(2*a+1)) - s->no_rounding,
|
||||||
|
s->h_edge_pos, s->v_edge_pos);
|
||||||
|
ff_gmc(dest_y+8, ptr, linesize, 16,
|
||||||
|
ox + s->sprite_delta[0][0]*8,
|
||||||
|
oy + s->sprite_delta[1][0]*8,
|
||||||
|
s->sprite_delta[0][0], s->sprite_delta[0][1],
|
||||||
|
s->sprite_delta[1][0], s->sprite_delta[1][1],
|
||||||
|
a+1, (1<<(2*a+1)) - s->no_rounding,
|
||||||
|
s->h_edge_pos, s->v_edge_pos);
|
||||||
|
|
||||||
|
if(s->flags&CODEC_FLAG_GRAY) return;
|
||||||
|
|
||||||
|
|
||||||
|
dest_cb+=dest_offset>>1;
|
||||||
|
dest_cr+=dest_offset>>1;
|
||||||
|
|
||||||
|
ox= s->sprite_offset[1][0] + s->sprite_delta[0][0]*s->mb_x*8 + s->sprite_delta[0][1]*s->mb_y*8;
|
||||||
|
oy= s->sprite_offset[1][1] + s->sprite_delta[1][0]*s->mb_x*8 + s->sprite_delta[1][1]*s->mb_y*8;
|
||||||
|
|
||||||
|
ptr = ref_picture[1] + (src_offset>>1);
|
||||||
|
ff_gmc(dest_cb, ptr, uvlinesize, 8,
|
||||||
|
ox,
|
||||||
|
oy,
|
||||||
|
s->sprite_delta[0][0], s->sprite_delta[0][1],
|
||||||
|
s->sprite_delta[1][0], s->sprite_delta[1][1],
|
||||||
|
a+1, (1<<(2*a+1)) - s->no_rounding,
|
||||||
|
s->h_edge_pos>>1, s->v_edge_pos>>1);
|
||||||
|
|
||||||
|
ptr = ref_picture[2] + (src_offset>>1);
|
||||||
|
ff_gmc(dest_cr, ptr, uvlinesize, 8,
|
||||||
|
ox,
|
||||||
|
oy,
|
||||||
|
s->sprite_delta[0][0], s->sprite_delta[0][1],
|
||||||
|
s->sprite_delta[1][0], s->sprite_delta[1][1],
|
||||||
|
a+1, (1<<(2*a+1)) - s->no_rounding,
|
||||||
|
s->h_edge_pos>>1, s->v_edge_pos>>1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static void emulated_edge_mc(MpegEncContext *s, UINT8 *src, int linesize, int block_w, int block_h,
|
static void emulated_edge_mc(MpegEncContext *s, UINT8 *src, int linesize, int block_w, int block_h,
|
||||||
int src_x, int src_y, int w, int h){
|
int src_x, int src_y, int w, int h){
|
||||||
int x, y;
|
int x, y;
|
||||||
@ -1357,9 +1434,13 @@ static inline void MPV_motion(MpegEncContext *s,
|
|||||||
switch(s->mv_type) {
|
switch(s->mv_type) {
|
||||||
case MV_TYPE_16X16:
|
case MV_TYPE_16X16:
|
||||||
if(s->mcsel){
|
if(s->mcsel){
|
||||||
gmc1_motion(s, dest_y, dest_cb, dest_cr, 0,
|
if(s->real_sprite_warping_points==1){
|
||||||
ref_picture, 0,
|
gmc1_motion(s, dest_y, dest_cb, dest_cr, 0,
|
||||||
16);
|
ref_picture, 0);
|
||||||
|
}else{
|
||||||
|
gmc_motion(s, dest_y, dest_cb, dest_cr, 0,
|
||||||
|
ref_picture, 0);
|
||||||
|
}
|
||||||
}else if(s->quarter_sample){
|
}else if(s->quarter_sample){
|
||||||
qpel_motion(s, dest_y, dest_cb, dest_cr, 0,
|
qpel_motion(s, dest_y, dest_cb, dest_cr, 0,
|
||||||
ref_picture, 0,
|
ref_picture, 0,
|
||||||
|
@ -369,9 +369,9 @@ typedef struct MpegEncContext {
|
|||||||
int sprite_brightness_change;
|
int sprite_brightness_change;
|
||||||
int num_sprite_warping_points;
|
int num_sprite_warping_points;
|
||||||
int real_sprite_warping_points;
|
int real_sprite_warping_points;
|
||||||
int sprite_offset[2][2];
|
int sprite_offset[2][2]; /* sprite offset[isChroma][isMVY] */
|
||||||
int sprite_delta[2][2][2];
|
int sprite_delta[2][2]; /* sprite_delta [isY][isMVY] */
|
||||||
int sprite_shift[2][2];
|
int sprite_shift[2]; /* sprite shift [isChroma] */
|
||||||
int mcsel;
|
int mcsel;
|
||||||
int quant_precision;
|
int quant_precision;
|
||||||
int quarter_sample; /* 1->qpel, 0->half pel ME/MC */
|
int quarter_sample; /* 1->qpel, 0->half pel ME/MC */
|
||||||
|
Loading…
x
Reference in New Issue
Block a user