diff options
Diffstat (limited to 'cmds')
-rw-r--r-- | cmds/screenrecord/FrameOutput.cpp | 8 | ||||
-rw-r--r-- | cmds/screenrecord/FrameOutput.h | 12 | ||||
-rw-r--r-- | cmds/screenrecord/Overlay.cpp | 9 | ||||
-rw-r--r-- | cmds/screenrecord/Overlay.h | 10 | ||||
-rw-r--r-- | cmds/stagefright/SimplePlayer.cpp | 4 | ||||
-rw-r--r-- | cmds/stagefright/SineSource.cpp | 4 | ||||
-rw-r--r-- | cmds/stagefright/audioloop.cpp | 170 | ||||
-rw-r--r-- | cmds/stagefright/codec.cpp | 3 | ||||
-rw-r--r-- | cmds/stagefright/muxer.cpp | 3 | ||||
-rw-r--r-- | cmds/stagefright/record.cpp | 2 | ||||
-rw-r--r-- | cmds/stagefright/recordvideo.cpp | 14 | ||||
-rw-r--r-- | cmds/stagefright/sf2.cpp | 65 | ||||
-rw-r--r-- | cmds/stagefright/stagefright.cpp | 12 | ||||
-rw-r--r-- | cmds/stagefright/stream.cpp | 7 |
14 files changed, 209 insertions, 114 deletions
diff --git a/cmds/screenrecord/FrameOutput.cpp b/cmds/screenrecord/FrameOutput.cpp index 6c37501..4da16bc 100644 --- a/cmds/screenrecord/FrameOutput.cpp +++ b/cmds/screenrecord/FrameOutput.cpp @@ -67,8 +67,10 @@ status_t FrameOutput::createInputSurface(int width, int height, return UNKNOWN_ERROR; } - mBufferQueue = new BufferQueue(/*new GraphicBufferAlloc()*/); - mGlConsumer = new GLConsumer(mBufferQueue, mExtTextureName, + sp<IGraphicBufferProducer> producer; + sp<IGraphicBufferConsumer> consumer; + BufferQueue::createBufferQueue(&producer, &consumer); + mGlConsumer = new GLConsumer(consumer, mExtTextureName, GL_TEXTURE_EXTERNAL_OES); mGlConsumer->setName(String8("virtual display")); mGlConsumer->setDefaultBufferSize(width, height); @@ -79,7 +81,7 @@ status_t FrameOutput::createInputSurface(int width, int height, mPixelBuf = new uint8_t[width * height * kGlBytesPerPixel]; - *pBufferProducer = mBufferQueue; + *pBufferProducer = producer; ALOGD("FrameOutput::createInputSurface OK"); return NO_ERROR; diff --git a/cmds/screenrecord/FrameOutput.h b/cmds/screenrecord/FrameOutput.h index 4ac3e8a..c49ec3b 100644 --- a/cmds/screenrecord/FrameOutput.h +++ b/cmds/screenrecord/FrameOutput.h @@ -34,9 +34,6 @@ public: mExtTextureName(0), mPixelBuf(NULL) {} - virtual ~FrameOutput() { - delete[] mPixelBuf; - } // Create an "input surface", similar in purpose to a MediaCodec input // surface, that the virtual display can send buffers to. Also configures @@ -59,6 +56,11 @@ private: FrameOutput(const FrameOutput&); FrameOutput& operator=(const FrameOutput&); + // Destruction via RefBase. + virtual ~FrameOutput() { + delete[] mPixelBuf; + } + // (overrides GLConsumer::FrameAvailableListener method) virtual void onFrameAvailable(); @@ -75,10 +77,6 @@ private: // Set by the FrameAvailableListener callback. bool mFrameAvailable; - // Our queue. The producer side is passed to the virtual display, the - // consumer side feeds into our GLConsumer. - sp<BufferQueue> mBufferQueue; - // This receives frames from the virtual display and makes them available // as an external texture. sp<GLConsumer> mGlConsumer; diff --git a/cmds/screenrecord/Overlay.cpp b/cmds/screenrecord/Overlay.cpp index 2e98874..94f560d 100644 --- a/cmds/screenrecord/Overlay.cpp +++ b/cmds/screenrecord/Overlay.cpp @@ -84,7 +84,7 @@ status_t Overlay::start(const sp<IGraphicBufferProducer>& outputSurface, assert(mState == RUNNING); ALOGV("Overlay::start successful"); - *pBufferProducer = mBufferQueue; + *pBufferProducer = mProducer; return NO_ERROR; } @@ -169,8 +169,9 @@ status_t Overlay::setup_l() { return UNKNOWN_ERROR; } - mBufferQueue = new BufferQueue(/*new GraphicBufferAlloc()*/); - mGlConsumer = new GLConsumer(mBufferQueue, mExtTextureName, + sp<IGraphicBufferConsumer> consumer; + BufferQueue::createBufferQueue(&mProducer, &consumer); + mGlConsumer = new GLConsumer(consumer, mExtTextureName, GL_TEXTURE_EXTERNAL_OES); mGlConsumer->setName(String8("virtual display")); mGlConsumer->setDefaultBufferSize(width, height); @@ -187,7 +188,7 @@ void Overlay::release_l() { ALOGV("Overlay::release_l"); mOutputSurface.clear(); mGlConsumer.clear(); - mBufferQueue.clear(); + mProducer.clear(); mTexProgram.release(); mExtTexProgram.release(); diff --git a/cmds/screenrecord/Overlay.h b/cmds/screenrecord/Overlay.h index b8473b4..b1b5c29 100644 --- a/cmds/screenrecord/Overlay.h +++ b/cmds/screenrecord/Overlay.h @@ -47,7 +47,6 @@ public: mLastFrameNumber(-1), mTotalDroppedFrames(0) {} - virtual ~Overlay() { assert(mState == UNINITIALIZED || mState == STOPPED); } // Creates a thread that performs the overlay. Pass in the surface that // output will be sent to. @@ -71,6 +70,9 @@ private: Overlay(const Overlay&); Overlay& operator=(const Overlay&); + // Destruction via RefBase. + virtual ~Overlay() { assert(mState == UNINITIALIZED || mState == STOPPED); } + // Draw the initial info screen. static void doDrawInfoPage(const EglWindow& window, const Program& texRender, TextRenderer& textRenderer); @@ -120,9 +122,9 @@ private: // surface. sp<IGraphicBufferProducer> mOutputSurface; - // Our queue. The producer side is passed to the virtual display, the - // consumer side feeds into our GLConsumer. - sp<BufferQueue> mBufferQueue; + // Producer side of queue, passed into the virtual display. + // The consumer end feeds into our GLConsumer. + sp<IGraphicBufferProducer> mProducer; // This receives frames from the virtual display and makes them available // as an external texture. diff --git a/cmds/stagefright/SimplePlayer.cpp b/cmds/stagefright/SimplePlayer.cpp index 5d2d721..1b2f792 100644 --- a/cmds/stagefright/SimplePlayer.cpp +++ b/cmds/stagefright/SimplePlayer.cpp @@ -23,6 +23,7 @@ #include <gui/Surface.h> #include <media/AudioTrack.h> #include <media/ICrypto.h> +#include <media/IMediaHTTPService.h> #include <media/stagefright/foundation/ABuffer.h> #include <media/stagefright/foundation/ADebug.h> #include <media/stagefright/foundation/AMessage.h> @@ -275,7 +276,8 @@ status_t SimplePlayer::onPrepare() { mExtractor = new NuMediaExtractor; - status_t err = mExtractor->setDataSource(mPath.c_str()); + status_t err = mExtractor->setDataSource( + NULL /* httpService */, mPath.c_str()); if (err != OK) { mExtractor.clear(); diff --git a/cmds/stagefright/SineSource.cpp b/cmds/stagefright/SineSource.cpp index 14b4306..587077a 100644 --- a/cmds/stagefright/SineSource.cpp +++ b/cmds/stagefright/SineSource.cpp @@ -24,7 +24,7 @@ SineSource::~SineSource() { } } -status_t SineSource::start(MetaData *params) { +status_t SineSource::start(MetaData * /* params */) { CHECK(!mStarted); mGroup = new MediaBufferGroup; @@ -58,7 +58,7 @@ sp<MetaData> SineSource::getFormat() { } status_t SineSource::read( - MediaBuffer **out, const ReadOptions *options) { + MediaBuffer **out, const ReadOptions * /* options */) { *out = NULL; MediaBuffer *buffer; diff --git a/cmds/stagefright/audioloop.cpp b/cmds/stagefright/audioloop.cpp index ed7d6cb..96073f1 100644 --- a/cmds/stagefright/audioloop.cpp +++ b/cmds/stagefright/audioloop.cpp @@ -1,4 +1,18 @@ -#include "SineSource.h" +/* + * Copyright (C) 2014 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/mediarecorder.h> @@ -10,41 +24,79 @@ #include <media/stagefright/MetaData.h> #include <media/stagefright/OMXClient.h> #include <media/stagefright/OMXCodec.h> - -#include <system/audio.h> +#include "SineSource.h" using namespace android; -int main() { - // We only have an AMR-WB encoder on sholes... - static bool outputWBAMR = false; - static const int32_t kSampleRate = outputWBAMR ? 16000 : 8000; - static const int32_t kNumChannels = 1; +static void usage(const char* name) +{ + fprintf(stderr, "Usage: %s [-d duration] [-m] [-w] [<output-file>]\n", name); + fprintf(stderr, "Encodes either a sine wave or microphone input to AMR format\n"); + fprintf(stderr, " -d duration in seconds, default 5 seconds\n"); + fprintf(stderr, " -m use microphone for input, default sine source\n"); + fprintf(stderr, " -w use AMR wideband (default narrowband)\n"); + fprintf(stderr, " <output-file> output file for AMR encoding," + " if unspecified, decode to speaker.\n"); +} - android::ProcessState::self()->startThreadPool(); +int main(int argc, char* argv[]) +{ + static const int channels = 1; // not permitted to be stereo now + unsigned duration = 5; + bool useMic = false; + bool outputWBAMR = false; + bool playToSpeaker = true; + const char* fileOut = NULL; + int ch; + while ((ch = getopt(argc, argv, "d:mw")) != -1) { + switch (ch) { + case 'd': + duration = atoi(optarg); + break; + case 'm': + useMic = true; + break; + case 'w': + outputWBAMR = true; + break; + default: + usage(argv[0]); + return -1; + } + } + argc -= optind; + argv += optind; + if (argc == 1) { + fileOut = argv[0]; + } + const int32_t kSampleRate = outputWBAMR ? 16000 : 8000; + const int32_t kBitRate = outputWBAMR ? 16000 : 8000; + android::ProcessState::self()->startThreadPool(); OMXClient client; CHECK_EQ(client.connect(), (status_t)OK); - -#if 0 - sp<MediaSource> source = new SineSource(kSampleRate, kNumChannels); -#else - sp<MediaSource> source = new AudioSource( - AUDIO_SOURCE_DEFAULT, - kSampleRate, - audio_channel_in_mask_from_count(kNumChannels)); -#endif + sp<MediaSource> source; + + if (useMic) { + // talk into the appropriate microphone for the duration + source = new AudioSource( + AUDIO_SOURCE_MIC, + kSampleRate, + channels); + } else { + // use a sine source at 500 hz. + source = new SineSource(kSampleRate, channels); + } sp<MetaData> meta = new MetaData; - meta->setCString( kKeyMIMEType, outputWBAMR ? MEDIA_MIMETYPE_AUDIO_AMR_WB - : MEDIA_MIMETYPE_AUDIO_AMR_NB); + : MEDIA_MIMETYPE_AUDIO_AMR_NB); - meta->setInt32(kKeyChannelCount, kNumChannels); + meta->setInt32(kKeyChannelCount, channels); meta->setInt32(kKeySampleRate, kSampleRate); - + meta->setInt32(kKeyBitRate, kBitRate); int32_t maxInputSize; if (source->getFormat()->findInt32(kKeyMaxInputSize, &maxInputSize)) { meta->setInt32(kKeyMaxInputSize, maxInputSize); @@ -55,47 +107,41 @@ int main() { meta, true /* createEncoder */, source); -#if 1 - sp<AMRWriter> writer = new AMRWriter("/sdcard/out.amr"); - writer->addSource(encoder); - writer->start(); - sleep(10); - writer->stop(); -#else - sp<MediaSource> decoder = OMXCodec::Create( - client.interface(), - meta, false /* createEncoder */, - encoder); - -#if 0 - AudioPlayer *player = new AudioPlayer(NULL); - player->setSource(decoder); - - player->start(); - - sleep(10); - - player->stop(); - - delete player; - player = NULL; -#elif 0 - CHECK_EQ(decoder->start(), (status_t)OK); - - MediaBuffer *buffer; - while (decoder->read(&buffer) == OK) { - // do something with buffer - - putchar('.'); - fflush(stdout); - - buffer->release(); - buffer = NULL; + if (fileOut != NULL) { + // target file specified, write encoded AMR output + sp<AMRWriter> writer = new AMRWriter(fileOut); + writer->addSource(encoder); + writer->start(); + sleep(duration); + writer->stop(); + } else { + // otherwise decode to speaker + sp<MediaSource> decoder = OMXCodec::Create( + client.interface(), + meta, false /* createEncoder */, + encoder); + + if (playToSpeaker) { + AudioPlayer *player = new AudioPlayer(NULL); + player->setSource(decoder); + player->start(); + sleep(duration); + source->stop(); // must stop source otherwise delete player will hang + delete player; // there is no player->stop()... + } else { + CHECK_EQ(decoder->start(), (status_t)OK); + MediaBuffer* buffer; + while (decoder->read(&buffer) == OK) { + // do something with buffer (save it eventually?) + // need to stop after some count though... + putchar('.'); + fflush(stdout); + buffer->release(); + buffer = NULL; + } + CHECK_EQ(decoder->stop(), (status_t)OK); + } } - CHECK_EQ(decoder->stop(), (status_t)OK); -#endif -#endif - return 0; } diff --git a/cmds/stagefright/codec.cpp b/cmds/stagefright/codec.cpp index d125ad1..fd02bcc 100644 --- a/cmds/stagefright/codec.cpp +++ b/cmds/stagefright/codec.cpp @@ -24,6 +24,7 @@ #include <binder/IServiceManager.h> #include <binder/ProcessState.h> #include <media/ICrypto.h> +#include <media/IMediaHTTPService.h> #include <media/IMediaPlayerService.h> #include <media/stagefright/foundation/ABuffer.h> #include <media/stagefright/foundation/ADebug.h> @@ -76,7 +77,7 @@ static int decode( static int64_t kTimeout = 500ll; sp<NuMediaExtractor> extractor = new NuMediaExtractor; - if (extractor->setDataSource(path) != OK) { + if (extractor->setDataSource(NULL /* httpService */, path) != OK) { fprintf(stderr, "unable to instantiate extractor.\n"); return 1; } diff --git a/cmds/stagefright/muxer.cpp b/cmds/stagefright/muxer.cpp index 90daea2..f4a33e8 100644 --- a/cmds/stagefright/muxer.cpp +++ b/cmds/stagefright/muxer.cpp @@ -20,6 +20,7 @@ #include <utils/Log.h> #include <binder/ProcessState.h> +#include <media/IMediaHTTPService.h> #include <media/stagefright/foundation/ABuffer.h> #include <media/stagefright/foundation/ADebug.h> #include <media/stagefright/foundation/ALooper.h> @@ -59,7 +60,7 @@ static int muxing( int trimEndTimeMs, int rotationDegrees) { sp<NuMediaExtractor> extractor = new NuMediaExtractor; - if (extractor->setDataSource(path) != OK) { + if (extractor->setDataSource(NULL /* httpService */, path) != OK) { fprintf(stderr, "unable to instantiate extractor. %s\n", path); return 1; } diff --git a/cmds/stagefright/record.cpp b/cmds/stagefright/record.cpp index b7a40c2..fdc352e 100644 --- a/cmds/stagefright/record.cpp +++ b/cmds/stagefright/record.cpp @@ -296,7 +296,7 @@ int main(int argc, char **argv) { } #else -int main(int argc, char **argv) { +int main(int /* argc */, char ** /* argv */) { android::ProcessState::self()->startThreadPool(); OMXClient client; diff --git a/cmds/stagefright/recordvideo.cpp b/cmds/stagefright/recordvideo.cpp index 1d267f9..9f547c7 100644 --- a/cmds/stagefright/recordvideo.cpp +++ b/cmds/stagefright/recordvideo.cpp @@ -73,7 +73,7 @@ public: return meta; } - virtual status_t start(MetaData *params) { + virtual status_t start(MetaData *params __unused) { mNumFramesOutput = 0; return OK; } @@ -83,7 +83,7 @@ public: } virtual status_t read( - MediaBuffer **buffer, const MediaSource::ReadOptions *options) { + MediaBuffer **buffer, const MediaSource::ReadOptions *options __unused) { if (mNumFramesOutput % 10 == 0) { fprintf(stderr, "."); @@ -100,8 +100,12 @@ public: // We don't care about the contents. we just test video encoder // Also, by skipping the content generation, we can return from // read() much faster. - //char x = (char)((double)rand() / RAND_MAX * 255); - //memset((*buffer)->data(), x, mSize); +#if 0 + // iterate through solid planes of color. + static unsigned char x = 0x60; + memset((*buffer)->data(), x, mSize); + x = x >= 0xa0 ? 0x60 : x + 1; +#endif (*buffer)->set_range(0, mSize); (*buffer)->meta_data()->clear(); (*buffer)->meta_data()->setInt64( @@ -163,7 +167,7 @@ int main(int argc, char **argv) { int level = -1; // Encoder specific default int profile = -1; // Encoder specific default int codec = 0; - char *fileName = "/sdcard/output.mp4"; + const char *fileName = "/sdcard/output.mp4"; bool preferSoftwareCodec = false; android::ProcessState::self()->startThreadPool(); diff --git a/cmds/stagefright/sf2.cpp b/cmds/stagefright/sf2.cpp index b2b9ce5..3c0c7ec 100644 --- a/cmds/stagefright/sf2.cpp +++ b/cmds/stagefright/sf2.cpp @@ -19,8 +19,12 @@ #include <inttypes.h> #include <utils/Log.h> +#include <signal.h> + #include <binder/ProcessState.h> +#include <media/IMediaHTTPService.h> + #include <media/stagefright/foundation/hexdump.h> #include <media/stagefright/foundation/ABuffer.h> #include <media/stagefright/foundation/ADebug.h> @@ -43,6 +47,18 @@ using namespace android; +volatile static bool ctrlc = false; + +static sighandler_t oldhandler = NULL; + +static void mysighandler(int signum) { + if (signum == SIGINT) { + ctrlc = true; + return; + } + oldhandler(signum); +} + struct Controller : public AHandler { Controller(const char *uri, bool decodeAudio, const sp<Surface> &surface, bool renderToSurface) @@ -63,7 +79,30 @@ protected: virtual ~Controller() { } + virtual void printStatistics() { + int64_t delayUs = ALooper::GetNowUs() - mStartTimeUs; + + if (mDecodeAudio) { + printf("%" PRId64 " bytes received. %.2f KB/sec\n", + mTotalBytesReceived, + mTotalBytesReceived * 1E6 / 1024 / delayUs); + } else { + printf("%d frames decoded, %.2f fps. %" PRId64 " bytes " + "received. %.2f KB/sec\n", + mNumOutputBuffersReceived, + mNumOutputBuffersReceived * 1E6 / delayUs, + mTotalBytesReceived, + mTotalBytesReceived * 1E6 / 1024 / delayUs); + } + } + virtual void onMessageReceived(const sp<AMessage> &msg) { + if (ctrlc) { + printf("\n"); + printStatistics(); + (new AMessage(kWhatStop, id()))->post(); + ctrlc = false; + } switch (msg->what()) { case kWhatStart: { @@ -76,7 +115,8 @@ protected: #endif sp<DataSource> dataSource = - DataSource::CreateFromURI(mURI.c_str()); + DataSource::CreateFromURI( + NULL /* httpService */, mURI.c_str()); sp<MediaExtractor> extractor = MediaExtractor::Create(dataSource); @@ -99,7 +139,10 @@ protected: break; } } - CHECK(mSource != NULL); + if (mSource == NULL) { + printf("no %s track found\n", mDecodeAudio ? "audio" : "video"); + exit (1); + } CHECK_EQ(mSource->start(), (status_t)OK); @@ -181,21 +224,7 @@ protected: || what == ACodec::kWhatError) { printf((what == ACodec::kWhatEOS) ? "$\n" : "E\n"); - int64_t delayUs = ALooper::GetNowUs() - mStartTimeUs; - - if (mDecodeAudio) { - printf("%" PRId64 " bytes received. %.2f KB/sec\n", - mTotalBytesReceived, - mTotalBytesReceived * 1E6 / 1024 / delayUs); - } else { - printf("%d frames decoded, %.2f fps. %" PRId64 " bytes " - "received. %.2f KB/sec\n", - mNumOutputBuffersReceived, - mNumOutputBuffersReceived * 1E6 / delayUs, - mTotalBytesReceived, - mTotalBytesReceived * 1E6 / 1024 / delayUs); - } - + printStatistics(); (new AMessage(kWhatStop, id()))->post(); } else if (what == ACodec::kWhatFlushCompleted) { mSeekState = SEEK_FLUSH_COMPLETED; @@ -639,6 +668,8 @@ int main(int argc, char **argv) { looper->registerHandler(controller); + signal(SIGINT, mysighandler); + controller->startAsync(); CHECK_EQ(looper->start(true /* runOnCallingThread */), (status_t)OK); diff --git a/cmds/stagefright/stagefright.cpp b/cmds/stagefright/stagefright.cpp index ab2c54b..b70afe6 100644 --- a/cmds/stagefright/stagefright.cpp +++ b/cmds/stagefright/stagefright.cpp @@ -29,6 +29,7 @@ #include <binder/IServiceManager.h> #include <binder/ProcessState.h> +#include <media/IMediaHTTPService.h> #include <media/IMediaPlayerService.h> #include <media/stagefright/foundation/ALooper.h> #include "include/NuCachedSource2.h" @@ -938,9 +939,11 @@ int main(int argc, char **argv) { } else { CHECK(useSurfaceTexAlloc); - sp<BufferQueue> bq = new BufferQueue(); - sp<GLConsumer> texture = new GLConsumer(bq, 0 /* tex */); - gSurface = new Surface(bq); + sp<IGraphicBufferProducer> producer; + sp<IGraphicBufferConsumer> consumer; + BufferQueue::createBufferQueue(&producer, &consumer); + sp<GLConsumer> texture = new GLConsumer(consumer, 0 /* tex */); + gSurface = new Surface(producer); } CHECK_EQ((status_t)OK, @@ -958,7 +961,8 @@ int main(int argc, char **argv) { const char *filename = argv[k]; - sp<DataSource> dataSource = DataSource::CreateFromURI(filename); + sp<DataSource> dataSource = + DataSource::CreateFromURI(NULL /* httpService */, filename); if (strncasecmp(filename, "sine:", 5) && dataSource == NULL) { fprintf(stderr, "Unable to create data source.\n"); diff --git a/cmds/stagefright/stream.cpp b/cmds/stagefright/stream.cpp index dba67a9..0566d14 100644 --- a/cmds/stagefright/stream.cpp +++ b/cmds/stagefright/stream.cpp @@ -21,6 +21,7 @@ #include <binder/ProcessState.h> #include <cutils/properties.h> // for property_get +#include <media/IMediaHTTPService.h> #include <media/IStreamSource.h> #include <media/mediaplayer.h> #include <media/stagefright/foundation/ADebug.h> @@ -159,7 +160,9 @@ private: MyConvertingStreamSource::MyConvertingStreamSource(const char *filename) : mCurrentBufferIndex(-1), mCurrentBufferOffset(0) { - sp<DataSource> dataSource = DataSource::CreateFromURI(filename); + sp<DataSource> dataSource = + DataSource::CreateFromURI(NULL /* httpService */, filename); + CHECK(dataSource != NULL); sp<MediaExtractor> extractor = MediaExtractor::Create(dataSource); @@ -371,7 +374,7 @@ int main(int argc, char **argv) { } sp<IMediaPlayer> player = - service->create(client, 0); + service->create(client, AUDIO_SESSION_ALLOCATE); if (player != NULL && player->setDataSource(source) == NO_ERROR) { player->setVideoSurfaceTexture(surface->getIGraphicBufferProducer()); |