📄 macroblock.c
字号:
/*******************************************************************
macroblock layer interface
*******************************************************************/
#define MACROBLOCK_C
#include "macroblock.h"
typedef struct {
int value;
int length;
} BASIC_VLC_ELEMENT;
int get_macroblock_address_increment(VIDEO_STREAM *in);
int read_macroblock(VIDEO_STREAM *in, MACROBLOCK *out, READ_MACROBLOCK_OPTION *opt);
int macroblock_to_read_block_option(MACROBLOCK *in, READ_BLOCK_OPTION *opt);
int macroblock_to_mc_parameter(MACROBLOCK *in, MC_PARAMETER *out);
int reset_motion_vector_predictor(MACROBLOCK *p);
int read_macroblock_type_snr_scalability(VIDEO_STREAM *in, MACROBLOCK *out);
int read_macroblock_type_b_spatial_scalability(VIDEO_STREAM *in, MACROBLOCK *out);
int read_macroblock_type_p_spatial_scalability(VIDEO_STREAM *in, MACROBLOCK *out);
int read_macroblock_type_i_spatial_scalability(VIDEO_STREAM *in, MACROBLOCK *out);
int read_macroblock_type_b(VIDEO_STREAM *in, MACROBLOCK *out);
int read_macroblock_type_p(VIDEO_STREAM *in, MACROBLOCK *out);
int read_macroblock_type_i(VIDEO_STREAM *in, MACROBLOCK *out);
int read_macroblock_type_d(VIDEO_STREAM *in, MACROBLOCK *out);
static int read_macroblock_mode(VIDEO_STREAM *in, MACROBLOCK *out, READ_MACROBLOCK_OPTION *opt);
static int get_motion_code(VIDEO_STREAM *in);
static int get_dmvector(VIDEO_STREAM *in);
static void read_dual_prime_motion_vector(VIDEO_STREAM *in, MACROBLOCK *out, READ_MACROBLOCK_OPTION *opt);
static void read_motion_vector(VIDEO_STREAM *in, MACROBLOCK *out, READ_MACROBLOCK_OPTION *opt, int s);
static void read_dmv(VIDEO_STREAM *in, MACROBLOCK *out, READ_MACROBLOCK_OPTION *opt, int s, int t);
static int get_motion_vector_predictor(VIDEO_STREAM *in, int predictor, int f_code, int half);
static void read_coded_block_mpeg2_420_intra(VIDEO_STREAM *in, MACROBLOCK *out);
static void read_coded_block_mpeg1_420_intra(VIDEO_STREAM *in, MACROBLOCK *out);
static void read_coded_block_mpeg2_422_intra(VIDEO_STREAM *in, MACROBLOCK *out);
static void read_coded_block_mpeg2_444_intra(VIDEO_STREAM *in, MACROBLOCK *out);
static void read_coded_block_mpeg2_420_nonintra_pattern(VIDEO_STREAM *in, MACROBLOCK *out);
static void read_coded_block_mpeg1_420_nonintra_pattern(VIDEO_STREAM *in, MACROBLOCK *out);
static void read_coded_block_mpeg2_422_nonintra_pattern(VIDEO_STREAM *in, MACROBLOCK *out);
static void read_coded_block_mpeg2_444_nonintra_pattern(VIDEO_STREAM *in, MACROBLOCK *out);
static void read_coded_block_420_nonintra_nopattern(VIDEO_STREAM *in, MACROBLOCK *out);
static void read_coded_block_422_nonintra_nopattern(VIDEO_STREAM *in, MACROBLOCK *out);
static void read_coded_block_444_nonintra_nopattern(VIDEO_STREAM *in, MACROBLOCK *out);
static int get_coded_block_pattern(VIDEO_STREAM *in);
static void read_spatial_temporal_weight(VIDEO_STREAM *in, MACROBLOCK *out, READ_MACROBLOCK_OPTION *opt);
typedef void (* READ_CODED_BLOCK)(VIDEO_STREAM *, MACROBLOCK *);
int read_macroblock(VIDEO_STREAM *in, MACROBLOCK *out, READ_MACROBLOCK_OPTION *opt)
{
static const READ_CODED_BLOCK rcb[2][3][2][2] = {
{ /* mpeg-2 */
{ /* 420 */
{ /* nonintra */
read_coded_block_420_nonintra_nopattern,
read_coded_block_mpeg2_420_nonintra_pattern,
},{ /* intra */
read_coded_block_mpeg2_420_intra,
read_coded_block_mpeg2_420_intra,
},
}, { /* 422 */
{ /* nonintra */
read_coded_block_422_nonintra_nopattern,
read_coded_block_mpeg2_422_nonintra_pattern,
},{ /* intra */
read_coded_block_mpeg2_422_intra,
read_coded_block_mpeg2_422_intra,
},
}, { /* 444 */
{ /* nonintra */
read_coded_block_444_nonintra_nopattern,
read_coded_block_mpeg2_444_nonintra_pattern,
},{ /* intra */
read_coded_block_mpeg2_444_intra,
read_coded_block_mpeg2_444_intra,
},
},
},{ /* mpeg-1 */
{ /* 420 */
{ /* nonintra */
read_coded_block_420_nonintra_nopattern,
read_coded_block_mpeg1_420_nonintra_pattern,
},{ /* intra */
read_coded_block_mpeg1_420_intra,
read_coded_block_mpeg1_420_intra,
},
},{ /* 422 - dummy */
{ /* nonintra */
read_coded_block_420_nonintra_nopattern,
read_coded_block_mpeg1_420_nonintra_pattern,
},{ /* intra */
read_coded_block_mpeg1_420_intra,
read_coded_block_mpeg1_420_intra,
},
},{ /* 444 - dummy */
{ /* nonintra */
read_coded_block_420_nonintra_nopattern,
read_coded_block_mpeg1_420_nonintra_pattern,
},{ /* intra */
read_coded_block_mpeg1_420_intra,
read_coded_block_mpeg1_420_intra,
},
},
},
};
if(!read_macroblock_mode(in, out, opt)){
return 0;
}
if(out->macroblock_quant){
out->quantizer_scale_code = vs_get_bits(in, 5);
}
if(out->macroblock_motion_forward || (out->macroblock_intra && opt->concealment_motion_vectors)){
read_motion_vector(in, out, opt, 0);
}
if(out->macroblock_motion_backward){
read_motion_vector(in, out, opt, 1);
}
if(out->macroblock_intra && opt->concealment_motion_vectors){
vs_get_bits(in, 1); /* marker bit */
}
rcb[opt->mpeg1][opt->chroma_format-1][out->macroblock_intra][out->macroblock_pattern](in, out);
return 1;
}
int macroblock_to_read_block_option(MACROBLOCK *in, READ_BLOCK_OPTION *out)
{
out->macroblock_intra = in->macroblock_intra;
out->dct_type = in->dct_type;
if(in->macroblock_quant){
out->qw[0] = out->qw_table[in->quantizer_scale_code][0];
out->qw[1] = out->qw_table[in->quantizer_scale_code][1];
out->qw[2] = out->qw_table[in->quantizer_scale_code][2];
out->qw[3] = out->qw_table[in->quantizer_scale_code][3];
}
if(! in->macroblock_intra){
reset_dc_dct_predictor(out);
}
return 1;
}
int get_macroblock_address_increment(VIDEO_STREAM *in)
{
int r;
int code;
static const BASIC_VLC_ELEMENT table_a[] = {
{9,7},{8,7},
{7,5},{7,5},{7,5},{7,5},{6,5},{6,5},{6,5},{6,5},
{5,4},{5,4},{5,4},{5,4},{5,4},{5,4},{5,4},{5,4},
{4,4},{4,4},{4,4},{4,4},{4,4},{4,4},{4,4},{4,4},
{3,3},{3,3},{3,3},{3,3},{3,3},{3,3},{3,3},{3,3},
{3,3},{3,3},{3,3},{3,3},{3,3},{3,3},{3,3},{3,3},
{2,3},{2,3},{2,3},{2,3},{2,3},{2,3},{2,3},{2,3},
{2,3},{2,3},{2,3},{2,3},{2,3},{2,3},{2,3},{2,3},
{1,1},{1,1},{1,1},{1,1},{1,1},{1,1},{1,1},{1,1},
{1,1},{1,1},{1,1},{1,1},{1,1},{1,1},{1,1},{1,1},
{1,1},{1,1},{1,1},{1,1},{1,1},{1,1},{1,1},{1,1},
{1,1},{1,1},{1,1},{1,1},{1,1},{1,1},{1,1},{1,1},
{1,1},{1,1},{1,1},{1,1},{1,1},{1,1},{1,1},{1,1},
{1,1},{1,1},{1,1},{1,1},{1,1},{1,1},{1,1},{1,1},
{1,1},{1,1},{1,1},{1,1},{1,1},{1,1},{1,1},{1,1},
{1,1},{1,1},{1,1},{1,1},{1,1},{1,1},{1,1},{1,1},
};
static const BASIC_VLC_ELEMENT table_b[] = {
{33,11},{32,11},{31,11},{30,11},{29,11},{28,11},{27,11},{26,11},
{25,11},{24,11},{23,11},{22,11},{21,10},{21,10},{20,10},{20,10},
{19,10},{19,10},{18,10},{18,10},{17,10},{17,10},{16,10},{16,10},
{15,8},{15,8},{15,8},{15,8},{15,8},{15,8},{15,8},{15,8},
{14,8},{14,8},{14,8},{14,8},{14,8},{14,8},{14,8},{14,8},
{13,8},{13,8},{13,8},{13,8},{13,8},{13,8},{13,8},{13,8},
{12,8},{12,8},{12,8},{12,8},{12,8},{12,8},{12,8},{12,8},
{11,8},{11,8},{11,8},{11,8},{11,8},{11,8},{11,8},{11,8},
{10,8},{10,8},{10,8},{10,8},{10,8},{10,8},{10,8},{10,8},
};
r = 0;
code = vs_read_bits(in, 11);
while( (code = vs_read_bits(in, 11)) == 8 ){
r += 33;
vs_erase_bits(in, 11);
}
if(code > 95){
code = (code >> 4) - 6;
r += table_a[code].value;
vs_erase_bits(in, table_a[code].length);
}else if(code > 23){
code -= 24;
r += table_b[code].value;
vs_erase_bits(in, table_b[code].length);
}else{
r = 0;
}
return r;
}
int macroblock_to_mc_parameter(MACROBLOCK *in, MC_PARAMETER *out)
{
int r,s,t;
out->macroblock_motion_forward = in->macroblock_motion_forward;
out->macroblock_motion_backward = in->macroblock_motion_backward;
out->prediction_type = in->prediction_type;
for(r=0;r<2;r++){
for(s=0;s<2;s++){
for(t=0;t<2;t++){
out->PMV[r][s][t] = in->PMV[r][s][t];
}
out->DMV[r][s] = in->DMV[r][s];
out->motion_vertical_field_select[r][s] = in->motion_vertical_field_select[r][s];
}
}
return 1;
}
int macroblock_to_error_concealment_mc_parameter(MACROBLOCK *in, MC_PARAMETER *out)
{
int r,s,t;
out->macroblock_motion_forward = in->macroblock_motion_forward;
out->macroblock_motion_backward = in->macroblock_motion_backward;
out->prediction_type = in->prediction_type;
for(r=0;r<2;r++){
for(s=0;s<2;s++){
for(t=0;t<2;t++){
out->PMV[r][s][t] = in->PMV[r][s][t];
}
out->DMV[r][s] = in->DMV[r][s];
out->motion_vertical_field_select[r][s] = in->motion_vertical_field_select[r][s];
}
}
if(in->macroblock_intra){
out->macroblock_motion_forward = 1;
out->prediction_type = PREDICTION_TYPE_FRAME_BASED;
memset(out->PMV, 0, sizeof(out->PMV));
if(out->picture_structure == 2){
out->motion_vertical_field_select[0][0] = 1;
}else{
out->motion_vertical_field_select[0][0] = 0;
}
}
return 1;
}
int reset_motion_vector_predictor(MACROBLOCK *p)
{
int r,s,t;
for(r=0;r<2;r++){
for(s=0;s<2;s++){
for(t=0;t<2;t++){
p->PMV[r][s][t] = 0;
}
}
}
return 1;
}
static int read_macroblock_mode(VIDEO_STREAM *in, MACROBLOCK *out, READ_MACROBLOCK_OPTION *opt)
{
int code;
if(!opt->read_macroblock_type(in, out)){
return 0;
}
if(out->spatial_temporal_weight_code_flag){
read_spatial_temporal_weight(in, out, opt);
}
if(out->macroblock_motion_forward || out->macroblock_motion_backward){
if(opt->picture_structure == 3){
if(! opt->frame_predictive_frame_dct){
code = vs_get_bits(in, 2);
switch(code){
case 0:
return 0;
case 1:
out->prediction_type = PREDICTION_TYPE_FIELD_BASED;
if( (out->spatial_temporal_weight_class == 0) || (out->spatial_temporal_weight_class == 1) ){
out->motion_vector_count = 2;
}else{
out->motion_vector_count = 1;
}
out->motion_vector_format = MOTION_VECTOR_FORMAT_FIELD;
out->dual_prime_motion_vector = 0;
break;
case 2:
out->prediction_type = PREDICTION_TYPE_FRAME_BASED;
out->motion_vector_count = 1;
out->motion_vector_format = MOTION_VECTOR_FORMAT_FRAME;
out->dual_prime_motion_vector = 0;
break;
case 3:
out->prediction_type = PREDICTION_TYPE_DUAL_PRIME;
out->motion_vector_count = 1;
out->motion_vector_format = MOTION_VECTOR_FORMAT_FIELD;
out->dual_prime_motion_vector = 1;
}
}else{
out->prediction_type = PREDICTION_TYPE_FRAME_BASED;
out->motion_vector_count = 1;
out->motion_vector_format = MOTION_VECTOR_FORMAT_FRAME;
out->dual_prime_motion_vector = 0;
}
}else{
code = vs_get_bits(in, 2);
switch(code){
case 0:
return 0;
case 1:
out->prediction_type = PREDICTION_TYPE_FIELD_BASED;
out->motion_vector_count = 1;
out->motion_vector_format = MOTION_VECTOR_FORMAT_FIELD;
out->dual_prime_motion_vector = 0;
break;
case 2:
out->prediction_type = PREDICTION_TYPE_16x8_MC;
out->motion_vector_count = 2;
out->motion_vector_format = MOTION_VECTOR_FORMAT_FIELD;
out->dual_prime_motion_vector = 0;
break;
case 3:
out->prediction_type = PREDICTION_TYPE_DUAL_PRIME;
out->motion_vector_count = 1;
out->motion_vector_format = MOTION_VECTOR_FORMAT_FIELD;
out->dual_prime_motion_vector = 1;
break;
}
}
}else if(out->macroblock_intra && opt->concealment_motion_vectors){
out->motion_vector_count = 1;
out->dual_prime_motion_vector = 0;
if(opt->picture_structure == 3){
out->prediction_type = PREDICTION_TYPE_FRAME_BASED;
out->motion_vector_format = MOTION_VECTOR_FORMAT_FRAME;
}else{
out->prediction_type = PREDICTION_TYPE_FIELD_BASED;
out->motion_vector_format = MOTION_VECTOR_FORMAT_FIELD;
}
}else{
out->motion_vector_count = 1;
out->dual_prime_motion_vector = 0;
reset_motion_vector_predictor(out);
switch(opt->picture_structure){
case 1:
out->prediction_type = PREDICTION_TYPE_FIELD_BASED;
out->motion_vector_format = MOTION_VECTOR_FORMAT_FIELD;
out->motion_vertical_field_select[0][0] = 0;
break;
case 2:
out->prediction_type = PREDICTION_TYPE_FIELD_BASED;
out->motion_vector_format = MOTION_VECTOR_FORMAT_FIELD;
out->motion_vertical_field_select[0][0] = 1;
break;
case 3:
out->prediction_type = PREDICTION_TYPE_FRAME_BASED;
out->motion_vector_format = MOTION_VECTOR_FORMAT_FRAME;
break;
}
}
if(opt->frame_predictive_frame_dct){
out->dct_type = 0;
}else if( opt->picture_structure == 3 && (out->macroblock_intra || out->macroblock_pattern) ){
out->dct_type = vs_get_bits(in, 1);
}else{
out->dct_type = 0;
}
return 1;
}
int read_macroblock_type_snr_scalability(VIDEO_STREAM *in, MACROBLOCK *out)
{
int code;
code = vs_read_bits(in, 3);
if( (code >> 2) == 1 ){
out->macroblock_quant = 0;
out->macroblock_motion_forward = 0;
out->macroblock_motion_backward = 0;
out->macroblock_pattern = 1;
out->macroblock_intra = 0;
out->spatial_temporal_weight_code_flag = 0;
out->spatial_temporal_weight_class = 0;
vs_erase_bits(in, 1);
}else if( (code >> 1) == 1){
out->macroblock_quant = 1;
out->macroblock_motion_forward = 0;
out->macroblock_motion_backward = 0;
out->macroblock_pattern = 1;
out->macroblock_intra = 0;
out->spatial_temporal_weight_code_flag = 0;
out->spatial_temporal_weight_class = 0;
vs_erase_bits(in, 2);
}else if(code == 1){
out->macroblock_quant = 0;
out->macroblock_motion_forward = 0;
out->macroblock_motion_backward = 0;
out->macroblock_pattern = 0;
out->macroblock_intra = 0;
out->spatial_temporal_weight_code_flag = 0;
out->spatial_temporal_weight_class = 0;
vs_erase_bits(in, 3);
}else{
return 0;
}
return 1;
}
int read_macroblock_type_b_spatial_scalability(VIDEO_STREAM *in, MACROBLOCK *out)
{
int code;
code = vs_read_bits(in, 9);
if( (code >> 7) == 2 ){
out->macroblock_quant = 0;
out->macroblock_motion_forward = 1;
out->macroblock_motion_backward = 1;
out->macroblock_pattern = 0;
out->macroblock_intra = 0;
out->spatial_temporal_weight_code_flag = 0;
out->spatial_temporal_weight_class = 0;
vs_erase_bits(in, 2);
}else if( (code >> 7) == 3 ){
out->macroblock_quant = 0;
out->macroblock_motion_forward = 1;
out->macroblock_motion_backward = 1;
out->macroblock_pattern = 1;
out->macroblock_intra = 0;
out->spatial_temporal_weight_code_flag = 0;
out->spatial_temporal_weight_class = 0;
vs_erase_bits(in, 2);
}else if( (code >> 6) == 2 ){
out->macroblock_quant = 0;
out->macroblock_motion_forward = 0;
out->macroblock_motion_backward = 1;
out->macroblock_pattern = 0;
out->macroblock_intra = 0;
out->spatial_temporal_weight_code_flag = 0;
out->spatial_temporal_weight_class = 0;
vs_erase_bits(in, 3);
}else if( (code >> 6) == 3 ){
out->macroblock_quant = 0;
out->macroblock_motion_forward = 0;
out->macroblock_motion_backward = 1;
out->macroblock_pattern = 1;
out->macroblock_intra = 0;
out->spatial_temporal_weight_code_flag = 0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -