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;
    
    }

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

  • 相关阅读:
    不用keytool,tomcat打开https
    sqlserver获取某一张表中的所有列中的最大长度
    不用keytool,tomcat打开https
    到底私钥和公钥哪个是用来加密 哪个是用来解密的
    空间支持php解压
    到底私钥和公钥哪个是用来加密 哪个是用来解密的
    sqlserver获取某一张表中的所有列中的最大长度
    数字签名(代码签名)流程
    功夫电影中非常经典(武术非常实用)
    数字签名(代码签名)流程
  • 原文地址:https://www.cnblogs.com/eaglexmw/p/14775738.html
Copyright © 2011-2022 走看看