1d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber/* 2d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber * Copyright 2012, The Android Open Source Project 3d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber * 4d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber * Licensed under the Apache License, Version 2.0 (the "License"); 5d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber * you may not use this file except in compliance with the License. 6d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber * You may obtain a copy of the License at 7d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber * 8d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber * http://www.apache.org/licenses/LICENSE-2.0 9d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber * 10d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber * Unless required by applicable law or agreed to in writing, software 11d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber * distributed under the License is distributed on an "AS IS" BASIS, 12d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber * See the License for the specific language governing permissions and 14d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber * limitations under the License. 15d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber */ 16d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 17d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber//#define LOG_NDEBUG 0 18d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#define LOG_TAG "Converter" 19d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#include <utils/Log.h> 20d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 21d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#include "Converter.h" 22d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 2396fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber#include "MediaPuller.h" 24a05822a368dfc8c220b413c3d23dcc1af58b4b5fAndreas Huber#include "include/avc_utils.h" 2596fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber 2644b59fd9326026d3f82dec25cde48c589b0438e7Andreas Huber#include <cutils/properties.h> 271a2952aee048ca7b1765e2bc09ebe9aeddaeafa3Mathias Agopian#include <gui/Surface.h> 28d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#include <media/ICrypto.h> 29d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#include <media/stagefright/foundation/ABuffer.h> 30d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#include <media/stagefright/foundation/ADebug.h> 31d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#include <media/stagefright/foundation/AMessage.h> 3296fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber#include <media/stagefright/MediaBuffer.h> 33d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#include <media/stagefright/MediaCodec.h> 34d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#include <media/stagefright/MediaDefs.h> 35d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#include <media/stagefright/MediaErrors.h> 36d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 37a05822a368dfc8c220b413c3d23dcc1af58b4b5fAndreas Huber#include <arpa/inet.h> 38a05822a368dfc8c220b413c3d23dcc1af58b4b5fAndreas Huber 3996076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber#include <OMX_Video.h> 4096076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber 41d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Hubernamespace android { 42d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 43d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas HuberConverter::Converter( 44d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber const sp<AMessage> ¬ify, 45d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber const sp<ALooper> &codecLooper, 46a05822a368dfc8c220b413c3d23dcc1af58b4b5fAndreas Huber const sp<AMessage> &outputFormat, 47a05822a368dfc8c220b413c3d23dcc1af58b4b5fAndreas Huber uint32_t flags) 48a05822a368dfc8c220b413c3d23dcc1af58b4b5fAndreas Huber : mNotify(notify), 49d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber mCodecLooper(codecLooper), 509fef8d453b15a91a2b748faac2bfaff713bcf1e1Andreas Huber mOutputFormat(outputFormat), 51a05822a368dfc8c220b413c3d23dcc1af58b4b5fAndreas Huber mFlags(flags), 52496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber mIsVideo(false), 53a05822a368dfc8c220b413c3d23dcc1af58b4b5fAndreas Huber mIsH264(false), 549fef8d453b15a91a2b748faac2bfaff713bcf1e1Andreas Huber mIsPCMAudio(false), 550224bf170a3904576bba81593eaab113c5d3a4e7Andreas Huber mNeedToManuallyPrependSPSPPS(false), 56cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber mDoMoreWorkPending(false) 57cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber#if ENABLE_SILENCE_DETECTION 58cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber ,mFirstSilentFrameUs(-1ll) 59cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber ,mInSilentMode(false) 60cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber#endif 61a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber ,mPrevVideoBitrate(-1) 62126568c7aeeb5570789e70a310477f44dbdbd885Andreas Huber ,mNumFramesToDrop(0) 63a05822a368dfc8c220b413c3d23dcc1af58b4b5fAndreas Huber ,mEncodingSuspended(false) 64cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber { 65496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber AString mime; 669fef8d453b15a91a2b748faac2bfaff713bcf1e1Andreas Huber CHECK(mOutputFormat->findString("mime", &mime)); 67496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber 68496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber if (!strncasecmp("video/", mime.c_str(), 6)) { 69496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber mIsVideo = true; 70a05822a368dfc8c220b413c3d23dcc1af58b4b5fAndreas Huber 71a05822a368dfc8c220b413c3d23dcc1af58b4b5fAndreas Huber mIsH264 = !strcasecmp(mime.c_str(), MEDIA_MIMETYPE_VIDEO_AVC); 729fef8d453b15a91a2b748faac2bfaff713bcf1e1Andreas Huber } else if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_RAW, mime.c_str())) { 739fef8d453b15a91a2b748faac2bfaff713bcf1e1Andreas Huber mIsPCMAudio = true; 74496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber } 75c8e07e483c116ecaca1c9c6991588607f1187b75Andreas Huber} 76c8e07e483c116ecaca1c9c6991588607f1187b75Andreas Huber 77c8e07e483c116ecaca1c9c6991588607f1187b75Andreas Hubervoid Converter::releaseEncoder() { 78c8e07e483c116ecaca1c9c6991588607f1187b75Andreas Huber if (mEncoder == NULL) { 79c8e07e483c116ecaca1c9c6991588607f1187b75Andreas Huber return; 80c8e07e483c116ecaca1c9c6991588607f1187b75Andreas Huber } 81c8e07e483c116ecaca1c9c6991588607f1187b75Andreas Huber 82c8e07e483c116ecaca1c9c6991588607f1187b75Andreas Huber mEncoder->release(); 83c8e07e483c116ecaca1c9c6991588607f1187b75Andreas Huber mEncoder.clear(); 84c8e07e483c116ecaca1c9c6991588607f1187b75Andreas Huber 8596e92b58b7e9647b4c7c2f54b62a1b357ab06b66Wei Jia mInputBufferQueue.clear(); 86c8e07e483c116ecaca1c9c6991588607f1187b75Andreas Huber mEncoderInputBuffers.clear(); 87c8e07e483c116ecaca1c9c6991588607f1187b75Andreas Huber mEncoderOutputBuffers.clear(); 88c8e07e483c116ecaca1c9c6991588607f1187b75Andreas Huber} 89c8e07e483c116ecaca1c9c6991588607f1187b75Andreas Huber 90d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas HuberConverter::~Converter() { 9196fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber CHECK(mEncoder == NULL); 9296fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber} 93a438123bd96c7faf145683876702387efe5628d9Andreas Huber 9496fc6cc65ca93009a759a3a874b82a35771b9714Andreas Hubervoid Converter::shutdownAsync() { 9596fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber ALOGV("shutdown"); 961d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar (new AMessage(kWhatShutdown, this))->post(); 97d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber} 98d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 99a05822a368dfc8c220b413c3d23dcc1af58b4b5fAndreas Huberstatus_t Converter::init() { 100a05822a368dfc8c220b413c3d23dcc1af58b4b5fAndreas Huber status_t err = initEncoder(); 101a05822a368dfc8c220b413c3d23dcc1af58b4b5fAndreas Huber 102a05822a368dfc8c220b413c3d23dcc1af58b4b5fAndreas Huber if (err != OK) { 103a05822a368dfc8c220b413c3d23dcc1af58b4b5fAndreas Huber releaseEncoder(); 104a05822a368dfc8c220b413c3d23dcc1af58b4b5fAndreas Huber } 105a05822a368dfc8c220b413c3d23dcc1af58b4b5fAndreas Huber 106a05822a368dfc8c220b413c3d23dcc1af58b4b5fAndreas Huber return err; 107a05822a368dfc8c220b413c3d23dcc1af58b4b5fAndreas Huber} 108a05822a368dfc8c220b413c3d23dcc1af58b4b5fAndreas Huber 109a05822a368dfc8c220b413c3d23dcc1af58b4b5fAndreas Hubersp<IGraphicBufferProducer> Converter::getGraphicBufferProducer() { 110a05822a368dfc8c220b413c3d23dcc1af58b4b5fAndreas Huber CHECK(mFlags & FLAG_USE_SURFACE_INPUT); 111a05822a368dfc8c220b413c3d23dcc1af58b4b5fAndreas Huber return mGraphicBufferProducer; 112d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber} 113d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 11466e72bc85fb762876baff60ef29de729da93cf26Andreas Hubersize_t Converter::getInputBufferCount() const { 11566e72bc85fb762876baff60ef29de729da93cf26Andreas Huber return mEncoderInputBuffers.size(); 11666e72bc85fb762876baff60ef29de729da93cf26Andreas Huber} 11766e72bc85fb762876baff60ef29de729da93cf26Andreas Huber 118d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Hubersp<AMessage> Converter::getOutputFormat() const { 119d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber return mOutputFormat; 120d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber} 121d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 1220224bf170a3904576bba81593eaab113c5d3a4e7Andreas Huberbool Converter::needToManuallyPrependSPSPPS() const { 1230224bf170a3904576bba81593eaab113c5d3a4e7Andreas Huber return mNeedToManuallyPrependSPSPPS; 1240224bf170a3904576bba81593eaab113c5d3a4e7Andreas Huber} 1250224bf170a3904576bba81593eaab113c5d3a4e7Andreas Huber 126eaf5381f38bf6c3ecb5fe32a8351c26a447549f5Andreas Huber// static 127eaf5381f38bf6c3ecb5fe32a8351c26a447549f5Andreas Huberint32_t Converter::GetInt32Property( 128eaf5381f38bf6c3ecb5fe32a8351c26a447549f5Andreas Huber const char *propName, int32_t defaultValue) { 12944b59fd9326026d3f82dec25cde48c589b0438e7Andreas Huber char val[PROPERTY_VALUE_MAX]; 13044b59fd9326026d3f82dec25cde48c589b0438e7Andreas Huber if (property_get(propName, val, NULL)) { 13144b59fd9326026d3f82dec25cde48c589b0438e7Andreas Huber char *end; 13244b59fd9326026d3f82dec25cde48c589b0438e7Andreas Huber unsigned long x = strtoul(val, &end, 10); 13344b59fd9326026d3f82dec25cde48c589b0438e7Andreas Huber 13444b59fd9326026d3f82dec25cde48c589b0438e7Andreas Huber if (*end == '\0' && end > val && x > 0) { 13544b59fd9326026d3f82dec25cde48c589b0438e7Andreas Huber return x; 13644b59fd9326026d3f82dec25cde48c589b0438e7Andreas Huber } 13744b59fd9326026d3f82dec25cde48c589b0438e7Andreas Huber } 13844b59fd9326026d3f82dec25cde48c589b0438e7Andreas Huber 13944b59fd9326026d3f82dec25cde48c589b0438e7Andreas Huber return defaultValue; 14044b59fd9326026d3f82dec25cde48c589b0438e7Andreas Huber} 14144b59fd9326026d3f82dec25cde48c589b0438e7Andreas Huber 142d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huberstatus_t Converter::initEncoder() { 143d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber AString outputMIME; 1449fef8d453b15a91a2b748faac2bfaff713bcf1e1Andreas Huber CHECK(mOutputFormat->findString("mime", &outputMIME)); 1459fef8d453b15a91a2b748faac2bfaff713bcf1e1Andreas Huber 1469fef8d453b15a91a2b748faac2bfaff713bcf1e1Andreas Huber bool isAudio = !strncasecmp(outputMIME.c_str(), "audio/", 6); 147d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 148e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber if (!mIsPCMAudio) { 149e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber mEncoder = MediaCodec::CreateByType( 150e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber mCodecLooper, outputMIME.c_str(), true /* encoder */); 151d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 152e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber if (mEncoder == NULL) { 153e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber return ERROR_UNSUPPORTED; 154e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber } 155d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 156d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 157e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber if (mIsPCMAudio) { 158e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber return OK; 159e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber } 160e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber 161eaf5381f38bf6c3ecb5fe32a8351c26a447549f5Andreas Huber int32_t audioBitrate = GetInt32Property("media.wfd.audio-bitrate", 128000); 162eaf5381f38bf6c3ecb5fe32a8351c26a447549f5Andreas Huber int32_t videoBitrate = GetInt32Property("media.wfd.video-bitrate", 5000000); 163a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber mPrevVideoBitrate = videoBitrate; 16444b59fd9326026d3f82dec25cde48c589b0438e7Andreas Huber 16544b59fd9326026d3f82dec25cde48c589b0438e7Andreas Huber ALOGI("using audio bitrate of %d bps, video bitrate of %d bps", 16644b59fd9326026d3f82dec25cde48c589b0438e7Andreas Huber audioBitrate, videoBitrate); 16744b59fd9326026d3f82dec25cde48c589b0438e7Andreas Huber 168d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber if (isAudio) { 16944b59fd9326026d3f82dec25cde48c589b0438e7Andreas Huber mOutputFormat->setInt32("bitrate", audioBitrate); 170d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } else { 17144b59fd9326026d3f82dec25cde48c589b0438e7Andreas Huber mOutputFormat->setInt32("bitrate", videoBitrate); 17296076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber mOutputFormat->setInt32("bitrate-mode", OMX_Video_ControlRateConstant); 1734a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Huber mOutputFormat->setInt32("frame-rate", 30); 17413e8a0e8a14faaf3fe0bcebf4da1f2694d59565dJames Dong mOutputFormat->setInt32("i-frame-interval", 15); // Iframes every 15 secs 17513e8a0e8a14faaf3fe0bcebf4da1f2694d59565dJames Dong 17613e8a0e8a14faaf3fe0bcebf4da1f2694d59565dJames Dong // Configure encoder to use intra macroblock refresh mode 17713e8a0e8a14faaf3fe0bcebf4da1f2694d59565dJames Dong mOutputFormat->setInt32("intra-refresh-mode", OMX_VIDEO_IntraRefreshCyclic); 17813e8a0e8a14faaf3fe0bcebf4da1f2694d59565dJames Dong 17913e8a0e8a14faaf3fe0bcebf4da1f2694d59565dJames Dong int width, height, mbs; 18013e8a0e8a14faaf3fe0bcebf4da1f2694d59565dJames Dong if (!mOutputFormat->findInt32("width", &width) 18113e8a0e8a14faaf3fe0bcebf4da1f2694d59565dJames Dong || !mOutputFormat->findInt32("height", &height)) { 18213e8a0e8a14faaf3fe0bcebf4da1f2694d59565dJames Dong return ERROR_UNSUPPORTED; 18313e8a0e8a14faaf3fe0bcebf4da1f2694d59565dJames Dong } 18413e8a0e8a14faaf3fe0bcebf4da1f2694d59565dJames Dong 18513e8a0e8a14faaf3fe0bcebf4da1f2694d59565dJames Dong // Update macroblocks in a cyclic fashion with 10% of all MBs within 18613e8a0e8a14faaf3fe0bcebf4da1f2694d59565dJames Dong // frame gets updated at one time. It takes about 10 frames to 18713e8a0e8a14faaf3fe0bcebf4da1f2694d59565dJames Dong // completely update a whole video frame. If the frame rate is 30, 18813e8a0e8a14faaf3fe0bcebf4da1f2694d59565dJames Dong // it takes about 333 ms in the best case (if next frame is not an IDR) 18913e8a0e8a14faaf3fe0bcebf4da1f2694d59565dJames Dong // to recover from a lost/corrupted packet. 19013e8a0e8a14faaf3fe0bcebf4da1f2694d59565dJames Dong mbs = (((width + 15) / 16) * ((height + 15) / 16) * 10) / 100; 19113e8a0e8a14faaf3fe0bcebf4da1f2694d59565dJames Dong mOutputFormat->setInt32("intra-refresh-CIR-mbs", mbs); 192d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 193d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 194d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber ALOGV("output format is '%s'", mOutputFormat->debugString(0).c_str()); 195d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 1960224bf170a3904576bba81593eaab113c5d3a4e7Andreas Huber mNeedToManuallyPrependSPSPPS = false; 1970224bf170a3904576bba81593eaab113c5d3a4e7Andreas Huber 1980224bf170a3904576bba81593eaab113c5d3a4e7Andreas Huber status_t err = NO_INIT; 1990224bf170a3904576bba81593eaab113c5d3a4e7Andreas Huber 2000224bf170a3904576bba81593eaab113c5d3a4e7Andreas Huber if (!isAudio) { 2010224bf170a3904576bba81593eaab113c5d3a4e7Andreas Huber sp<AMessage> tmp = mOutputFormat->dup(); 2020224bf170a3904576bba81593eaab113c5d3a4e7Andreas Huber tmp->setInt32("prepend-sps-pps-to-idr-frames", 1); 2030224bf170a3904576bba81593eaab113c5d3a4e7Andreas Huber 2040224bf170a3904576bba81593eaab113c5d3a4e7Andreas Huber err = mEncoder->configure( 2050224bf170a3904576bba81593eaab113c5d3a4e7Andreas Huber tmp, 2060224bf170a3904576bba81593eaab113c5d3a4e7Andreas Huber NULL /* nativeWindow */, 2070224bf170a3904576bba81593eaab113c5d3a4e7Andreas Huber NULL /* crypto */, 2080224bf170a3904576bba81593eaab113c5d3a4e7Andreas Huber MediaCodec::CONFIGURE_FLAG_ENCODE); 2090224bf170a3904576bba81593eaab113c5d3a4e7Andreas Huber 2100224bf170a3904576bba81593eaab113c5d3a4e7Andreas Huber if (err == OK) { 2110224bf170a3904576bba81593eaab113c5d3a4e7Andreas Huber // Encoder supported prepending SPS/PPS, we don't need to emulate 2120224bf170a3904576bba81593eaab113c5d3a4e7Andreas Huber // it. 2130224bf170a3904576bba81593eaab113c5d3a4e7Andreas Huber mOutputFormat = tmp; 2140224bf170a3904576bba81593eaab113c5d3a4e7Andreas Huber } else { 2150224bf170a3904576bba81593eaab113c5d3a4e7Andreas Huber mNeedToManuallyPrependSPSPPS = true; 2160224bf170a3904576bba81593eaab113c5d3a4e7Andreas Huber 2170224bf170a3904576bba81593eaab113c5d3a4e7Andreas Huber ALOGI("We going to manually prepend SPS and PPS to IDR frames."); 2180224bf170a3904576bba81593eaab113c5d3a4e7Andreas Huber } 2190224bf170a3904576bba81593eaab113c5d3a4e7Andreas Huber } 2200224bf170a3904576bba81593eaab113c5d3a4e7Andreas Huber 2210224bf170a3904576bba81593eaab113c5d3a4e7Andreas Huber if (err != OK) { 2220224bf170a3904576bba81593eaab113c5d3a4e7Andreas Huber // We'll get here for audio or if we failed to configure the encoder 2230224bf170a3904576bba81593eaab113c5d3a4e7Andreas Huber // to automatically prepend SPS/PPS in the case of video. 2240224bf170a3904576bba81593eaab113c5d3a4e7Andreas Huber 2250224bf170a3904576bba81593eaab113c5d3a4e7Andreas Huber err = mEncoder->configure( 2260224bf170a3904576bba81593eaab113c5d3a4e7Andreas Huber mOutputFormat, 2270224bf170a3904576bba81593eaab113c5d3a4e7Andreas Huber NULL /* nativeWindow */, 2280224bf170a3904576bba81593eaab113c5d3a4e7Andreas Huber NULL /* crypto */, 2290224bf170a3904576bba81593eaab113c5d3a4e7Andreas Huber MediaCodec::CONFIGURE_FLAG_ENCODE); 2300224bf170a3904576bba81593eaab113c5d3a4e7Andreas Huber } 231d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 232d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber if (err != OK) { 233d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber return err; 234d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 235d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 236a05822a368dfc8c220b413c3d23dcc1af58b4b5fAndreas Huber if (mFlags & FLAG_USE_SURFACE_INPUT) { 237a05822a368dfc8c220b413c3d23dcc1af58b4b5fAndreas Huber CHECK(mIsVideo); 238a05822a368dfc8c220b413c3d23dcc1af58b4b5fAndreas Huber 239a05822a368dfc8c220b413c3d23dcc1af58b4b5fAndreas Huber err = mEncoder->createInputSurface(&mGraphicBufferProducer); 240a05822a368dfc8c220b413c3d23dcc1af58b4b5fAndreas Huber 241a05822a368dfc8c220b413c3d23dcc1af58b4b5fAndreas Huber if (err != OK) { 242a05822a368dfc8c220b413c3d23dcc1af58b4b5fAndreas Huber return err; 243a05822a368dfc8c220b413c3d23dcc1af58b4b5fAndreas Huber } 244a05822a368dfc8c220b413c3d23dcc1af58b4b5fAndreas Huber } 245a05822a368dfc8c220b413c3d23dcc1af58b4b5fAndreas Huber 246d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber err = mEncoder->start(); 247d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 248d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber if (err != OK) { 249d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber return err; 250d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 251d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 252d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber err = mEncoder->getInputBuffers(&mEncoderInputBuffers); 253d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 254d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber if (err != OK) { 255d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber return err; 256d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 257d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 258a05822a368dfc8c220b413c3d23dcc1af58b4b5fAndreas Huber err = mEncoder->getOutputBuffers(&mEncoderOutputBuffers); 259a05822a368dfc8c220b413c3d23dcc1af58b4b5fAndreas Huber 260a05822a368dfc8c220b413c3d23dcc1af58b4b5fAndreas Huber if (err != OK) { 261a05822a368dfc8c220b413c3d23dcc1af58b4b5fAndreas Huber return err; 262a05822a368dfc8c220b413c3d23dcc1af58b4b5fAndreas Huber } 263a05822a368dfc8c220b413c3d23dcc1af58b4b5fAndreas Huber 264a05822a368dfc8c220b413c3d23dcc1af58b4b5fAndreas Huber if (mFlags & FLAG_USE_SURFACE_INPUT) { 265a05822a368dfc8c220b413c3d23dcc1af58b4b5fAndreas Huber scheduleDoMoreWork(); 266a05822a368dfc8c220b413c3d23dcc1af58b4b5fAndreas Huber } 267a05822a368dfc8c220b413c3d23dcc1af58b4b5fAndreas Huber 268a05822a368dfc8c220b413c3d23dcc1af58b4b5fAndreas Huber return OK; 269d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber} 270d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 271d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Hubervoid Converter::notifyError(status_t err) { 272d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber sp<AMessage> notify = mNotify->dup(); 273d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber notify->setInt32("what", kWhatError); 274d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber notify->setInt32("err", err); 275d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber notify->post(); 276d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber} 277d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 278cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber// static 279cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huberbool Converter::IsSilence(const sp<ABuffer> &accessUnit) { 280cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber const uint8_t *ptr = accessUnit->data(); 281cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber const uint8_t *end = ptr + accessUnit->size(); 282cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber while (ptr < end) { 283cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber if (*ptr != 0) { 284cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber return false; 285cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber } 286cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber ++ptr; 287cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber } 288cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber 289cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber return true; 290cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber} 291cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber 292d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Hubervoid Converter::onMessageReceived(const sp<AMessage> &msg) { 293d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber switch (msg->what()) { 29496fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber case kWhatMediaPullerNotify: 295d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber { 29696fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber int32_t what; 29796fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber CHECK(msg->findInt32("what", &what)); 298d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 299e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber if (!mIsPCMAudio && mEncoder == NULL) { 30096fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber ALOGV("got msg '%s' after encoder shutdown.", 30196fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber msg->debugString().c_str()); 302d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 30396fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber if (what == MediaPuller::kWhatAccessUnit) { 30496fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber sp<ABuffer> accessUnit; 30596fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber CHECK(msg->findBuffer("accessUnit", &accessUnit)); 306d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 30796e92b58b7e9647b4c7c2f54b62a1b357ab06b66Wei Jia accessUnit->setMediaBufferBase(NULL); 30896fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber } 30996fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber break; 31096fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber } 31196fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber 31296fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber if (what == MediaPuller::kWhatEOS) { 31396fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber mInputBufferQueue.push_back(NULL); 31496fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber 31596fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber feedEncoderInputBuffers(); 31696fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber 31796fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber scheduleDoMoreWork(); 31896fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber } else { 31996fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber CHECK_EQ(what, MediaPuller::kWhatAccessUnit); 32096fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber 32196fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber sp<ABuffer> accessUnit; 32296fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber CHECK(msg->findBuffer("accessUnit", &accessUnit)); 32396fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber 324a05822a368dfc8c220b413c3d23dcc1af58b4b5fAndreas Huber if (mNumFramesToDrop > 0 || mEncodingSuspended) { 325a05822a368dfc8c220b413c3d23dcc1af58b4b5fAndreas Huber if (mNumFramesToDrop > 0) { 326a05822a368dfc8c220b413c3d23dcc1af58b4b5fAndreas Huber --mNumFramesToDrop; 327a05822a368dfc8c220b413c3d23dcc1af58b4b5fAndreas Huber ALOGI("dropping frame."); 328a05822a368dfc8c220b413c3d23dcc1af58b4b5fAndreas Huber } 329a05822a368dfc8c220b413c3d23dcc1af58b4b5fAndreas Huber 33096e92b58b7e9647b4c7c2f54b62a1b357ab06b66Wei Jia accessUnit->setMediaBufferBase(NULL); 331126568c7aeeb5570789e70a310477f44dbdbd885Andreas Huber break; 332126568c7aeeb5570789e70a310477f44dbdbd885Andreas Huber } 333126568c7aeeb5570789e70a310477f44dbdbd885Andreas Huber 33496fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber#if 0 33596e92b58b7e9647b4c7c2f54b62a1b357ab06b66Wei Jia MediaBuffer *mbuf = 33696e92b58b7e9647b4c7c2f54b62a1b357ab06b66Wei Jia (MediaBuffer *)(accessUnit->getMediaBufferBase()); 33796e92b58b7e9647b4c7c2f54b62a1b357ab06b66Wei Jia if (mbuf != NULL) { 33896fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber ALOGI("queueing mbuf %p", mbuf); 33996e92b58b7e9647b4c7c2f54b62a1b357ab06b66Wei Jia mbuf->release(); 34096fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber } 34196fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber#endif 34296fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber 343cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber#if ENABLE_SILENCE_DETECTION 344cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber if (!mIsVideo) { 345cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber if (IsSilence(accessUnit)) { 3468d16bbc5a354d302abfd912b8d88d9c7feb3948fAndreas Huber if (mInSilentMode) { 3478d16bbc5a354d302abfd912b8d88d9c7feb3948fAndreas Huber break; 3488d16bbc5a354d302abfd912b8d88d9c7feb3948fAndreas Huber } 3498d16bbc5a354d302abfd912b8d88d9c7feb3948fAndreas Huber 3508d16bbc5a354d302abfd912b8d88d9c7feb3948fAndreas Huber int64_t nowUs = ALooper::GetNowUs(); 3518d16bbc5a354d302abfd912b8d88d9c7feb3948fAndreas Huber 3528d16bbc5a354d302abfd912b8d88d9c7feb3948fAndreas Huber if (mFirstSilentFrameUs < 0ll) { 3538d16bbc5a354d302abfd912b8d88d9c7feb3948fAndreas Huber mFirstSilentFrameUs = nowUs; 3548d16bbc5a354d302abfd912b8d88d9c7feb3948fAndreas Huber } else if (nowUs >= mFirstSilentFrameUs + 10000000ll) { 3558d16bbc5a354d302abfd912b8d88d9c7feb3948fAndreas Huber mInSilentMode = true; 3568d16bbc5a354d302abfd912b8d88d9c7feb3948fAndreas Huber ALOGI("audio in silent mode now."); 3578d16bbc5a354d302abfd912b8d88d9c7feb3948fAndreas Huber break; 358cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber } 359cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber } else { 360cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber if (mInSilentMode) { 361cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber ALOGI("audio no longer in silent mode."); 362cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber } 363cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber mInSilentMode = false; 364cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber mFirstSilentFrameUs = -1ll; 365cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber } 366cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber } 367cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber#endif 368cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber 36996fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber mInputBufferQueue.push_back(accessUnit); 370d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 37196fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber feedEncoderInputBuffers(); 372d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 37396fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber scheduleDoMoreWork(); 37496fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber } 375d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber break; 376d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 377d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 378575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber case kWhatEncoderActivity: 379d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber { 380575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber#if 0 381575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber int64_t whenUs; 382575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber if (msg->findInt64("whenUs", &whenUs)) { 383575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber int64_t nowUs = ALooper::GetNowUs(); 384575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber ALOGI("[%s] kWhatEncoderActivity after %lld us", 385575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber mIsVideo ? "video" : "audio", nowUs - whenUs); 386575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber } 387575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber#endif 388575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber 389d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber mDoMoreWorkPending = false; 39096fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber 39196fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber if (mEncoder == NULL) { 39296fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber break; 39396fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber } 39496fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber 395d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber status_t err = doMoreWork(); 396d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 397d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber if (err != OK) { 398d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber notifyError(err); 399d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } else { 400d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber scheduleDoMoreWork(); 401d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 402d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber break; 403d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 404d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 405496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber case kWhatRequestIDRFrame: 406496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber { 40796fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber if (mEncoder == NULL) { 40896fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber break; 40996fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber } 41096fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber 411496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber if (mIsVideo) { 412a05822a368dfc8c220b413c3d23dcc1af58b4b5fAndreas Huber ALOGV("requesting IDR frame"); 413496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber mEncoder->requestIDRFrame(); 414496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber } 415496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber break; 416496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber } 417496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber 41896fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber case kWhatShutdown: 41996fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber { 420c8e07e483c116ecaca1c9c6991588607f1187b75Andreas Huber ALOGI("shutting down %s encoder", mIsVideo ? "video" : "audio"); 421e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber 422c8e07e483c116ecaca1c9c6991588607f1187b75Andreas Huber releaseEncoder(); 42396fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber 42496fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber AString mime; 4259fef8d453b15a91a2b748faac2bfaff713bcf1e1Andreas Huber CHECK(mOutputFormat->findString("mime", &mime)); 42696fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber ALOGI("encoder (%s) shut down.", mime.c_str()); 427a05822a368dfc8c220b413c3d23dcc1af58b4b5fAndreas Huber 428a05822a368dfc8c220b413c3d23dcc1af58b4b5fAndreas Huber sp<AMessage> notify = mNotify->dup(); 429a05822a368dfc8c220b413c3d23dcc1af58b4b5fAndreas Huber notify->setInt32("what", kWhatShutdownCompleted); 430a05822a368dfc8c220b413c3d23dcc1af58b4b5fAndreas Huber notify->post(); 43196fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber break; 43296fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber } 43396fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber 434126568c7aeeb5570789e70a310477f44dbdbd885Andreas Huber case kWhatDropAFrame: 435126568c7aeeb5570789e70a310477f44dbdbd885Andreas Huber { 436126568c7aeeb5570789e70a310477f44dbdbd885Andreas Huber ++mNumFramesToDrop; 437126568c7aeeb5570789e70a310477f44dbdbd885Andreas Huber break; 438126568c7aeeb5570789e70a310477f44dbdbd885Andreas Huber } 439126568c7aeeb5570789e70a310477f44dbdbd885Andreas Huber 440308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang case kWhatReleaseOutputBuffer: 441308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang { 442308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang if (mEncoder != NULL) { 443308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang size_t bufferIndex; 444308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang CHECK(msg->findInt32("bufferIndex", (int32_t*)&bufferIndex)); 445308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang CHECK(bufferIndex < mEncoderOutputBuffers.size()); 446308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang mEncoder->releaseOutputBuffer(bufferIndex); 447308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang } 448308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang break; 449308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang } 450308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang 451a05822a368dfc8c220b413c3d23dcc1af58b4b5fAndreas Huber case kWhatSuspendEncoding: 452a05822a368dfc8c220b413c3d23dcc1af58b4b5fAndreas Huber { 453a05822a368dfc8c220b413c3d23dcc1af58b4b5fAndreas Huber int32_t suspend; 454a05822a368dfc8c220b413c3d23dcc1af58b4b5fAndreas Huber CHECK(msg->findInt32("suspend", &suspend)); 455a05822a368dfc8c220b413c3d23dcc1af58b4b5fAndreas Huber 456a05822a368dfc8c220b413c3d23dcc1af58b4b5fAndreas Huber mEncodingSuspended = suspend; 457a05822a368dfc8c220b413c3d23dcc1af58b4b5fAndreas Huber 458a05822a368dfc8c220b413c3d23dcc1af58b4b5fAndreas Huber if (mFlags & FLAG_USE_SURFACE_INPUT) { 459a05822a368dfc8c220b413c3d23dcc1af58b4b5fAndreas Huber sp<AMessage> params = new AMessage; 460a05822a368dfc8c220b413c3d23dcc1af58b4b5fAndreas Huber params->setInt32("drop-input-frames",suspend); 461a05822a368dfc8c220b413c3d23dcc1af58b4b5fAndreas Huber mEncoder->setParameters(params); 462a05822a368dfc8c220b413c3d23dcc1af58b4b5fAndreas Huber } 463a05822a368dfc8c220b413c3d23dcc1af58b4b5fAndreas Huber break; 464a05822a368dfc8c220b413c3d23dcc1af58b4b5fAndreas Huber } 465a05822a368dfc8c220b413c3d23dcc1af58b4b5fAndreas Huber 466d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber default: 467d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber TRESPASS(); 468d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 469d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber} 470d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 471d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Hubervoid Converter::scheduleDoMoreWork() { 472e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber if (mIsPCMAudio) { 473e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber // There's no encoder involved in this case. 474e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber return; 475e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber } 476e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber 477d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber if (mDoMoreWorkPending) { 478d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber return; 479d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 480d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 481d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber mDoMoreWorkPending = true; 482575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber 483575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber#if 1 484575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber if (mEncoderActivityNotify == NULL) { 4851d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar mEncoderActivityNotify = new AMessage(kWhatEncoderActivity, this); 486575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber } 487575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber mEncoder->requestActivityNotification(mEncoderActivityNotify->dup()); 488575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber#else 4891d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar sp<AMessage> notify = new AMessage(kWhatEncoderActivity, this); 490575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber notify->setInt64("whenUs", ALooper::GetNowUs()); 491575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber mEncoder->requestActivityNotification(notify); 492575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber#endif 493d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber} 494d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 495e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huberstatus_t Converter::feedRawAudioInputBuffers() { 496e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber // Split incoming PCM audio into buffers of 6 AUs of 80 audio frames each 497e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber // and add a 4 byte header according to the wifi display specs. 498e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber 499e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber while (!mInputBufferQueue.empty()) { 500e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber sp<ABuffer> buffer = *mInputBufferQueue.begin(); 501e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber mInputBufferQueue.erase(mInputBufferQueue.begin()); 502e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber 503e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber int16_t *ptr = (int16_t *)buffer->data(); 504e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber int16_t *stop = (int16_t *)(buffer->data() + buffer->size()); 505e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber while (ptr < stop) { 506e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber *ptr = htons(*ptr); 507e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber ++ptr; 508e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber } 509e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber 510e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber static const size_t kFrameSize = 2 * sizeof(int16_t); // stereo 511e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber static const size_t kFramesPerAU = 80; 512e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber static const size_t kNumAUsPerPESPacket = 6; 513e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber 514e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber if (mPartialAudioAU != NULL) { 515e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber size_t bytesMissingForFullAU = 516e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber kNumAUsPerPESPacket * kFramesPerAU * kFrameSize 517e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber - mPartialAudioAU->size() + 4; 518e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber 519e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber size_t copy = buffer->size(); 520e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber if(copy > bytesMissingForFullAU) { 521e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber copy = bytesMissingForFullAU; 522e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber } 523e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber 524e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber memcpy(mPartialAudioAU->data() + mPartialAudioAU->size(), 525e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber buffer->data(), 526e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber copy); 527e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber 528e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber mPartialAudioAU->setRange(0, mPartialAudioAU->size() + copy); 529e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber 530e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber buffer->setRange(buffer->offset() + copy, buffer->size() - copy); 531e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber 532e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber int64_t timeUs; 533e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber CHECK(buffer->meta()->findInt64("timeUs", &timeUs)); 534e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber 535e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber int64_t copyUs = (int64_t)((copy / kFrameSize) * 1E6 / 48000.0); 536e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber timeUs += copyUs; 537e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber buffer->meta()->setInt64("timeUs", timeUs); 538e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber 539e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber if (bytesMissingForFullAU == copy) { 540e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber sp<AMessage> notify = mNotify->dup(); 541e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber notify->setInt32("what", kWhatAccessUnit); 542e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber notify->setBuffer("accessUnit", mPartialAudioAU); 543e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber notify->post(); 544e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber 545e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber mPartialAudioAU.clear(); 546e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber } 547e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber } 548e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber 549e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber while (buffer->size() > 0) { 550e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber sp<ABuffer> partialAudioAU = 551e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber new ABuffer( 552e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber 4 553e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber + kNumAUsPerPESPacket * kFrameSize * kFramesPerAU); 554e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber 555e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber uint8_t *ptr = partialAudioAU->data(); 556e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber ptr[0] = 0xa0; // 10100000b 557e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber ptr[1] = kNumAUsPerPESPacket; 558e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber ptr[2] = 0; // reserved, audio _emphasis_flag = 0 559e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber 560e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber static const unsigned kQuantizationWordLength = 0; // 16-bit 561e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber static const unsigned kAudioSamplingFrequency = 2; // 48Khz 562e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber static const unsigned kNumberOfAudioChannels = 1; // stereo 563e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber 564e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber ptr[3] = (kQuantizationWordLength << 6) 565e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber | (kAudioSamplingFrequency << 3) 566e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber | kNumberOfAudioChannels; 567e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber 568e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber size_t copy = buffer->size(); 569e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber if (copy > partialAudioAU->size() - 4) { 570e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber copy = partialAudioAU->size() - 4; 571e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber } 572e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber 573e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber memcpy(&ptr[4], buffer->data(), copy); 574e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber 575e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber partialAudioAU->setRange(0, 4 + copy); 576e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber buffer->setRange(buffer->offset() + copy, buffer->size() - copy); 577e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber 578e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber int64_t timeUs; 579e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber CHECK(buffer->meta()->findInt64("timeUs", &timeUs)); 580e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber 581e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber partialAudioAU->meta()->setInt64("timeUs", timeUs); 582e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber 583e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber int64_t copyUs = (int64_t)((copy / kFrameSize) * 1E6 / 48000.0); 584e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber timeUs += copyUs; 585e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber buffer->meta()->setInt64("timeUs", timeUs); 586e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber 58790a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber if (copy == partialAudioAU->capacity() - 4) { 588e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber sp<AMessage> notify = mNotify->dup(); 589e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber notify->setInt32("what", kWhatAccessUnit); 590e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber notify->setBuffer("accessUnit", partialAudioAU); 591e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber notify->post(); 592e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber 593e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber partialAudioAU.clear(); 594e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber continue; 595e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber } 596e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber 597e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber mPartialAudioAU = partialAudioAU; 598e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber } 599e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber } 600e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber 601e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber return OK; 602e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber} 603e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber 604d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huberstatus_t Converter::feedEncoderInputBuffers() { 605e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber if (mIsPCMAudio) { 606e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber return feedRawAudioInputBuffers(); 607e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber } 608e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber 609d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber while (!mInputBufferQueue.empty() 610d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber && !mAvailEncoderInputIndices.empty()) { 611d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber sp<ABuffer> buffer = *mInputBufferQueue.begin(); 612d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber mInputBufferQueue.erase(mInputBufferQueue.begin()); 613d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 614d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber size_t bufferIndex = *mAvailEncoderInputIndices.begin(); 615d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber mAvailEncoderInputIndices.erase(mAvailEncoderInputIndices.begin()); 616d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 617d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber int64_t timeUs = 0ll; 618d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber uint32_t flags = 0; 619d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 620d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber if (buffer != NULL) { 621d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber CHECK(buffer->meta()->findInt64("timeUs", &timeUs)); 622d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 623d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber memcpy(mEncoderInputBuffers.itemAt(bufferIndex)->data(), 624d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber buffer->data(), 625d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber buffer->size()); 626d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 62796e92b58b7e9647b4c7c2f54b62a1b357ab06b66Wei Jia MediaBuffer *mediaBuffer = 62896e92b58b7e9647b4c7c2f54b62a1b357ab06b66Wei Jia (MediaBuffer *)(buffer->getMediaBufferBase()); 62996e92b58b7e9647b4c7c2f54b62a1b357ab06b66Wei Jia if (mediaBuffer != NULL) { 63096e92b58b7e9647b4c7c2f54b62a1b357ab06b66Wei Jia mEncoderInputBuffers.itemAt(bufferIndex)->setMediaBufferBase( 63196e92b58b7e9647b4c7c2f54b62a1b357ab06b66Wei Jia mediaBuffer); 632d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 63396e92b58b7e9647b4c7c2f54b62a1b357ab06b66Wei Jia buffer->setMediaBufferBase(NULL); 634d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 635d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } else { 636d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber flags = MediaCodec::BUFFER_FLAG_EOS; 637d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 638d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 639d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber status_t err = mEncoder->queueInputBuffer( 640d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber bufferIndex, 0, (buffer == NULL) ? 0 : buffer->size(), 641d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber timeUs, flags); 642d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 643d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber if (err != OK) { 644d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber return err; 645d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 646d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 647d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 648d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber return OK; 649d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber} 650d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 651a05822a368dfc8c220b413c3d23dcc1af58b4b5fAndreas Hubersp<ABuffer> Converter::prependCSD(const sp<ABuffer> &accessUnit) const { 652a05822a368dfc8c220b413c3d23dcc1af58b4b5fAndreas Huber CHECK(mCSD0 != NULL); 653a05822a368dfc8c220b413c3d23dcc1af58b4b5fAndreas Huber 654a05822a368dfc8c220b413c3d23dcc1af58b4b5fAndreas Huber sp<ABuffer> dup = new ABuffer(accessUnit->size() + mCSD0->size()); 655a05822a368dfc8c220b413c3d23dcc1af58b4b5fAndreas Huber memcpy(dup->data(), mCSD0->data(), mCSD0->size()); 656a05822a368dfc8c220b413c3d23dcc1af58b4b5fAndreas Huber memcpy(dup->data() + mCSD0->size(), accessUnit->data(), accessUnit->size()); 657a05822a368dfc8c220b413c3d23dcc1af58b4b5fAndreas Huber 658a05822a368dfc8c220b413c3d23dcc1af58b4b5fAndreas Huber int64_t timeUs; 659a05822a368dfc8c220b413c3d23dcc1af58b4b5fAndreas Huber CHECK(accessUnit->meta()->findInt64("timeUs", &timeUs)); 660a05822a368dfc8c220b413c3d23dcc1af58b4b5fAndreas Huber 661a05822a368dfc8c220b413c3d23dcc1af58b4b5fAndreas Huber dup->meta()->setInt64("timeUs", timeUs); 662a05822a368dfc8c220b413c3d23dcc1af58b4b5fAndreas Huber 663a05822a368dfc8c220b413c3d23dcc1af58b4b5fAndreas Huber return dup; 664a05822a368dfc8c220b413c3d23dcc1af58b4b5fAndreas Huber} 665a05822a368dfc8c220b413c3d23dcc1af58b4b5fAndreas Huber 666d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huberstatus_t Converter::doMoreWork() { 667575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber status_t err; 668575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber 669a05822a368dfc8c220b413c3d23dcc1af58b4b5fAndreas Huber if (!(mFlags & FLAG_USE_SURFACE_INPUT)) { 670a05822a368dfc8c220b413c3d23dcc1af58b4b5fAndreas Huber for (;;) { 671a05822a368dfc8c220b413c3d23dcc1af58b4b5fAndreas Huber size_t bufferIndex; 672a05822a368dfc8c220b413c3d23dcc1af58b4b5fAndreas Huber err = mEncoder->dequeueInputBuffer(&bufferIndex); 673575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber 674a05822a368dfc8c220b413c3d23dcc1af58b4b5fAndreas Huber if (err != OK) { 675a05822a368dfc8c220b413c3d23dcc1af58b4b5fAndreas Huber break; 676a05822a368dfc8c220b413c3d23dcc1af58b4b5fAndreas Huber } 677a05822a368dfc8c220b413c3d23dcc1af58b4b5fAndreas Huber 678a05822a368dfc8c220b413c3d23dcc1af58b4b5fAndreas Huber mAvailEncoderInputIndices.push_back(bufferIndex); 679575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber } 680d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 681a05822a368dfc8c220b413c3d23dcc1af58b4b5fAndreas Huber feedEncoderInputBuffers(); 682d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 683d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 684cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber for (;;) { 685575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber size_t bufferIndex; 686cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber size_t offset; 687cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber size_t size; 688cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber int64_t timeUs; 689cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber uint32_t flags; 690308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang native_handle_t* handle = NULL; 691cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber err = mEncoder->dequeueOutputBuffer( 692cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber &bufferIndex, &offset, &size, &timeUs, &flags); 693cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber 694cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber if (err != OK) { 695b489b1639c0c12fdd498def46d3f5be3e1fdf6b9Andreas Huber if (err == INFO_FORMAT_CHANGED) { 696b489b1639c0c12fdd498def46d3f5be3e1fdf6b9Andreas Huber continue; 697b489b1639c0c12fdd498def46d3f5be3e1fdf6b9Andreas Huber } else if (err == INFO_OUTPUT_BUFFERS_CHANGED) { 698b489b1639c0c12fdd498def46d3f5be3e1fdf6b9Andreas Huber mEncoder->getOutputBuffers(&mEncoderOutputBuffers); 699b489b1639c0c12fdd498def46d3f5be3e1fdf6b9Andreas Huber continue; 700b489b1639c0c12fdd498def46d3f5be3e1fdf6b9Andreas Huber } 701b489b1639c0c12fdd498def46d3f5be3e1fdf6b9Andreas Huber 702cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber if (err == -EAGAIN) { 703cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber err = OK; 704cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber } 705cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber break; 706cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber } 707d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 708d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber if (flags & MediaCodec::BUFFER_FLAG_EOS) { 709d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber sp<AMessage> notify = mNotify->dup(); 710d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber notify->setInt32("what", kWhatEOS); 711d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber notify->post(); 712d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } else { 7139fef8d453b15a91a2b748faac2bfaff713bcf1e1Andreas Huber#if 0 7149fef8d453b15a91a2b748faac2bfaff713bcf1e1Andreas Huber if (mIsVideo) { 7159fef8d453b15a91a2b748faac2bfaff713bcf1e1Andreas Huber int32_t videoBitrate = GetInt32Property( 7169fef8d453b15a91a2b748faac2bfaff713bcf1e1Andreas Huber "media.wfd.video-bitrate", 5000000); 7179fef8d453b15a91a2b748faac2bfaff713bcf1e1Andreas Huber 7189fef8d453b15a91a2b748faac2bfaff713bcf1e1Andreas Huber setVideoBitrate(videoBitrate); 7199fef8d453b15a91a2b748faac2bfaff713bcf1e1Andreas Huber } 7209fef8d453b15a91a2b748faac2bfaff713bcf1e1Andreas Huber#endif 7219fef8d453b15a91a2b748faac2bfaff713bcf1e1Andreas Huber 722308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang sp<ABuffer> buffer; 723308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang sp<ABuffer> outbuf = mEncoderOutputBuffers.itemAt(bufferIndex); 724308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang 725308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang if (outbuf->meta()->findPointer("handle", (void**)&handle) && 726308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang handle != NULL) { 727308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang int32_t rangeLength, rangeOffset; 728308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang CHECK(outbuf->meta()->findInt32("rangeOffset", &rangeOffset)); 729308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang CHECK(outbuf->meta()->findInt32("rangeLength", &rangeLength)); 730308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang outbuf->meta()->setPointer("handle", NULL); 731308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang 732308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang // MediaSender will post the following message when HDCP 733308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang // is done, to release the output buffer back to encoder. 7341d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar sp<AMessage> notify(new AMessage(kWhatReleaseOutputBuffer, this)); 735308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang notify->setInt32("bufferIndex", bufferIndex); 736308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang 737308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang buffer = new ABuffer( 738308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang rangeLength > (int32_t)size ? rangeLength : size); 739308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang buffer->meta()->setPointer("handle", handle); 740308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang buffer->meta()->setInt32("rangeOffset", rangeOffset); 741308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang buffer->meta()->setInt32("rangeLength", rangeLength); 742308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang buffer->meta()->setMessage("notify", notify); 743308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang } else { 744308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang buffer = new ABuffer(size); 745308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang } 746308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang 747d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber buffer->meta()->setInt64("timeUs", timeUs); 748d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 7498d16bbc5a354d302abfd912b8d88d9c7feb3948fAndreas Huber ALOGV("[%s] time %lld us (%.2f secs)", 750ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar mIsVideo ? "video" : "audio", (long long)timeUs, timeUs / 1E6); 751cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber 752308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang memcpy(buffer->data(), outbuf->base() + offset, size); 753d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 754d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber if (flags & MediaCodec::BUFFER_FLAG_CODECCONFIG) { 755308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang if (!handle) { 756a05822a368dfc8c220b413c3d23dcc1af58b4b5fAndreas Huber if (mIsH264) { 757a05822a368dfc8c220b413c3d23dcc1af58b4b5fAndreas Huber mCSD0 = buffer; 758a05822a368dfc8c220b413c3d23dcc1af58b4b5fAndreas Huber } 759308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang mOutputFormat->setBuffer("csd-0", buffer); 760308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang } 761d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } else { 762a05822a368dfc8c220b413c3d23dcc1af58b4b5fAndreas Huber if (mNeedToManuallyPrependSPSPPS 763a05822a368dfc8c220b413c3d23dcc1af58b4b5fAndreas Huber && mIsH264 764a05822a368dfc8c220b413c3d23dcc1af58b4b5fAndreas Huber && (mFlags & FLAG_PREPEND_CSD_IF_NECESSARY) 765a05822a368dfc8c220b413c3d23dcc1af58b4b5fAndreas Huber && IsIDR(buffer)) { 766a05822a368dfc8c220b413c3d23dcc1af58b4b5fAndreas Huber buffer = prependCSD(buffer); 767a05822a368dfc8c220b413c3d23dcc1af58b4b5fAndreas Huber } 768a05822a368dfc8c220b413c3d23dcc1af58b4b5fAndreas Huber 769d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber sp<AMessage> notify = mNotify->dup(); 770d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber notify->setInt32("what", kWhatAccessUnit); 771d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber notify->setBuffer("accessUnit", buffer); 772d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber notify->post(); 773d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 774d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 775d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 776308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang if (!handle) { 777308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang mEncoder->releaseOutputBuffer(bufferIndex); 778308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang } 779cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber 780cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber if (flags & MediaCodec::BUFFER_FLAG_EOS) { 781cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber break; 782cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber } 783d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 784d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 785d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber return err; 786d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber} 787d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 788496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Hubervoid Converter::requestIDRFrame() { 7891d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar (new AMessage(kWhatRequestIDRFrame, this))->post(); 790496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber} 791496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber 792126568c7aeeb5570789e70a310477f44dbdbd885Andreas Hubervoid Converter::dropAFrame() { 793a05822a368dfc8c220b413c3d23dcc1af58b4b5fAndreas Huber // Unsupported in surface input mode. 794a05822a368dfc8c220b413c3d23dcc1af58b4b5fAndreas Huber CHECK(!(mFlags & FLAG_USE_SURFACE_INPUT)); 795a05822a368dfc8c220b413c3d23dcc1af58b4b5fAndreas Huber 7961d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar (new AMessage(kWhatDropAFrame, this))->post(); 797126568c7aeeb5570789e70a310477f44dbdbd885Andreas Huber} 798126568c7aeeb5570789e70a310477f44dbdbd885Andreas Huber 799a05822a368dfc8c220b413c3d23dcc1af58b4b5fAndreas Hubervoid Converter::suspendEncoding(bool suspend) { 8001d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar sp<AMessage> msg = new AMessage(kWhatSuspendEncoding, this); 801a05822a368dfc8c220b413c3d23dcc1af58b4b5fAndreas Huber msg->setInt32("suspend", suspend); 802a05822a368dfc8c220b413c3d23dcc1af58b4b5fAndreas Huber msg->post(); 803a05822a368dfc8c220b413c3d23dcc1af58b4b5fAndreas Huber} 804a05822a368dfc8c220b413c3d23dcc1af58b4b5fAndreas Huber 8052aea9552aeba92bbaf9e56c666049ea2d14057b5Andreas Huberint32_t Converter::getVideoBitrate() const { 8062aea9552aeba92bbaf9e56c666049ea2d14057b5Andreas Huber return mPrevVideoBitrate; 8072aea9552aeba92bbaf9e56c666049ea2d14057b5Andreas Huber} 8082aea9552aeba92bbaf9e56c666049ea2d14057b5Andreas Huber 8092aea9552aeba92bbaf9e56c666049ea2d14057b5Andreas Hubervoid Converter::setVideoBitrate(int32_t bitRate) { 8102aea9552aeba92bbaf9e56c666049ea2d14057b5Andreas Huber if (mIsVideo && mEncoder != NULL && bitRate != mPrevVideoBitrate) { 8112aea9552aeba92bbaf9e56c666049ea2d14057b5Andreas Huber sp<AMessage> params = new AMessage; 812530fdbdc1b5491f3fbf172752834d1515701e142Lajos Molnar params->setInt32("video-bitrate", bitRate); 8132aea9552aeba92bbaf9e56c666049ea2d14057b5Andreas Huber 8142aea9552aeba92bbaf9e56c666049ea2d14057b5Andreas Huber mEncoder->setParameters(params); 8152aea9552aeba92bbaf9e56c666049ea2d14057b5Andreas Huber 8162aea9552aeba92bbaf9e56c666049ea2d14057b5Andreas Huber mPrevVideoBitrate = bitRate; 8172aea9552aeba92bbaf9e56c666049ea2d14057b5Andreas Huber } 8182aea9552aeba92bbaf9e56c666049ea2d14057b5Andreas Huber} 8192aea9552aeba92bbaf9e56c666049ea2d14057b5Andreas Huber 820d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber} // namespace android 821