TCPMP0.72RC1的編譯與移植以及自己另外做UI完整方法

 一、編譯。

關於編譯,我是引用的別人的文章,我實驗過,確實可行。如下所言:

開發環境:windows xp sp2 + EVC4.0(SP4)
目標平臺:Windows CE5.0(ARMV4)

1.下載源碼,可以去http://picard.exceed.hu/tcpmp/下載TCPMP源代碼。我下載的源碼版本是0.72RC1。

2.編譯環境.我安裝的是evc4.2(SP4)+standard sdk+Win32(WCE ARMV4) Release.如果是編譯x86或者Emulator版本的.要下載一個nasm彙編工具.這點在readme.txt裏面提到.nasm的下載地址http://nasm.sourceforge.net/.否則的話會因爲缺少彙編器而報大量的錯誤。

3.下載下來的源碼包中不包含ARM的解碼器源碼,可以從下面2個網址下載AMR的解碼器的源代碼:http://www.3gpp.org/ftp/Specs/archive/26_series/26.104/26104-610.zip
http://www.3gpp.org/ftp/Specs/archive/26_series/26.204/26204-600.zip
並且分別拷貝到AMR目錄下的26104和26204中。同樣,這個信息在readme.txt中提到。            

4.準備ARM的彙編器,根據實踐經驗,從ARM官網上面下載下來的彙編器編譯時會報錯,不適合使用,建議使用VS2005的ARM彙編器ARMASM.EXE,將其拷貝到C:/Microsoft eMbedded C++ 4.0/EVC/WCE400/BIN下面。

5.編譯的時候切勿rebuild all,否則會報大量的錯誤,從Project—-Dependencies下來框裏選擇player_ce3(主項目),可以看到子項目間的相互依賴關係,所以player_ce3是最後一個編譯的項目。隨便在下拉框中選擇一個子項目,在依賴項中都會發現common項目,說明該項目應該是首先需要進行編譯的,下面我們首先從common項目入手。

6.將player_ce3項目set as active project,編譯版本直接選擇Win32 (WCE ARMV4) Release。這個項目將最後一個進行編譯,最終生成一個player_ce3.exe的應用程序,那我們的目標也就達成了。但編譯這個程序依賴許多的庫。這些庫就是其他的project編譯後提供的。

7.在EVC左邊的文件查看模式裏首先選擇common files,右鍵菜單Build(selection only)進行common項目的編譯,會很順利的過去。接下來由上而下順序爲子項目進行編譯,當然,在Project—-Dependencies中沒有關聯的項目不需要進行編譯(總共6項:player_ce2、sample_ce3、setup_ce2、setup_ce3、template、vorbislq),其它的把asap、flac、player_ce3三項放下來最後處理,這三項需要對編譯器進行額外配置,否則會報大量錯誤。不出意外的話,都會順利編譯過去。接下來我們需要處理剩下來的3個項目。

8.編譯asap項目。右鍵點asap files –>settings–>c/c++–>Category–>Preprocessor在Additional include directories:中增加項目路徑(注意這個是相對路徑,以下所有需添加內容都不包括引號)”.,asap,atari800/src”.不然一堆頭文件會找不到.在Preprocessor definitions:中增加一個宏定義”,ASAP”當然這2步動作也可以在源代碼中修改.如此設置完畢後,asap files project就可以正確編譯了.

9.編譯flac項目。同8,打開flac的settings到相同界面.在Additional include directories:中增加路徑”flac/include,flac/src/libFLAC/include”,不然一堆頭文件找不到。然後,在Preprocessor definitions添加”,FLAC__NO_DLL”。增加這個定義避免使用_declspec(dllexport)定義函數造成的一大堆c2491錯誤.如此設置後,flac project應該可以正確編譯.

10.同理修改player_ce3項目,在Additional include directories中增加路徑 ”../asap/asap,../asap,../asap/atari800/src,flac/include,flac/src/libFLAC/include”。然後在Preprocessor difinitions:增加”,ASAP”。這是最後一個項目文件,也是主項目文件,成功編譯player_ce3.exe。

11. 拷貝包含player_ce3.exe在內所有的生成文件到目標板上(所有文件必須放在同一個目錄中),可以運行!但是菜單沒有顯示正確。主要原因是現實語言配置文件沒有加載上去,可以將源碼lang目錄下面的多國語言支持文件拷貝到目標板同一個目錄下面。如果只需要簡體中文和英文的,只要拷貝lang_std.txt lang_en.txt,lang_chs.txt,lang_ca.def四個文件(四個語言配置文件一定要和應用程序放在同一個目錄)就可以了,打開後默認顯示是英語,你可以更改到簡體中文,前提是你的CE平臺支持簡體中文。

我是在VS2005中用開發平臺的模擬器跑的,一切正常,就是播放不流暢,後期需要對這塊進行優化。

我也嘗試將其編譯到ARMV4I平臺上,結果也是可行的,不過由於的平臺的特殊性,有部分配置需要改動,也有部分插件不被支持,不過不影響使用,大體總結如下:

1.經驗總結表明在ARMV4I平臺的編譯工作中,TCPMP有部分模塊不被支持,編譯提示缺少相應文件。由於該部分不被支持的模塊不影響播放器的正常使用,可以在Project–Dependenties中下拉框中選擇player_ce3,然後將以下幾項前面的勾拿掉:ffmpeg、mpc、speex 這三項可以不必編譯。

2.Win32 (WCE ARMV4I) Debug及Release版本需要自己手動創建。在Build–Configurations裏爲每個子項目選擇ADD(上面提到的3項,和依賴項中不需要編譯的6項不必添加),CPU選擇Win32 (WCE ARMV4I),在Copy settings from裏選擇Win32 (WCE ARMV4) Release,然後選擇OK,你就爲該子項目添加了相應編譯版本。

3.右擊需要編譯的子項目,選擇Settings–Link,在Category中選擇General,然後再下面Project Options裏將最後一行語句:/MACHINE:ARM 改成 /MACHINE:THUMB (每個項目都必須要改)

4.其它步驟按照按照上文ARMV4的過程來就可以了,相應的修改也是需要的,先從common開始,以player_ce3結束。

經過以上過程,你就可以定製自己專用的TCPMP播放器了,可以在interface項目中更改TCPMP的外觀,當然,重頭工作還在於對於特定平臺的一些優化工作:)

二、關於控制TCPMP(張挺 [email protected]

說到控制,世界上很多東西需要控制,就象女人也同樣需要控制,控制的好,於是社會才能和諧!

1、讓TCPMP播放時能在我們自己指定的窗口.

呵呵,要真正讓TCPMP播放器在我們指定的窗口播放,是需要修改COMMON插件的.請同志們把COMMON設置成當前工程,然後把GetDC函數全部搜索出來,然後通通GetDC(Context()->Wnd)代替,並且ReleaseDC(NULL,DC)也通通用ReleaseDC(Context()->Wnd,DC)代替;然後編譯出來的插件就是我們需要的插件.只有這樣,才能使Context_Wnd(this->GetSafeHwnd())真正有效.

2、建立一個MFC的對話框工程.下面貼出代碼:

下載代碼請到:http://download.csdn.net/source/1229925

下面貼出主要代碼:

頭文件:

// TCPMP_MyUIDlg.h : header file
// 張挺 2009-04-20 eMail:[email protected]

#if !defined(AFX_TCPMP_MYUIDLG_H__B5DD421B_AF1E_4678_AD26_08A3F0DE3087__INCLUDED_)
#define AFX_TCPMP_MYUIDLG_H__B5DD421B_AF1E_4678_AD26_08A3F0DE3087__INCLUDED_

#if _MSC_VER >= 1000
#pragma once
#endif // _MSC_VER >= 1000

//包含TCPMP的頭文件
#include "include/common.h"

/////////////////////////////////////////////////////////////////////////////
// CTCPMP_MyUIDlg dialog

class CTCPMP_MyUIDlg : public CDialog
{
// Construction
public:
 CTCPMP_MyUIDlg(CWnd* pParent = NULL); // standard constructor

// Dialog Data
 //{{AFX_DATA(CTCPMP_MyUIDlg)
 enum { IDD = IDD_TCPMP_MYUI_DIALOG };
 CSliderCtrl m_sliderPlay;
 CStatic m_TextOutLable;
 //}}AFX_DATA

 // ClassWizard generated virtual function overrides
 //{{AFX_VIRTUAL(CTCPMP_MyUIDlg)
 public:
 virtual BOOL DestroyWindow();
 protected:
 virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
 //}}AFX_VIRTUAL

public:
 int m_TrackPos;
 CString m_TextOutStr,m_TotalTimeStr;

 BOOL m_bPlayOrPaulse;//"播放/暫停"標誌

 player* m_Player;//操控TCPMP播放器的指針

 
 BOOL InitTcpmp();//初始化TCPMP


 CString TickToStringZhang(int Tick);//時間轉換

protected:
 HICON m_hIcon;

 // Generated message map functions
 //{{AFX_MSG(CTCPMP_MyUIDlg)
 virtual BOOL OnInitDialog();
 afx_msg void OnPlay();
 afx_msg void OnStop();
 //}}AFX_MSG

 afx_msg LRESULT PlayerEventMsg(WPARAM wParam, LPARAM lParam);

 DECLARE_MESSAGE_MAP()
};

//{{AFX_INSERT_LOCATION}}
// Microsoft eMbedded Visual C++ will insert additional declarations immediately before the previous line.

#endif // !defined(AFX_TCPMP_MYUIDLG_H__B5DD421B_AF1E_4678_AD26_08A3F0DE3087__INCLUDED_)

下面是CPP文件:

// TCPMP_MyUIDlg.cpp : implementation file
//
// 張挺 2009-04-20 eMail:[email protected]
#include "stdafx.h"
#include "TCPMP_MyUI.h"
#include "TCPMP_MyUIDlg.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

#define WM_PLAYER_EVENTMSG WM_USER + 1985//播放器事件消息

notify Notify;//通知

CWnd *g_pPlayerWnd =NULL;

int PlayerNotify(node* Player,int Param,int Param2)
{

 g_pPlayerWnd->PostMessage(WM_PLAYER_EVENTMSG,Param,(LPARAM)Param2);


 return ERR_NONE;
}


/////////////////////////////////////////////////////////////////////////////
// CTCPMP_MyUIDlg dialog

CTCPMP_MyUIDlg::CTCPMP_MyUIDlg(CWnd* pParent /*=NULL*/)
: CDialog(CTCPMP_MyUIDlg::IDD, pParent),m_bPlayOrPaulse(true)
{
 //{{AFX_DATA_INIT(CTCPMP_MyUIDlg)
 //}}AFX_DATA_INIT
 // Note that LoadIcon does not require a subsequent DestroyIcon in Win32
 m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);

 m_Player = NULL;

 m_TrackPos = 0;

}

void CTCPMP_MyUIDlg::DoDataExchange(CDataExchange* pDX)
{
 CDialog::DoDataExchange(pDX);
 //{{AFX_DATA_MAP(CTCPMP_MyUIDlg)
 DDX_Control(pDX, IDC_PERCENT, m_sliderPlay);
 DDX_Control(pDX, IDC_TIME, m_TextOutLable);
 //}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CTCPMP_MyUIDlg, CDialog)
 //{{AFX_MSG_MAP(CTCPMP_MyUIDlg)
 ON_BN_CLICKED(IDC_PLAY, OnPlay)
 ON_BN_CLICKED(IDC_STOP, OnStop)
 //}}AFX_MSG_MAP
 ON_MESSAGE(WM_PLAYER_EVENTMSG, PlayerEventMsg)
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CTCPMP_MyUIDlg message handlers

BOOL CTCPMP_MyUIDlg::OnInitDialog()
{
 CDialog::OnInitDialog();

 // Set the icon for this dialog.  The framework does this automatically
 //  when the application's main window is not a dialog
 SetIcon(m_hIcon, TRUE);   // Set big icon
 SetIcon(m_hIcon, FALSE);  // Set small icon
 
 CenterWindow(GetDesktopWindow()); // center to the hpc screen

 // TODO: Add extra initialization here
 g_pPlayerWnd = this;

 m_sliderPlay.SetRange(0,30000);

 InitTcpmp();


 return TRUE;  // return TRUE  unless you set the focus to a control
}


rect DefaultRect = {0,0,320,240};//播放電影窗口區域
tchar_t URL[] = _T("//SDMMC Card//TCPMP72NEW//008.mp4");//播放文件的路徑

//初始化TCPMP
BOOL CTCPMP_MyUIDlg::InitTcpmp()
{
 //初始化
 if(Context_Init(_T("TCPMP"),_T("0.72RC1"),3,(tchar_t*)AfxGetApp()->m_lpCmdLine,NULL))//
 {
 
  context* pContext=Context();//獲得上下文

  if(pContext)
   m_Player=(player*)(pContext->Player);
  else
   return false;
 

    Context_Wnd(this->GetSafeHwnd());//播放窗口關聯

  //設置通知處理函數
  Notify.Func = (notifyfunc)PlayerNotify;
  Notify.This = (void*)m_Player;

  if(m_Player)
   m_Player->Set(m_Player,PLAYER_NOTIFY,&Notify,sizeof(Notify));
 

  int i = 0;
  m_Player->Set(m_Player,PLAYER_LIST_COUNT,&i,sizeof(int));//播放列表清空

  m_Player->Set(m_Player,PLAYER_LIST_URL+0,URL,sizeof(URL));

  m_Player->Set(m_Player,PLAYER_SKIN_VIEWPORT,&DefaultRect,sizeof(rect));//設置播放電影窗口區域

  int index = 0;
  m_Player->Set(m_Player,PLAYER_LIST_CURRIDX,&index,sizeof(int));//設置播放列表裏的某個文件爲當前播放文件

  m_Player->Set(m_Player,PLAYER_PLAY,&m_bPlayOrPaulse,sizeof(BOOL));//開始播放

 }
 else
  return false;

 return true;

}

void CTCPMP_MyUIDlg::OnPlay()//播放/暫停
{

 if(m_Player)
 {

  m_bPlayOrPaulse = !m_bPlayOrPaulse;
 
  m_Player->Set(m_Player,PLAYER_PLAY,&m_bPlayOrPaulse,sizeof(BOOL));

 }


 
}

void CTCPMP_MyUIDlg::OnStop()//停止
{

 if(m_Player)
  m_Player->Set(m_Player,PLAYER_STOP,NULL,0);

}

BOOL CTCPMP_MyUIDlg::DestroyWindow()//程序退出
{

 if(m_Player)
 {
    
  Context_Wnd(NULL);
 
  Context_Done();

  ::Sleep(200);
 }

 return CDialog::DestroyWindow();
}

CString CTCPMP_MyUIDlg::TickToStringZhang(int Tick)
{
 if (Tick<0)
  Tick = -Tick;
 
 int Hour,Min,Sec;

 Hour = Tick / 3600 / TICKSPERSEC;//獲得小時
 Tick -= Hour * 3600 * TICKSPERSEC;
 Min = Tick / 60 / TICKSPERSEC;//獲得分鐘
 Tick -= Min * 60 * TICKSPERSEC;
 Sec = Tick / TICKSPERSEC;//獲得秒鐘
 Tick -= Sec * TICKSPERSEC;

 CString strTime;

 strTime.Format(_T("0%d:%d:%d"),Hour,Min,Sec);
 if(Min<10)
  strTime.Insert(3,'0');
 if(Sec<10)
  strTime.Insert(strTime.GetLength()-1,'0');

 return strTime;
}

LRESULT CTCPMP_MyUIDlg::PlayerEventMsg(WPARAM wParam, LPARAM lParam)
{
 fraction f;
 int Msg_Id = (int)wParam;
 int Msg_Status = (int)lParam;


 switch(Msg_Id)
 {
 case PLAYER_PERCENT:

  if(Msg_Status == 1)
  {
   m_Player->Get(m_Player,PLAYER_PERCENT,&f,sizeof(fraction));
   m_TrackPos = Scale(30000,f.Num,f.Den);

   if(m_TrackPos>=29700)
    m_TrackPos = 30000;

    m_sliderPlay.SetPos( m_TrackPos );

   tick_t Time =0;
 //  tchar_t Dur[32];
   if (m_Player->Get(m_Player,PLAYER_POSITION,&Time,sizeof(tick_t)) == ERR_NONE)//PLAYER_DURATION
   {
   
   }
   else
   {
   
   }
   m_TextOutStr.Empty();
   m_TextOutStr=TickToStringZhang(Time);
   m_TextOutStr+=_T("/");
   m_TextOutStr+=m_TotalTimeStr;
   //m_TextOutStr+=_T(" ");
   //m_TextOutStr+=m_TitleNameStr;

   m_TextOutLable.SetWindowText(m_TextOutStr);
  }

  break;
 case PLAYER_PLAY:

  break;
 case PLAYER_TITLE:

  break;
 default:
  break;

 
 }

 return true;

}

呵呵,請結合代碼進行查看,一切變的很簡單!

 

本文來自CSDN博客,轉載請標明出處:http://blog.csdn.net/zhangting00_2000/archive/2009/04/20/4095272.aspx

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章