#pragma once
#include "afxwin.h"
#include "afxcmn.h"
#include "MyButton.h"
struct Sample
{
UINT Size;
ULONGLONG Offset;
BOOL KeyFrame = FALSE;
};
class CDlg5 : public CDialogEx
{
DECLARE_DYNAMIC(CDlg5)
public:
CDlg5(CWnd* pParent = NULL);
virtual ~CDlg5();
#ifdef AFX_DESIGN_TIME
enum { IDD = IDD_DIALOG5 };
#endif
protected:
virtual void DoDataExchange(CDataExchange* pDX);
DECLARE_MESSAGE_MAP()
public:
afx_msg void OnBnClickedOk();
virtual BOOL OnInitDialog();
CFont font1, font2;
CBrush brush1, brush2;
HANDLE hFile = NULL;
UINT ListCount = 0;
DWORD* pSampleList = NULL;
void GetFrames();
void Get();
CProgressCtrl pro;
CEdit edit;
afx_msg void OnBnClickedButton1();
CEdit edit2;
afx_msg HBRUSH OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor);
void SetPos();
CMyButton btn;
afx_msg BOOL OnEraseBkgnd(CDC* pDC);
afx_msg void OnDestroy();
virtual BOOL PreTranslateMessage(MSG* pMsg);
};
BYTE ReadOne(HANDLE hFile);
WORD ReadTwo(HANDLE hFile);
UINT ReadThree(HANDLE hFile);
UINT ReadFour(HANDLE hFile);
UINT Read4Return(HANDLE hFile, LONGLONG& pos);
ULONGLONG Read8Return(HANDLE hFile, LONGLONG& pos);
HRESULT MoveFilePointer(HANDLE hFile, LONGLONG size, int flag);
UINT FindBox(HANDLE hFile, char* pBoxName);
BOOL IsEnd(HANDLE hFile);
LONGLONG GetFilePos(HANDLE hFile);
void GetHdlrType(HANDLE hFile, char* pch);
LONGLONG FindTrak(HANDLE hFile, char* pCh);
LONGLONG FindMdia(HANDLE hFile);
LONGLONG FindMdhd(HANDLE hFile);
LONGLONG FindHdlr(HANDLE hFile);
LONGLONG FindMinf(HANDLE hFile);
LONGLONG FindStbl(HANDLE hFile);
LONGLONG FindStblSub(HANDLE hFile, char* pch);
#include "stdafx.h"
#include "解析MP4.h"
#include "Dlg5.h"
#include "afxdialogex.h"
#include "解析MP4Dlg.h"
IMPLEMENT_DYNAMIC(CDlg5, CDialogEx)
CDlg5::CDlg5(CWnd* pParent )
: CDialogEx(IDD_DIALOG5, pParent)
{
font1.CreatePointFont(100, L"微软雅黑");
font2.CreatePointFont(100, L"仿宋");
brush1.CreateSolidBrush(RGB(13, 221, 242));
brush2.CreateSolidBrush(RGB(20, 20, 20));
ListCount = 0;
}
CDlg5::~CDlg5()
{
}
void CDlg5::DoDataExchange(CDataExchange* pDX)
{
CDialogEx::DoDataExchange(pDX);
DDX_Control(pDX, IDC_PROGRESS1, pro);
DDX_Control(pDX, IDC_EDIT1, edit);
DDX_Control(pDX, IDC_EDIT2, edit2);
DDX_Control(pDX, IDC_BUTTON1, btn);
}
BEGIN_MESSAGE_MAP(CDlg5, CDialogEx)
ON_BN_CLICKED(IDOK, &CDlg5::OnBnClickedOk)
ON_BN_CLICKED(IDC_BUTTON1, &CDlg5::OnBnClickedButton1)
ON_WM_CTLCOLOR()
ON_WM_ERASEBKGND()
ON_WM_DESTROY()
END_MESSAGE_MAP()
void CDlg5::OnBnClickedOk()
{
}
void CDlg5::Get()
{
C解析MP4Dlg* pDlg = (C解析MP4Dlg*)theApp.m_pMainWnd;
if (pDlg->Path.IsEmpty())return;
hFile = CreateFile(pDlg->Path, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (hFile == INVALID_HANDLE_VALUE)
{
MessageBox(L"打开文件失败"); return;
}
EnableWindow(FALSE);
for (UINT i = 0; i < ListCount; i++)
{
Sample* pS = (Sample*)pSampleList[i]; delete pS;
}
if (pSampleList)delete[] pSampleList;
FindTrak(hFile, "vide");
LONGLONG MdiaStar = FindMdia(hFile);
FindMdhd(hFile);
MoveFilePointer(hFile, MdiaStar, FILE_BEGIN);
FindMinf(hFile);
LONGLONG StblStar = FindStbl(hFile);
LONGLONG SttsStar = FindStblSub(hFile, "stts");
MoveFilePointer(hFile, SttsStar + 12, FILE_BEGIN);
UINT SttsEnter = ReadFour(hFile);
UINT uL;
ListCount = 0;
for (UINT i = 0; i < SttsEnter; i++)
{
UINT uS = ReadFour(hFile); uL = ReadFour(hFile); ListCount += uS;
}
MoveFilePointer(hFile, StblStar, FILE_BEGIN);
LONGLONG StssStar = FindStblSub(hFile, "stss");
MoveFilePointer(hFile, StblStar, FILE_BEGIN);
LONGLONG StscStar = FindStblSub(hFile, "stsc");
MoveFilePointer(hFile, StblStar, FILE_BEGIN);
LONGLONG StszStar = FindStblSub(hFile, "stsz");
MoveFilePointer(hFile, StblStar, FILE_BEGIN);
LONGLONG StcoStar = FindStblSub(hFile, "stco");
MoveFilePointer(hFile, StblStar, FILE_BEGIN);
LONGLONG Co64Star = FindStblSub(hFile, "co64");
pSampleList = new DWORD[ListCount];
pro.SetRange32(0, ListCount);
UINT index = 0;
LONGLONG stss_enter_star = StssStar + 16;
LONGLONG stco_enter_star = StcoStar + 16;
LONGLONG co64_enter_star = Co64Star + 16;
LONGLONG stsz_enter_star = StszStar + 20;
UINT KeyFrame = Read4Return(hFile, stss_enter_star);
MoveFilePointer(hFile, StscStar + 12, FILE_BEGIN);
UINT StscNu = ReadFour(hFile);
UINT First = ReadFour(hFile);
UINT NextFirst;
UINT Nu;
for (UINT i = 0; i < StscNu; i++)
{
UINT nSample = ReadFour(hFile);
UINT id = ReadFour(hFile);
if (i != StscNu - 1)
{
NextFirst = ReadFour(hFile);
Nu = NextFirst - First;
First = NextFirst;
}
else
{
Nu = 1;
}
if (StscNu == 1)nSample = ListCount;
for (UINT j = 0; j < Nu; j++)
{
ULONGLONG Offset;
if (StcoStar)
{
Offset = Read4Return(hFile, stco_enter_star);
}
else
{
Offset = Read8Return(hFile, co64_enter_star);
}
ULONGLONG NextOffset;
for (UINT k = 0; k < nSample; k++)
{
UINT size = Read4Return(hFile, stsz_enter_star);
ULONGLONG offset;
if (k == 0)offset = Offset;
else offset = NextOffset;
NextOffset = offset + size;
BOOL KEY = FALSE;
if (KeyFrame == index + 1)
{
KEY = TRUE;
KeyFrame = Read4Return(hFile, stss_enter_star);
}
Sample* pSample = new Sample();
pSample->Size = size;
pSample->Offset = offset;
if (KEY)pSample->KeyFrame = TRUE;
pSampleList[index] = (DWORD)pSample;
index++;
pro.SetPos(index);
}
}
}
CString str; str.Format(L"%u", index);
edit.SetWindowText(str);
CloseHandle(hFile);
EnableWindow(TRUE);
}
UINT Thread5(LPVOID pParam)
{
CDlg5* pdlg5 = (CDlg5*)pParam;
pdlg5->Get();
return 1;
}
BOOL CDlg5::OnInitDialog()
{
CDialogEx::OnInitDialog();
edit.SetFont(&font1); edit2.SetFont(&font2);
edit2.LimitText(UINT_MAX);
CRect rect(0, 0, 600, 600);
DWORD style = GetExStyle();
if (style & WS_EX_CLIENTEDGE)
{
CalcWindowRect(rect, CWnd::adjustOutside);
}
else
{
CalcWindowRect(rect, CWnd::adjustBorder);
}
MoveWindow(&rect);
CenterWindow();
SetPos();
SetWindowTheme(pro.GetSafeHwnd(), _T(""), _T(""));
pro.SetBarColor(RGB(250, 60, 10));
pro.SetBkColor(RGB(50, 60, 100));
return TRUE;
}
void CDlg5::GetFrames()
{
AfxBeginThread(Thread5, this, 0, 0, 0);
}
void CDlg5::OnBnClickedButton1()
{
C解析MP4Dlg* pDlg = (C解析MP4Dlg*)theApp.m_pMainWnd;
UINT index = GetDlgItemInt(IDC_EDIT1);
if (index < 1)index = 1;
if (index > ListCount)index = ListCount;
SetDlgItemInt(IDC_EDIT1, index);
Sample* pSample = (Sample*)pSampleList[index - 1];
BYTE* pB = new BYTE[pSample->Size];
CFile F;
F.Open(pDlg->Path, CFile::modeRead);
F.Seek(pSample->Offset, CFile::begin);
F.Read(pB, pSample->Size);
F.Close();
CString item;
for (UINT i = 0; i < pSample->Size; i++)
{
CString s; s.Format(L"%0*X ", 2, pB[i]); item += s;
}
delete[] pB;
edit2.SetWindowText(item);
}
void CDlg5::SetPos()
{
edit.MoveWindow(6, 7, 152, 18); btn.MoveWindow(164, 5, 106, 22); pro.MoveWindow(275, 10, 320, 12);
edit2.MoveWindow(5, 34, 590, 561);
}
HBRUSH CDlg5::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{
HBRUSH hbr = CDialogEx::OnCtlColor(pDC, pWnd, nCtlColor);
if (pWnd->GetDlgCtrlID() == IDC_EDIT1)
{
pDC->SetTextColor(RGB(0, 0, 0)); pDC->SetBkColor(RGB(13, 221, 242));
return brush1;
}
if (pWnd->GetDlgCtrlID() == IDC_EDIT2)
{
pDC->SetTextColor(RGB(0, 255, 255)); pDC->SetBkColor(RGB(20, 20, 20));
return brush2;
}
return hbr;
}
BOOL CDlg5::OnEraseBkgnd(CDC* pDC)
{
CRect rect; GetClientRect(rect);
pDC->FillSolidRect(rect, RGB(9, 26, 10));
CRect RT; RT.CopyRect(rect); RT.bottom = 30;
pDC->FillSolidRect(RT, RGB(30, 80, 80));
CRect r1, r2;
edit.GetWindowRect(r1); ScreenToClient(r1); r1.InflateRect(1, 1);
pDC->FrameRect(r1, &CBrush(RGB(0, 0, 0)));
pro.GetWindowRect(r2); ScreenToClient(r2); r2.InflateRect(1, 1);
pDC->FrameRect(r2, &CBrush(RGB(0, 0, 0)));
return TRUE;
}
BOOL CDlg5::PreTranslateMessage(MSG* pMsg)
{
if (GetFocus() == GetDlgItem(IDC_EDIT1) && pMsg->message == WM_KEYDOWN && pMsg->wParam == VK_RETURN)
{
OnBnClickedButton1();
}
return CDialogEx::PreTranslateMessage(pMsg);
}
void CDlg5::OnDestroy()
{
CDialogEx::OnDestroy();
for (UINT i = 0; i < ListCount; i++)
{
Sample* pS = (Sample*)pSampleList[i]; delete pS;
}
if (pSampleList)delete[] pSampleList;
}
ULONGLONG FindExBox(HANDLE hFile, char* pBoxName)
{
UINT box_size = ReadFour(hFile);
ReadFile(hFile, pBoxName, 4, NULL, NULL); pBoxName[4] = 0;
ULONGLONG Hi = ReadFour(hFile); UINT Lo = ReadFour(hFile);
ULONGLONG Exbox_size = (Hi << 32) + Lo;
MoveFilePointer(hFile, -16, FILE_CURRENT);
return Exbox_size;
}
LONGLONG FindTrak(HANDLE hFile, char* pCh)
{
SetFilePointer(hFile, 0, NULL, FILE_BEGIN);
char ch[5];
Agan:
ULONGLONG box_size = FindBox(hFile, ch);
if (box_size == 1)box_size = FindExBox(hFile, ch);
if (strcmp(ch, "moov") == 0)
{
ULONGLONG moov_size = box_size - 8;
MoveFilePointer(hFile, 8, FILE_CURRENT);
moov_Agan:
box_size = FindBox(hFile, ch);
if (strcmp(ch, "trak") == 0)
{
LONGLONG TrakPos = GetFilePos(hFile);
FindMdia(hFile); FindHdlr(hFile);
GetHdlrType(hFile, ch);
MoveFilePointer(hFile, TrakPos, FILE_BEGIN);
if (strcmp(ch, pCh) == 0)return TrakPos;
else
{
MoveFilePointer(hFile, box_size, FILE_CURRENT);
moov_size -= box_size;
if (moov_size>0)goto moov_Agan;
}
}
else
{
MoveFilePointer(hFile, box_size, FILE_CURRENT);
moov_size -= box_size;
if (moov_size>0)goto moov_Agan;
}
}
else
{
MoveFilePointer(hFile, box_size, FILE_CURRENT);
if (IsEnd(hFile))return 0;
goto Agan;
}
AfxMessageBox(L"查找trak失败");
return 0;
}
LONGLONG FindMdia(HANDLE hFile)
{
char ch[5];
UINT box_size = FindBox(hFile, ch);
UINT trak_size = box_size - 8;
MoveFilePointer(hFile, 8, FILE_CURRENT);
trak_Agan:
box_size = FindBox(hFile, ch);
if (strcmp(ch, "mdia") == 0)
{
return GetFilePos(hFile);
}
else
{
MoveFilePointer(hFile, box_size, FILE_CURRENT);
trak_size -= box_size;
if (trak_size > 0)goto trak_Agan;
}
AfxMessageBox(L"查找mdia失败");
return 0;
}
LONGLONG FindMdhd(HANDLE hFile)
{
char ch[5];
UINT box_size = FindBox(hFile, ch);
UINT mdia_size = box_size - 8;
MoveFilePointer(hFile, 8, FILE_CURRENT);
mdia_Agan:
box_size = FindBox(hFile, ch);
if (strcmp(ch, "mdhd") == 0)
{
return GetFilePos(hFile);
}
else
{
MoveFilePointer(hFile, box_size, FILE_CURRENT);
mdia_size -= box_size;
if (mdia_size > 0)goto mdia_Agan;
}
AfxMessageBox(L"查找mdhd失败");
return 0;
}
LONGLONG FindHdlr(HANDLE hFile)
{
char ch[5];
UINT box_size = FindBox(hFile, ch);
UINT mdia_size = box_size - 8;
MoveFilePointer(hFile, 8, FILE_CURRENT);
mdia_Agan:
box_size = FindBox(hFile, ch);
if (strcmp(ch, "hdlr") == 0)
{
return GetFilePos(hFile);
}
else
{
MoveFilePointer(hFile, box_size, FILE_CURRENT);
mdia_size -= box_size;
if (mdia_size > 0)goto mdia_Agan;
}
AfxMessageBox(L"查找hdlr失败");
return 0;
}
LONGLONG FindMinf(HANDLE hFile)
{
char ch[5];
UINT box_size = FindBox(hFile, ch);
UINT mdia_size = box_size - 8;
MoveFilePointer(hFile, 8, FILE_CURRENT);
mdia_Agan:
box_size = FindBox(hFile, ch);
if (strcmp(ch, "minf") == 0)
{
return GetFilePos(hFile);
}
else
{
MoveFilePointer(hFile, box_size, FILE_CURRENT);
mdia_size -= box_size;
if (mdia_size > 0)goto mdia_Agan;
}
AfxMessageBox(L"查找minf失败");
return 0;
}
LONGLONG FindStbl(HANDLE hFile)
{
char ch[5];
UINT box_size = FindBox(hFile, ch);
UINT minf_size = box_size - 8;
MoveFilePointer(hFile, 8, FILE_CURRENT);
minf_Agan:
box_size = FindBox(hFile, ch);
if (strcmp(ch, "stbl") == 0)
{
return GetFilePos(hFile);
}
else
{
MoveFilePointer(hFile, box_size, FILE_CURRENT);
minf_size -= box_size;
if (minf_size > 0)goto minf_Agan;
}
AfxMessageBox(L"查找stbl失败");
return 0;
}
LONGLONG FindStblSub(HANDLE hFile, char* pch)
{
LONGLONG Star = GetFilePos(hFile);
char ch[5];
UINT box_size = FindBox(hFile, ch);
UINT stbl_size = box_size - 8;
MoveFilePointer(hFile, 8, FILE_CURRENT);
stbl_Agan:
box_size = FindBox(hFile, ch);
if (strcmp(ch, pch) == 0)
{
return GetFilePos(hFile);
}
else
{
MoveFilePointer(hFile, box_size, FILE_CURRENT);
stbl_size -= box_size;
if (stbl_size > 0)goto stbl_Agan;
}
MoveFilePointer(hFile, Star, FILE_BEGIN);
return 0;
}
void GetHdlrType(HANDLE hFile, char* pch)
{
MoveFilePointer(hFile, 16, FILE_CURRENT);
ReadFile(hFile, pch, 4, NULL, NULL); pch[4] = 0;
}
BYTE ReadOne(HANDLE hFile)
{
BYTE mby1;
ReadFile(hFile, &mby1, 1, NULL, NULL);
return mby1;
}
WORD ReadTwo(HANDLE hFile)
{
BYTE mby1, mby2;
ReadFile(hFile, &mby1, 1, NULL, NULL); ReadFile(hFile, &mby2, 1, NULL, NULL);
WORD size = mby1 * 256 + mby2;
return size;
}
UINT ReadThree(HANDLE hFile)
{
BYTE mby1, mby2, mby3;
ReadFile(hFile, &mby1, 1, NULL, NULL); ReadFile(hFile, &mby2, 1, NULL, NULL); ReadFile(hFile, &mby3, 1, NULL, NULL);
UINT size = mby1 * 256 * 256 + mby2 * 256 + mby3;
return size;
}
UINT ReadFour(HANDLE hFile)
{
BYTE mby1, mby2, mby3, mby4;
ReadFile(hFile, &mby1, 1, NULL, NULL); ReadFile(hFile, &mby2, 1, NULL, NULL); ReadFile(hFile, &mby3, 1, NULL, NULL); ReadFile(hFile, &mby4, 1, NULL, NULL);
UINT size = mby1 * 256 * 256 * 256 + mby2 * 256 * 256 + mby3 * 256 + mby4;
return size;
}
UINT Read4Return(HANDLE hFile, LONGLONG& pos)
{
LONGLONG Cur = GetFilePos(hFile);
MoveFilePointer(hFile, pos, FILE_BEGIN);
UINT size = ReadFour(hFile); pos += 4;
MoveFilePointer(hFile, Cur, FILE_BEGIN);
return size;
}
ULONGLONG Read8Return(HANDLE hFile, LONGLONG& pos)
{
LONGLONG Cur = GetFilePos(hFile);
MoveFilePointer(hFile, pos, FILE_BEGIN);
ULONGLONG size1 = ReadFour(hFile); UINT size2 = ReadFour(hFile);
ULONGLONG UL = (size1 << 32) + size2;
pos += 8;
MoveFilePointer(hFile, Cur, FILE_BEGIN);
return UL;
}
HRESULT MoveFilePointer(HANDLE hFile, LONGLONG size, int flag)
{
LARGE_INTEGER move;
move.QuadPart = size;
SetFilePointerEx(hFile, move, NULL, flag);
return S_OK;
}
UINT FindBox(HANDLE hFile, char* pBoxName)
{
UINT box_size = ReadFour(hFile);
ReadFile(hFile, pBoxName, 4, NULL, NULL); pBoxName[4] = 0;
MoveFilePointer(hFile, -8, FILE_CURRENT);
return box_size;
}
BOOL IsEnd(HANDLE hFile)
{
LARGE_INTEGER SIZE;
GetFileSizeEx(hFile, &SIZE);
LONGLONG Pos = GetFilePos(hFile);
if (Pos == SIZE.QuadPart)return TRUE;
else return FALSE;
}
LONGLONG GetFilePos(HANDLE hFile)
{
LARGE_INTEGER move;
move.QuadPart = 0;
LARGE_INTEGER CUR;
SetFilePointerEx(hFile, move, &CUR, FILE_CURRENT);
return CUR.QuadPart;
}
#include "stdafx.h"
#include "解析MP4.h"
#include "MyButton.h"
IMPLEMENT_DYNAMIC(CMyButton, CButton)
CMyButton::CMyButton()
{
font1.CreatePointFont(90, _T("微软雅黑"), NULL);
}
CMyButton::~CMyButton()
{
}
BEGIN_MESSAGE_MAP(CMyButton, CButton)
END_MESSAGE_MAP()
void CMyButton::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
{
CDC dc;
dc.Attach(lpDrawItemStruct->hDC);
dc.SelectObject(&font1);
dc.SetBkMode(TRANSPARENT); dc.SetTextColor(RGB(0, 255, 255));
CString str;
if (lpDrawItemStruct->CtlID == IDC_BUTTON1)
{
CRect rect(lpDrawItemStruct->rcItem);
dc.FillSolidRect(&rect, RGB(30, 80, 80));
CRgn rgn;
rgn.CreateRoundRectRgn(rect.left, rect.top, rect.right, rect.bottom, 4, 4);
CRect r1; r1.CopyRect(rect); r1.DeflateRect(1, 1);
CRgn rgn1; rgn1.CreateRoundRectRgn(r1.left, r1.top, r1.right, r1.bottom, 2, 2);
CRgn rgnA; rgnA.CreateRectRgn(rect.left, rect.top, rect.right, rect.bottom);
rgnA.CombineRgn(&rgn, &rgn1, RGN_DIFF);
dc.FillRgn(&rgnA, &CBrush(RGB(0, 255, 255)));
dc.SelectObject(&font1); dc.SetTextColor(RGB(0, 255, 255));
GetWindowText(str);
dc.DrawText(str, &rect, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
}
dc.Detach();
}