"The first chapter-android platform buffer play Explore" Buffer play Demo

Source: Internet
Author: User

From Google's release of the various versions of the Android version of the source, android4.0 started to support the buffer playback of the interface and demo, after compiling the Android SDK in out will generate an executable file stream, This is a very good demo test program, support H264 TS playback, program source code location with android4.3 as an example, directory: Android4.3\frameworks\av\cmds\stagefright, The corresponding file for Stream.cpp, universal player with buffer to do a breach here oh, from here, interested can do so, first do a demo of their own, first play the local file, and then the streaming media protocol added in the set achievement OK, this file code is as follows:

/*

* Copyright (C) The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* You are not a use this file except in compliance with the License.
* Obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable or agreed to writing, software
* Distributed under the License is distributed on a "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.
*/


#define LOG_NDEBUG 0
#define LOG_TAG "Stream"
#include "Utils/log.h"


#include <binder/ProcessState.h>
#include <cutils/properties.h>//For Property_get


#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/MPEG2TSWriter.h>
#include <media/stagefright/MediaExtractor.h>
#include <media/stagefright/MediaSource.h>
#include <media/stagefright/MetaData.h>


#include <binder/IServiceManager.h>
#include <media/IMediaPlayerService.h>
#include <gui/ISurfaceComposer.h>
#include <gui/SurfaceComposerClient.h>
#include <gui/Surface.h>


#include <fcntl.h>
#include <ui/DisplayInfo.h>


using namespace Android;


struct Mystreamsource:public Bnstreamsource {
Object assumes ownership of FD.
Mystreamsource (int fd);


virtual void Setlistener (const sp<istreamlistener> &listener);
virtual void setbuffers (const vector<sp<imemory> > &buffers);


virtual void onbufferavailable (size_t index);


Protected
Virtual ~mystreamsource ();


Private
int mFd;
off64_t mfilesize;
uint64_t mnumpacketssent;


Sp<istreamlistener> Mlistener;
vector<sp<imemory> > Mbuffers;


Disallow_evil_constructors (Mystreamsource);
};


Mystreamsource::mystreamsource (int fd)
: MFd (FD),
Mfilesize (0),
Mnumpacketssent (0) {
Check_ge (FD, 0);


Mfilesize = lseek64 (FD, 0, seek_end);
Lseek64 (FD, 0, Seek_set);
}


Mystreamsource::~mystreamsource () {
Close (mFd);
MFd =-1;
}


void Mystreamsource::setlistener (const sp<istreamlistener> &listener) {
Mlistener = listener;
}


void Mystreamsource::setbuffers (const vector<sp<imemory> > &buffers) {
Mbuffers = buffers;
}


