[原创]基于Blankfin平台的多媒体播放器--代码
0赞
发表于 9/28/2011 10:33:24 PM
阅读(3759)
下午有个同学跑过来问我关于播放器的问题,跟他交流了很久,突发奇想,我能不能编写一个基于blankfin平台的播放器,说干就干,晚饭就喊同学给我带到实验室了,呵呵!!!
自己敲代码好累,画了个流程图,喊了几个大三的同学,布置了任务,他们敲,我修改,问题多多,不过比我敲要舒服一些,调试了很久,就在1分钟前成功在板子上跑起来了,很有成就感,发下代码,大家交流下,看我的播放器怎么样。。。。
// mediaplayer.cpp : Defines the entry point for the application.
//
#include "stdafx.h"
#include "mediaplayer.h"
#include <commctrl.h>
#include <windows.h>
#include <dshow.h>
#include <atlbase.h>
//#include <memory.h>
#include <commdlg.h>define MAX_LOADSTRING 200
#define WM_GRAPHNOTIFY WM_APP + 1//定义自己的消息
#define STOP 1//停止状态
#define PLAY 2//播放状态
#define PAUSE 3//暂停状态
#define INIT 4//刚刚初始化完成
//定义视频播放用到的全局变量
IGraphBuilder *pIGraphBuilder=NULL;
IMediaControl *pIMediaControl=NULL;
IMediaEventEx *pIMediaEventEx=NULL;
IVideoWindow *pIVideoWndow=NULL;
IMediaSeeking *pIMediaSeeking = NULL;
IBasicVideo *pIBasicVideo = NULL;
int CurrentState=NULL;//表示当前状态
BOOL AudioOnly=TRUE;
HWND hwndCB;
HINSTANCE hInst;//当前实例
HWND hWinMain;//主窗口句柄
void InitGraphBuilder(void);
void AddFileToPlayer(HWND hWnd);
void ConnectToWindow(HWND hWnd,RECT grc);
void PlayClip(HWND hWnd);
void PauseClip(void);
void SetVideoPosition(RECT grc);
void StopClip(void);
void PauseClip(void);
void OpenAFile(HWND hWnd,LPWSTR fn);
void ResetClip();
void ResetClip()
{
if (!pIMediaSeeking)
return;
LONGLONG pos = 0;
StopClip();
pIMediaSeeking->SetPositions(&pos, AM_SEEKING_AbsolutePositioning ,
NULL, AM_SEEKING_NoPositioning);
PlayClip(hWinMain);
PauseClip();
}
void InitGraphBuilder()
{
if(SUCCEEDED(CoCreateInstance(CLSID_FilterGraph,NULL,CLSCTX_INPROC,IID_IGraphBuilder,(void **)&pIGraphBuilder))
&&SUCCEEDED(pIGraphBuilder->QueryInterface(IID_IMediaControl, (void **)&pIMediaControl))
&&SUCCEEDED(pIGraphBuilder->QueryInterface(IID_IMediaEventEx, (void **)&pIMediaEventEx))
&&SUCCEEDED(pIGraphBuilder->QueryInterface(IID_IVideoWindow, (void **)&pIVideoWndow)))
{
(pIGraphBuilder->QueryInterface(IID_IMediaSeeking, (void **)&pIMediaSeeking));
if(SUCCEEDED(pIGraphBuilder->QueryInterface(IID_IBasicVideo, (void **)&pIBasicVideo)))
AudioOnly=FALSE;
CurrentState=INIT;
}
else exit(1);//如果初始化不成功则退出
return;
}
void AddFileToPlayer(HWND hWnd)
{
static WCHAR fn[MAX_LOADSTRING];//文件名
static OPENFILENAMEW FileName;
LPCWSTR pszOpenFilter=L"All Files(*.*)\0*.*\0\0";//文件过滤器
HRESULT hr;
FileName.lStructSize=sizeof(FileName);
FileName.hwndOwner=hWnd;
FileName.lpstrFile=fn;
FileName.nMaxFile=MAX_LOADSTRING;
FileName.lpstrFilter=pszOpenFilter;
FileName.Flags=OFN_FILEMUSTEXIST | OFN_READONLY | OFN_PATHMUSTEXIST;
//如果已经初始化过且文件正常打开则还原文件
if((GetOpenFileNameW(&FileName)!=0)&&(CurrentState==INIT))
pIGraphBuilder->QueryInterface(IID_IMediaEventEx, (void **)&pIMediaEventEx);
if(SUCCEEDED(hr=pIGraphBuilder->RenderFile(fn, NULL)))
{
//如果还原文件成功
CurrentState=STOP;
}
else
{
//否则提示出错
MessageBox(NULL,TEXT("Render Failed!"),TEXT("Error"),MB_OK);
}
return;
}
void ConnectToWindow(HWND hWnd,RECT grc)
{
//指定播放影片的窗口
pIVideoWndow->put_Owner((OAHWND)hWnd);
//指定风格
pIVideoWndow->put_WindowStyle(WS_CHILD | WS_CLIPSIBLINGS|WS_CLIPCHILDREN);
//
pIVideoWndow->put_MessageDrain((OAHWND)hWnd);
//将消息交给父窗口处理
pIGraphBuilder->QueryInterface(IID_IMediaEventEx, (void **)&pIMediaEventEx);
pIMediaEventEx->SetNotifyWindow((OAHWND)hWnd, WM_GRAPHNOTIFY, 0);
//设置播放位置
SetVideoPosition(grc);
return;
}
void SetVideoPosition(RECT grc)
{
//设定视频窗口位置
pIVideoWndow->SetWindowPosition(grc.left, grc.top+CommandBar_Height(hwndCB),grc.right, grc.bottom-CommandBar_Height(hwndCB));
return;
}
void PlayClip(HWND hWnd)
{
if(CurrentState==PAUSE||CurrentState==STOP)
if(SUCCEEDED(pIMediaControl->Run()))
CurrentState=PLAY;
}
void PauseClip()
{
//如果当前状态为播放则暂停
if(CurrentState==PLAY)
if(SUCCEEDED(pIMediaControl->Pause()))
CurrentState=PAUSE;
}
void StopClip()
{
//如果当前状态为播放或暂停则停止
if((CurrentState==PLAY)||(CurrentState==PAUSE))
if(SUCCEEDED(pIMediaControl->Stop()))
CurrentState=STOP;
}
void ReleaseAll()
{
//如果当前状态不是刚初始化过或未初始化
if(CurrentState!=NULL)
{
StopClip();//停止播放
pIVideoWndow->put_Visible(OAFALSE);
pIVideoWndow->put_Owner(NULL);
pIMediaControl->Release();
pIMediaControl=NULL;
pIMediaEventEx->Release();
pIMediaEventEx=NULL;
pIGraphBuilder->Release();
pIGraphBuilder=NULL;
CurrentState=NULL;
}
}
void InitVideoWindow(HWND hWnd)
{
LONG VideoWidth,VideoHeight;
int ScreenCX=GetSystemMetrics(SM_CXSCREEN);
int ScreenCY=GetSystemMetrics(SM_CYSCREEN);
int WindowLeft=0;
int WindowTop=0;
int WindowWidth=0;
int WindowHeight=0;
RECT grc;
if(!AudioOnly)
if(pIBasicVideo->GetVideoSize(&VideoWidth, &VideoHeight) != E_NOINTERFACE)
{
int FixWidth= (GetSystemMetrics(SM_CXBORDER)*2);//边界宽
int FixHeight=(GetSystemMetrics(SM_CYCAPTION)+CommandBar_Height(hwndCB)+GetSystemMetrics(SM_CYBORDER)*2);
WindowWidth= VideoWidth + FixWidth;
WindowHeight=VideoHeight + FixHeight;
WindowLeft=(ScreenCX-WindowWidth)/2+1;
WindowTop=(ScreenCY-WindowHeight)/2+1;
#if 1
if(WindowLeft<1)
{
WindowLeft=1;
WindowWidth=ScreenCX;
WindowHeight=(int)(((float)(WindowWidth-FixWidth))/((float)VideoWidth)*((float)VideoHeight)+FixHeight);
WindowTop=(ScreenCY-WindowHeight)/2+1;
}
if(WindowTop<1)
{
WindowTop=1;
WindowHeight=ScreenCY;
WindowWidth=(int)(((float)(WindowHeight-FixHeight))/((float)VideoHeight)*((float)VideoWidth)+FixWidth);
WindowLeft=(ScreenCX-WindowWidth)/2+1;
}
#endif
}
else
{
WindowWidth=ScreenCX/2;
WindowHeight=ScreenCY/2;
WindowLeft=ScreenCX/4+1;
WindowTop=ScreenCY/4+1;
}
SetWindowPos(hWnd, NULL, WindowLeft, WindowTop, WindowWidth,WindowHeight,SWP_NOOWNERZORDER|SWP_SHOWWINDOW);
//重绘commandbar
CommandBar_Destroy(hwndCB);
hwndCB = CommandBar_Create(hInst, hWnd, 1);
CommandBar_InsertMenubar(hwndCB, hInst, IDM_MENU, 0);
CommandBar_AddAdornments(hwndCB, 0, 0);
if (hwndCB)
CommandBar_Show(hwndCB, TRUE);
GetClientRect(hWnd, &grc);
SetVideoPosition(grc);
}
// Forward declarations of functions included in this code module:
ATOM MyRegisterClass (HINSTANCE);
BOOL InitInstance (HINSTANCE, int);
LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM);
int WINAPI WinMain( HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPTSTR lpCmdLine,
int nCmdShow)
{
MSG msg;
HACCEL hAccelTable;
// Perform application initialization:
if (!InitInstance (hInstance, nCmdShow))
{
return FALSE;
}
hAccelTable = LoadAccelerators(hInstance, (LPCTSTR)IDC_MEDIAPLAYER);
if(FAILED(CoInitialize(NULL)))
{
MessageBox(NULL,TEXT("CoInitialize Failed!\r\n"),TEXT("ERROR"),MB_OK);
exit(1);
}
InitGraphBuilder();
// 主消息循环
while (GetMessage(&msg, NULL, 0, 0))
{
if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
return msg.wParam;
}
//
// FUNCTION: MyRegisterClass()
//
// PURPOSE: Registers the window class.
//
// COMMENTS:
//
// It is important to call this function so that the application
// will get 'well formed' small icons associated with it.
//
ATOM MyRegisterClass(HINSTANCE hInstance)
{
WNDCLASS wc;
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = (WNDPROC) WndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_MEDIAPLAYER));
wc.hCursor = 0;
wc.hbrBackground = (HBRUSH) GetStockObject(WHITE_BRUSH);
wc.lpszMenuName = 0;
wc.lpszClassName = TEXT("miniplayer");
return RegisterClass(&wc);
}
//
// FUNCTION: InitInstance(HANDLE, int)
//
// PURPOSE: Saves instance handle and creates main window
//
// COMMENTS:
//
// In this function, we save the instance handle in a global variable and
// create and display the main program window.
//
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
HWND hWnd;
hInst = hInstance; // Store instance handle in our global variable
// Initialize global strings
MyRegisterClass(hInstance);
//获取屏幕尺寸
int ScreenCX,ScreenCY;
ScreenCX=GetSystemMetrics(SM_CXSCREEN);
ScreenCY=GetSystemMetrics(SM_CYSCREEN);
hWnd = CreateWindow(TEXT("miniplayer"), TEXT("miniplayer"), WS_SIZEBOX|WS_OVERLAPPEDWINDOW | WS_CAPTION | WS_CLIPCHILDREN,
ScreenCX/4, ScreenCY/4, ScreenCX/2, ScreenCY/2, NULL, NULL,
hInstance, NULL);
hWinMain=hWnd;
//如果窗口无法创建则退出
if (!hWnd)
{
exit(1);
}
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);
if (hwndCB)
CommandBar_Show(hwndCB, TRUE);
return TRUE;
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
HDC hdc;
PAINTSTRUCT ps;
RECT grc;
switch (message)
{
case WM_COMMAND:
switch(LOWORD(wParam))
{
case IDexit:
SendMessage(hWnd, WM_DESTROY, 0, 0);
break;
case IDopen:
{
ReleaseAll();
InitGraphBuilder();
AddFileToPlayer(hWnd);
GetClientRect(hWnd, &grc);
ConnectToWindow(hWnd,grc);
InitVideoWindow(hWnd);
SendMessage(hWnd, WM_COMMAND, IDplay, 0);
}
break;
case IDstop:
StopClip();
ResetClip();
break;
case IDplay:
if(CurrentState==PLAY)
PauseClip();
else
{
PlayClip(hWnd);
}
break;
default:
break;
}
break;
case WM_GRAPHNOTIFY:
LONG evCode, evParam1, evParam2;
if (!pIMediaEventEx)
return S_OK;
while(SUCCEEDED(pIMediaEventEx->GetEvent(&evCode, (LONG_PTR *) &evParam1,
(LONG_PTR *) &evParam2, 0)))
{
pIMediaEventEx->FreeEventParams(evCode, evParam1, evParam2);
if(EC_COMPLETE == evCode)
{
SendMessage(hWnd, WM_COMMAND, IDstop, 0);
}
}
break;
case WM_MOVE:
case WM_SIZE:
if(CurrentState==PLAY)
{
//重绘commandbar
CommandBar_Destroy(hwndCB);
hwndCB = CommandBar_Create(hInst, hWnd, 1);
CommandBar_InsertMenubar(hwndCB, hInst, IDM_MENU, 0);
CommandBar_AddAdornments(hwndCB, 0, 0);
if (hwndCB)
CommandBar_Show(hwndCB, TRUE);
GetClientRect(hWnd, &grc);
SetVideoPosition(grc);
}
break;
case WM_LBUTTONDOWN:
SendMessage(hWnd, WM_COMMAND, IDplay, 0);
break;
case WM_SYSCOMMAND:
if(wParam==SC_CLOSE)
SendMessage(hWnd, WM_COMMAND, IDexit, 0);
else
return DefWindowProc(hWnd, message, wParam, lParam);
break;
case WM_CREATE:
hwndCB = CommandBar_Create(hInst, hWnd, 1);
CommandBar_InsertMenubar(hwndCB, hInst, IDM_MENU, 0);
CommandBar_AddAdornments(hwndCB, 0, 0);
break;
case WM_PAINT:
hdc = BeginPaint(hWnd, &ps);
EndPaint(hWnd, &ps);
break;
case WM_DESTROY:
CommandBar_Destroy(hwndCB);
ReleaseAll();
CoUninitialize();
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
有兴趣的朋友,大家可以一起交流哦,switch(LOWORD(wParam))是我的特点,其他几个初始化函数是我以前就写过的,放了一曲《神话》,学生们很激动。。。。。。
