zoukankan      html  css  js  c++  java
  • [转载]TCPMP0.72RC1的编译与移植以及自己另外做UI完整方法

    原文地址:http://blog.csdn.net/zhangting00_2000/archive/2009/04/20/4095272.aspx

    我叫张挺,虽然开博,除了转了一篇黄色文章以外,技术文章从来没有写,所以呢,感到很不好意思!于是决定还写一篇在网上也留点痕迹。我这里主要是介 绍TCPMP的移植以及如何把这个鸟鸟整到自己的界面中来.网上关于TCPMP的开发文章不是很多,有一点点呢,犹如JJ太短,不能深入;又或者不实用. 今天呢,我先讲如何编译,然后讲如何操控制.eMail:zt00@tom.com

    一、编译。

    关于编译,我是引用的别人的文章,我实验过,确实可行。如下所言:

    开发环境:windows xp sp2 + EVC4.0(SP4)
    目标平台:Windows CE5.0(ARMV4)

    1.下载源码,可以去下载TCPMP源代码。我下载的源码版本是0.72RC1。

    2.编译环境.我安装的是evc4.2(SP4)+standard sdk+Win32(WCE ARMV4) Release.如果是编译x86或者Emulator版本的.要下载一个nasm汇编工具.这点在readme.txt里面提到.nasm的下载地址否则的话会因为缺少汇编器而报大量的错误。

    3.下载下来的源码包中不包含ARM的解码器源码,可以从下面2个网址下载AMR的解码器的源代码: 
     
    并且分别拷贝到AMR目录下的26104和26204中。同样,这个信息在readme.txt中提到。             

    4.准备ARM的汇编器,根据实践经验,从ARM官网上面下载下来的汇编器编译时会报错,不适合使用,建议使用VS2005的ARM汇编器ARMASM.EXE,将其拷贝到C:Microsoft eMbedded C++ 4.0EVCWCE400BIN下面。

    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(张挺 )

    说到控制,世界上很多东西需要控制,就象女人也同样需要控制,控制的好,于是社会才能和谐!

    1、让TCPMP播放时能在我们自己指定的窗口.

    呵呵,要真正让TCPMP播放器在我们指定的窗口播放,是需要修改COMMON插件的.请同志们把COMMON设置成当前工程,然后把GetDC函 数全部搜索出来,然后通通GetDC(Context()->Wnd)代替,并且ReleaseDC(NULL,DC)也通通用 ReleaseDC(Context()->Wnd,DC)代替;然后编译出来的插件就是我们需要的插件.只有这样,才能使 Context_Wnd(this->GetSafeHwnd())真正有效.

    2、建立一个MFC的对话框工程.下面贴出代码:

    下载代码请到:

    下面贴出主要代码:

    头文件:

    // TCPMP_MyUIDlg.h : header file
    // 张挺 2009-04-20 eMail:zt00@tom.com
    
    #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:zt00@tom.com
    #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(" 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;
    
    }

    呵呵,请结合代码进行查看,一切变的很简单!

  • 相关阅读:
    数据绑定表达式语法(Eval,Bind区别)
    使用博客园的第一件事 自定义主题
    sql2000 跨服务器复制表数据
    使用UpdatePanel 局部刷新出现中文乱码的解决方法!!
    MMC不能打开文件MSC文件
    sql 日期 、时间相关
    loaded AS2 swf call function in AS3 holder
    Rewrite the master page form action attribute in asp.net 2.0
    100万个不重复的8位的随机数
    flash 中实现斜切变型
  • 原文地址:https://www.cnblogs.com/eaglexmw/p/14775738.html
Copyright © 2011-2022 走看看