snifer

[原创]基于Blankfin平台的多媒体播放器--代码

0
阅读(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))是我的特点,其他几个初始化函数是我以前就写过的,放了一曲《神话》,学生们很激动。。。。。。
Baidu
map