[原创]基于Blankfin平台的多媒体播放器--代码
0赞
发表于 9/28/2011 10:33:24 PM
阅读(2592)
下午有个同学跑过来问我关于播放器的问题,跟他交流了很久,突发奇想,我能不能编写一个基于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))是我的特点,其他几个初始化函数是我以前就写过的,放了一曲《神话》,学生们很激动。。。。。。