📄 macroblock.c
字号:
vs_erase_bits(in, 2);
return 1;
}
return 0;
}
static int get_motion_code(VIDEO_STREAM *in)
{
int r;
int code;
static const BASIC_VLC_ELEMENT table_a[] = {
{ 2, 4}, {-2, 4},
{ 1, 3}, { 1, 3}, {-1,3}, {-1, 3},
{ 0, 1}, { 0, 1}, { 0,1}, { 0, 1},
{ 0, 1}, { 0, 1}, { 0,1}, { 0, 1},
};
static const BASIC_VLC_ELEMENT table_b[] = {
{ 7, 8}, {-7, 8}, { 6, 8}, {-6, 8}, { 5, 8}, {-5, 8},
{ 4, 7}, { 4, 7}, {-4, 7}, {-4, 7},
{ 3, 5}, { 3, 5}, { 3, 5}, { 3, 5},
{ 3, 5}, { 3, 5}, { 3, 5}, { 3, 5},
{-3, 5}, {-3, 5}, {-3, 5}, {-3, 5},
{-3, 5}, {-3, 5}, {-3, 5}, {-3, 5},
};
static const BASIC_VLC_ELEMENT table_c[] = {
{16,11}, {-16,11}, {15,11}, {-15,11},
{14,11}, {-14,11}, {13,11}, {-13,11},
{12,11}, {-12,11}, {11,11}, {-11,11},
{10,10}, {10,10}, {-10,10}, {-10,10},
{ 9,10}, { 9,10}, { -9,10}, { -9,10},
{ 8,10}, { 8,10}, { -8,10}, { -8,10},
};
code = vs_read_bits(in, 11);
if(code > 255){
code = (code >> 7) - 2;
r = table_a[code].value;
vs_erase_bits(in, table_a[code].length);
}else if(code > 47){
code = (code >> 3) - 6;
r = table_b[code].value;
vs_erase_bits(in, table_b[code].length);
}else{
code -= 24;
r = table_c[code].value;
vs_erase_bits(in, table_c[code].length);
}
return r;
}
static int get_dmvector(VIDEO_STREAM *in)
{
int code;
static const BASIC_VLC_ELEMENT table[] = {
{ 0, 1}, { 0, 1}, { 1, 2}, {-1, 2}
};
code = vs_read_bits(in, 2);
vs_erase_bits(in, table[code].length);
return table[code].value;
}
static void read_motion_vector(VIDEO_STREAM *in, MACROBLOCK *out, READ_MACROBLOCK_OPTION *opt, int s)
{
int r,t;
int half;
if( (out->motion_vector_format == MOTION_VECTOR_FORMAT_FIELD) && (opt->picture_structure == 3) ){
half = 2;
}else if( opt->full_pel_vector[s] ){
half = 3;
}else{
half = 0;
}
if(out->motion_vector_count == 1){
if( (out->motion_vector_format == MOTION_VECTOR_FORMAT_FIELD) && (out->dual_prime_motion_vector != 1) ){
out->motion_vertical_field_select[0][s] = vs_get_bits(in, 1);
}
for(t=0;t<2;t++){
out->PMV[0][s][t] = get_motion_vector_predictor(in, out->PMV[0][s][t], opt->f_code[s][t], (half & (t+1)) );
if(out->dual_prime_motion_vector == 1){
read_dmv(in, out, opt, s, t);
}
out->PMV[1][s][t] = out->PMV[0][s][t];
}
}else{
for(r=0;r<2;r++){
out->motion_vertical_field_select[r][s] = vs_get_bits(in, 1);
for(t=0;t<2;t++){
out->PMV[r][s][t] = get_motion_vector_predictor(in, out->PMV[r][s][t], opt->f_code[s][t], (half && t));
}
}
}
}
static void read_dmv(VIDEO_STREAM *in, MACROBLOCK *out, READ_MACROBLOCK_OPTION *opt, int s, int t)
{
int v;
int dmvector;
dmvector = get_dmvector(in);
if(opt->picture_structure == 3){
if(t){
v = out->PMV[0][s][t] >> 1;
}else{
v = out->PMV[0][s][t];
}
if(opt->top_field_first){
out->DMV[0][t] = ( ( v + (v>0) )>>1 ) + dmvector - t;
out->DMV[1][t] = ( ( v*3 + (v>0) )>>1 ) + dmvector + t;
}else{
out->DMV[0][t] = ( ( v*3 + (v>0) )>>1 ) + dmvector - t;
out->DMV[1][t] = ( ( v + (v>0) )>>1 ) + dmvector + t;
}
}else{
v = out->PMV[0][s][t];
out->DMV[0][t] = ( ( v + (v>0) )>>1) + dmvector;
if(opt->picture_structure == 1){
out->DMV[0][t] -= t;
}else{
out->DMV[0][t] += t;
}
}
}
static int get_motion_vector_predictor(VIDEO_STREAM *in, int prediction, int f_code, int half)
{
int r;
int f;
int r_size;
int high;
int low;
int range;
int delta;
int motion_code;
int motion_residual;
r_size = f_code - 1;
f = 1 << r_size;
high = 16 * f - 1;
low = -16 * f;
range = 32 * f;
motion_code = get_motion_code(in);
if( (!r_size) || (motion_code == 0) ){
delta = motion_code;
}else{
motion_residual = vs_get_bits(in, r_size);
delta = (abs(motion_code) - 1) * f + motion_residual + 1;
if(motion_code < 0){
delta = 0 - delta;
}
}
if(half){
prediction >>= 1;
}
r = prediction + delta;
if(r < low){
r += range;
}else if(r > high){
r -= range;
}
if(half){
r <<= 1;
}
return r;
}
static void read_coded_block_mpeg2_420_intra(VIDEO_STREAM *in, MACROBLOCK *out)
{
int i;
out->block_count = 6;
for(i=0;i<4;i++){
out->read_block[i] = read_block_mpeg2_intra_luminance;
}
out->read_block[4] = read_block_mpeg2_intra_cb;
out->read_block[5] = read_block_mpeg2_intra_cr;
}
static void read_coded_block_mpeg1_420_intra(VIDEO_STREAM *in, MACROBLOCK *out)
{
int i;
out->block_count = 6;
for(i=0;i<4;i++){
out->read_block[i] = read_block_mpeg1_intra_luminance;
}
out->read_block[4] = read_block_mpeg1_intra_cb;
out->read_block[5] = read_block_mpeg1_intra_cr;
}
static void read_coded_block_mpeg2_422_intra(VIDEO_STREAM *in, MACROBLOCK *out)
{
int i;
out->block_count = 8;
for(i=0;i<4;i++){
out->read_block[i] = read_block_mpeg2_intra_luminance;
}
out->read_block[4] = read_block_mpeg2_intra_cb;
out->read_block[5] = read_block_mpeg2_intra_cr;
out->read_block[6] = read_block_mpeg2_intra_cb;
out->read_block[7] = read_block_mpeg2_intra_cr;
}
static void read_coded_block_mpeg2_444_intra(VIDEO_STREAM *in, MACROBLOCK *out)
{
int i;
out->block_count = 12;
for(i=0;i<4;i++){
out->read_block[i] = read_block_mpeg2_intra_luminance;
}
for(i=4;i<12;i+=2){
out->read_block[i] = read_block_mpeg2_intra_cb;
out->read_block[i+1] = read_block_mpeg2_intra_cr;
}
}
static void read_coded_block_mpeg2_420_nonintra_pattern(VIDEO_STREAM *in, MACROBLOCK *out)
{
int i;
int coded_block_pattern;
static const READ_BLOCK rb_y_table[2] = {
read_block_null,
read_block_mpeg2_nonintra_luminance,
};
static const READ_BLOCK rb_c_table[2] = {
read_block_null,
read_block_mpeg2_nonintra_chrominance,
};
out->block_count = 6;
coded_block_pattern = get_coded_block_pattern(in);
for(i=0;i<4;i++){
out->read_block[i] = rb_y_table[ ((coded_block_pattern >> (out->block_count - 1 - i)) & 1) ];
}
for(i=4;i<6;i++){
out->read_block[i] = rb_c_table[ ((coded_block_pattern >> (out->block_count - 1 - i)) & 1) ];
}
}
static void read_coded_block_mpeg1_420_nonintra_pattern(VIDEO_STREAM *in, MACROBLOCK *out)
{
int i;
int coded_block_pattern;
static const READ_BLOCK rb_table[2] = {
read_block_null,
read_block_mpeg1_nonintra,
};
out->block_count = 6;
coded_block_pattern = get_coded_block_pattern(in);
for(i=0;i<6;i++){
out->read_block[i] = rb_table[ ((coded_block_pattern >> (out->block_count - 1 - i)) & 1) ];
}
}
static void read_coded_block_mpeg2_422_nonintra_pattern(VIDEO_STREAM *in, MACROBLOCK *out)
{
int i;
int coded_block_pattern;
static const READ_BLOCK rb_y_table[2] = {
read_block_null,
read_block_mpeg2_nonintra_luminance,
};
static const READ_BLOCK rb_c_table[2] = {
read_block_null,
read_block_mpeg2_nonintra_chrominance,
};
out->block_count = 8;
coded_block_pattern = get_coded_block_pattern(in);
coded_block_pattern <<= 2;
coded_block_pattern += vs_get_bits(in, 2);
for(i=0;i<4;i++){
out->read_block[i] = rb_y_table[ ((coded_block_pattern >> (out->block_count - 1 - i)) & 1) ];
}
for(i=4;i<8;i++){
out->read_block[i] = rb_c_table[ ((coded_block_pattern >> (out->block_count - 1 - i)) & 1) ];
}
}
static void read_coded_block_mpeg2_444_nonintra_pattern(VIDEO_STREAM *in, MACROBLOCK *out)
{
int i;
int coded_block_pattern;
static const READ_BLOCK rb_y_table[2] = {
read_block_null,
read_block_mpeg2_nonintra_luminance,
};
static const READ_BLOCK rb_c_table[2] = {
read_block_null,
read_block_mpeg2_nonintra_chrominance,
};
out->block_count = 12;
coded_block_pattern = get_coded_block_pattern(in);
coded_block_pattern <<= 6;
coded_block_pattern += vs_get_bits(in, 6);
for(i=0;i<4;i++){
out->read_block[i] = rb_y_table[ ((coded_block_pattern >> (out->block_count - 1 - i)) & 1) ];
}
for(i=4;i<12;i++){
out->read_block[i] = rb_c_table[ ((coded_block_pattern >> (out->block_count - 1 - i)) & 1) ];
}
}
static void read_coded_block_420_nonintra_nopattern(VIDEO_STREAM *in, MACROBLOCK *out)
{
int i;
out->block_count = 6;
for(i=0;i<6;i++){
out->read_block[i] = read_block_null;
}
}
static void read_coded_block_422_nonintra_nopattern(VIDEO_STREAM *in, MACROBLOCK *out)
{
int i;
out->block_count = 8;
for(i=0;i<8;i++){
out->read_block[i] = read_block_null;
}
}
static void read_coded_block_444_nonintra_nopattern(VIDEO_STREAM *in, MACROBLOCK *out)
{
int i;
out->block_count = 12;
for(i=0;i<12;i++){
out->read_block[i] = read_block_null;
}
}
static int get_coded_block_pattern(VIDEO_STREAM *in)
{
int r;
int code;
static const BASIC_VLC_ELEMENT table_a[] = {
{63,6},{ 3,6},{36,6},{24,6},{62,5},{62,5},{ 2,5},{ 2,5},
{61,5},{61,5},{ 1,5},{ 1,5},{56,5},{56,5},{52,5},{52,5},
{44,5},{44,5},{28,5},{28,5},{40,5},{40,5},{20,5},{20,5},
{48,5},{48,5},{12,5},{12,5},{32,4},{32,4},{32,4},{32,4},
{16,4},{16,4},{16,4},{16,4},{ 8,4},{ 8,4},{ 8,4},{ 8,4},
{ 4,4},{ 4,4},{ 4,4},{ 4,4},{60,3},{60,3},{60,3},{60,3},
{60,3},{60,3},{60,3},{60,3},
};
static const BASIC_VLC_ELEMENT table_b[] = {
{ 0,0},{ 0,9},{39,9},{27,9},{59,9},{55,9},{47,9},{31,9},
{58,8},{58,8},{54,8},{54,8},{46,8},{46,8},{30,8},{30,8},
{57,8},{57,8},{53,8},{53,8},{45,8},{45,8},{29,8},{29,8},
{38,8},{38,8},{26,8},{26,8},{37,8},{37,8},{25,8},{25,8},
{43,8},{43,8},{23,8},{23,8},{51,8},{51,8},{15,8},{15,8},
{42,8},{42,8},{22,8},{22,8},{50,8},{50,8},{14,8},{14,8},
{41,8},{41,8},{21,8},{21,8},{49,8},{49,8},{13,8},{13,8},
{35,8},{35,8},{19,8},{19,8},{11,8},{11,8},{ 7,8},{ 7,8},
{34,7},{34,7},{34,7},{34,7},{18,7},{18,7},{18,7},{18,7},
{10,7},{10,7},{10,7},{10,7},{ 6,7},{ 6,7},{ 6,7},{ 6,7},
{33,7},{33,7},{33,7},{33,7},{17,7},{17,7},{17,7},{17,7},
{ 9,7},{ 9,7},{ 9,7},{ 9,7},{ 5,7},{ 5,7},{ 5,7},{ 5,7},
};
code = vs_read_bits(in, 9);
if(code > 95){
code = (code >> 3) - 12;
r = table_a[code].value;
vs_erase_bits(in, table_a[code].length);
}else{
r = table_b[code].value;
vs_erase_bits(in, table_b[code].length);
}
return r;
}
typedef struct {
int weight_top;
int weight_bottom;
int class;
int integer_weight;
} SPATIAL_TEMPORAL_WEIGHT_TABLE_ELEMENT;
static void read_spatial_temporal_weight(VIDEO_STREAM *in, MACROBLOCK *out, READ_MACROBLOCK_OPTION *opt)
{
int code;
static const SPATIAL_TEMPORAL_WEIGHT_TABLE_ELEMENT table[4][4] = {
{
{1, 1, 1, 0},
{1, 1, 1, 0},
{1, 1, 1, 0},
{1, 1, 1, 0},
}, /* table_index_0 */
{
{0, 2, 3, 1},
{0, 1, 1, 0},
{1, 2, 3, 0},
{1, 1, 1, 0},
}, /* table_index_1 */
{
{2, 0, 2, 1},
{1, 0, 1, 0},
{2, 1, 2, 0},
{1, 1, 1, 0},
}, /* table_index_2 */
{
{2, 0, 2, 1},
{2, 1, 2, 0},
{1, 2, 3, 0},
{1, 1, 1, 0},
}, /* table_index_4 */
};
if(opt->spatial_temporal_weight_code_table_index){
code = vs_get_bits(in, 2);
out->spatial_temporal_weight[0] = table[opt->spatial_temporal_weight_code_table_index][code].weight_top;
out->spatial_temporal_weight[1] = table[opt->spatial_temporal_weight_code_table_index][code].weight_bottom;
out->spatial_temporal_weight_class = table[opt->spatial_temporal_weight_code_table_index][code].class;
out->spatial_temporal_integer_weight = table[opt->spatial_temporal_weight_code_table_index][code].integer_weight;
}else{
out->spatial_temporal_weight[0] = 1;
out->spatial_temporal_weight[1] = 1;
out->spatial_temporal_weight_class = 1;
out->spatial_temporal_integer_weight = 0;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -