📄 h264ce.cpp
字号:
// H264CE.cpp : Defines the entry point for the application.
//
#include "stdafx.h"
#include "H264CE.h"
#include <commctrl.h>
#include <aygshell.h>
#include <sipapi.h>
//进行H264解码的包含文件、定义以及变量
#include "common.h"
#include "dsputil.h"
#include "avcodec.h"
#include "mpegvideo.h"
#include "h264data.h"
#include "golomb.h"
#include "cabac.h"
#include <stdlib.h> //Add by ty
#include <stdio.h> //Add by ty
#define MAX_LOADSTRING 100
// Global Variables:
HINSTANCE g_hInst; // The current instance
HWND g_hwndCB; // The command bar handle
static SHACTIVATEINFO s_sai;
// Forward declarations of functions included in this code module:
ATOM MyRegisterClass (HINSTANCE, LPTSTR);
BOOL InitInstance (HINSTANCE, int);
LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM);
LRESULT CALLBACK About (HWND, UINT, WPARAM, LPARAM);
HWND CreateRpCommandBar(HWND);
//H264相关函数和变量
//解码线程函数
DWORD DecodeThread(void *para);
HANDLE hDecodeThread;
DWORD dwThreadID;
//GAPI显示以及硬件按键结构体变量
GXDisplayProperties g_gxdp; // GX struct
GXKeyList g_gxkl; // GX struct
//GAPI显示函数
BOOL m_bGapi;
BOOL OpenGAPI(HWND* Wnd);
void Blt(int x,int y,int width,int height,unsigned char* data);
BOOL CloseGAPI();
typedef struct THDP
{
HWND hWnd;
TCHAR *File;
}THDP;
#define interlaced_dct interlaced_dct_is_a_bad_name#define mb_intra mb_intra_isnt_initalized_see_mb_type#define LUMA_DC_BLOCK_INDEX 25#define CHROMA_DC_BLOCK_INDEX 26#define CHROMA_DC_COEFF_TOKEN_VLC_BITS 8#define COEFF_TOKEN_VLC_BITS 8#define TOTAL_ZEROS_VLC_BITS 9#define CHROMA_DC_TOTAL_ZEROS_VLC_BITS 3#define RUN_VLC_BITS 3#define RUN7_VLC_BITS 6#define MAX_SPS_COUNT 32#define MAX_PPS_COUNT 256#define MAX_MMCO_COUNT 66/** * Sequence parameter set */typedef struct SPS{ int profile_idc; int level_idc; int log2_max_frame_num; ///< log2_max_frame_num_minus4 + 4 int poc_type; ///< pic_order_cnt_type int log2_max_poc_lsb; ///< log2_max_pic_order_cnt_lsb_minus4 int delta_pic_order_always_zero_flag; int offset_for_non_ref_pic; int offset_for_top_to_bottom_field; int poc_cycle_length; ///< num_ref_frames_in_pic_order_cnt_cycle int ref_frame_count; ///< num_ref_frames int gaps_in_frame_num_allowed_flag; int mb_width; ///< frame_width_in_mbs_minus1 + 1 int mb_height; ///< frame_height_in_mbs_minus1 + 1 int frame_mbs_only_flag; int mb_aff; ///<mb_adaptive_frame_field_flag int direct_8x8_inference_flag; int crop; ///< frame_cropping_flag int crop_left; ///< frame_cropping_rect_left_offset int crop_right; ///< frame_cropping_rect_right_offset int crop_top; ///< frame_cropping_rect_top_offset int crop_bottom; ///< frame_cropping_rect_bottom_offset int vui_parameters_present_flag; AVRational sar; short offset_for_ref_frame[256]; //FIXME dyn aloc?}SPS;/** * Picture parameter set */typedef struct PPS{ int sps_id; int cabac; ///< entropy_coding_mode_flag int pic_order_present; ///< pic_order_present_flag int slice_group_count; ///< num_slice_groups_minus1 + 1 int mb_slice_group_map_type; int ref_count[2]; ///< num_ref_idx_l0/1_active_minus1 + 1 int weighted_pred; ///< weighted_pred_flag int weighted_bipred_idc; int init_qp; ///< pic_init_qp_minus26 + 26 int init_qs; ///< pic_init_qs_minus26 + 26 int chroma_qp_index_offset; int deblocking_filter_parameters_present; ///< deblocking_filter_parameters_present_flag int constrained_intra_pred; ///< constrained_intra_pred_flag int redundant_pic_cnt_present; ///< redundant_pic_cnt_present_flag}PPS;/** * Memory management control operation opcode. */typedef enum MMCOOpcode{ MMCO_END=0, MMCO_SHORT2UNUSED, MMCO_LONG2UNUSED, MMCO_SHORT2LONG, MMCO_SET_MAX_LONG, MMCO_RESET, MMCO_LONG,} MMCOOpcode;/** * Memory management control operation. */typedef struct MMCO{ MMCOOpcode opcode; int short_frame_num; int long_index;} MMCO;/** * H264Context */typedef struct H264Context{ MpegEncContext s; int nal_ref_idc; int nal_unit_type;#define NAL_SLICE 1#define NAL_DPA 2#define NAL_DPB 3#define NAL_DPC 4#define NAL_IDR_SLICE 5#define NAL_SEI 6#define NAL_SPS 7#define NAL_PPS 8#define NAL_PICTURE_DELIMITER 9#define NAL_FILTER_DATA 10 uint8_t *rbsp_buffer; int rbsp_buffer_size; int chroma_qp; //QPc int prev_mb_skiped; //FIXME remove (IMHO not used) //prediction stuff int chroma_pred_mode; int intra16x16_pred_mode; int8_t intra4x4_pred_mode_cache[5*8]; int8_t (*intra4x4_pred_mode)[8]; void (*pred4x4 [9+3])(uint8_t *src, uint8_t *topright, int stride);//FIXME move to dsp? void (*pred8x8 [4+3])(uint8_t *src, int stride); void (*pred16x16[4+3])(uint8_t *src, int stride); unsigned int topleft_samples_available; unsigned int top_samples_available; unsigned int topright_samples_available; unsigned int left_samples_available; uint8_t (*top_border)[16+2*8]; uint8_t left_border[17+2*9]; /** * non zero coeff count cache. * is 64 if not available. */ uint8_t non_zero_count_cache[6*8]; uint8_t (*non_zero_count)[16]; /** * Motion vector cache. */ int16_t mv_cache[2][5*8][2]; int8_t ref_cache[2][5*8];#define LIST_NOT_USED -1 //FIXME rename?#define PART_NOT_AVAILABLE -2 /** * is 1 if the specific list MV&references are set to 0,0,-2. */ int mv_cache_clean[2]; int block_offset[16+8]; int chroma_subblock_offset[16]; //FIXME remove uint16_t *mb2b_xy; //FIXME are these 4 a good idea? uint16_t *mb2b8_xy; int b_stride; int b8_stride; int halfpel_flag; int thirdpel_flag; int unknown_svq3_flag; int next_slice_index; SPS sps_buffer[MAX_SPS_COUNT]; SPS sps; ///< current sps PPS pps_buffer[MAX_PPS_COUNT]; /** * current pps */ PPS pps; //FIXME move tp Picture perhaps? (->no) do we need that? int slice_num; uint8_t *slice_table_base; uint8_t *slice_table; ///< slice_table_base + mb_stride + 1 int slice_type; int slice_type_fixed; //interlacing specific flags int mb_field_decoding_flag; int sub_mb_type[4]; //POC stuff int poc_lsb; int poc_msb; int delta_poc_bottom; int delta_poc[2]; int frame_num; int prev_poc_msb; ///< poc_msb of the last reference pic for POC type 0 int prev_poc_lsb; ///< poc_lsb of the last reference pic for POC type 0 int frame_num_offset; ///< for POC type 2 int prev_frame_num_offset; ///< for POC type 2 int prev_frame_num; ///< frame_num of the last pic for POC type 1/2 /** * frame_num for frames or 2*frame_num for field pics. */ int curr_pic_num; /** * max_frame_num or 2*max_frame_num for field pics. */ int max_pic_num; //Weighted pred stuff int luma_log2_weight_denom; int chroma_log2_weight_denom; int luma_weight[2][16]; int luma_offset[2][16]; int chroma_weight[2][16][2]; int chroma_offset[2][16][2]; //deblock int deblocking_filter; ///< disable_deblocking_filter_idc with 1<->0 int slice_alpha_c0_offset; int slice_beta_offset; int redundant_pic_count; int direct_spatial_mv_pred; /** * num_ref_idx_l0/1_active_minus1 + 1 */ int ref_count[2];// FIXME split for AFF Picture *short_ref[16]; Picture *long_ref[16]; Picture default_ref_list[2][32]; Picture ref_list[2][32]; //FIXME size? Picture field_ref_list[2][32]; //FIXME size? /** * memory management control operations buffer. */ MMCO mmco[MAX_MMCO_COUNT]; int mmco_index; int long_ref_count; ///< number of actual long term references int short_ref_count; ///< number of actual short term references //data partitioning GetBitContext intra_gb; GetBitContext inter_gb; GetBitContext *intra_gb_ptr; GetBitContext *inter_gb_ptr; DCTELEM mb[16*24] __align8; /** * Cabac */ CABACContext cabac; uint8_t cabac_state[399]; int cabac_init_idc; /* 0x100 -> non null luma_dc, 0x80/0x40 -> non null chroma_dc (cb/cr), 0x?0 -> chroma_cbp(0,1,2), 0x0? luma_cbp */ uint16_t *cbp_table; uint8_t *chroma_pred_mode_table; int last_qscale_diff; int16_t (*mvd_table[2])[2]; int16_t mvd_cache[2][5*8][2];}H264Context;static VLC coeff_token_vlc[4];static VLC chroma_dc_coeff_token_vlc;static VLC total_zeros_vlc[15];static VLC chroma_dc_total_zeros_vlc[3];static VLC run_vlc[6];static VLC run7_vlc;
//AS by tiany for test on 20060403
int FindStartCode (unsigned char *Buf, int zeros_in_startcode)
{
int info;
int i;
info = 1;
for (i = 0; i < zeros_in_startcode; i++)
if(Buf[i] != 0)
info = 0;
if(Buf[i] != 1)
info = 0;
return info;
}
int getNextNal(FILE* inpf, unsigned char* Buf)
{
int pos = 0;
int StartCodeFound = 0;
int info2 = 0;
int info3 = 0;
while(!feof(inpf) && (Buf[pos++]=fgetc(inpf))==0);
while (!StartCodeFound)
{
if (feof (inpf))
{
// return -1;
return pos-1;
}
Buf[pos++] = fgetc (inpf);
info3 = FindStartCode(&Buf[pos-4], 3);
if(info3 != 1)
info2 = FindStartCode(&Buf[pos-3], 2);
StartCodeFound = (info2 == 1 || info3 == 1);
}
fseek (inpf, -4, SEEK_CUR);
return pos - 4;
}
//H.264全局变量
AVCodec *codec; // Codec
AVCodecContext *c; // Codec Context
AVFrame *picture; // Frame
/////////////////////////////////////////////////////////////////////////////
//进行YUV->RGB转换以及显示视频的函数
//用来显示的全局变量
unsigned char *src[3];
BOOL PlayingVideo=FALSE;
unsigned char *clp = NULL;
unsigned char *clp1;
int width,height;
unsigned char bufRGB[80000];
unsigned char* rgbdatanew;
//进行YUV->RGB转换的函数
long int crv_tab[256];
long int cbu_tab[256];
long int cgu_tab[256];
long int cgv_tab[256];
long int tab_76309[256];
void init_dither_tab ()
{
long int crv, cbu, cgu, cgv;
int i;
crv = 104597;
cbu = 132201; /* fra matrise i global.h */
cgu = 25675;
cgv = 53279;
for (i = 0; i < 256; i++)
{
crv_tab[i] = (i - 128) * crv;
cbu_tab[i] = (i - 128) * cbu;
cgu_tab[i] = (i - 128) * cgu;
cgv_tab[i] = (i - 128) * cgv;
tab_76309[i] = 76309 * (i - 16);
}
if (!(clp = (unsigned char *)malloc(sizeof(unsigned char)*1024)))
{
::MessageBox(NULL,L"安排解码码表内存失败!",L"错误",MB_OK);
}
clp1 = clp;
clp += 384;
for (i = -384; i < 640; i++)
clp[i] = (i < 0) ? 0 : ((i > 255) ? 255 : i);
}
void ConvertYUVtoRGB (unsigned char *src0, unsigned char *src1, unsigned char *src2,
unsigned char *dst_ori,int width,int height)
{
int y11, y21;
int y12, y22;
int y13, y23;
int y14, y24;
int u, v;
int i, j;
int c11, c21, c31, c41;
int c12, c22, c32, c42;
unsigned int DW;
unsigned int *id1, *id2;
unsigned char *py1, *py2, *pu, *pv;
unsigned char *d1, *d2;
d1 = dst_ori;
d1 += width * height * 3 - width * 3;
d2 = d1 - width * 3;
py1 = src0;
pu = src1;
pv = src2;
py2 = py1 + width;
id1 = (unsigned int *) d1;
id2 = (unsigned int *) d2;
for (j = 0; j < height; j += 2)
{
/* line j + 0 */
for (i = 0; i < width; i += 4)
{
u = *pu++;
v = *pv++;
c11 = crv_tab[v];
c21 = cgu_tab[u];
c31 = cgv_tab[v];
c41 = cbu_tab[u];
u = *pu++;
v = *pv++;
c12 = crv_tab[v];
c22 = cgu_tab[u];
c32 = cgv_tab[v];
c42 = cbu_tab[u];
y11 = tab_76309[*py1++]; /* (255/219)*65536 */
y12 = tab_76309[*py1++];
y13 = tab_76309[*py1++]; /* (255/219)*65536 */
y14 = tab_76309[*py1++];
y21 = tab_76309[*py2++];
y22 = tab_76309[*py2++];
y23 = tab_76309[*py2++];
y24 = tab_76309[*py2++];
/* RGBR */
DW = ((clp[(y11 + c41) >> 16])) |
((clp[(y11 - c21 - c31) >> 16]) << 8) |
((clp[(y11 + c11) >> 16]) << 16) |
((clp[(y12 + c41) >> 16]) << 24);
*id1++ = DW;
/* GBRG */
DW = ((clp[(y12 - c21 - c31) >> 16])) |
((clp[(y12 + c11) >> 16]) << 8) |
((clp[(y13 + c42) >> 16]) << 16) |
((clp[(y13 - c22 - c32) >> 16]) << 24);
*id1++ = DW;
/* BRGB */
DW = ((clp[(y13 + c12) >> 16])) |
((clp[(y14 + c42) >> 16]) << 8) |
((clp[(y14 - c22 - c32) >> 16]) << 16) |
((clp[(y14 + c12) >> 16]) << 24);
*id1++ = DW;
/* RGBR */
DW = ((clp[(y21 + c41) >> 16])) |
((clp[(y21 - c21 - c31) >> 16]) << 8) |
((clp[(y21 + c11) >> 16]) << 16) |
((clp[(y22 + c41) >> 16]) << 24);
*id2++ = DW;
/* GBRG */
DW = ((clp[(y22 - c21 - c31) >> 16])) |
((clp[(y22 + c11) >> 16]) << 8) |
((clp[(y23 + c42) >> 16]) << 16) |
((clp[(y23 - c22 - c32) >> 16]) << 24);
*id2++ = DW;
/* BRGB */
DW = ((clp[(y23 + c12) >> 16])) |
((clp[(y24 + c42) >> 16]) << 8) |
((clp[(y24 - c22 - c32) >> 16]) << 16) |
((clp[(y24 + c12) >> 16]) << 24);
*id2++ = DW;
}
id1 -= (9 * width) >> 2;
id2 -= (9 * width) >> 2;
py1 += width;
py2 += width;
}
}
__inline DWORD RGBto16bit565(unsigned char r,unsigned char g,unsigned char b)
{
return (((WORD)r<<8)&0xf800)|(((WORD)g<<3)&0x07e0)|((WORD)b>>3);
}
BOOL OpenGAPI(HWND *Wnd)
{
//打开GAPI显示
if(GXOpenDisplay(*Wnd,GX_FULLSCREEN)==0)
{
return FALSE; //无法进行GAPI绘图
}
else
{
//取得显示属性
g_gxdp = GXGetDisplayProperties();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -