📄 motion.c
字号:
#include "mpeg3video.h"
#include "vlc.h"
#include <stdio.h>
/* calculate motion vector component */
void mpeg3video_calc_mv(int *pred, int r_size, int motion_code, int motion_r, int full_pel_vector)
{
int lim = 16 << r_size;
int vec = full_pel_vector ? (*pred >> 1) : (*pred);
if(motion_code > 0)
{
vec += ((motion_code - 1) << r_size) + motion_r + 1;
if(vec >= lim) vec -= lim + lim;
}
else
if(motion_code < 0)
{
vec -= ((-motion_code - 1) << r_size) + motion_r + 1;
if(vec < -lim) vec += lim + lim;
}
*pred = full_pel_vector ? (vec << 1) : vec;
}
/*
int *dmvector, * differential motion vector *
int mvx, int mvy * decoded mv components (always in field format) *
*/
void mpeg3video_calc_dmv(mpeg3video_t *video,
int DMV[][2],
int *dmvector,
int mvx,
int mvy)
{
if(video->pict_struct == FRAME_PICTURE)
{
if(video->topfirst)
{
/* vector for prediction of top field from bottom field */
DMV[0][0] = ((mvx + (mvx>0)) >> 1) + dmvector[0];
DMV[0][1] = ((mvy + (mvy>0)) >> 1) + dmvector[1] - 1;
/* vector for prediction of bottom field from top field */
DMV[1][0] = ((3 * mvx + (mvx > 0)) >> 1) + dmvector[0];
DMV[1][1] = ((3 * mvy + (mvy > 0)) >> 1) + dmvector[1] + 1;
}
else
{
/* vector for prediction of top field from bottom field */
DMV[0][0] = ((3 * mvx + (mvx>0)) >> 1) + dmvector[0];
DMV[0][1] = ((3 * mvy + (mvy>0)) >> 1) + dmvector[1] - 1;
/* vector for prediction of bottom field from top field */
DMV[1][0] = ((mvx + (mvx>0)) >> 1) + dmvector[0];
DMV[1][1] = ((mvy + (mvy>0)) >> 1) + dmvector[1] + 1;
}
}
else
{
/* vector for prediction from field of opposite 'parity' */
DMV[0][0] = ((mvx + (mvx > 0)) >> 1) + dmvector[0];
DMV[0][1] = ((mvy + (mvy > 0)) >> 1) + dmvector[1];
/* correct for vertical field shift */
if(video->pict_struct == TOP_FIELD)
DMV[0][1]--;
else
DMV[0][1]++;
}
}
int mpeg3video_get_mv(mpeg3_slice_t *slice)
{
int code;
mpeg3_slice_buffer_t *slice_buffer = slice->slice_buffer;
if(mpeg3slice_getbit(slice_buffer))
{
return 0;
}
if((code = mpeg3slice_showbits9(slice_buffer)) >= 64)
{
code >>= 6;
mpeg3slice_flushbits(slice_buffer, mpeg3_MVtab0[code].len);
return mpeg3slice_getbit(slice_buffer) ? -mpeg3_MVtab0[code].val : mpeg3_MVtab0[code].val;
}
if(code >= 24)
{
code >>= 3;
mpeg3slice_flushbits(slice_buffer, mpeg3_MVtab1[code].len);
return mpeg3slice_getbit(slice_buffer) ? -mpeg3_MVtab1[code].val : mpeg3_MVtab1[code].val;
}
if((code -= 12) < 0)
{
/* fprintf(stdout,"mpeg3video_get_mv: invalid motion_vector code\n"); */
slice->fault = 1;
return 1;
}
mpeg3slice_flushbits(slice_buffer, mpeg3_MVtab2[code].len);
return mpeg3slice_getbit(slice_buffer) ? -mpeg3_MVtab2[code].val : mpeg3_MVtab2[code].val;
}
/* get differential motion vector (for dual prime prediction) */
int mpeg3video_get_dmv(mpeg3_slice_t *slice)
{
mpeg3_slice_buffer_t *slice_buffer = slice->slice_buffer;
if(mpeg3slice_getbit(slice_buffer))
{
return mpeg3slice_getbit(slice_buffer) ? -1 : 1;
}
else
{
return 0;
}
}
/* get and decode motion vector and differential motion vector */
void mpeg3video_motion_vector(mpeg3_slice_t *slice,
mpeg3video_t *video,
int *PMV,
int *dmvector,
int h_r_size,
int v_r_size,
int dmv,
int mvscale,
int full_pel_vector)
{
int motion_r;
int motion_code = mpeg3video_get_mv(slice);
mpeg3_slice_buffer_t *slice_buffer = slice->slice_buffer;
if(slice->fault) return;
motion_r = (h_r_size != 0 && motion_code != 0) ? mpeg3slice_getbits(slice_buffer, h_r_size) : 0;
mpeg3video_calc_mv(&PMV[0], h_r_size, motion_code, motion_r, full_pel_vector);
if(dmv) dmvector[0] = mpeg3video_get_dmv(slice);
motion_code = mpeg3video_get_mv(slice);
if(slice->fault) return;
motion_r = (v_r_size != 0 && motion_code != 0) ? mpeg3slice_getbits(slice_buffer, v_r_size) : 0;
/* DIV 2 */
if(mvscale) PMV[1] >>= 1;
mpeg3video_calc_mv(&PMV[1], v_r_size, motion_code, motion_r, full_pel_vector);
if(mvscale) PMV[1] <<= 1;
if(dmv) dmvector[1] = mpeg3video_get_dmv(slice);
}
int mpeg3video_motion_vectors(mpeg3_slice_t *slice,
mpeg3video_t *video,
int PMV[2][2][2],
int dmvector[2],
int mv_field_sel[2][2],
int s,
int mv_count,
int mv_format,
int h_r_size,
int v_r_size,
int dmv,
int mvscale)
{
int result = 0;
mpeg3_slice_buffer_t *slice_buffer = slice->slice_buffer;
if(mv_count == 1)
{
if(mv_format == MV_FIELD && !dmv)
{
mv_field_sel[1][s] = mv_field_sel[0][s] = mpeg3slice_getbit(slice_buffer);
}
mpeg3video_motion_vector(slice,
video,
PMV[0][s],
dmvector,
h_r_size,
v_r_size,
dmv,
mvscale,
0);
if(slice->fault) return 1;
/* update other motion vector predictors */
PMV[1][s][0] = PMV[0][s][0];
PMV[1][s][1] = PMV[0][s][1];
}
else
{
mv_field_sel[0][s] = mpeg3slice_getbit(slice_buffer);
mpeg3video_motion_vector(slice,
video,
PMV[0][s],
dmvector,
h_r_size,
v_r_size,
dmv,
mvscale,
0);
if(slice->fault) return 1;
mv_field_sel[1][s] = mpeg3slice_getbit(slice_buffer);
mpeg3video_motion_vector(slice,
video,
PMV[1][s],
dmvector,
h_r_size,
v_r_size,
dmv,
mvscale,
0);
if(slice->fault) return 1;
}
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -