📄 mpeg_video.c
字号:
in->dec_buf.current = new_frame(in->seq.h_size, in->seq.v_size);
in->cur_prm.index = in->bwd_prm.index;
picture_header_to_output_parameter(&(in->pic), &(in->cur_prm));
if(in->pic.picture_coding_type != 3){
r = rotate_reference_frame(in, frame);
}
in->cur_prm.closed_gop = in->closed_gop;
if( in->pic.picture_coding_type == 3 ){
if( in->dec_buf.backward == NULL) {
delete_frame(in->dec_buf.current);
in->dec_prm->mc_parameter.first_field = 0;
return r;
}else if( in->dec_buf.forward == NULL ){
if(in->closed_gop){
/* closed_gop error concealment */
in->dec_buf.forward = in->dec_buf.backward;
}else{
delete_frame(in->dec_buf.current);
in->dec_prm->mc_parameter.first_field = 0;
return r;
}
}
}else if((in->pic.picture_coding_type == 2) && (in->dec_buf.forward == NULL)){
delete_frame(in->dec_buf.current);
in->dec_prm->mc_parameter.first_field = 0;
return r;
}
decode_picture(&(in->bitstream), &(in->dec_buf), in->dec_prm);
if(in->pic.has_picture_coding_extension && in->pic.pc.picture_structure != 3){
decode_2nd_field(in);
}
if(in->dec_buf.forward == in->dec_buf.backward){
/* teardown closed_gop error concealment */
in->dec_buf.forward = NULL;
}
if(in->pic.picture_coding_type == 3){
r = store_current_decoding_frame(in, frame);
}
return r;
}
static OUT_BUFFER_ELEMENT *store_forward_reference_frame(MPEG_VIDEO *in, __int64 frame)
{
delete_frame(in->dec_buf.forward);
in->dec_buf.forward = NULL;
return NULL;
}
static OUT_BUFFER_ELEMENT *store_backward_reference_frame(MPEG_VIDEO *in, __int64 frame)
{
OUT_BUFFER_ELEMENT *w;
OUT_BUFFER_ELEMENT *r;
FRAME *rff_buf;
r = NULL;
if(in->bwd_prm.repeat_first_field && (in->bwd_prm.top_field_first == in->disp_field_order)){
rff_buf = copy_frame(in->dec_buf.backward);
w = add_frame_out_buffer_with_resize(in, rff_buf, &(in->bwd_prm));
delete_frame(rff_buf);
if(in->bwd_prm.index == frame){
r = w;
}
in->bwd_prm.index += 1;
in->bwd_prm.top_field_first = !(in->disp_field_order);
in->bwd_prm.repeat_first_field = 0;
in->bwd_prm.picture_coding_type = 3;
}
if((in->bwd_prm.picture_coding_type == 1) && (in->bwd_prm.index != in->current.start_frame) ){
in->current.frame_count = in->bwd_prm.index - in->current.start_frame;
in->current.start_frame = in->bwd_prm.index;
}
w = add_frame_out_buffer_with_resize(in, in->dec_buf.backward, &(in->bwd_prm));
if(in->bwd_prm.index == frame){
r = w;
}
delete_frame(in->dec_buf.backward);
in->dec_buf.backward = NULL;
return r;
}
static OUT_BUFFER_ELEMENT *store_current_decoding_frame(MPEG_VIDEO *in, __int64 frame)
{
OUT_BUFFER_ELEMENT *w;
OUT_BUFFER_ELEMENT *r;
FRAME *rff_buf;
r = NULL;
if(in->cur_prm.repeat_first_field && (in->cur_prm.top_field_first == in->disp_field_order)){
rff_buf = copy_frame(in->dec_buf.current);
w = add_frame_out_buffer_with_resize(in, rff_buf, &(in->cur_prm));
delete_frame(rff_buf);
if(in->cur_prm.index == frame){
r = w;
}
in->cur_prm.index += 1;
in->cur_prm.top_field_first = !(in->disp_field_order);
in->cur_prm.repeat_first_field = 0;
in->cur_prm.picture_coding_type = 3;
in->bwd_prm.index += 1;
}
w = add_frame_out_buffer_with_resize(in, in->dec_buf.current, &(in->cur_prm));
delete_frame(in->dec_buf.current);
if(in->cur_prm.index == frame){
r = w;
}
in->bwd_prm.index += 1;
return r;
}
static OUT_BUFFER_ELEMENT *rotate_reference_frame(MPEG_VIDEO *in, __int64 frame)
{
OUT_BUFFER_ELEMENT *w;
OUT_BUFFER_ELEMENT *r;
FRAME *rff_buf;
OUTPUT_PARAMETER rff_prm;
r = NULL;
if(in->dec_buf.forward){
delete_frame(in->dec_buf.forward);
}
in->dec_buf.forward = in->dec_buf.backward;
in->dec_buf.backward = in->dec_buf.current;
in->fwd_prm = in->bwd_prm;
in->bwd_prm = in->cur_prm;
in->bwd_prm.index += 1;
if((in->fwd_prm.picture_coding_type == 1) && (in->fwd_prm.index != in->current.start_frame) ){
in->current.frame_count = in->fwd_prm.index - in->current.start_frame;
in->current.start_frame = in->fwd_prm.index;
}
if(in->fwd_prm.repeat_first_field && (in->fwd_prm.top_field_first == in->disp_field_order) ){
rff_buf = copy_frame(in->dec_buf.forward);
rff_prm = in->fwd_prm;
rff_prm.index += 1;
rff_prm.picture_coding_type = 3;
rff_prm.top_field_first = !(in->disp_field_order);
rff_prm.repeat_first_field = 0;
w = add_frame_out_buffer_with_resize(in, rff_buf, &rff_prm);
delete_frame(rff_buf);
if(rff_prm.index == frame){
r = w;
}
in->bwd_prm.index += 1;
}
if(in->dec_buf.forward){
w = add_frame_out_buffer_with_resize(in, in->dec_buf.forward, &(in->fwd_prm));
if(in->fwd_prm.index == frame){
r = w;
}
}
if(in->closed_gop == 1){
in->closed_gop = 2;
}else{
in->closed_gop = 0;
}
return r;
}
static int is_seek_required(MPEG_VIDEO *p, __int64 frame)
{
__int64 n,m;
if(p->dec_buf.backward){
if(p->bwd_prm.index == frame){
return 0;
}
}
n = p->current.start_frame + p->current.frame_count;
m = p->bwd_prm.index + 10;
if(n<m){
n = m;
}
if( (p->bwd_prm.index > 0) && (frame > p->bwd_prm.index) && (frame < n) ){
return 0;
}
return 1;
}
static void sequence_header_to_decode_picture_parameter(SEQUENCE_HEADER *in, DECODE_PICTURE_PARAMETER *out)
{
sequence_header_to_read_slice_header_option(in, &(out->slice_option));
sequence_header_to_read_macroblock_option(in, &(out->macroblock_option));
sequence_header_to_read_block_option(in, &(out->block_option));
sequence_header_to_mc_parameter(in, &(out->mc_parameter));
}
static void picture_header_to_decode_picture_parameter(PICTURE_HEADER *in, DECODE_PICTURE_PARAMETER *out)
{
picture_header_to_read_macroblock_option(in, &(out->macroblock_option));
picture_header_to_read_block_option(in, &(out->block_option));
picture_header_to_mc_parameter(in, &(out->mc_parameter));
}
static void decode_2nd_field(MPEG_VIDEO *p)
{
int code;
__int64 offset;
while(vs_next_start_code(&(p->bitstream))){
code = vs_read_bits(&(p->bitstream), 32);
if(code == 0x100){
offset = video_stream_tell(&(p->bitstream));
vs_erase_bits(&(p->bitstream), 32);
read_picture_header(&(p->bitstream), &(p->pic), &(p->pic_opt));
if(p->pic.has_picture_coding_extension && (p->pic.pc.picture_structure !=3) ){
picture_header_to_decode_picture_parameter(&(p->pic), p->dec_prm);
decode_picture(&(p->bitstream), &(p->dec_buf), p->dec_prm);
}else{
video_stream_seek(&(p->bitstream), offset, SEEK_SET);
}
return;
}else{
return;
}
}
}
static OUT_BUFFER_ELEMENT *add_frame_out_buffer_with_resize(MPEG_VIDEO *p, FRAME *data, OUTPUT_PARAMETER *frame_prm)
{
OUT_BUFFER_ELEMENT *r;
FRAME *rsz;
p->upsmp_c[frame_prm->progressive_frame](data);
rsz = resize(data, p->rsz_prm);
r = add_frame_out_buffer(&(p->out_buf), rsz, frame_prm);
if(rsz != data){
delete_frame(rsz);
}
return r;
}
static int is_registered_suffix(char *filepath)
{
int i;
static char *registered_suffix[] = {
".mpeg",
".mpg",
".m2p",
".mp2",
".vob",
".vro",
".m2v",
".m1v",
".mpv",
".ves",
".m2t",
".ssg",
".ts",
".bs",
"", /* sentinel */
};
i = 0;
while(registered_suffix[i][0]){
if(check_suffix(filepath, registered_suffix[i])){
return 1;
}
i += 1;
}
return 0;
}
static void setup_chroma_upsampling_function(MPEG_VIDEO *p, int chroma_format, int simd)
{
if(chroma_format == 1){
if(simd & M2V_CONFIG_USE_SSE2){
p->upsmp_c[0] = upsample_chroma_420i_sse2;
p->upsmp_c[1] = upsample_chroma_420p_sse2;
}else if(simd & M2V_CONFIG_USE_MMX){
p->upsmp_c[0] = upsample_chroma_420i_mmx;
p->upsmp_c[1] = upsample_chroma_420p_mmx;
}else{
p->upsmp_c[0] = upsample_chroma_420i;
p->upsmp_c[1] = upsample_chroma_420p;
}
}else{
p->upsmp_c[0] = upsample_chroma_none;
p->upsmp_c[1] = upsample_chroma_none;
}
}
static void setup_convert_function(MPEG_VIDEO *p, int chroma_format, int simd)
{
if(chroma_format == 3){
p->to_bgr = yuv444_to_bgr;
p->to_yuy2 = yuv444_to_yuy2;
}else{
if(simd & M2V_CONFIG_USE_SSE2){
p->to_bgr = yuv422_to_bgr_sse2;
p->to_yuy2 = yuv422_to_yuy2_sse2;
}else if(simd & M2V_CONFIG_USE_MMX){
p->to_bgr = yuv422_to_bgr_mmx;
p->to_yuy2 = yuv422_to_yuy2_mmx;
}else{
p->to_bgr = yuv422_to_bgr;
p->to_yuy2 = yuv422_to_yuy2;
}
}
}
static void setup_qw_function(DECODE_PICTURE_PARAMETER *p, int simd)
{
if(simd & M2V_CONFIG_USE_SSE2){
p->block_option.setup_qw = setup_qw_sse2;
}else if(simd & M2V_CONFIG_USE_MMX){
p->block_option.setup_qw = setup_qw_mmx;
}else{
p->block_option.setup_qw = setup_qw_nosimd;
}
}
static void setup_idct_function(DECODE_PICTURE_PARAMETER *p, M2V_CONFIG *prm)
{
if(prm->idct_type == M2V_CONFIG_IDCT_REFERENCE){
if(prm->simd & M2V_CONFIG_USE_SSE){
p->idct_func = idct_reference_sse;
}else{
p->idct_func = idct_reference;
}
}else if (prm->idct_type == M2V_CONFIG_IDCT_LLM_INT){
if(prm->simd & M2V_CONFIG_USE_MMX){
p->idct_func = idct_llm_mmx;
}else{
p->idct_func = idct_llm_int;
}
}else{
if(prm->simd & M2V_CONFIG_USE_SSE2){
p->idct_func = idct_ap922_sse2;
}else if(prm->simd & M2V_CONFIG_USE_SSE){
p->idct_func = idct_ap922_sse;
}else if(prm->simd & M2V_CONFIG_USE_MMX){
p->idct_func = idct_ap922_mmx;
}else{
p->idct_func = idct_ap922_int;
}
}
}
static void setup_mc_function(DECODE_PICTURE_PARAMETER *p, M2V_CONFIG *prm)
{
if(prm->simd & M2V_CONFIG_USE_SSE2){
p->mc_parameter.prediction_func = prediction_sse2;
}else if(prm->simd & M2V_CONFIG_USE_SSE){
p->mc_parameter.prediction_func = prediction_sse;
}else if(prm->simd & M2V_CONFIG_USE_MMX){
p->mc_parameter.prediction_func = prediction_mmx;
}else{
p->mc_parameter.prediction_func = prediction;
}
}
static void setup_add_block_function(DECODE_PICTURE_PARAMETER *p, M2V_CONFIG *prm)
{
if(prm->simd & M2V_CONFIG_USE_MMX){
p->add_block_func = add_block_data_to_frame_mmx;
}else{
p->add_block_func = add_block_data_to_frame;
}
}
static void clear_output_parameters(MPEG_VIDEO *p)
{
memset(&(p->fwd_prm), 0, sizeof(OUTPUT_PARAMETER));
memset(&(p->cur_prm), 0, sizeof(OUTPUT_PARAMETER));
memset(&(p->bwd_prm), 0, sizeof(OUTPUT_PARAMETER));
p->fwd_prm.index = p->current.start_frame - 1;
p->bwd_prm.index = p->current.start_frame - 1;
}
static void setup_m2v_config(M2V_CONFIG *p)
{
p->simd = get_simd_mode();
p->bt601 = get_color_conversion_type();
p->yuy2 = get_yuy2_mode();
p->aspect_ratio = get_resize_mode();
p->field_mode = get_field_mode();
p->idct_type = get_idct_type();
p->color_matrix = get_color_matrix();
p->gl = get_gl_mode();
}
static void setup_field_order(MPEG_VIDEO *p, M2V_CONFIG *prm)
{
switch(prm->field_mode){
case M2V_CONFIG_FRAME_KEEP_ORIGINAL:
p->disp_field_order = p->orig_field_order;
break;
case M2V_CONFIG_FRAME_TOP_FIRST:
p->disp_field_order = TOP_FIELD_FIRST;
break;
case M2V_CONFIG_FRAME_BOTTOM_FIRST:
p->disp_field_order = BOTTOM_FIELD_FIRST;
break;
default:
p->disp_field_order = p->orig_field_order;
}
if(p->disp_field_order != p->orig_field_order){
p->total -= 1;
}
}
static void resize_parameter_to_bgr_conversion_parameter(RESIZE_PARAMETER *in, BGR_CONVERSION_PARAMETER *out)
{
if(in == NULL){
return;
}
out->prm.width = in->l.width;
out->prm.height = in->l.height;
out->prm.in_step = in->l.out_step;
out->prm.c_offset = in->c.out_offset;
}
static YUY2_CONVERT select_yuy2_convert_function(int simd)
{
YUY2_CONVERT r;
r = yuy2_convert;
if(simd & M2V_CONFIG_USE_SSE2){
r = yuy2_convert_sse2;
}else if(simd & M2V_CONFIG_USE_SSE){
r = yuy2_convert_mmx;
}else if(simd & M2V_CONFIG_USE_MMX){
r = yuy2_convert_mmx;
}
return r;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -