[Chapter 1-buffer playback on the android platform] buffer play demo,-androidbuffer
From the source code of various android versions released by google, android has implemented interfaces and Demos supporting buffer playback. After compiling the android SDK, an executable file stream is generated in the out, this is a very good demo test program that supports ts playback of H264. the source code of the program is described in android4.3 as an example. The directory is android4.3 \ frameworks \ av \ cmds \ stagefright, the corresponding file is stream. cpp: the universal player uses buffer as the breakthrough point. From here on, you can do this if you are interested. First, you must make your own DEMO and play the local file first, then, add the Streaming Media Protocol to the integration. The code for this file is as follows:
/*
* Copyright (C) 2010 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License ");
* You may not use this file before t in compliance with the License.
* You may obtain a copy of the License
*
* 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.
*/
// # 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 & gt; = 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: DISCONTINUITY, 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 ready y (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: ProcessState: self ()-> startThreadPool ();
DataSource: registerdefadefasniffers ();
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;
}
In the case of BufferOverflowException during android app development, what is the error?
The code you posted in jingyan.baidu.com/... B .htmlhas nothing to do with this error. It should be an eclipse issue. Here are several solutions you can refer
Buffer for android to watch online videos
This may be written into the player code.
Difficult to find files