void Mystreamsource::onbufferavailable (size_t index) {
CHECK_LT (Index, Mbuffers.size ());


#if 0
if (mnumpacketssent >= 20000) {
Alogi ("Signalling discontinuity Now");


off64_t offset = 0;
CHECK ((offset% 188) = = 0);


Lseek (mFd, offset, seek_set);


Sp<amessage> extra = new Amessage;
Extra->setint32 (istreamlistener::kkeyformatchange, 0);


Mlistener->issuecommand (
Istreamlistener::D iscontinuity, FALSE/* synchronous */, extra);


mnumpacketssent = 0;
}
#endif


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


struct Myconvertingstreamsource:public Bnstreamsource {
Myconvertingstreamsource (const char *filename);


virtual void Setlistener (const sp<istreamlistener> &listener);
virtual void setbuffers (const vector<sp<imemory> > &buffers);


virtual void onbufferavailable (size_t index);


Protected
Virtual ~myconvertingstreamsource ();


Private
Mutex MLock;
Condition mcondition;


Sp<istreamlistener> Mlistener;
vector<sp<imemory> > Mbuffers;


Sp<mpeg2tswriter> Mwriter;


ssize_t Mcurrentbufferindex;
size_t Mcurrentbufferoffset;


List<size_t> Mbufferqueue;


Static ssize_t writedatawrapper (void *me, const void *data, size_t size);
ssize_t writedata (const void *data, size_t size);


Disallow_evil_constructors (Myconvertingstreamsource);
};


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


Myconvertingstreamsource::myconvertingstreamsource (const char *filename)
: Mcurrentbufferindex (-1),
Mcurrentbufferoffset (0) {
sp<datasource> DataSource = Datasource::createfromuri (filename);
CHECK (DataSource! = NULL);


sp<mediaextractor> extractor = mediaextractor::create (DataSource);
CHECK (Extractor! = NULL);


Mwriter = new Mpeg2tswriter (
this, &myconvertingstreamsource::writedatawrapper);


for (size_t i = 0; i < extractor->counttracks (); ++i) {
Const sp<metadata> &meta = Extractor->gettrackmetadata (i);


const char *mime;
CHECK (Meta->findcstring (Kkeymimetype, &mime));


if (strncasecmp ("video/", mime, 6) && strncasecmp ("audio/", mime, 6)) {
Continue
}


Check_eq (Mwriter->addsource (Extractor->gettrack (i)), (status_t) OK);
}


Check_eq (Mwriter->start (), (status_t) OK);
}


Myconvertingstreamsource::~myconvertingstreamsource () {
}


void Myconvertingstreamsource::setlistener (
Const sp<istreamlistener> &listener) {
Mlistener = listener;
}


void Myconvertingstreamsource::setbuffers (
Const vector<sp<imemory> > &buffers) {
Mbuffers = buffers;
}


ssize_t Myconvertingstreamsource::writedatawrapper (
void *me, const void *data, size_t size) {
return Static_cast<myconvertingstreamsource *> (Me)->writedata (data, size);
}


ssize_t myconvertingstreamsource::writedata (const void *data, size_t size) {
size_t totalwritten = 0;


while (Size > 0) {
Mutex::autolock Autolock (MLock);


if (Mcurrentbufferindex < 0) {
while (Mbufferqueue.empty ()) {
Mcondition.wait (MLock);
}


Mcurrentbufferindex = *mbufferqueue.begin ();
Mcurrentbufferoffset = 0;


Mbufferqueue.erase (Mbufferqueue.begin ());
}


Sp<imemory> mem = Mbuffers.itemat (Mcurrentbufferindex);


size_t copy = size;
if (copy + Mcurrentbufferoffset > mem->size ()) {
copy = Mem->size ()-mcurrentbufferoffset;
}


memcpy ((uint8_t *) mem->pointer () + mcurrentbufferoffset, data, copy);
Mcurrentbufferoffset + = copy;


if (Mcurrentbufferoffset = = Mem->size ()) {
Mlistener->queuebuffer (Mcurrentbufferindex, Mcurrentbufferoffset);
Mcurrentbufferindex =-1;
}


data = (const uint8_t *) data + copy;
Size-= copy;


Totalwritten + = copy;
}


Return (ssize_t) Totalwritten;
}


void Myconvertingstreamsource::onbufferavailable (size_t index) {
Mutex::autolock Autolock (MLock);


Mbufferqueue.push_back (index);
Mcondition.signal ();


if (Mwriter->reachedeos ()) {
if (mcurrentbufferindex >= 0) {
Mlistener->queuebuffer (Mcurrentbufferindex, Mcurrentbufferoffset);
Mcurrentbufferindex =-1;
}


Mlistener->issuecommand (Istreamlistener::eos, FALSE/* synchronous */);
}
}


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


struct Myclient:public bnmediaplayerclient {
MyClient ()
: Meos (False) {
}


virtual void Notify (int msg, int ext1, int ext2, const Parcel *obj) {
Mutex::autolock Autolock (MLock);


if (msg = = Media_error | | msg = = media_playback_complete) {
Meos = true;
Mcondition.signal ();
}
}


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


int main (int argc, char **argv) {
Android::P rocessstate::self ()->startthreadpool ();


Datasource::registerdefaultsniffers ();


if (argc! = 2) {
fprintf (stderr, "Usage:%s filename\n", argv[0]);
return 1;
}


sp<surfacecomposerclient> composerclient = new Surfacecomposerclient;
Check_eq (Composerclient->initcheck (), (status_t) OK);


sp<ibinder> Display (Surfacecomposerclient::getbuiltindisplay (
Isurfacecomposer::edisplayidmain));
DisplayInfo info;
Surfacecomposerclient::getdisplayinfo (display, &info);
ssize_t displaywidth = INFO.W;
ssize_t displayheight = info.h;


ALOGV ("Display is%d x%d\n", Displaywidth, Displayheight);


sp<surfacecontrol> control =
Composerclient->createsurface (
String8 ("A Surface"),
Displaywidth,
Displayheight,
pixel_format_rgb_565,
0);


CHECK (Control! = NULL);
CHECK (Control->isvalid ());


Surfacecomposerclient::openglobaltransaction ();
Check_eq (Control->setlayer (Int_max), (status_t) OK);
Check_eq (Control->show (), (status_t) OK);
Surfacecomposerclient::closeglobaltransaction ();


sp<surface> Surface = Control->getsurface ();
CHECK (surface! = NULL);


sp<iservicemanager> sm = Defaultservicemanager ();
sp<ibinder> Binder = Sm->getservice (String16 ("Media.player"));
sp<imediaplayerservice> service = interface_cast<imediaplayerservice> (binder);


CHECK (Service.get ()! = NULL);


sp<myclient> client = new MyClient;


Sp<istreamsource> source;


Char Prop[property_value_max];
BOOL Usemp4 = Property_get ("Media.stagefright.use-mp4source", prop, NULL) &&
(!STRCMP (prop, "1") | |!strcasecmp (prop, "true"));


size_t len = strlen (argv[1]);
if ((!usemp4 && len >= 3 &&!strcasecmp (". ts", &argv[1][len-3])) | |
(Usemp4 && len >= 4 &&
(!STRCASECMP (". mp4", &argv[1][len-4])
|| !STRCASECMP (". 3gp", &argv[1][len-4])
|| !STRCASECMP (". 3g2", &argv[1][len-4]))) {
int fd = open (argv[1], o_rdonly);


if (FD < 0) {
fprintf (stderr, "Failed to open file '%s '.", argv[1]);
return 1;
}


Source = new Mystreamsource (FD);
} else {
printf ("Converting file to transport stream for streaming...\n");


Source = new Myconvertingstreamsource (argv[1]);
}


Sp<imediaplayer> player =
Service->create (client, 0);


if (player! = NULL && player->setdatasource (source) = = No_error) {
Player->setvideosurfacetexture (Surface->getigraphicbufferproducer ());
Player->start ();


Client->waitforeos ();


Player->stop ();
} else {
fprintf (stderr, "failed to instantiate player.\n");
}


Composerclient->dispose ();


return 0;
}

"The first chapter-android platform buffer play Explore" Buffer play Demo

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.