MediaCodecSource.cpp revision 72cecca17d735db6532c45f0a7e10c47ee6f065a
172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang/* 272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang * Copyright 2014, The Android Open Source Project 372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang * 472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang * Licensed under the Apache License, Version 2.0 (the "License"); 572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang * you may not use this file except in compliance with the License. 672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang * You may obtain a copy of the License at 772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang * 872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang * http://www.apache.org/licenses/LICENSE-2.0 972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang * 1072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang * Unless required by applicable law or agreed to in writing, software 1172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang * distributed under the License is distributed on an "AS IS" BASIS, 1272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang * See the License for the specific language governing permissions and 1472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang * limitations under the License. 1572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang */ 1672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 1772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang//#define LOG_NDEBUG 0 1872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang#define LOG_TAG "MediaCodecSource" 1972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang#define DEBUG_DRIFT_TIME 0 2072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang#include <gui/IGraphicBufferProducer.h> 2172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang#include <gui/Surface.h> 2272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang#include <media/ICrypto.h> 2372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang#include <media/stagefright/foundation/ABuffer.h> 2472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang#include <media/stagefright/foundation/ADebug.h> 2572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang#include <media/stagefright/foundation/ALooper.h> 2672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang#include <media/stagefright/foundation/AMessage.h> 2772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang#include <media/stagefright/MediaBuffer.h> 2872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang#include <media/stagefright/MediaCodec.h> 2972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang#include <media/stagefright/MetaData.h> 3072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang#include <media/stagefright/MediaErrors.h> 3172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang#include <media/stagefright/MediaSource.h> 3272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang#include <media/stagefright/MediaCodecSource.h> 3372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang#include <media/stagefright/Utils.h> 3472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 3572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhangnamespace android { 3672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 3772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhangstatic void ReleaseMediaBufferReference(const sp<ABuffer> &accessUnit) { 3872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang void *mbuf; 3972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang if (accessUnit->meta()->findPointer("mediaBuffer", &mbuf) 4072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang && mbuf != NULL) { 4172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang ALOGV("releasing mbuf %p", mbuf); 4272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 4372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang accessUnit->meta()->setPointer("mediaBuffer", NULL); 4472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 4572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang static_cast<MediaBuffer *>(mbuf)->release(); 4672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mbuf = NULL; 4772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 4872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang} 4972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 5072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhangstruct MediaCodecSource::Puller : public AHandler { 5172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang Puller(const sp<MediaSource> &source); 5272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 5372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang status_t start(const sp<MetaData> &meta, const sp<AMessage> ¬ify); 5472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang void stopAsync(); 5572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 5672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang void pause(); 5772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang void resume(); 5872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 5972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhangprotected: 6072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang virtual void onMessageReceived(const sp<AMessage> &msg); 6172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang virtual ~Puller(); 6272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 6372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhangprivate: 6472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang enum { 6572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang kWhatStart = 'msta', 6672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang kWhatStop, 6772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang kWhatPull, 6872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang kWhatPause, 6972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang kWhatResume, 7072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang }; 7172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 7272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang sp<MediaSource> mSource; 7372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang sp<AMessage> mNotify; 7472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang sp<ALooper> mLooper; 7572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang int32_t mPullGeneration; 7672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang bool mIsAudio; 7772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang bool mPaused; 7872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang bool mReachedEOS; 7972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 8072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang status_t postSynchronouslyAndReturnError(const sp<AMessage> &msg); 8172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang void schedulePull(); 8272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang void handleEOS(); 8372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 8472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang DISALLOW_EVIL_CONSTRUCTORS(Puller); 8572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang}; 8672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 8772cecca17d735db6532c45f0a7e10c47ee6f065aChong ZhangMediaCodecSource::Puller::Puller(const sp<MediaSource> &source) 8872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang : mSource(source), 8972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mLooper(new ALooper()), 9072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mPullGeneration(0), 9172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mIsAudio(false), 9272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mPaused(false), 9372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mReachedEOS(false) { 9472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang sp<MetaData> meta = source->getFormat(); 9572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang const char *mime; 9672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang CHECK(meta->findCString(kKeyMIMEType, &mime)); 9772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 9872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mIsAudio = !strncasecmp(mime, "audio/", 6); 9972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 10072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mLooper->setName("pull_looper"); 10172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang} 10272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 10372cecca17d735db6532c45f0a7e10c47ee6f065aChong ZhangMediaCodecSource::Puller::~Puller() { 10472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mLooper->unregisterHandler(id()); 10572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mLooper->stop(); 10672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang} 10772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 10872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhangstatus_t MediaCodecSource::Puller::postSynchronouslyAndReturnError( 10972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang const sp<AMessage> &msg) { 11072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang sp<AMessage> response; 11172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang status_t err = msg->postAndAwaitResponse(&response); 11272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 11372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang if (err != OK) { 11472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang return err; 11572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 11672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 11772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang if (!response->findInt32("err", &err)) { 11872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang err = OK; 11972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 12072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 12172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang return err; 12272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang} 12372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 12472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhangstatus_t MediaCodecSource::Puller::start(const sp<MetaData> &meta, 12572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang const sp<AMessage> ¬ify) { 12672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang ALOGV("puller (%s) start", mIsAudio ? "audio" : "video"); 12772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mLooper->start( 12872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang false /* runOnCallingThread */, 12972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang false /* canCallJava */, 13072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang PRIORITY_AUDIO); 13172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mLooper->registerHandler(this); 13272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mNotify = notify; 13372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 13472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang sp<AMessage> msg = new AMessage(kWhatStart, id()); 13572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang msg->setObject("meta", meta); 13672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang return postSynchronouslyAndReturnError(msg); 13772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang} 13872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 13972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhangvoid MediaCodecSource::Puller::stopAsync() { 14072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang ALOGV("puller (%s) stopAsync", mIsAudio ? "audio" : "video"); 14172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang (new AMessage(kWhatStop, id()))->post(); 14272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang} 14372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 14472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhangvoid MediaCodecSource::Puller::pause() { 14572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang (new AMessage(kWhatPause, id()))->post(); 14672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang} 14772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 14872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhangvoid MediaCodecSource::Puller::resume() { 14972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang (new AMessage(kWhatResume, id()))->post(); 15072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang} 15172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 15272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhangvoid MediaCodecSource::Puller::schedulePull() { 15372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang sp<AMessage> msg = new AMessage(kWhatPull, id()); 15472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang msg->setInt32("generation", mPullGeneration); 15572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang msg->post(); 15672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang} 15772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 15872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhangvoid MediaCodecSource::Puller::handleEOS() { 15972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang if (!mReachedEOS) { 16072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang ALOGV("puller (%s) posting EOS", mIsAudio ? "audio" : "video"); 16172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mReachedEOS = true; 16272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang sp<AMessage> notify = mNotify->dup(); 16372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang notify->setPointer("accessUnit", NULL); 16472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang notify->post(); 16572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 16672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang} 16772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 16872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhangvoid MediaCodecSource::Puller::onMessageReceived(const sp<AMessage> &msg) { 16972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang switch (msg->what()) { 17072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang case kWhatStart: 17172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang { 17272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang sp<RefBase> obj; 17372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang CHECK(msg->findObject("meta", &obj)); 17472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 17572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mReachedEOS = false; 17672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 17772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang status_t err = mSource->start(static_cast<MetaData *>(obj.get())); 17872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 17972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang if (err == OK) { 18072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang schedulePull(); 18172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 18272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 18372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang sp<AMessage> response = new AMessage; 18472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang response->setInt32("err", err); 18572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 18672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang uint32_t replyID; 18772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang CHECK(msg->senderAwaitsResponse(&replyID)); 18872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang response->postReply(replyID); 18972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang break; 19072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 19172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 19272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang case kWhatStop: 19372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang { 19472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang ALOGV("source (%s) stopping", mIsAudio ? "audio" : "video"); 19572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mSource->stop(); 19672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang ALOGV("source (%s) stopped", mIsAudio ? "audio" : "video"); 19772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang ++mPullGeneration; 19872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 19972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang handleEOS(); 20072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang break; 20172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 20272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 20372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang case kWhatPull: 20472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang { 20572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang int32_t generation; 20672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang CHECK(msg->findInt32("generation", &generation)); 20772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 20872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang if (generation != mPullGeneration) { 20972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang break; 21072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 21172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 21272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang MediaBuffer *mbuf; 21372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang status_t err = mSource->read(&mbuf); 21472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 21572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang if (mPaused) { 21672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang if (err == OK) { 21772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mbuf->release(); 21872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mbuf = NULL; 21972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 22072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 22172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang msg->post(); 22272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang break; 22372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 22472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 22572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang if (err != OK) { 22672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang if (err == ERROR_END_OF_STREAM) { 22772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang ALOGV("stream ended, mbuf %p", mbuf); 22872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } else { 22972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang ALOGE("error %d reading stream.", err); 23072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 23172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang handleEOS(); 23272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } else { 23372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang sp<AMessage> notify = mNotify->dup(); 23472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 23572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang notify->setPointer("accessUnit", mbuf); 23672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang notify->post(); 23772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 23872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang msg->post(); 23972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 24072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang break; 24172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 24272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 24372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang case kWhatPause: 24472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang { 24572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mPaused = true; 24672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang break; 24772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 24872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 24972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang case kWhatResume: 25072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang { 25172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mPaused = false; 25272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang break; 25372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 25472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 25572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang default: 25672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang TRESPASS(); 25772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 25872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang} 25972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 26072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang// static 26172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhangsp<MediaCodecSource> MediaCodecSource::Create( 26272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang const sp<ALooper> &looper, 26372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang const sp<AMessage> &format, 26472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang const sp<MediaSource> &source, 26572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang uint32_t flags) { 26672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang sp<MediaCodecSource> mediaSource = 26772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang new MediaCodecSource(looper, format, source, flags); 26872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 26972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang if (mediaSource->init() == OK) { 27072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang return mediaSource; 27172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 27272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang return NULL; 27372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang} 27472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 27572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhangstatus_t MediaCodecSource::start(MetaData* params) { 27672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang sp<AMessage> msg = new AMessage(kWhatStart, mReflector->id()); 27772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang msg->setObject("meta", params); 27872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang return postSynchronouslyAndReturnError(msg); 27972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang} 28072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 28172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhangstatus_t MediaCodecSource::stop() { 28272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang sp<AMessage> msg = new AMessage(kWhatStop, mReflector->id()); 28372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang return postSynchronouslyAndReturnError(msg); 28472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang} 28572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 28672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhangstatus_t MediaCodecSource::pause() { 28772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang (new AMessage(kWhatPause, mReflector->id()))->post(); 28872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang return OK; 28972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang} 29072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 29172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhangsp<IGraphicBufferProducer> MediaCodecSource::getGraphicBufferProducer() { 29272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang CHECK(mFlags & FLAG_USE_SURFACE_INPUT); 29372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang return mGraphicBufferProducer; 29472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang} 29572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 29672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhangstatus_t MediaCodecSource::read(MediaBuffer** buffer, 29772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang const ReadOptions* options) { 29872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang Mutex::Autolock autolock(mOutputBufferLock); 29972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 30072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang *buffer = NULL; 30172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang while (mOutputBufferQueue.size() == 0 && !mEncodedReachedEOS) { 30272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mOutputBufferCond.wait(mOutputBufferLock); 30372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 30472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang if (!mEncodedReachedEOS) { 30572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang *buffer = *mOutputBufferQueue.begin(); 30672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mOutputBufferQueue.erase(mOutputBufferQueue.begin()); 30772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang return OK; 30872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 30972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang return mErrorCode; 31072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang} 31172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 31272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhangvoid MediaCodecSource::signalBufferReturned(MediaBuffer *buffer) { 31372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang buffer->setObserver(0); 31472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang buffer->release(); 31572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang} 31672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 31772cecca17d735db6532c45f0a7e10c47ee6f065aChong ZhangMediaCodecSource::MediaCodecSource( 31872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang const sp<ALooper> &looper, 31972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang const sp<AMessage> &outputFormat, 32072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang const sp<MediaSource> &source, 32172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang uint32_t flags) 32272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang : mLooper(looper), 32372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mOutputFormat(outputFormat), 32472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mMeta(new MetaData), 32572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mFlags(flags), 32672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mIsVideo(false), 32772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mStarted(false), 32872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mStopping(false), 32972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mDoMoreWorkPending(false), 33072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mPullerReachedEOS(false), 33172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mFirstSampleTimeUs(-1ll), 33272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mEncodedReachedEOS(false), 33372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mErrorCode(OK) { 33472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang CHECK(mLooper != NULL); 33572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 33672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang AString mime; 33772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang CHECK(mOutputFormat->findString("mime", &mime)); 33872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 33972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang if (!strncasecmp("video/", mime.c_str(), 6)) { 34072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mIsVideo = true; 34172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 34272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 34372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang if (!(mFlags & FLAG_USE_SURFACE_INPUT)) { 34472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mPuller = new Puller(source); 34572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 34672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang} 34772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 34872cecca17d735db6532c45f0a7e10c47ee6f065aChong ZhangMediaCodecSource::~MediaCodecSource() { 34972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang releaseEncoder(); 35072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 35172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mCodecLooper->stop(); 35272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mLooper->unregisterHandler(mReflector->id()); 35372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang} 35472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 35572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhangstatus_t MediaCodecSource::init() { 35672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang status_t err = initEncoder(); 35772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 35872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang if (err != OK) { 35972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang releaseEncoder(); 36072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 36172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 36272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang return err; 36372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang} 36472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 36572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhangstatus_t MediaCodecSource::initEncoder() { 36672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mReflector = new AHandlerReflector<MediaCodecSource>(this); 36772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mLooper->registerHandler(mReflector); 36872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 36972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mCodecLooper = new ALooper; 37072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mCodecLooper->setName("codec_looper"); 37172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mCodecLooper->start(); 37272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 37372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang if (mFlags & FLAG_USE_METADATA_INPUT) { 37472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mOutputFormat->setInt32("store-metadata-in-buffers", 1); 37572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 37672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 37772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang if (mFlags & FLAG_USE_SURFACE_INPUT) { 37872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mOutputFormat->setInt32("create-input-buffers-suspended", 1); 37972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 38072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 38172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang AString outputMIME; 38272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang CHECK(mOutputFormat->findString("mime", &outputMIME)); 38372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 38472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mEncoder = MediaCodec::CreateByType( 38572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mCodecLooper, outputMIME.c_str(), true /* encoder */); 38672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 38772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang if (mEncoder == NULL) { 38872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang return NO_INIT; 38972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 39072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 39172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang ALOGV("output format is '%s'", mOutputFormat->debugString(0).c_str()); 39272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 39372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang status_t err = mEncoder->configure( 39472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mOutputFormat, 39572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang NULL /* nativeWindow */, 39672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang NULL /* crypto */, 39772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang MediaCodec::CONFIGURE_FLAG_ENCODE); 39872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 39972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang if (err != OK) { 40072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang return err; 40172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 40272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 40372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mEncoder->getOutputFormat(&mOutputFormat); 40472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang convertMessageToMetaData(mOutputFormat, mMeta); 40572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 40672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang if (mFlags & FLAG_USE_SURFACE_INPUT) { 40772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang CHECK(mIsVideo); 40872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 40972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang err = mEncoder->createInputSurface(&mGraphicBufferProducer); 41072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 41172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang if (err != OK) { 41272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang return err; 41372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 41472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 41572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 41672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang err = mEncoder->start(); 41772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 41872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang if (err != OK) { 41972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang return err; 42072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 42172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 42272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang err = mEncoder->getInputBuffers(&mEncoderInputBuffers); 42372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 42472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang if (err != OK) { 42572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang return err; 42672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 42772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 42872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang err = mEncoder->getOutputBuffers(&mEncoderOutputBuffers); 42972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 43072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang if (err != OK) { 43172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang return err; 43272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 43372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 43472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mEncodedReachedEOS = false; 43572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mErrorCode = OK; 43672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 43772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang return OK; 43872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang} 43972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 44072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhangvoid MediaCodecSource::releaseEncoder() { 44172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang if (mEncoder == NULL) { 44272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang return; 44372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 44472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 44572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mEncoder->release(); 44672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mEncoder.clear(); 44772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 44872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang while (!mInputBufferQueue.empty()) { 44972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang MediaBuffer *mbuf = *mInputBufferQueue.begin(); 45072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mInputBufferQueue.erase(mInputBufferQueue.begin()); 45172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang if (mbuf != NULL) { 45272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mbuf->release(); 45372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 45472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 45572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 45672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang for (size_t i = 0; i < mEncoderInputBuffers.size(); ++i) { 45772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang sp<ABuffer> accessUnit = mEncoderInputBuffers.itemAt(i); 45872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang ReleaseMediaBufferReference(accessUnit); 45972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 46072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 46172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mEncoderInputBuffers.clear(); 46272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mEncoderOutputBuffers.clear(); 46372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang} 46472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 46572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhangbool MediaCodecSource::reachedEOS() { 46672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang return mEncodedReachedEOS && ((mPuller == NULL) || mPullerReachedEOS); 46772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang} 46872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 46972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhangstatus_t MediaCodecSource::postSynchronouslyAndReturnError( 47072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang const sp<AMessage> &msg) { 47172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang sp<AMessage> response; 47272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang status_t err = msg->postAndAwaitResponse(&response); 47372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 47472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang if (err != OK) { 47572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang return err; 47672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 47772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 47872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang if (!response->findInt32("err", &err)) { 47972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang err = OK; 48072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 48172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 48272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang return err; 48372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang} 48472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 48572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhangvoid MediaCodecSource::signalEOS(status_t err) { 48672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang if (!mEncodedReachedEOS) { 48772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang ALOGI("encoder (%s) reached EOS", mIsVideo ? "video" : "audio"); 48872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang { 48972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang Mutex::Autolock autoLock(mOutputBufferLock); 49072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang // release all unread media buffers 49172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang for (List<MediaBuffer*>::iterator it = mOutputBufferQueue.begin(); 49272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang it != mOutputBufferQueue.end(); it++) { 49372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang (*it)->release(); 49472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 49572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mOutputBufferQueue.clear(); 49672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mEncodedReachedEOS = true; 49772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mErrorCode = err; 49872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mOutputBufferCond.signal(); 49972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 50072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 50172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang releaseEncoder(); 50272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 50372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang if (mStopping && reachedEOS()) { 50472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang ALOGI("MediaCodecSource (%s) fully stopped", 50572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mIsVideo ? "video" : "audio"); 50672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang // posting reply to everyone that's waiting 50772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang List<uint32_t>::iterator it; 50872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang for (it = mStopReplyIDQueue.begin(); 50972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang it != mStopReplyIDQueue.end(); it++) { 51072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang (new AMessage)->postReply(*it); 51172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 51272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mStopReplyIDQueue.clear(); 51372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mStopping = false; 51472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 51572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang} 51672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 51772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhangvoid MediaCodecSource::suspend() { 51872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang CHECK(mFlags & FLAG_USE_SURFACE_INPUT); 51972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang if (mEncoder != NULL) { 52072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang sp<AMessage> params = new AMessage; 52172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang params->setInt32("drop-input-frames", true); 52272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mEncoder->setParameters(params); 52372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 52472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang} 52572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 52672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhangvoid MediaCodecSource::resume(int64_t skipFramesBeforeUs) { 52772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang CHECK(mFlags & FLAG_USE_SURFACE_INPUT); 52872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang if (mEncoder != NULL) { 52972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang sp<AMessage> params = new AMessage; 53072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang params->setInt32("drop-input-frames", false); 53172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang if (skipFramesBeforeUs > 0) { 53272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang params->setInt64("skip-frames-before", skipFramesBeforeUs); 53372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 53472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mEncoder->setParameters(params); 53572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 53672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang} 53772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 53872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhangvoid MediaCodecSource::scheduleDoMoreWork() { 53972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang if (mDoMoreWorkPending) { 54072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang return; 54172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 54272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 54372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mDoMoreWorkPending = true; 54472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 54572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang if (mEncoderActivityNotify == NULL) { 54672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mEncoderActivityNotify = new AMessage( 54772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang kWhatEncoderActivity, mReflector->id()); 54872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 54972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mEncoder->requestActivityNotification(mEncoderActivityNotify); 55072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang} 55172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 55272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhangstatus_t MediaCodecSource::feedEncoderInputBuffers() { 55372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang while (!mInputBufferQueue.empty() 55472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang && !mAvailEncoderInputIndices.empty()) { 55572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang MediaBuffer* mbuf = *mInputBufferQueue.begin(); 55672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mInputBufferQueue.erase(mInputBufferQueue.begin()); 55772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 55872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang size_t bufferIndex = *mAvailEncoderInputIndices.begin(); 55972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mAvailEncoderInputIndices.erase(mAvailEncoderInputIndices.begin()); 56072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 56172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang int64_t timeUs = 0ll; 56272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang uint32_t flags = 0; 56372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang size_t size = 0; 56472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 56572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang if (mbuf != NULL) { 56672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang CHECK(mbuf->meta_data()->findInt64(kKeyTime, &timeUs)); 56772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 56872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang // push decoding time for video, or drift time for audio 56972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang if (mIsVideo) { 57072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mDecodingTimeQueue.push_back(timeUs); 57172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } else { 57272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang#if DEBUG_DRIFT_TIME 57372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang if (mFirstSampleTimeUs < 0ll) { 57472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mFirstSampleTimeUs = timeUs; 57572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 57672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 57772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang int64_t driftTimeUs = 0; 57872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang if (mbuf->meta_data()->findInt64(kKeyDriftTime, &driftTimeUs) 57972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang && driftTimeUs) { 58072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang driftTimeUs = timeUs - mFirstSampleTimeUs - driftTimeUs; 58172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 58272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mDriftTimeQueue.push_back(driftTimeUs); 58372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang#endif // DEBUG_DRIFT_TIME 58472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 58572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 58672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang size = mbuf->size(); 58772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 58872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang memcpy(mEncoderInputBuffers.itemAt(bufferIndex)->data(), 58972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mbuf->data(), size); 59072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 59172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang if (mIsVideo) { 59272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang // video encoder will release MediaBuffer when done 59372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang // with underlying data. 59472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mEncoderInputBuffers.itemAt(bufferIndex)->meta() 59572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang ->setPointer("mediaBuffer", mbuf); 59672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } else { 59772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mbuf->release(); 59872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 59972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } else { 60072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang flags = MediaCodec::BUFFER_FLAG_EOS; 60172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 60272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 60372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang status_t err = mEncoder->queueInputBuffer( 60472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang bufferIndex, 0, size, timeUs, flags); 60572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 60672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang if (err != OK) { 60772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang return err; 60872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 60972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 61072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 61172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang return OK; 61272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang} 61372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 61472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhangstatus_t MediaCodecSource::doMoreWork() { 61572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang status_t err; 61672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 61772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang if (!(mFlags & FLAG_USE_SURFACE_INPUT)) { 61872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang for (;;) { 61972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang size_t bufferIndex; 62072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang err = mEncoder->dequeueInputBuffer(&bufferIndex); 62172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 62272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang if (err != OK) { 62372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang break; 62472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 62572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 62672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mAvailEncoderInputIndices.push_back(bufferIndex); 62772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 62872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 62972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang feedEncoderInputBuffers(); 63072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 63172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 63272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang for (;;) { 63372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang size_t bufferIndex; 63472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang size_t offset; 63572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang size_t size; 63672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang int64_t timeUs; 63772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang uint32_t flags; 63872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang native_handle_t* handle = NULL; 63972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang err = mEncoder->dequeueOutputBuffer( 64072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang &bufferIndex, &offset, &size, &timeUs, &flags); 64172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 64272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang if (err != OK) { 64372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang if (err == INFO_FORMAT_CHANGED) { 64472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang continue; 64572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } else if (err == INFO_OUTPUT_BUFFERS_CHANGED) { 64672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mEncoder->getOutputBuffers(&mEncoderOutputBuffers); 64772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang continue; 64872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 64972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 65072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang if (err == -EAGAIN) { 65172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang err = OK; 65272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 65372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang break; 65472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 65572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang if (!(flags & MediaCodec::BUFFER_FLAG_EOS)) { 65672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang sp<ABuffer> outbuf = mEncoderOutputBuffers.itemAt(bufferIndex); 65772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 65872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang MediaBuffer *mbuf = new MediaBuffer(outbuf->size()); 65972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang memcpy(mbuf->data(), outbuf->data(), outbuf->size()); 66072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 66172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang if (!(flags & MediaCodec::BUFFER_FLAG_CODECCONFIG)) { 66272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang if (mIsVideo) { 66372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang int64_t decodingTimeUs; 66472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang if (mFlags & FLAG_USE_SURFACE_INPUT) { 66572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang // GraphicBufferSource is supposed to discard samples 66672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang // queued before start, and offset timeUs by start time 66772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang CHECK_GE(timeUs, 0ll); 66872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang // TODO: 66972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang // Decoding time for surface source is unavailable, 67072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang // use presentation time for now. May need to move 67172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang // this logic into MediaCodec. 67272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang decodingTimeUs = timeUs; 67372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } else { 67472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang CHECK(!mDecodingTimeQueue.empty()); 67572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang decodingTimeUs = *(mDecodingTimeQueue.begin()); 67672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mDecodingTimeQueue.erase(mDecodingTimeQueue.begin()); 67772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 67872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mbuf->meta_data()->setInt64(kKeyDecodingTime, decodingTimeUs); 67972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 68072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang ALOGV("[video] time %lld us (%.2f secs), dts/pts diff %lld", 68172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang timeUs, timeUs / 1E6, decodingTimeUs - timeUs); 68272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } else { 68372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang int64_t driftTimeUs = 0; 68472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang#if DEBUG_DRIFT_TIME 68572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang CHECK(!mDriftTimeQueue.empty()); 68672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang driftTimeUs = *(mDriftTimeQueue.begin()); 68772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mDriftTimeQueue.erase(mDriftTimeQueue.begin()); 68872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mbuf->meta_data()->setInt64(kKeyDriftTime, driftTimeUs); 68972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang#endif // DEBUG_DRIFT_TIME 69072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang ALOGV("[audio] time %lld us (%.2f secs), drift %lld", 69172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang timeUs, timeUs / 1E6, driftTimeUs); 69272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 69372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mbuf->meta_data()->setInt64(kKeyTime, timeUs); 69472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } else { 69572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mbuf->meta_data()->setInt32(kKeyIsCodecConfig, true); 69672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 69772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang if (flags & MediaCodec::BUFFER_FLAG_SYNCFRAME) { 69872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mbuf->meta_data()->setInt32(kKeyIsSyncFrame, true); 69972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 70072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mbuf->setObserver(this); 70172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mbuf->add_ref(); 70272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 70372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang { 70472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang Mutex::Autolock autoLock(mOutputBufferLock); 70572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mOutputBufferQueue.push_back(mbuf); 70672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mOutputBufferCond.signal(); 70772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 70872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 70972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 71072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mEncoder->releaseOutputBuffer(bufferIndex); 71172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 71272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang if (flags & MediaCodec::BUFFER_FLAG_EOS) { 71372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang err = ERROR_END_OF_STREAM; 71472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang break; 71572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 71672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 71772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 71872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang return err; 71972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang} 72072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 72172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhangstatus_t MediaCodecSource::onStart(MetaData *params) { 72272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang if (mStopping) { 72372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang ALOGE("Failed to start while we're stopping"); 72472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang return INVALID_OPERATION; 72572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 72672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 72772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang if (mStarted) { 72872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang ALOGI("MediaCodecSource (%s) resuming", mIsVideo ? "video" : "audio"); 72972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang if (mFlags & FLAG_USE_SURFACE_INPUT) { 73072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang resume(); 73172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } else { 73272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang CHECK(mPuller != NULL); 73372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mPuller->resume(); 73472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 73572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang return OK; 73672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 73772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 73872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang ALOGI("MediaCodecSource (%s) starting", mIsVideo ? "video" : "audio"); 73972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 74072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang status_t err = OK; 74172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 74272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang if (mFlags & FLAG_USE_SURFACE_INPUT) { 74372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang int64_t startTimeUs; 74472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang if (!params || !params->findInt64(kKeyTime, &startTimeUs)) { 74572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang startTimeUs = -1ll; 74672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 74772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang resume(startTimeUs); 74872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang scheduleDoMoreWork(); 74972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } else { 75072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang CHECK(mPuller != NULL); 75172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang sp<AMessage> notify = new AMessage( 75272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang kWhatPullerNotify, mReflector->id()); 75372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang err = mPuller->start(params, notify); 75472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang if (err != OK) { 75572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mPullerReachedEOS = true; 75672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang return err; 75772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 75872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 75972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 76072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang ALOGI("MediaCodecSource (%s) started", mIsVideo ? "video" : "audio"); 76172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 76272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mStarted = true; 76372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang return OK; 76472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang} 76572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 76672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhangvoid MediaCodecSource::onMessageReceived(const sp<AMessage> &msg) { 76772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang switch (msg->what()) { 76872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang case kWhatPullerNotify: 76972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang { 77072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang MediaBuffer *mbuf; 77172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang CHECK(msg->findPointer("accessUnit", (void**)&mbuf)); 77272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 77372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang if (mbuf == NULL) { 77472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang ALOGI("puller (%s) reached EOS", 77572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mIsVideo ? "video" : "audio"); 77672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mPullerReachedEOS = true; 77772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 77872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 77972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang if (mEncoder == NULL) { 78072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang ALOGV("got msg '%s' after encoder shutdown.", 78172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang msg->debugString().c_str()); 78272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 78372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang if (mbuf != NULL) { 78472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mbuf->release(); 78572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } else { 78672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang signalEOS(); 78772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 78872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang break; 78972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 79072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 79172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mInputBufferQueue.push_back(mbuf); 79272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 79372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang feedEncoderInputBuffers(); 79472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang scheduleDoMoreWork(); 79572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 79672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang break; 79772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 79872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang case kWhatEncoderActivity: 79972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang { 80072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mDoMoreWorkPending = false; 80172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 80272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang if (mEncoder == NULL) { 80372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang break; 80472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 80572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 80672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang status_t err = doMoreWork(); 80772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 80872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang if (err == OK) { 80972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang scheduleDoMoreWork(); 81072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } else { 81172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang // reached EOS, or error 81272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang signalEOS(err); 81372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 81472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 81572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang break; 81672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 81772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang case kWhatStart: 81872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang { 81972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang uint32_t replyID; 82072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang CHECK(msg->senderAwaitsResponse(&replyID)); 82172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 82272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang sp<RefBase> obj; 82372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang CHECK(msg->findObject("meta", &obj)); 82472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang MetaData *params = static_cast<MetaData *>(obj.get()); 82572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 82672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang sp<AMessage> response = new AMessage; 82772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang response->setInt32("err", onStart(params)); 82872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang response->postReply(replyID); 82972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang break; 83072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 83172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang case kWhatStop: 83272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang { 83372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang ALOGI("MediaCodecSource (%s) stopping", mIsVideo ? "video" : "audio"); 83472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 83572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang uint32_t replyID; 83672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang CHECK(msg->senderAwaitsResponse(&replyID)); 83772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 83872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang if (reachedEOS()) { 83972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang // if we already reached EOS, reply and return now 84072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang ALOGI("MediaCodecSource (%s) already stopped", 84172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mIsVideo ? "video" : "audio"); 84272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang (new AMessage)->postReply(replyID); 84372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang break; 84472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 84572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 84672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mStopReplyIDQueue.push_back(replyID); 84772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang if (mStopping) { 84872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang // nothing to do if we're already stopping, reply will be posted 84972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang // to all when we're stopped. 85072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang break; 85172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 85272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 85372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mStopping = true; 85472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 85572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang // if using surface, signal source EOS and wait for EOS to come back. 85672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang // otherwise, release encoder and post EOS if haven't done already 85772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang if (mFlags & FLAG_USE_SURFACE_INPUT) { 85872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mEncoder->signalEndOfInputStream(); 85972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } else { 86072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang CHECK(mPuller != NULL); 86172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mPuller->stopAsync(); 86272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang signalEOS(); 86372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 86472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang break; 86572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 86672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang case kWhatPause: 86772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang { 86872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang if (mFlags && FLAG_USE_SURFACE_INPUT) { 86972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang suspend(); 87072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } else { 87172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang CHECK(mPuller != NULL); 87272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mPuller->pause(); 87372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 87472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang break; 87572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 87672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang default: 87772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang TRESPASS(); 87872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 87972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang} 88072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 88172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang} // namespace android 882