jing_105 发表于 2011-8-25 20:42:46

分享C++流媒体解码编程技巧

C/C++以速度快,性能高而著称,C/C++本质是一种中级的计算机程序设计语言,它即保证了类似低级汇编语言效率,同时也坚固类似高级语言所具有的特点,C/C++的程序编写不依赖于计算机的硬件,所以你即可以拿它来编写系统软件,也可以用来开发应用软件,它的应用越乎我们的想像,除了PC机上的开发外,也被广泛的用在单片机,嵌入式等手机开发等领域,目前市场上流行的大部分程序都是建立在C语言的基础上来完成的
现在”3G网络”的概念成为了人们对未来网络最常见的一种说法,不过什么是3g呢,其实它的全称为3rd Generation,即第三代数字通信。它能够处理比以前更多的服务,如图像,音视频等多种多媒体形式提供给用户,而它和前两代的唯一区别就是3G网络最大的速率可以达到2Mbps,远远超过了前两代网络,这使得手机影院等大数据流应用,可以实现,为用户带来更好的移动体验。电信运营商及通信设备制造商都非常关注。
3G网络的到来,为移运运营商提供了商机,目前中国三个运营商纷纷引入自己的3g标准,其中,移动做为3g的先导者,自然不会错失这个机会,在今年08年推出了自己的手机系统OPhone OS平台,OPhone OS平台本身是基于Linux开放系统所设计,并不断的完善,相信不少见过OPhone OS手机的用户都被它的惊人的人性化界面所打动,其实OPhone OS系统所拥有的不单单是这些,为了极大的满足人们日益的需求,OPhone OS平台除保留了Gmail,Gtalk等原有业务外,还内置了中国移动的全部增值服务,为用户提供了更贴心的体验。同时移动还推出了线上软件销售商店Mobile Market,为个人和公司提供了面向移动拥有的5亿手机用户和庞大商业客户的销售机会。这样看来,手机上的个人娱乐软件和商业管理软件,如果中国移动大力推动,会带来很大市场。联通、电信虽然手机用户规模相对小些,但相信也会大力发展。
和Linux一样,OPhone OS保留了原有的开发语言C/C++,Java,不过OPhone OS对其进行了极大的优化,C/C++虽然效率高,不过这样并不安全,因为恶意的程序,会使得系统变得不安全,Java虽然很安全,不过效率太低,不利于大的项目开发,而且单纯的Java程序并不能完成一些特定的任务,在这种情况下,OPhone OS平台寻求到了完美的解决方案,JNI(Java Native Interface,Java本地化方法)技术运用而生,JNI简单的说,是让C/C++做完底层开发,并为Java提供接口以为调用,这样,JNI方式即不失低效率,也保证了平台安全性
OPhone OS平台的流媒体支持
OpenCore模块为OPhone OS平台提供了核心的多媒体支持,它处于整个平台的Libraries层,以os的方式为上层语言提供服务,OpenCore主要是用C/C++来实现,开发者可以修改及移植别的编/解码器,然后通过上层软件使用,OpenCore不能直接被用户所使用,必需借住其它的方式调用,如Java的JNI方式,OpenCore模块内置了OpenMAX1L interface接口进行扩展,这种技术分离了具体硬件的依赖,方便了开发者的移植,目前OPhone OS平台提供了3GP,MP4,ACV等媒体格式的支持,如果是在线看的话,还支持http,rtp等协议
OPhone OS媒体源码文件
Opencore目录包括了所有关于媒体方面的源码,其中最重要的是android,engines和codecs_v2,protocols四个目录,android主要包括了一些纯虚类,为适配器,engines为媒体引擎部分,主要是OPhone OS平台内置的编解码程序,后一个为第三方所提供,为OPhone OS系统的扩展应用,protocols目录里提供了在线流媒体的协议,包括http,rtp,rtsp,我们重点说一下protocols的结构,
opencore\protocols\http_parcom\include\http_composer.h头文件中enum HTTPVersion
{
    HTTP_V1_0 = 0,
    HTTP_V1_1
};
// HTTPMethod enum
enum HTTPMethod
{
    HTTP_METHOD_GET = 0,            // both HTTP 1.0 and HTTP 1.1
    HTTP_METHOD_HEAD,          // both HTTP 1.0 and HTTP 1.1
    HTTP_METHOD_POST,          // both HTTP 1.0 and HTTP 1.1
    HTTP_METHOD_DELETE,        // both HTTP 1.0 and HTTP 1.1
    HTTP_METHOD_LINK,          // HTTP 1.0 only
    HTTP_METHOD_UNLINK,        // HTTP 1.0 only
    HTTP_METHOD_OPTIONS,        // HTTP 1.1 only
    HTTP_METHOD_PUT,            // HTTP 1.1 only
    HTTP_METHOD_TRACE,          // HTTP 1.1 only
    HTTP_METHOD_CONNECT,        // HTTP 1.1 only
};
列出来http协议下流媒体的支持的http协议为1.0和1.1,从中我们可以看出来,OPhone OS媒体部分支持Get和Post方式播放数据
下面我们来通过Java的JNI方式去调用,我们以SDK中的MediaPlayerDemo_Video.java说明
package com.example.android.apis.media;
import com.example.android.apis.R;
import com.example.android.apis.app.AlarmController;
import android.app.Activity;
import android.graphics.PixelFormat;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnBufferingUpdateListener;
import android.media.MediaPlayer.OnCompletionListener;
import android.os.Bundle;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.Toast;

public class MediaPlayerDemo_Video extends Activity implements
        OnBufferingUpdateListener, OnCompletionListener,
        MediaPlayer.OnPreparedListener, SurfaceHolder.Callback {
    private static final String TAG = "MediaPlayerDemo";
    private int mVideoWidth;
    private int mVideoHeight;
    private MediaPlayer mMediaPlayer;
    private SurfaceView mPreview;
    private SurfaceHolder holder;
    private String path;
    private Bundle extras;
    private static final String MEDIA = "media";
    private static final int LOCAL_AUDIO = 1;
    private static final int STREAM_AUDIO = 2;
    private static final int RESOURCES_AUDIO = 3;
    private static final int LOCAL_VIDEO = 4;
    private static final int STREAM_VIDEO = 5;
    /**
    *
    * Called when the activity is first created.
    */
    public void onCreate(Bundle icicle) {
        super.onCreate(icicle);
        setContentView(R.layout.mediaplayer_2);
        mPreview = (SurfaceView) findViewById(R.id.surface);
        holder = mPreview.getHolder();
        holder.addCallback(this);
        holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
        extras = getIntent().getExtras();
    }
    private void playVideo(Integer Media) {
        try {
            switch (Media) {
                case LOCAL_VIDEO:
                    /*
                    * TODO: Set the path variable to a local media file path.
                    */
                    path = "";
                    if (path == "") {
                        // Tell the user to provide a media file URL.
                        Toast
                                .makeText(
                                        MediaPlayerDemo_Video.this,
                                        "Please edit MediaPlayerDemo_Video Activity, "
                                                + "and set the path variable to your media file path."
                                                + " Your media file must be stored on sdcard.",
                                        Toast.LENGTH_LONG).show();
                    }
                    break;
                case STREAM_VIDEO:
                    /*
                    * TODO: Set path variable to progressive streamable mp4 or
                    * 3gpp format URL. Http protocol should be used.
                    * Mediaplayer can only play "progressive streamable
                    * contents" which basically means: 1. the movie atom has to
                    * precede all the media data atoms. 2. The clip has to be
                    * reasonably interleaved.
                    *
                    */
                    path = "http://xxx.xxx.xxx.xxx/xxx.3gp";
                    if (path == "") {
                        // Tell the user to provide a media file URL.
                        Toast
                                .makeText(
                                        MediaPlayerDemo_Video.this,
                                        "Please edit MediaPlayerDemo_Video Activity,"
                                                + " and set the path variable to your media file URL.",
                                        Toast.LENGTH_LONG).show();
                    }
                    break;

            }
            // Create a new media player and set the listeners
            mMediaPlayer = new MediaPlayer();
            mMediaPlayer.setDataSource(path);
            mMediaPlayer.setDisplay(holder);
            mMediaPlayer.prepare();
            mMediaPlayer.setOnBufferingUpdateListener(this);
            mMediaPlayer.setOnCompletionListener(this);
            mMediaPlayer.setOnPreparedListener(this);
            mMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);

        } catch (Exception e) {
            Log.e(TAG, "error: " + e.getMessage(), e);
        }
    }
    public void onBufferingUpdate(MediaPlayer arg0, int percent) {
        Log.d(TAG, "onBufferingUpdate percent:" + percent);
    }
    public void onCompletion(MediaPlayer arg0) {
        Log.d(TAG, "onCompletion called");
    }
    public void onPrepared(MediaPlayer mediaplayer) {
        Log.d(TAG, "onPrepared called");
        mVideoWidth = mMediaPlayer.getVideoWidth();
        mVideoHeight = mMediaPlayer.getVideoHeight();
        if (mVideoWidth != 0 && mVideoHeight != 0) {
            holder.setFixedSize(mVideoWidth, mVideoHeight);
            mMediaPlayer.start();
        }
    }
    public void surfaceChanged(SurfaceHolder surfaceholder, int i, int j, int k) {
        Log.d(TAG, "surfaceChanged called");
    }
    public void surfaceDestroyed(SurfaceHolder surfaceholder) {
        Log.d(TAG, "surfaceDestroyed called");
    }

    public void surfaceCreated(SurfaceHolder holder) {
        // TODO Auto-generated method stub
        Log.d(TAG, "surfaceCreated called");
        playVideo(extras.getInt(MEDIA));

    }
    @Override
    protected void onDestroy() {
        super.onDestroy();
        // TODO Auto-generated method stub
        if (mMediaPlayer != null) {
            mMediaPlayer.release();
            mMediaPlayer = null;
        }
    }
}
case STREAM_VIDEO:
path = "http://xxx.xxx.xxx.xxx/xxx.3gp";
这里大家可以为MediaPlayer指定一个URL,播放器会为这个通过http播放媒体数据OPhone OS平台目前只支持HTTP download方式来播放media文件. 下一个版本会支持streaming流媒体,以前程序的巧妙之处在于,JNI方式将java和C/C++分工来完成一个复杂的任务,目前在流媒体方式,大家可以下载Spb TV

