📄 video.c
字号:
/*mxFree(vid_stream->group.ext_data);*/ vid_stream->group.ext_data = NULL; } vid_stream->group.ext_data = get_ext_data(); } /* If next start code is user data, parse off user data. */ if (next_bits(32, USER_START_CODE)) { flush_bits32; if (vid_stream->group.user_data != NULL) { /*mxFree(vid_stream->group.user_data);*/ vid_stream->group.user_data = NULL; } vid_stream->group.user_data = get_ext_data(); } return PARSE_OK;}/* *-------------------------------------------------------------- * * ParsePicture -- * * Parses picture header. Marks picture to be presented * at particular time given a time stamp. * * Results: * Values from picture header put into video stream structure. * * Side effects: * Bit stream irreversibly parsed. * *-------------------------------------------------------------- */static intParsePicture(VidStream *vid_stream, TimeStamp time_stamp){ unsigned int data; int i; /* Flush header start code. */ flush_bits32; /* Parse off temporal reference. */ get_bits10(data); vid_stream->picture.temp_ref = data; /* Parse of picture type. */ get_bits3(data); vid_stream->picture.code_type = data; if ((vid_stream->picture.code_type == B_TYPE) && (No_B_Flag || (vid_stream->past == NULL) || (vid_stream->future == NULL))) return SKIP_PICTURE; if ((vid_stream->picture.code_type == P_TYPE) && (No_P_Flag || (vid_stream->future == NULL))) return SKIP_PICTURE;#ifdef ANALYSIS StartTime(); stat_a[0].frametype = vid_stream->picture.code_type; stat_a[0].number = 1; stat_a[0].totsize = 45; pictureSizeCount = bitCountRead();#endif /* Parse off vbv buffer delay value. */ get_bits16(data); vid_stream->picture.vbv_delay = data; /* If P or B type frame... */ if ((vid_stream->picture.code_type == 2) || (vid_stream->picture.code_type == 3)) { /* Parse off forward vector full pixel flag. */ get_bits1(data); if (data) vid_stream->picture.full_pel_forw_vector = TRUE; else vid_stream->picture.full_pel_forw_vector = FALSE; /* Parse of forw_r_code. */ get_bits3(data); /* Decode forw_r_code into forw_r_size and forw_f. */ vid_stream->picture.forw_r_size = data - 1; vid_stream->picture.forw_f = (1 << vid_stream->picture.forw_r_size); } /* If B type frame... */ if (vid_stream->picture.code_type == 3) { /* Parse off back vector full pixel flag. */ get_bits1(data); if (data) vid_stream->picture.full_pel_back_vector = TRUE; else vid_stream->picture.full_pel_back_vector = FALSE; /* Parse off back_r_code. */ get_bits3(data); /* Decode back_r_code into back_r_size and back_f. */ vid_stream->picture.back_r_size = data - 1; vid_stream->picture.back_f = (1 << vid_stream->picture.back_r_size); } /* Get extra bit picture info. */ if (vid_stream->picture.extra_info != NULL) { /*mxFree(vid_stream->picture.extra_info);*/ vid_stream->picture.extra_info = NULL; } vid_stream->picture.extra_info = get_extra_bit_info(); /* Goto next start code. */ next_start_code(); /* If start code is extension start code, parse off extension data. */ if (next_bits(32, EXT_START_CODE)) { flush_bits32; if (vid_stream->picture.ext_data != NULL) { /* mxFree(vid_stream->picture.ext_data);*/ vid_stream->picture.ext_data = NULL; } vid_stream->picture.ext_data = get_ext_data(); } /* If start code is user start code, parse off user data. */ if (next_bits(32, USER_START_CODE)) { flush_bits32; if (vid_stream->picture.user_data != NULL) { /*mxFree(vid_stream->picture.user_data);*/ vid_stream->picture.user_data = NULL; } vid_stream->picture.user_data = get_ext_data(); } /* Find a pict image structure in ring buffer not currently locked. */ i = 0; while (vid_stream->ring[i]->locked != 0) { if (++i >= RING_BUF_SIZE) { mexErrMsgTxt("Fatal error converting MPEG file."); } } /* Set current pict image structure to the one just found in ring. */ vid_stream->current = vid_stream->ring[i]; /* Set time stamp. */ vid_stream->current->show_time = time_stamp; /* Reset past macroblock address field. */ vid_stream->mblock.past_mb_addr = -1; return PARSE_OK;}/* *-------------------------------------------------------------- * * ParseSlice -- * * Parses off slice header. * * Results: * Values found in slice header put into video stream structure. * * Side effects: * Bit stream irreversibly parsed. * *-------------------------------------------------------------- */static intParseSlice(VidStream *vid_stream){ unsigned int data; /* Flush slice start code. */ flush_bits(24); /* Parse off slice vertical position. */ get_bits8(data); vid_stream->slice.vert_pos = data; /* Parse off quantization scale. */ get_bits5(data); vid_stream->slice.quant_scale = data; /* Parse off extra bit slice info. */ if (vid_stream->slice.extra_info != NULL) { /* mxFree(vid_stream->slice.extra_info);*/ vid_stream->slice.extra_info = NULL; } vid_stream->slice.extra_info = get_extra_bit_info(); /* Reset past intrablock address. */ vid_stream->mblock.past_intra_addr = -2; /* Reset previous recon motion vectors. */ vid_stream->mblock.recon_right_for_prev = 0; vid_stream->mblock.recon_down_for_prev = 0; vid_stream->mblock.recon_right_back_prev = 0; vid_stream->mblock.recon_down_back_prev = 0; /* Reset macroblock address. */ vid_stream->mblock.mb_address = ((vid_stream->slice.vert_pos - 1) * vid_stream->mb_width) - 1; /* Reset past dct dc y, cr, and cb values. */ vid_stream->block.dct_dc_y_past = 1024; vid_stream->block.dct_dc_cr_past = 1024; vid_stream->block.dct_dc_cb_past = 1024; return PARSE_OK;}/* *-------------------------------------------------------------- * * ParseMacroBlock -- * * Parseoff macroblock. Reconstructs DCT values. Applies * inverse DCT, reconstructs motion vectors, calculates and * set pixel values for macroblock in current pict image * structure. * * Results: * Here's where everything really happens. Welcome to the * heart of darkness. * * Side effects: * Bit stream irreversibly parsed off. * *-------------------------------------------------------------- */static intParseMacroBlock(VidStream *vid_stream){ int addr_incr; unsigned int data; int mask, i, recon_right_for, recon_down_for, recon_right_back, recon_down_back; int zero_block_flag; BOOLEAN mb_quant, mb_motion_forw, mb_motion_back, mb_pattern; int no_dith_flag = 0;#ifdef ANALYSIS mbSizeCount = bitCountRead();#endif /* * Parse off macroblock address increment and add to macroblock address. */ do { DecodeMBAddrInc(addr_incr); if (addr_incr == MB_ESCAPE) { vid_stream->mblock.mb_address += 33; addr_incr = MB_STUFFING; } } while (addr_incr == MB_STUFFING); vid_stream->mblock.mb_address += addr_incr; if (vid_stream->mblock.mb_address > (vid_stream->mb_height * vid_stream->mb_width - 1)) return SKIP_TO_START_CODE; /* * If macroblocks have been skipped, process skipped macroblocks. */ if (vid_stream->mblock.mb_address - vid_stream->mblock.past_mb_addr > 1) { if (vid_stream->picture.code_type == P_TYPE) ProcessSkippedPFrameMBlocks(vid_stream); else if (vid_stream->picture.code_type == B_TYPE) ProcessSkippedBFrameMBlocks(vid_stream); } /* Set past macroblock address to current macroblock address. */ vid_stream->mblock.past_mb_addr = vid_stream->mblock.mb_address; /* Based on picture type decode macroblock type. */ switch (vid_stream->picture.code_type) { case I_TYPE: DecodeMBTypeI(mb_quant, mb_motion_forw, mb_motion_back, mb_pattern, vid_stream->mblock.mb_intra); break; case P_TYPE: DecodeMBTypeP(mb_quant, mb_motion_forw, mb_motion_back, mb_pattern, vid_stream->mblock.mb_intra); break; case B_TYPE: DecodeMBTypeB(mb_quant, mb_motion_forw, mb_motion_back, mb_pattern, vid_stream->mblock.mb_intra); break; } /* If quantization flag set, parse off new quantization scale. */ if (mb_quant == TRUE) { get_bits5(data); vid_stream->slice.quant_scale = data; } /* If forward motion vectors exist... */ if (mb_motion_forw == TRUE) { /* Parse off and decode horizontal forward motion vector. */ DecodeMotionVectors(vid_stream->mblock.motion_h_forw_code); /* If horiz. forward r data exists, parse off. */ if ((vid_stream->picture.forw_f != 1) && (vid_stream->mblock.motion_h_forw_code != 0)) { get_bitsn(vid_stream->picture.forw_r_size, data); vid_stream->mblock.motion_h_forw_r = data; } /* Parse off and decode vertical forward motion vector. */ DecodeMotionVectors(vid_stream->mblock.motion_v_forw_code); /* If vert. forw. r data exists, parse off. */ if ((vid_stream->picture.forw_f != 1) && (vid_stream->mblock.motion_v_forw_code != 0)) { get_bitsn(vid_stream->picture.forw_r_size, data); vid_stream->mblock.motion_v_forw_r = data; } } /* If back motion vectors exist... */ if (mb_motion_back == TRUE) { /* Parse off and decode horiz. back motion vector. */ DecodeMotionVectors(vid_stream->mblock.motion_h_back_code); /* If horiz. back r data exists, parse off. */ if ((vid_stream->picture.back_f != 1) && (vid_stream->mblock.motion_h_back_code != 0)) { get_bitsn(vid_stream->picture.back_r_size, data); vid_stream->mblock.motion_h_back_r = data; } /* Parse off and decode vert. back motion vector. */ DecodeMotionVectors(vid_stream->mblock.motion_v_back_code); /* If vert. back r data exists, parse off. */ if ((vid_stream->picture.back_f != 1) && (vid_stream->mblock.motion_v_back_code != 0)) { get_bitsn(vid_stream->picture.back_r_size, data); vid_stream->mblock.motion_v_back_r = data; } }#ifdef ANALYSIS if (vid_stream->mblock.mb_intra) { stat_a[0].i_mbnum++; mbCBPPtr = stat_a[0].i_mbcbp; mbCoeffPtr = stat_a[0].i_mbcoeff; mbSizePtr = &(stat_a[0].i_mbsize); } else if (mb_motion_back && mb_motion_forw) { stat_a[0].bi_mbnum++; mbCBPPtr = stat_a[0].bi_mbcbp; mbCoeffPtr = stat_a[0].bi_mbcoeff; mbSizePtr = &(stat_a[0].bi_mbsize); } else if (mb_motion_back) { stat_a[0].b_mbnum++; mbCBPPtr = stat_a[0].b_mbcbp; mbCoeffPtr = stat_a[0].b_mbcoeff; mbSizePtr = &(stat_a[0].b_mbsize); } else { stat_a[0].p_mbnum++; mbCBPPtr = stat_a[0].p_mbcbp; mbCoeffPtr = stat_a[0].p_mbcoeff; mbSizePtr = &(stat_a[0].p_mbsize); }#endif /* If mblock pattern flag set, parse and decode CBP (code block pattern). */ if (mb_pattern == TRUE) { DecodeCBP(vid_stream->mblock.cbp); } /* Otherwise, set CBP to zero. */ else vid_stream->mblock.cbp = 0;#ifdef ANALYSIS mbCBPPtr[vid_stream->mblock.cbp]++;#endif /* Reconstruct motion vectors depending on picture type. */ if (vid_stream->picture.code_type == P_TYPE) { /* * If no forw motion vectors, reset previous and current vectors to 0. */ if (!mb_motion_forw) { recon_right_for = 0; recon_down_for = 0; vid_stream->mblock.recon_right_for_prev = 0; vid_stream->mblock.recon_down_for_prev = 0; } /* * Otherwise, compute new forw motion vectors. Reset previous vectors to * current vectors. */ else { ComputeForwVector(&recon_right_for, &recon_down_for); } } if (vid_stream->picture.code_type == B_TYPE) { /* Reset prev. and current vectors to zero if mblock is intracoded. */ if (vid_stream->mblock.mb_intra) { vid_stream->mblock.recon_right_for_prev = 0; vid_stream->mblock.recon_down_for_prev = 0; vid_stream->mblock.recon_right_back_prev = 0; vid_stream->mblock.recon_down_back_prev = 0; } else { /* If no forw vectors, current vectors equal prev. vectors. */ if (!mb_motion_forw) { recon_right_for = vid_stream->mblock.recon_right_for_prev; recon_down_for = vid_stream->mblock.recon_down_for_prev; } /* * Otherwise compute forw. vectors. Reset prev vectors to new values. */ else { ComputeForwVector(&recon_right_for, &recon_down_for); } /* If no back vectors, set back vectors to prev back vectors. */ if (!mb_motion_back) { recon_right_back = vid_stream->mblock.recon_right_back_prev; recon_down_back = vid_stream->mblock.recon_down_back_prev; } /* Otherwise compute new vectors and reset prev. back vectors. */ else { ComputeBackVector(&recon_right_back, &recon_down_back); } /* * Store vector existance flags in structure for possible skipped * macroblocks to follow. */ vid_stream->mblock.bpict_past_forw = mb_motion_forw; vid_stream->mblock.bpict_past_back = mb_motion_back; } } /* For each possible block in macroblock. */ if (ditherType == GRAY_DITHER || ditherType == MONO_DITHER || ditherType == MONO_THRESHOLD) { for (mask = 32, i = 0; i < 4; mask >>= 1, i++) { /* If block exists... */ if ((vid_stream->mblock.mb_intra) || (vid_stream->mblock.cbp & mask)) { zero_block_flag = 0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -