【第三篇章-android平台buffer播放源码】核心展示

对于这个buffer播放demo,谢谢大家的关注,一直以来没时间来分享demo的实现,今天抽空给大家看看核心代码,欢迎关注的朋友们提宝贵的建议!

chodison_mediaplayer.cpp

/*
 * Copyright (C) 2010 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <binder/ProcessState.h>

#include <media/IStreamSource.h>
#include <media/mediaplayer.h>
#include <media/stagefright/foundation/ADebug.h>
#include <media/stagefright/foundation/AMessage.h>
#include <media/stagefright/DataSource.h>
#include <media/stagefright/MediaSource.h>
#include <media/stagefright/MetaData.h>

#include <binder/IServiceManager.h>
#include <media/IMediaPlayerService.h>

#include <fcntl.h>

#include "chodison_mediaplayer.h"


using namespace android;


#if defined(ANDROID_4DOT2)

#pragma message("chodison mediaplayer android4.2")

#elif defined(ANDROID_4DOT3)

#pragma message("chodison mediaplayer android4.3")

#elif defined(ANDROID_4DOT4)

#pragma message("chodison mediaplayer android4.4")

#endif


struct MyStreamSource : public BnStreamSource {
    // Object assumes ownership of fd.
    MyStreamSource(int fd);
	void setFd(int fd);
	void closeFd(void);

    virtual void setListener(const sp<IStreamListener> &listener);
    virtual void setBuffers(const Vector<sp<IMemory> > &buffers);

    virtual void onBufferAvailable(size_t index);
	//virtual uint32_t flags() const ;

protected:
    virtual ~MyStreamSource();

private:
    int mFd;
    off64_t mFileSize;
    uint64_t mNumPacketsSent;

    sp<IStreamListener> mListener;
    Vector<sp<IMemory> > mBuffers;

    DISALLOW_EVIL_CONSTRUCTORS(MyStreamSource);
};

sp<IMediaPlayer> Mediaplayer;
sp<MyStreamSource> msource;


MyStreamSource::MyStreamSource(int fd)
    : mFd(fd),
      mFileSize(0),
      mNumPacketsSent(0) {
	
	MYSTREAM_LOGI("[%s-%d] file len=%lld...\n",__FUNCTION__,__LINE__,mFileSize);

}

MyStreamSource::~MyStreamSource() {
    close(mFd);
    mFd = -1;
}

void MyStreamSource::setFd(int fd) {
	MYSTREAM_LOGI("[%s-%d]...\n",__FUNCTION__,__LINE__);
	
    CHECK_GE(fd, 0);

    mFileSize = lseek64(fd, 0, SEEK_END);
    lseek64(fd, 0, SEEK_SET);

	mFd = fd;
}

void MyStreamSource::closeFd(void){
	MYSTREAM_LOGI("[%s-%d]...\n",__FUNCTION__,__LINE__);

    close(mFd);
    mFd = -1;	
}

#if 0
uint32_t MyStreamSource::flags() const { 
	return IStreamSource::kFlagAlignedVideoData; 
}
#endif

void MyStreamSource::setListener(const sp<IStreamListener> &listener) {
	MYSTREAM_LOGI("[%s-%d]...\n",__FUNCTION__,__LINE__);

	mListener = listener;
}

void MyStreamSource::setBuffers(const Vector<sp<IMemory> > &buffers) {
	MYSTREAM_LOGI("[%s-%d]...\n",__FUNCTION__,__LINE__);

	mBuffers = buffers;
}

void MyStreamSource::onBufferAvailable(size_t index) {
    CHECK_LT(index, mBuffers.size());

    sp<IMemory> mem = mBuffers.itemAt(index);

    ssize_t n = read(mFd, mem->pointer(), mem->size());
    if (n <= 0) {
        mListener->issueCommand(IStreamListener::EOS, false /* synchronous */);
    } else {
        mListener->queueBuffer(index, n);

        mNumPacketsSent += n / 188;
    }
	
	//printf("[%s-%d].%d..\n",__FUNCTION__,__LINE__,n);
}

////////////////////////////////////////////////////////////////////////////////

struct MyClient : public BnMediaPlayerClient {
    MyClient()
        : mEOS(false) {
    }

    //virtual void notify(int msg, int ext1, int ext2, const Parcel *obj) {
    virtual void notify(int msg, int ext1, int ext2, const Parcel *obj, Parcel *replyObj=NULL) {
        Mutex::Autolock autoLock(mLock);

		MYSTREAM_LOGI("[%s-%d]...msg=%d\n",__FUNCTION__,__LINE__, msg);

        if (msg == MEDIA_ERROR || msg == MEDIA_PLAYBACK_COMPLETE) {
            mEOS = true;
            mCondition.signal();
        }

		if(msg == MEDIA_SET_VIDEO_SIZE)
		{
			static int i = 0;
			if(i != 0)
			{
				Mediaplayer->stop();

				Mediaplayer->prepareAsync();
				
				Mediaplayer->start();
			}
			
			i ++;
		}

		if(msg == MEDIA_PREPARED)
		{
			Mediaplayer->start();
		}

		if(msg == MEDIA_PLAYBACK_COMPLETE)
		{
			Mediaplayer->stop();
		}
    }

    void waitForEOS() {
        Mutex::Autolock autoLock(mLock);
        while (!mEOS) {
            mCondition.wait(mLock);
        }
    }

protected:
    virtual ~MyClient() {
    }

private:
    Mutex mLock;
    Condition mCondition;

    bool mEOS;

    DISALLOW_EVIL_CONSTRUCTORS(MyClient);
};


static bool IsHLSURL(const char *url) {
    if (!strncasecmp("http://", url, 7)
            || !strncasecmp("https://", url, 8)) {
        size_t len = strlen(url);
        if (len >= 5 && !strcasecmp(".m3u8", &url[len - 5])) {
            return true;
        }

        if (strstr(url,"m3u8")) {
            return true;
        }
    }

    return false;
}

/*
** external API
*/
void Mediaplayer_SetSurface(android::Surface* pSurface)
{
	MYSTREAM_LOGI("[%s-%d]...\n",__FUNCTION__,__LINE__);

	/*android 4.2*/
	#if defined(ANDROID_4DOT2)
		Mediaplayer->setVideoSurfaceTexture(pSurface->getSurfaceTexture());
	/*android 4.3*/
	#elif (defined(ANDROID_4DOT3) || defined(ANDROID_4DOT4))
		Mediaplayer->setVideoSurfaceTexture(pSurface->getIGraphicBufferProducer());
	#endif
}


int Mediaplayer_Init(void)
{
	MYSTREAM_LOGI("[%s-%d]...\n",__FUNCTION__,__LINE__);

	DataSource::RegisterDefaultSniffers();
	
	sp<MyClient> client = new MyClient;

	sp<IStreamSource> source;

	msource = new MyStreamSource(-1);
	source = msource;
	
	sp<IServiceManager> sm = defaultServiceManager();
	sp<IBinder> binder = sm->getService(String16("media.player"));
	sp<IMediaPlayerService> service = interface_cast<IMediaPlayerService>(binder);

	CHECK(service.get() != NULL);	
	/*android 4.2*/
	#if defined(ANDROID_4DOT2)
		Mediaplayer = service->create(getpid(), client, 0);
	/*android 4.3*/
	#elif (defined(ANDROID_4DOT3) || defined(ANDROID_4DOT4))
		Mediaplayer = service->create(client, 0);
	#else
		#error no define system version
	#endif

	if (Mediaplayer != NULL)
	{
		status_t st = Mediaplayer->setDataSource(source);
		if(NO_ERROR != st)
		{
			return 1;
		}
	}

	return 0;
}

int Mediaplayer_Deinit(void)
{
	MYSTREAM_LOGI("[%s-%d]...\n",__FUNCTION__,__LINE__);
	
	return 0;
}


int Mediaplayer_Start(char *url)
{
	size_t	len = 0;
	int		fd = 0;
	
	MYSTREAM_LOGI("[%s-%d].url=%s..\n",__FUNCTION__,__LINE__,url);
	
    len = strlen(url);
    if(len >= 3 && !strcasecmp(".ts", &url[len - 3]))
	{
        fd = open(url, O_RDWR);

        if (fd < 0) 
		{
			MYSTREAM_LOGE("[%s-%d].Failed to open file..\n",__FUNCTION__,__LINE__);
			return 1;
        }  
				
		msource->setFd(fd);		
    }
    else if(IsHLSURL(url))
	{
		status_t st = Mediaplayer->setDataSource(url,0);
		if(NO_ERROR != st)
		{
			return 1;
		}
	}
	else
	{
		MYSTREAM_LOGE("[%s-%d].unsupport play media file..\n",__FUNCTION__,__LINE__);
        return 1;
	}	
	
	Mediaplayer->prepareAsync();
	
	return 0;
}

