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" 2496fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber 2544b59fd9326026d3f82dec25cde48c589b0438e7Andreas Huber#include <cutils/properties.h> 26d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#include <gui/SurfaceTextureClient.h> 27d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#include <media/ICrypto.h> 28d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#include <media/stagefright/foundation/ABuffer.h> 29d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#include <media/stagefright/foundation/ADebug.h> 30d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#include <media/stagefright/foundation/AMessage.h> 3196fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber#include <media/stagefright/MediaBuffer.h> 32d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#include <media/stagefright/MediaCodec.h> 33d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#include <media/stagefright/MediaDefs.h> 34d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#include <media/stagefright/MediaErrors.h> 35d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 3696076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber#include <OMX_Video.h> 3796076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber 38d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Hubernamespace android { 39d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 40d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas HuberConverter::Converter( 41d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber const sp<AMessage> ¬ify, 42d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber const sp<ALooper> &codecLooper, 43e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber const sp<AMessage> &format, 44e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber bool usePCMAudio) 45d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber : mInitCheck(NO_INIT), 46d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber mNotify(notify), 47d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber mCodecLooper(codecLooper), 48d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber mInputFormat(format), 49496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber mIsVideo(false), 50e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber mIsPCMAudio(usePCMAudio), 51cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber mDoMoreWorkPending(false) 52cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber#if ENABLE_SILENCE_DETECTION 53cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber ,mFirstSilentFrameUs(-1ll) 54cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber ,mInSilentMode(false) 55cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber#endif 56cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber { 57496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber AString mime; 58496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber CHECK(mInputFormat->findString("mime", &mime)); 59496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber 60496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber if (!strncasecmp("video/", mime.c_str(), 6)) { 61496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber mIsVideo = true; 62496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber } 63496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber 64e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber CHECK(!usePCMAudio || !mIsVideo); 65e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber 66d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber mInitCheck = initEncoder(); 673a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber 683a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber if (mInitCheck != OK) { 693a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber if (mEncoder != NULL) { 703a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber mEncoder->release(); 713a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber mEncoder.clear(); 723a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber } 733a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber } 74d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber} 75d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 76d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas HuberConverter::~Converter() { 7796fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber CHECK(mEncoder == NULL); 7896fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber} 79a438123bd96c7faf145683876702387efe5628d9Andreas Huber 8096fc6cc65ca93009a759a3a874b82a35771b9714Andreas Hubervoid Converter::shutdownAsync() { 8196fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber ALOGV("shutdown"); 8296fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber (new AMessage(kWhatShutdown, id()))->post(); 83d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber} 84d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 85d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huberstatus_t Converter::initCheck() const { 86d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber return mInitCheck; 87d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber} 88d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 8966e72bc85fb762876baff60ef29de729da93cf26Andreas Hubersize_t Converter::getInputBufferCount() const { 9066e72bc85fb762876baff60ef29de729da93cf26Andreas Huber return mEncoderInputBuffers.size(); 9166e72bc85fb762876baff60ef29de729da93cf26Andreas Huber} 9266e72bc85fb762876baff60ef29de729da93cf26Andreas Huber 93d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Hubersp<AMessage> Converter::getOutputFormat() const { 94d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber return mOutputFormat; 95d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber} 96d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 9744b59fd9326026d3f82dec25cde48c589b0438e7Andreas Huberstatic int32_t getBitrate(const char *propName, int32_t defaultValue) { 9844b59fd9326026d3f82dec25cde48c589b0438e7Andreas Huber char val[PROPERTY_VALUE_MAX]; 9944b59fd9326026d3f82dec25cde48c589b0438e7Andreas Huber if (property_get(propName, val, NULL)) { 10044b59fd9326026d3f82dec25cde48c589b0438e7Andreas Huber char *end; 10144b59fd9326026d3f82dec25cde48c589b0438e7Andreas Huber unsigned long x = strtoul(val, &end, 10); 10244b59fd9326026d3f82dec25cde48c589b0438e7Andreas Huber 10344b59fd9326026d3f82dec25cde48c589b0438e7Andreas Huber if (*end == '\0' && end > val && x > 0) { 10444b59fd9326026d3f82dec25cde48c589b0438e7Andreas Huber return x; 10544b59fd9326026d3f82dec25cde48c589b0438e7Andreas Huber } 10644b59fd9326026d3f82dec25cde48c589b0438e7Andreas Huber } 10744b59fd9326026d3f82dec25cde48c589b0438e7Andreas Huber 10844b59fd9326026d3f82dec25cde48c589b0438e7Andreas Huber return defaultValue; 10944b59fd9326026d3f82dec25cde48c589b0438e7Andreas Huber} 11044b59fd9326026d3f82dec25cde48c589b0438e7Andreas Huber 111d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huberstatus_t Converter::initEncoder() { 112d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber AString inputMIME; 113d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber CHECK(mInputFormat->findString("mime", &inputMIME)); 114d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 115d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber AString outputMIME; 116d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber bool isAudio = false; 117d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber if (!strcasecmp(inputMIME.c_str(), MEDIA_MIMETYPE_AUDIO_RAW)) { 118e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber if (mIsPCMAudio) { 119e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber outputMIME = MEDIA_MIMETYPE_AUDIO_RAW; 120e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber } else { 121e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber outputMIME = MEDIA_MIMETYPE_AUDIO_AAC; 122e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber } 123d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber isAudio = true; 124d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } else if (!strcasecmp(inputMIME.c_str(), MEDIA_MIMETYPE_VIDEO_RAW)) { 125d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber outputMIME = MEDIA_MIMETYPE_VIDEO_AVC; 126d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } else { 127d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber TRESPASS(); 128d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 129d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 130e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber if (!mIsPCMAudio) { 131e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber mEncoder = MediaCodec::CreateByType( 132e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber mCodecLooper, outputMIME.c_str(), true /* encoder */); 133d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 134e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber if (mEncoder == NULL) { 135e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber return ERROR_UNSUPPORTED; 136e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber } 137d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 138d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 139d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber mOutputFormat = mInputFormat->dup(); 140e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber 141e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber if (mIsPCMAudio) { 142e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber return OK; 143e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber } 144e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber 145d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber mOutputFormat->setString("mime", outputMIME.c_str()); 146d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 147f58cac48e5732dbc4a5f33eed9cd39f109146ca4Dave Burke int32_t audioBitrate = getBitrate("media.wfd.audio-bitrate", 128000); 1482295ce2c6fcf07ffaa134440691a8cea5fe35b43Dave Burke int32_t videoBitrate = getBitrate("media.wfd.video-bitrate", 5000000); 14944b59fd9326026d3f82dec25cde48c589b0438e7Andreas Huber 15044b59fd9326026d3f82dec25cde48c589b0438e7Andreas Huber ALOGI("using audio bitrate of %d bps, video bitrate of %d bps", 15144b59fd9326026d3f82dec25cde48c589b0438e7Andreas Huber audioBitrate, videoBitrate); 15244b59fd9326026d3f82dec25cde48c589b0438e7Andreas Huber 153d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber if (isAudio) { 15444b59fd9326026d3f82dec25cde48c589b0438e7Andreas Huber mOutputFormat->setInt32("bitrate", audioBitrate); 155d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } else { 15644b59fd9326026d3f82dec25cde48c589b0438e7Andreas Huber mOutputFormat->setInt32("bitrate", videoBitrate); 15796076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber mOutputFormat->setInt32("bitrate-mode", OMX_Video_ControlRateConstant); 1584a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Huber mOutputFormat->setInt32("frame-rate", 30); 159ee93c8c0f65cc1965ca09c9e33ae672f8bc9b88cDave Burke mOutputFormat->setInt32("i-frame-interval", 1); // Iframes every 1 secs 160c6920dfdca378a168a2168f4a64d21af4d37d539Andreas Huber mOutputFormat->setInt32("prepend-sps-pps-to-idr-frames", 1); 161d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 162d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 163d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber ALOGV("output format is '%s'", mOutputFormat->debugString(0).c_str()); 164d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 165d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber status_t err = mEncoder->configure( 166d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber mOutputFormat, 167d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber NULL /* nativeWindow */, 168d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber NULL /* crypto */, 169d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber MediaCodec::CONFIGURE_FLAG_ENCODE); 170d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 171d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber if (err != OK) { 172d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber return err; 173d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 174d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 175d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber err = mEncoder->start(); 176d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 177d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber if (err != OK) { 178d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber return err; 179d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 180d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 181d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber err = mEncoder->getInputBuffers(&mEncoderInputBuffers); 182d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 183d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber if (err != OK) { 184d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber return err; 185d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 186d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 187d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber return mEncoder->getOutputBuffers(&mEncoderOutputBuffers); 188d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber} 189d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 190d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Hubervoid Converter::notifyError(status_t err) { 191d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber sp<AMessage> notify = mNotify->dup(); 192d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber notify->setInt32("what", kWhatError); 193d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber notify->setInt32("err", err); 194d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber notify->post(); 195d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber} 196d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 197cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber// static 198cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huberbool Converter::IsSilence(const sp<ABuffer> &accessUnit) { 199cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber const uint8_t *ptr = accessUnit->data(); 200cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber const uint8_t *end = ptr + accessUnit->size(); 201cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber while (ptr < end) { 202cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber if (*ptr != 0) { 203cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber return false; 204cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber } 205cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber ++ptr; 206cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber } 207cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber 208cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber return true; 209cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber} 210cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber 211d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Hubervoid Converter::onMessageReceived(const sp<AMessage> &msg) { 212d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber switch (msg->what()) { 21396fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber case kWhatMediaPullerNotify: 214d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber { 21596fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber int32_t what; 21696fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber CHECK(msg->findInt32("what", &what)); 217d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 218e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber if (!mIsPCMAudio && mEncoder == NULL) { 21996fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber ALOGV("got msg '%s' after encoder shutdown.", 22096fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber msg->debugString().c_str()); 221d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 22296fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber if (what == MediaPuller::kWhatAccessUnit) { 22396fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber sp<ABuffer> accessUnit; 22496fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber CHECK(msg->findBuffer("accessUnit", &accessUnit)); 225d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 22696fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber void *mbuf; 22796fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber if (accessUnit->meta()->findPointer("mediaBuffer", &mbuf) 22896fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber && mbuf != NULL) { 22996fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber ALOGV("releasing mbuf %p", mbuf); 230d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 23196fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber accessUnit->meta()->setPointer("mediaBuffer", NULL); 23296fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber 23396fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber static_cast<MediaBuffer *>(mbuf)->release(); 23496fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber mbuf = NULL; 23596fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber } 23696fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber } 23796fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber break; 23896fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber } 23996fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber 24096fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber if (what == MediaPuller::kWhatEOS) { 24196fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber mInputBufferQueue.push_back(NULL); 24296fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber 24396fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber feedEncoderInputBuffers(); 24496fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber 24596fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber scheduleDoMoreWork(); 24696fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber } else { 24796fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber CHECK_EQ(what, MediaPuller::kWhatAccessUnit); 24896fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber 24996fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber sp<ABuffer> accessUnit; 25096fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber CHECK(msg->findBuffer("accessUnit", &accessUnit)); 25196fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber 25296fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber#if 0 25396fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber void *mbuf; 25496fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber if (accessUnit->meta()->findPointer("mediaBuffer", &mbuf) 25596fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber && mbuf != NULL) { 25696fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber ALOGI("queueing mbuf %p", mbuf); 25796fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber } 25896fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber#endif 25996fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber 260cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber#if ENABLE_SILENCE_DETECTION 261cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber if (!mIsVideo) { 262cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber if (IsSilence(accessUnit)) { 2638d16bbc5a354d302abfd912b8d88d9c7feb3948fAndreas Huber if (mInSilentMode) { 2648d16bbc5a354d302abfd912b8d88d9c7feb3948fAndreas Huber break; 2658d16bbc5a354d302abfd912b8d88d9c7feb3948fAndreas Huber } 2668d16bbc5a354d302abfd912b8d88d9c7feb3948fAndreas Huber 2678d16bbc5a354d302abfd912b8d88d9c7feb3948fAndreas Huber int64_t nowUs = ALooper::GetNowUs(); 2688d16bbc5a354d302abfd912b8d88d9c7feb3948fAndreas Huber 2698d16bbc5a354d302abfd912b8d88d9c7feb3948fAndreas Huber if (mFirstSilentFrameUs < 0ll) { 2708d16bbc5a354d302abfd912b8d88d9c7feb3948fAndreas Huber mFirstSilentFrameUs = nowUs; 2718d16bbc5a354d302abfd912b8d88d9c7feb3948fAndreas Huber } else if (nowUs >= mFirstSilentFrameUs + 10000000ll) { 2728d16bbc5a354d302abfd912b8d88d9c7feb3948fAndreas Huber mInSilentMode = true; 2738d16bbc5a354d302abfd912b8d88d9c7feb3948fAndreas Huber ALOGI("audio in silent mode now."); 2748d16bbc5a354d302abfd912b8d88d9c7feb3948fAndreas Huber break; 275cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber } 276cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber } else { 277cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber if (mInSilentMode) { 278cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber ALOGI("audio no longer in silent mode."); 279cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber } 280cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber mInSilentMode = false; 281cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber mFirstSilentFrameUs = -1ll; 282cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber } 283cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber } 284cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber#endif 285cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber 28696fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber mInputBufferQueue.push_back(accessUnit); 287d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 28896fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber feedEncoderInputBuffers(); 289d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 29096fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber scheduleDoMoreWork(); 29196fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber } 292d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber break; 293d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 294d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 295575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber case kWhatEncoderActivity: 296d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber { 297575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber#if 0 298575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber int64_t whenUs; 299575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber if (msg->findInt64("whenUs", &whenUs)) { 300575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber int64_t nowUs = ALooper::GetNowUs(); 301575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber ALOGI("[%s] kWhatEncoderActivity after %lld us", 302575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber mIsVideo ? "video" : "audio", nowUs - whenUs); 303575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber } 304575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber#endif 305575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber 306d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber mDoMoreWorkPending = false; 30796fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber 30896fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber if (mEncoder == NULL) { 30996fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber break; 31096fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber } 31196fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber 312d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber status_t err = doMoreWork(); 313d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 314d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber if (err != OK) { 315d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber notifyError(err); 316d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } else { 317d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber scheduleDoMoreWork(); 318d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 319d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber break; 320d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 321d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 322496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber case kWhatRequestIDRFrame: 323496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber { 32496fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber if (mEncoder == NULL) { 32596fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber break; 32696fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber } 32796fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber 328496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber if (mIsVideo) { 329496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber ALOGI("requesting IDR frame"); 330496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber mEncoder->requestIDRFrame(); 331496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber } 332496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber break; 333496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber } 334496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber 33596fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber case kWhatShutdown: 33696fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber { 33796fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber ALOGI("shutting down encoder"); 338e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber 339e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber if (mEncoder != NULL) { 340e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber mEncoder->release(); 341e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber mEncoder.clear(); 342e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber } 34396fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber 34496fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber AString mime; 34596fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber CHECK(mInputFormat->findString("mime", &mime)); 34696fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber ALOGI("encoder (%s) shut down.", mime.c_str()); 34796fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber break; 34896fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber } 34996fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber 350d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber default: 351d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber TRESPASS(); 352d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 353d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber} 354d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 355d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Hubervoid Converter::scheduleDoMoreWork() { 356e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber if (mIsPCMAudio) { 357e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber // There's no encoder involved in this case. 358e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber return; 359e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber } 360e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber 361d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber if (mDoMoreWorkPending) { 362d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber return; 363d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 364d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 365d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber mDoMoreWorkPending = true; 366575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber 367575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber#if 1 368575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber if (mEncoderActivityNotify == NULL) { 369575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber mEncoderActivityNotify = new AMessage(kWhatEncoderActivity, id()); 370575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber } 371575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber mEncoder->requestActivityNotification(mEncoderActivityNotify->dup()); 372575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber#else 373575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber sp<AMessage> notify = new AMessage(kWhatEncoderActivity, id()); 374575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber notify->setInt64("whenUs", ALooper::GetNowUs()); 375575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber mEncoder->requestActivityNotification(notify); 376575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber#endif 377d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber} 378d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 379e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huberstatus_t Converter::feedRawAudioInputBuffers() { 380e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber // Split incoming PCM audio into buffers of 6 AUs of 80 audio frames each 381e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber // and add a 4 byte header according to the wifi display specs. 382e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber 383e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber while (!mInputBufferQueue.empty()) { 384e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber sp<ABuffer> buffer = *mInputBufferQueue.begin(); 385e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber mInputBufferQueue.erase(mInputBufferQueue.begin()); 386e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber 387e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber int16_t *ptr = (int16_t *)buffer->data(); 388e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber int16_t *stop = (int16_t *)(buffer->data() + buffer->size()); 389e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber while (ptr < stop) { 390e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber *ptr = htons(*ptr); 391e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber ++ptr; 392e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber } 393e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber 394e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber static const size_t kFrameSize = 2 * sizeof(int16_t); // stereo 395e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber static const size_t kFramesPerAU = 80; 396e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber static const size_t kNumAUsPerPESPacket = 6; 397e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber 398e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber if (mPartialAudioAU != NULL) { 399e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber size_t bytesMissingForFullAU = 400e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber kNumAUsPerPESPacket * kFramesPerAU * kFrameSize 401e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber - mPartialAudioAU->size() + 4; 402e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber 403e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber size_t copy = buffer->size(); 404e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber if(copy > bytesMissingForFullAU) { 405e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber copy = bytesMissingForFullAU; 406e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber } 407e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber 408e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber memcpy(mPartialAudioAU->data() + mPartialAudioAU->size(), 409e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber buffer->data(), 410e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber copy); 411e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber 412e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber mPartialAudioAU->setRange(0, mPartialAudioAU->size() + copy); 413e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber 414e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber buffer->setRange(buffer->offset() + copy, buffer->size() - copy); 415e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber 416e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber int64_t timeUs; 417e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber CHECK(buffer->meta()->findInt64("timeUs", &timeUs)); 418e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber 419e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber int64_t copyUs = (int64_t)((copy / kFrameSize) * 1E6 / 48000.0); 420e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber timeUs += copyUs; 421e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber buffer->meta()->setInt64("timeUs", timeUs); 422e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber 423e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber if (bytesMissingForFullAU == copy) { 424e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber sp<AMessage> notify = mNotify->dup(); 425e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber notify->setInt32("what", kWhatAccessUnit); 426e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber notify->setBuffer("accessUnit", mPartialAudioAU); 427e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber notify->post(); 428e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber 429e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber mPartialAudioAU.clear(); 430e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber } 431e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber } 432e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber 433e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber while (buffer->size() > 0) { 434e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber sp<ABuffer> partialAudioAU = 435e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber new ABuffer( 436e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber 4 437e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber + kNumAUsPerPESPacket * kFrameSize * kFramesPerAU); 438e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber 439e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber uint8_t *ptr = partialAudioAU->data(); 440e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber ptr[0] = 0xa0; // 10100000b 441e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber ptr[1] = kNumAUsPerPESPacket; 442e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber ptr[2] = 0; // reserved, audio _emphasis_flag = 0 443e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber 444e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber static const unsigned kQuantizationWordLength = 0; // 16-bit 445e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber static const unsigned kAudioSamplingFrequency = 2; // 48Khz 446e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber static const unsigned kNumberOfAudioChannels = 1; // stereo 447e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber 448e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber ptr[3] = (kQuantizationWordLength << 6) 449e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber | (kAudioSamplingFrequency << 3) 450e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber | kNumberOfAudioChannels; 451e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber 452e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber size_t copy = buffer->size(); 453e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber if (copy > partialAudioAU->size() - 4) { 454e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber copy = partialAudioAU->size() - 4; 455e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber } 456e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber 457e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber memcpy(&ptr[4], buffer->data(), copy); 458e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber 459e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber partialAudioAU->setRange(0, 4 + copy); 460e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber buffer->setRange(buffer->offset() + copy, buffer->size() - copy); 461e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber 462e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber int64_t timeUs; 463e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber CHECK(buffer->meta()->findInt64("timeUs", &timeUs)); 464e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber 465e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber partialAudioAU->meta()->setInt64("timeUs", timeUs); 466e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber 467e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber int64_t copyUs = (int64_t)((copy / kFrameSize) * 1E6 / 48000.0); 468e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber timeUs += copyUs; 469e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber buffer->meta()->setInt64("timeUs", timeUs); 470e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber 47190a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber if (copy == partialAudioAU->capacity() - 4) { 472e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber sp<AMessage> notify = mNotify->dup(); 473e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber notify->setInt32("what", kWhatAccessUnit); 474e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber notify->setBuffer("accessUnit", partialAudioAU); 475e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber notify->post(); 476e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber 477e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber partialAudioAU.clear(); 478e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber continue; 479e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber } 480e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber 481e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber mPartialAudioAU = partialAudioAU; 482e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber } 483e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber } 484e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber 485e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber return OK; 486e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber} 487e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber 488d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huberstatus_t Converter::feedEncoderInputBuffers() { 489e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber if (mIsPCMAudio) { 490e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber return feedRawAudioInputBuffers(); 491e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber } 492e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber 493d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber while (!mInputBufferQueue.empty() 494d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber && !mAvailEncoderInputIndices.empty()) { 495d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber sp<ABuffer> buffer = *mInputBufferQueue.begin(); 496d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber mInputBufferQueue.erase(mInputBufferQueue.begin()); 497d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 498d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber size_t bufferIndex = *mAvailEncoderInputIndices.begin(); 499d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber mAvailEncoderInputIndices.erase(mAvailEncoderInputIndices.begin()); 500d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 501d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber int64_t timeUs = 0ll; 502d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber uint32_t flags = 0; 503d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 504d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber if (buffer != NULL) { 505d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber CHECK(buffer->meta()->findInt64("timeUs", &timeUs)); 506d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 507d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber memcpy(mEncoderInputBuffers.itemAt(bufferIndex)->data(), 508d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber buffer->data(), 509d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber buffer->size()); 510d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 511d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber void *mediaBuffer; 512d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber if (buffer->meta()->findPointer("mediaBuffer", &mediaBuffer) 513d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber && mediaBuffer != NULL) { 514d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber mEncoderInputBuffers.itemAt(bufferIndex)->meta() 515d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber ->setPointer("mediaBuffer", mediaBuffer); 516d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 517d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber buffer->meta()->setPointer("mediaBuffer", NULL); 518d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 519d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } else { 520d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber flags = MediaCodec::BUFFER_FLAG_EOS; 521d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 522d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 523d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber status_t err = mEncoder->queueInputBuffer( 524d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber bufferIndex, 0, (buffer == NULL) ? 0 : buffer->size(), 525d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber timeUs, flags); 526d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 527d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber if (err != OK) { 528d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber return err; 529d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 530d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 531d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 532d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber return OK; 533d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber} 534d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 535d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huberstatus_t Converter::doMoreWork() { 536575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber status_t err; 537575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber 538575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber for (;;) { 539575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber size_t bufferIndex; 540575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber err = mEncoder->dequeueInputBuffer(&bufferIndex); 541575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber 542575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber if (err != OK) { 543575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber break; 544575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber } 545d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 546d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber mAvailEncoderInputIndices.push_back(bufferIndex); 547d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 548d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 549575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber feedEncoderInputBuffers(); 550575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber 551cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber for (;;) { 552575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber size_t bufferIndex; 553cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber size_t offset; 554cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber size_t size; 555cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber int64_t timeUs; 556cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber uint32_t flags; 557cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber err = mEncoder->dequeueOutputBuffer( 558cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber &bufferIndex, &offset, &size, &timeUs, &flags); 559cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber 560cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber if (err != OK) { 561cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber if (err == -EAGAIN) { 562cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber err = OK; 563cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber } 564cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber break; 565cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber } 566d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 567d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber if (flags & MediaCodec::BUFFER_FLAG_EOS) { 568d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber sp<AMessage> notify = mNotify->dup(); 569d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber notify->setInt32("what", kWhatEOS); 570d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber notify->post(); 571d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } else { 572d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber sp<ABuffer> buffer = new ABuffer(size); 573d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber buffer->meta()->setInt64("timeUs", timeUs); 574d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 5758d16bbc5a354d302abfd912b8d88d9c7feb3948fAndreas Huber ALOGV("[%s] time %lld us (%.2f secs)", 5768d16bbc5a354d302abfd912b8d88d9c7feb3948fAndreas Huber mIsVideo ? "video" : "audio", timeUs, timeUs / 1E6); 577cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber 578d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber memcpy(buffer->data(), 579d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber mEncoderOutputBuffers.itemAt(bufferIndex)->base() + offset, 580d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber size); 581d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 582d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber if (flags & MediaCodec::BUFFER_FLAG_CODECCONFIG) { 583d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber mOutputFormat->setBuffer("csd-0", buffer); 584d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } else { 585d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber sp<AMessage> notify = mNotify->dup(); 586d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber notify->setInt32("what", kWhatAccessUnit); 587d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber notify->setBuffer("accessUnit", buffer); 588d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber notify->post(); 589d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 590d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 591d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 592cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber mEncoder->releaseOutputBuffer(bufferIndex); 593cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber 594cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber if (flags & MediaCodec::BUFFER_FLAG_EOS) { 595cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber break; 596cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber } 597d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 598d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 599d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber return err; 600d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber} 601d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 602496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Hubervoid Converter::requestIDRFrame() { 603496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber (new AMessage(kWhatRequestIDRFrame, id()))->post(); 604496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber} 605496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber 606d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber} // namespace android 607