ovwpa 发表于 2011-8-29 23:10:23

多晴酷夏 发表于 2011-8-30 12:56:01

以后需再关注,现在先帮你顶一下











static/image/common/sigline.gif

http://img2081.poco.cn/mypoco/myphoto/20110822/16/64165363201108221627279573116820626_005.jpg

cncus 发表于 2011-10-3 01:30:42

玉液琼浆新开传奇私发布网,传奇世界s发布网网通传奇私发布服。新开热血传奇私服传奇似发服网1.85;快速减肥药网通传奇sf网站新开100%仿盛大传奇湖南湘潭县687215,网通倚天荣耀sf将记忆重叠天下归心;黯然香的唯美不离╮|牵右手,伤人伤己传奇私服革故鼎新,-[壹嗰朲寂寞[盡此而已c↘愛我所愛無怨無悔↙。‘心乱如麻的大全-≮9天赐金牛刚开一秒SF传奇皓月版本1.92新开传奇变态私服。四川旺苍395066,七彩转生传奇冰炭不洽牧童的简单;讳莫如深布衣粝食,忧心如捣懂得了疗伤,放蕩的年紀丶固執的青春。d一口咬定。管中窥豹风行一时,用谎言撑起e海底捞针。











static/image/common/sigline.gif
http://www.43919.com,http://855d.com传奇私服,
www.39ms.com减肥网,www.71TL.COM天龙八部私服
www.ms19.com魔兽世界私服,www.B5S5.COM左旋肉碱
www.LE76.COM广州开发票,www.WUQIJI.COM奇迹私服
www.04my.com魔域私服,www.zx40.com诛仙私服
www.939a.com小游戏

侃呀侃之灵 发表于 2011-10-4 08:13:50

真是好东西,顶啊!











static/image/common/sigline.gif
1.76精品 1.80复古传奇  1.76复古传奇 轻变传奇 英雄合击 新开传奇sf
页: [1]
查看完整版本: 分享C++流媒体解码编程技巧