int Mediaplayer_Init2(void)
{
	MYSTREAM_LOGI("[%s-%d]...\n",__FUNCTION__,__LINE__);

	DataSource::RegisterDefaultSniffers();
	
	sp<MyClient> client = new MyClient;
	
	sp<IServiceManager> sm = defaultServiceManager();
	sp<IBinder> binder = sm->getService(String16("media.player"));
	sp<IMediaPlayerService> service = interface_cast<IMediaPlayerService>(binder);

	CHECK(service.get() != NULL);	
	/*android 4.2*/
	#if defined(ANDROID_4DOT2)
		Mediaplayer = service->create(getpid(), client, 0);
	/*android 4.3*/
	#elif (defined(ANDROID_4DOT3) || defined(ANDROID_4DOT4))
		Mediaplayer = service->create(client, 0);
	#else
		#error no define system version
	#endif


	if (Mediaplayer != NULL)
	{
		//status_t st = Mediaplayer->setDataSource("http://218.17.157.168:8008/hls_test/playlist.m3u8",0);
		status_t st = Mediaplayer->setDataSource("/sdcard/media_1280x720.ts",0);
		if(NO_ERROR != st)
		{
			return 1;
		}
	}

	return 0;
}

int Mediaplayer_Start2(void)
{
	
	MYSTREAM_LOGI("[%s-%d]...\n",__FUNCTION__,__LINE__);
	
	
	Mediaplayer->start();
	
	return 0;
}


int Mediaplayer_Stop(void)
{
	MYSTREAM_LOGI("[%s-%d]...\n",__FUNCTION__,__LINE__);
	
	Mediaplayer->stop();

	return 0;
}

int Mediaplayer_Pause(void)
{
	MYSTREAM_LOGI("[%s-%d]...\n",__FUNCTION__,__LINE__);

	Mediaplayer->pause();
	
	return 0;
}

int Mediaplayer_Resume(void)
{
	MYSTREAM_LOGI("[%s-%d]...\n",__FUNCTION__,__LINE__);

	Mediaplayer->start();

	return 0;
}

int Mediaplayer_Seek(int sec)
{
	MYSTREAM_LOGI("[%s-%d]...\n",__FUNCTION__,__LINE__);

	status_t st = Mediaplayer->seekTo(sec*1000);

	return st;
}

int Mediaplayer_getCurrentPosition(void)
{
	int		cur_time = 0;	

	Mediaplayer->getCurrentPosition(&cur_time);
	
	MYSTREAM_LOGI("[%s-%d].cur_time=%d ms..\n",__FUNCTION__,__LINE__,cur_time);

	return cur_time/1000;
}

int Mediaplayer_getDuration(void)
{
	int		duration = 0;
	
	Mediaplayer->getDuration(&duration);
	
	MYSTREAM_LOGI("[%s-%d].duration=%d ms..\n",__FUNCTION__,__LINE__,duration);

	return duration/1000;
}



chodison_mediaplayer.h

#ifndef _CHODISON_MEDIAPLAYER_H_
#define _CHODISON_MEDIAPLAYER_H_

#include <gui/Surface.h>

#include <android/log.h>
#define MYSTREAM_LOG_TAG "mystream_mediaplayer"

#define MYSTREAM_LOGE(...) __android_log_print(ANDROID_LOG_ERROR, MYSTREAM_LOG_TAG, __VA_ARGS__)
#define MYSTREAM_LOGI(...) __android_log_print(ANDROID_LOG_INFO, MYSTREAM_LOG_TAG, __VA_ARGS__)

void Mediaplayer_SetSurface(android::Surface* pSurface);

int Mediaplayer_Init(void);
int Mediaplayer_Deinit(void);
int Mediaplayer_Start(char *url);
int Mediaplayer_Init2(void);
int Mediaplayer_Start2(void);
int Mediaplayer_Stop(void);
int Mediaplayer_Pause(void);
int Mediaplayer_Resume(void);
int Mediaplayer_Seek(int sec);
int Mediaplayer_getCurrentPosition(void);
int Mediaplayer_getDuration(void);

#endif



 

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。