C++ 解析H264檔案
阿新 • • 發佈:2019-02-18
http://download.csdn.net/detail/sz76211822/9717609#include "stdafx.h" #include <windows.h> typedef enum { NALU_TYPE_SLICE = 1, NALU_TYPE_DPA = 2, NALU_TYPE_DPB = 3, NALU_TYPE_DPC = 4, NALU_TYPE_IDR = 5, NALU_TYPE_SEI = 6, NALU_TYPE_SPS = 7, NALU_TYPE_PPS = 8, NALU_TYPE_AUD = 9, NALU_TYPE_EOSEQ = 10, NALU_TYPE_EOSTREAM = 11, NALU_TYPE_FILL = 12, } NaluType; typedef enum { NALU_PRIORITY_DISPOSABLE = 0, NALU_PRIRITY_LOW = 1, NALU_PRIORITY_HIGH = 2, NALU_PRIORITY_HIGHEST = 3 } NaluPriority; void printfH264(int j, int i, int nLen, int nFrameType) { printf("%d %d", j, i); int nForbiddenBit = (nFrameType>>7) & 0x1;//第1位禁止位,值為1表示語法出錯 int nReference_idc = (nFrameType>>5) & 0x03;//第2~3位為參考級別 int nType = nFrameType & 0x1f;//第4~8為是nal單元型別 printf(" "); switch(nReference_idc){ case NALU_PRIORITY_DISPOSABLE: printf("DISPOS"); break; case NALU_PRIRITY_LOW: printf("LOW"); break; case NALU_PRIORITY_HIGH: printf("HIGH"); break; case NALU_PRIORITY_HIGHEST: printf("HIGHEST"); break; } printf(" "); switch(nType){ case NALU_TYPE_SLICE: printf("SLICE"); break; case NALU_TYPE_DPA: printf("DPA"); break; case NALU_TYPE_DPB: printf("DPB"); break; case NALU_TYPE_DPC: printf("DPC"); break; case NALU_TYPE_IDR: printf("IDR"); break; case NALU_TYPE_SEI: printf("SEI"); break; case NALU_TYPE_SPS: printf("SPS"); break; case NALU_TYPE_PPS: printf("PPS"); break; case NALU_TYPE_AUD: printf("AUD"); break; case NALU_TYPE_EOSEQ: printf("EOSEQ"); break; case NALU_TYPE_EOSTREAM: printf("EOSTREAM"); break; case NALU_TYPE_FILL: printf("FILL"); break; } printf(" %d\r\n", nLen); } int GetLen(int nPos, int nTotalSize, BYTE* btData) { int nStart = nPos; while (nStart < nTotalSize){ if (btData[nStart] == 0x00 && btData[nStart + 1] == 0x00 && btData[nStart + 2] == 0x01){ return nStart - nPos; } else if (btData[nStart] == 0x00 && btData[nStart + 1] == 0x00 && btData[nStart + 2] == 0x00 && btData[nStart + 3] == 0x01){ return nStart - nPos; } else{ nStart++; } } return nTotalSize - nPos;//最後一幀。 } int _tmain(int argc, _TCHAR* argv[]) { BYTE *btData = NULL; DWORD dwFileSize = 0; HANDLE hFile = CreateFile(L"E:\\video\\sintel.h264", GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (hFile != INVALID_HANDLE_VALUE){ dwFileSize = GetFileSize(hFile, NULL); btData = new BYTE[dwFileSize]; memset(btData, 0, dwFileSize); DWORD dwRead = 0; ReadFile(hFile, btData, dwFileSize, &dwRead, NULL); CloseHandle(hFile); } int j = 0;//多少幀 int i = 0;//偏移量 while (i < dwFileSize - 4){ if (btData[i] == 0x00 && btData[i + 1] == 0x00 && btData[i + 2] == 0x01){ int nLen = GetLen(i + 3, dwFileSize, btData); printfH264(j, i, nLen, btData[i + 3]); j++; i += 3; } else if (btData[i] == 0x00 && btData[i + 1] == 0x00 && btData[i + 2] == 0x00 && btData[i + 3] == 0x01){ int nLen = GetLen(i + 4, dwFileSize, btData); printfH264(j, i, nLen, btData[i + 4]); j++; i += 4; } else{ i++; } } if (btData){ delete[] btData; } return 0; }