#ifndef D_FRAME_H #define D_FRAME_H #include #include #include #include #include #include "Constants.h" #include "D_GOB.h" #include "D_Slice.h" #include "PSC_Fifo.h" #include "Tree.h" #include "Yuv_video.h" #include "SAC.h" #include "Frameq.h" #include "yuv_frame.h" #ifdef WIN32 #include #define pthread_mutex_t CRITICAL_SECTION #define pthread_t DWORD #else #include #endif using namespace std; // These are used by Entropy Decoder static const char* _MCBPCI_Table[9] = // For MCBPC I picture VLC coding {"1","001","010","011","0001","000001","000010","000011","000000001"}; static const char* _MCBPCP_Table[25] = // For MCBPC P picture VLC coding {"1","0011","0010","000101","011", "0000111","0000110","000000101","010","0000101", "0000100","00000101","00011","00000100","00000011", "0000011","000100","000000100","000000011","000000010", "000000001","00000000010","0000000001100","0000000001110","0000000001111"}; static const char* _CBPY_Table[16] = // For CBPY VLC coding {"0011","00101","00100","1001", "00011","0111","000010","1011", "00010","000011","0101","1010", "0100","1000","0110","11"}; static const char* _MVD_Table[64] = // MVD VLC coding {"0000000000101","0000000000111","000000000101","000000000111", "000000001001","000000001011","000000001101","000000001111", "00000001001","00000001011","00000001101","00000001111", "00000010001","00000010011","00000010101","00000010111", "00000011001","00000011011","00000011101","00000011111", "00000100001","00000100011","0000010011","0000010101", "0000010111","00000111","00001001","00001011", "0000111","00011","0011","011", "1","010","0010","00010", "0000110","00001010","00001000","00000110", "0000010110","0000010100","0000010010","00000100010", "00000100000","00000011110","00000011100","00000011010", "00000011000","00000010110","00000010100","00000010010", "00000010000","00000001110","00000001100","00000001010", "00000001000","000000001110","000000001100","000000001010", "000000001000","000000000110","000000000100","0000000000110"}; static const char* _TCOEF_Table[103] = // TCOEF VLC coding {"10","1111","010101","0010111","00011111", "000100101","000100100","0000100001","0000100000","00000000111", "00000000110","00000100000","110","010100","00011110", "0000001111","00000100001","000001010000","1110","00011101", "0000001110","000001010001","01101","000100011","0000001101", "01100","000100010","000001010010","01011","0000001100", "000001010011","010011","0000001011","000001010100","010010", "0000001010","010001","0000001001","010000","0000001000", "0010110","000001010101","0010101","0010100","00011100", "00011011","000100001","000100000","000011111","000011110", "000011101","000011100","000011011","000011010","00000100010", "00000100011","000001010110","000001010111","0111","000011001", "00000000101","001111","00000000100","001110","001101", "001100","0010011","0010010","0010001","0010000", "00011010","00011001","00011000","00010111","00010110", "00010101","00010100","00010011","000011000","000010111", "000010110","000010101","000010100","000010011","000010010", "000010001","0000000111","0000000110","0000000101","0000000100", "00000100100","00000100101","00000100110","00000100111","000001011000", "000001011001","000001011010","000001011011","000001011100","000001011101", "000001011110","000001011111","0000011"}; static const short int _RunLevel[103][2] = // Transform Coefficients run-level lookup table { 0,1, 0,2, 0,3, 0,4, 0,5, 0,6, 0,7, 0,8, 0,9, 0,10, 0,11, 0,12, 1,1, 1,2, 1,3, 1,4, 1,5, 1,6, 2,1, 2,2, 2,3, 2,4, 3,1, 3,2, 3,3, 4,1, 4,2, 4,3, 5,1, 5,2, 5,3, 6,1, 6,2, 6,3, 7,1, 7,2, 8,1, 8,2, 9,1, 9,2, 10,1, 10,2, 11,1, 12,1, 13,1, 14,1, 15,1, 16,1, 17,1, 18,1, 19,1, 20,1, 21,1, 22,1, 23,1, 24,1, 25,1, 26,1, 0,1, 0,2, 0,3, 1,1, 1,2, 2,1, 3,1, 4,1, 5,1, 6,1, 7,1, 8,1, 9,1, 10,1, 11,1, 12,1, 13,1, 14,1, 15,1, 16,1, 17,1, 18,1, 19,1, 20,1, 21,1, 22,1, 23,1, 24,1, 25,1, 26,1, 27,1, 28,1, 29,1, 30,1, 31,1, 32,1, 33,1, 34,1, 35,1, 36,1, 37,1, 38,1, 39,1, 40,1, 0,0}; static int MBA_Length[5] = { 6, 7, 9, 11, 13 }; static int SWI_Length[5] = { 4, 4, 5, 6, 7 }; class D_Frame { // data members are sorted according to their element data size protected: D_GOB *_GOB_list; D_Slice *_SLICE_list; D_Macroblock *_MB_list; D_Block *_BLK_list; FILE *lfile; bool _rtp_header; void AttachRTPHeader(PSC_Fifo &bit_ostream, bool end); int _fr_num, _fr_to_skip, _trb, _trd; int _picture_size, _picture_size_quarter; int _frame_xsize, _frame_ysize, _buffer_size; int _frame_xsize_half, _frame_ysize_half; int _GOB_Y_offset, _GOB_UV_offset; int _seg_num, _SLICE_per_frame, _Segment_per_frame; int _MB_per_gob, _GOB_per_frame; int _pquant, _dbquant; int _PB_offset; bool _encode_mode; // Temporal Routines' variables unsigned short _current_MAD; unsigned short _min_MAD; short _thresh_no_residue; short _thresh_large; // Picture Buffer short *_fast_frame; // 1D representation, (decoded) residue frame buffer short *_evil_predict_frame; // 1D representation, predict frame in evil speed mode short *_recov_frame; // 1D representation, recovered frame or reconstructued frame short *_zigzaged_central; // 1D representation, zigzaged (transformed) coefficients // Macroblock parameters short *_mtype, *_mquant, *_bquant; short *_mv_type1, *_mv_x1, *_mv_y1; short *_mv_type2, *_mv_x2, *_mv_y2; short *_mv_type3, *_mv_x3, *_mv_y3; short *_mv_type4, *_mv_x4, *_mv_y4; short *_mcbpc, *_mcbpy, *_mcbpb; short *_zero_mv_type, *_zero_mv_x, *_zero_mv_y; short *_mvd_type, *_mvd_x, *_mvd_y; // Delta motion vector short *_mv_type1_f, *_mv_x1_f, *_mv_y1_f; // Forward & Backward motion vectors short *_mv_type1_b, *_mv_x1_b, *_mv_y1_b; short *_mv_type2_f, *_mv_x2_f, *_mv_y2_f; short *_mv_type2_b, *_mv_x2_b, *_mv_y2_b; short *_mv_type3_f, *_mv_x3_f, *_mv_y3_f; short *_mv_type3_b, *_mv_x3_b, *_mv_y3_b; short *_mv_type4_f, *_mv_x4_f, *_mv_y4_f; short *_mv_type4_b, *_mv_x4_b, *_mv_y4_b; short *_mv_type_uv_f, *_mv_uvx_f, *_mv_uvy_f; // Chrominance motion vectors short *_mv_type_uv_b, *_mv_uvx_b, *_mv_uvy_b; // Annex K & R: Video Segment data structure // Slice level buffer short *_slice_size, *_slice_MBA; // Macroblock level buffer short *_fake_ID; short *_seg_ID, *_seg_size; short *_right_span, *_left_span; short *_mvx0_high, *_mvx0_low; short *_mvx1_high, *_mvx1_low; short *_mvx2_high, *_mvx2_low; short *_mvx3_high, *_mvx3_low; short *_mvx4_high, *_mvx4_low; short *_mvy0_high, *_mvy0_low; short *_mvy1_high, *_mvy1_low; short *_mvy2_high, *_mvy2_low; short *_mvy3_high, *_mvy3_low; short *_mvy4_high, *_mvy4_low; short *_x_bound_high, *_x_bound_low; short *_y_bound_high, *_y_bound_low; // Dynamically Allocated Memory unsigned char *_this_2D_frame; // 2D representation, storing original YUV data unsigned char *_this_1D_frame; // 1D representation, storing original YUV data unsigned char *_shift_frame; // 1D motion vector pointed data for each macroblock unsigned char *_padded_UMV_frame; unsigned char *_ISD_extrapolated_frame; // frames needed with isd + apb unsigned char *_ISD_extrapolated_frame_half_full; unsigned char *_ISD_extrapolated_frame_full_half; unsigned char *_ISD_extrapolated_frame_half_half; unsigned char *_ptr_ISD_extrapolated_frame; // pointer to index array unsigned char *_ptr_ISD_extrapolated_frame_half_full; unsigned char *_ptr_ISD_extrapolated_frame_full_half; unsigned char *_ptr_ISD_extrapolated_frame_half_half; // Data structures to build sub_pixel interpolated data unsigned char *_left_shift; // 2D representation unsigned char *_upper_shift; // 2D representation unsigned char *_upper_left_shift; // 2D representation unsigned char *_decoded_frame; // 2D representation; aka _decoded_frame_full_full unsigned char *_decoded_frame_half_full; // 2D representation unsigned char *_decoded_frame_full_half; // 2D representation unsigned char *_decoded_frame_half_half; // 2D representation unsigned char *_padded_UMV_frame_half_full; unsigned char *_padded_UMV_frame_full_half; unsigned char *_padded_UMV_frame_half_half; unsigned char *_padded_left_shift; unsigned char *_padded_upper_shift; unsigned char *_padded_upper_left_shift; bool _Created_Data_Structures; bool *_cgi; // GOB Mode Decision Support : Coded GOB Indicator bool *_cmi; // Macroblock Mode Decision Support: Coded Macroblock Indicator bool *_flag_zero_mv; bool _ME_enabled, _inter_frame_mode, _RCONTROL; bool _coded_mvd_flag, _PB_Ppicture_flag; bool _reset_segment_flag; // Annex K & R: Video Segment data structure bool *_mvx_border_high, *_mvx_border_low; // Used for advanced prediction mode bool *_mvy_border_high, *_mvy_border_low; // Advanced Options Flags bool _advanced_prediction_mode, _AP_conditions_checked; bool _evil_speed_mode; bool _forward_error_correction_mode; bool _independent_segment_mode; bool _PB_frame_mode, _PB_conditions_checked; bool _reference_picture_selection; bool _slice_mode, _rectangular_submode, _arbitrary_order_submode; bool _syntax_arithmetic_coding_mode, _SAC_conditions_checked; bool _unrestricted_motion_vector_mode, _UMV_conditions_checked; // Intialization routines void Init_Structure(void); void Initializer(void); void Fast_Structure(void); void Fast_Decoded_Structure(void); void Fast_Differential_Motion_Vector(void); void Transform_2D_To_1D(void); void Evil_Predict_Frame(void); void Reset_MQuant(void); void Temporal_Prediction_Module(void); void Temporal_Compression_Control(void); void Temporal_Compresser(void); void Set_MCBP(void); void Image_Recovery_Module(void); void Subpixel_Interpolation_Module(void); void Transform_1D_To_2D(void); // Entropy Encoder void Entropy_Encoder(PSC_Fifo &bit_ostream); // Motion Estimation void Motion_Estimation(void); void Distance_ME(unsigned char *prev_frame, int ysn, int xsn, int yso, int xso); void Three_Step_Search_ME(int x1, int y1, int x2, int y2, int *x3, int *y3, int blocksize, int ylow, int yhigh, int xlow, int xhigh); void Four_Step_Search_ME(int x1, int y1, int x2, int y2, int *x3, int *y3, int blocksize, int ylow, int yhigh, int xlow, int xhigh); int Full_Search_ME(int ysn, int xsn, int yso, int xso, int *xmot, int *ymot, int blocksize, int ylow, int yhigh, int xlow, int xhigh); int Voting_ME(int current_posy, int current_posx, int *medianx, int *mediany); int Voting_ME(int current_posy, int current_posx, int *medianx, int *mediany, int whichblock); int Median_ME(int a, int b, int c); // Annex D: Unrestricted Motion Vector Mode void Make_UMV_Padded_Frame(unsigned char * source_frame); void Motion_Estimation(bool umv_mode); void Distance_ME(unsigned char *prev_frame, int ysn, int xsn, int yso, int xso, bool umv_mode); void Three_Step_Search_ME(int x1, int y1, int x2, int y2, int *x3, int *y3, bool umv_mode); void Four_Step_Search_ME(int x1, int y1, int x2, int y2, int *x3, int *y3, bool umv_mode); // Annex F: Advanced Prediction; Overlapped Motion Compensation void Make_OPMC_Frame(bool encoder); void Help_OPMC(short *type0, short *typetop, short *typebottom, short *typeleft, short *typeright, unsigned char **res0, unsigned char **restop, unsigned char **resbottom, unsigned char **resleft, unsigned char **resright); // Annex G: PB Frame void Dump(bool P_picture); void Fast_PB_Structure(void); void Transform_1D_To_2D(bool P_picture); void Interpolate_Bpicture_Motion_Vectors(void); void Temporal_Prediction_Module(bool PB_AP); void Temporal_Compresser(bool P_picture); void Image_Recovery_Module(bool P_picture); void Set_MCBPB(void); void Transform_2D_To_1D(bool P_picture); // Annex K: Slice Structure void Fast_Slice_Structure(void); void Reset_Segment(void); void Update_Segment(void); void Sort_Segment(int l, int r); // Annex N: Reference Picture Selection void AssignReferenceFrames(void); void StoreDecodedFrames(void); void Fast_RPS_Structure(void); int GetReferenceIndex(void); void VerifyContent(void); int _max_frame_stored, _frame_count, _ref_index; int *_trp; FrameQueue *_prev_frames, *_prev_half_full, *_prev_full_half, *_prev_half_half; // Annex R: Independent Segment Decoding void Make_ISD_Extrapolated_Frame(short x_low, short x_high, short y_low, short y_high); void Make_OPMC_Segment(void); void Decode_OPMC_Segment(void); void Help_OPMC(short *type0, short *typetop, short *typebottom, short *typeleft, short *typeright, unsigned char **res0, unsigned char **restop, unsigned char **resbottom, unsigned char **resleft, unsigned char **resright, bool isd_apm); // Entropy Decoder Tree* _MCBPCI_Tree; Tree* _MCBPCP_Tree; Tree* _CBPY_Tree; Tree* _MVD_Tree; Tree* _TCOEF_Tree; bool _ed_bits[32]; // Temporary bit storage short _ed_quant; // Current Quant // For Header_Decode short _ed_header; // Decoded header bool _want_header; // For Picture_Decode bool _plusptype; // Plus PTYPE has been sent bool _psc_found; // PSC header is not empty int _ed_tr, _ed_last_tr; // Temporal Reference int _ed_ptype, _ed_last_ptype; // Type Information int _ed_ciftype; // Bits 6-8 of PTYPE // For GOB_Decode int _ed_gn, _ed_last_gn; // Group number int _ed_gfid; // GOB Frame ID int _max_gn; // (# of GN's in a picture) - 1; // For MB_Decode int _ed_mba; // Macroblock Address int _max_mba; // (# of MB's in a GOB) - 1 symbol *sac; public: static int _sformat; static int _pskipped; char* _ed_outfilename; // Encoder routines D_Frame(FILE *); D_Frame(void); ~D_Frame(void); void Create_Data_Structure(const bool encode); void Set_Skip(const int skip); void Set_PQuant(const int pquant, const int dbquant); void Enable_ME(void); void Disable_ME(void); void Set_Frame_Mode_INTER(void); void Set_Frame_Mode_INTRA(void); //Advanced Optional Modes void Enable_AP_Mode(void); void Enable_ES_Mode(void); void Enable_FEC_Mode(void); void Enable_ISD_Mode(void); void Enable_PB_Mode(void); void Enable_RPS_Mode(void); void Enable_SAC_Mode(void); void Enable_SLICE_Mode(const bool rect_submode, const bool arbitrary_submode); void Enable_UMV_Mode(void); void Disable_AP_Mode(void); void Disable_ES_Mode(void); void Disable_FEC_Mode(void); void Disable_ISD_Mode(void); void Disable_PB_Mode(void); void Disable_RPS_Mode(void); void Disable_SAC_Mode(void); void Disable_SLICE_Mode(void); void Disable_UMV_Mode(void); void Formal_Verify_AP_Preconditions(void); void Formal_Verify_PB_Preconditions(void); void Formal_Verify_SAC_Preconditions(void); void Formal_Verify_UMV_Preconditions(void); void Encode_Frame(yuv_video *yuv_ostream, yuv_video *yuv_istream, PSC_Fifo &bit_ostream, const int yuv_fr_index); void Encode_Frame(yuv_video *yuv_ostream, yuv_video *yuv_istream, PSC_Fifo &bit_ostream, const int skip_override, const int P_fr_index); // Decoder routines void Initialize_Entropy_Decoder(void); void Destroy_Entropy_Decoder(void); bool Decode_Bit(PSC_Fifo &input); bool Decode_Header(PSC_Fifo &input, bool &want_header); bool Decode_Picture(PSC_Fifo &input, yuv_video &yuv_post); bool Decode_GOB(PSC_Fifo &input); bool Decode_Slice(PSC_Fifo &input, bool psc_found); bool Decode_MB(PSC_Fifo &input); bool Decode_SAC_MB(PSC_Fifo &input, symbol *); void SendToPlayer(void); vector *framevec; vector *indexvec; pthread_mutex_t *vmutex; int id; }; #endif