130ab66297501757d745b9ae10da61adcd891f497Andreas Huber/* 230ab66297501757d745b9ae10da61adcd891f497Andreas Huber * Copyright (C) 2009 The Android Open Source Project 330ab66297501757d745b9ae10da61adcd891f497Andreas Huber * 430ab66297501757d745b9ae10da61adcd891f497Andreas Huber * Licensed under the Apache License, Version 2.0 (the "License"); 530ab66297501757d745b9ae10da61adcd891f497Andreas Huber * you may not use this file except in compliance with the License. 630ab66297501757d745b9ae10da61adcd891f497Andreas Huber * You may obtain a copy of the License at 730ab66297501757d745b9ae10da61adcd891f497Andreas Huber * 830ab66297501757d745b9ae10da61adcd891f497Andreas Huber * http://www.apache.org/licenses/LICENSE-2.0 930ab66297501757d745b9ae10da61adcd891f497Andreas Huber * 1030ab66297501757d745b9ae10da61adcd891f497Andreas Huber * Unless required by applicable law or agreed to in writing, software 1130ab66297501757d745b9ae10da61adcd891f497Andreas Huber * distributed under the License is distributed on an "AS IS" BASIS, 1230ab66297501757d745b9ae10da61adcd891f497Andreas Huber * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1330ab66297501757d745b9ae10da61adcd891f497Andreas Huber * See the License for the specific language governing permissions and 1430ab66297501757d745b9ae10da61adcd891f497Andreas Huber * limitations under the License. 1530ab66297501757d745b9ae10da61adcd891f497Andreas Huber */ 1630ab66297501757d745b9ae10da61adcd891f497Andreas Huber 1730ab66297501757d745b9ae10da61adcd891f497Andreas Huber//#define LOG_NDEBUG 0 1830ab66297501757d745b9ae10da61adcd891f497Andreas Huber#define LOG_TAG "StagefrightRecorder" 19377b2ec9a2885f9b6405b07ba900a9e3f4349c38Kévin PETIT#include <inttypes.h> 2030ab66297501757d745b9ae10da61adcd891f497Andreas Huber#include <utils/Log.h> 2130ab66297501757d745b9ae10da61adcd891f497Andreas Huber 22114819633470ebd5b346c13c2a82a0025d2d39c0Robert Shih#include "WebmWriter.h" 2330ab66297501757d745b9ae10da61adcd891f497Andreas Huber#include "StagefrightRecorder.h" 2430ab66297501757d745b9ae10da61adcd891f497Andreas Huber 25c96cfbe66d7bf261c57ff93984bc6a4b3a58f6fcLajos Molnar#include <algorithm> 26c96cfbe66d7bf261c57ff93984bc6a4b3a58f6fcLajos Molnar 27d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala#include <android/hardware/ICamera.h> 28d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala 2975b0b5473c7b43f8c5972db7e6e8930988ead751Gloria Wang#include <binder/IPCThreadState.h> 3075b0b5473c7b43f8c5972db7e6e8930988ead751Gloria Wang#include <binder/IServiceManager.h> 3175b0b5473c7b43f8c5972db7e6e8930988ead751Gloria Wang 3275b0b5473c7b43f8c5972db7e6e8930988ead751Gloria Wang#include <media/IMediaPlayerService.h> 33ac4e4189db77dc0af7671b162d11be5ccec69339Ray Essick#include <media/MediaAnalyticsItem.h> 3472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang#include <media/stagefright/foundation/ABuffer.h> 35f1d5aa162c02a16b7195a43a9bcea4d592600ac4James Dong#include <media/stagefright/foundation/ADebug.h> 3672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang#include <media/stagefright/foundation/AMessage.h> 3772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang#include <media/stagefright/foundation/ALooper.h> 38a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar#include <media/stagefright/ACodec.h> 392dce41ad26cb3e9e15c9e456a84bcf5309548ca0Andreas Huber#include <media/stagefright/AudioSource.h> 402dce41ad26cb3e9e15c9e456a84bcf5309548ca0Andreas Huber#include <media/stagefright/AMRWriter.h> 41760943b5e7a09b602aba04ec451e97662f48b0a4James Dong#include <media/stagefright/AACWriter.h> 4230ab66297501757d745b9ae10da61adcd891f497Andreas Huber#include <media/stagefright/CameraSource.h> 4365e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra#include <media/stagefright/CameraSourceTimeLapse.h> 4459b7dc39ea8332d3418a599e51447d7edb612ac4Andreas Huber#include <media/stagefright/MPEG2TSWriter.h> 4530ab66297501757d745b9ae10da61adcd891f497Andreas Huber#include <media/stagefright/MPEG4Writer.h> 4630ab66297501757d745b9ae10da61adcd891f497Andreas Huber#include <media/stagefright/MediaDefs.h> 4730ab66297501757d745b9ae10da61adcd891f497Andreas Huber#include <media/stagefright/MetaData.h> 4872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang#include <media/stagefright/MediaCodecSource.h> 49addf2cbb120346ae42e78fa739245a353db5edadChong Zhang#include <media/stagefright/PersistentSurface.h> 5099c2a076b4a46762a22bbb4dfbd51d107e0532d9James Dong#include <media/MediaProfiles.h> 51ef9d0cd72e476a4b7556833fb09505a51b626797James Dong#include <camera/CameraParameters.h> 52b33f3407bab0970a7f9241680723a1140b177c50Pannag Sanketi 5330ab66297501757d745b9ae10da61adcd891f497Andreas Huber#include <utils/Errors.h> 54c32cd79d9ad4aba7d959b5b3be7361b4715e6f18James Dong#include <sys/types.h> 55050b28a593350047845a45a14cc5026221ac1620James Dong#include <ctype.h> 56ca2fa61ef03cac008ea86e6fe16b2e5f9f1a2be3Nipun Kwatra#include <unistd.h> 5730ab66297501757d745b9ae10da61adcd891f497Andreas Huber 5864760240f931714858a59c1579f07264d7182ba2Dima Zavin#include <system/audio.h> 59fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin 6039ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber#include "ARTPWriter.h" 6139ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 6230ab66297501757d745b9ae10da61adcd891f497Andreas Hubernamespace android { 6330ab66297501757d745b9ae10da61adcd891f497Andreas Huber 642da225766572a3d4746b4e21cb231a0243b114abLajos Molnarstatic const float kTypicalDisplayRefreshingRate = 60.f; 652da225766572a3d4746b4e21cb231a0243b114abLajos Molnar// display refresh rate drops on battery saver 662da225766572a3d4746b4e21cb231a0243b114abLajos Molnarstatic const float kMinTypicalDisplayRefreshingRate = kTypicalDisplayRefreshingRate / 2; 672da225766572a3d4746b4e21cb231a0243b114abLajos Molnarstatic const int kMaxNumVideoTemporalLayers = 8; 682da225766572a3d4746b4e21cb231a0243b114abLajos Molnar 69ac4e4189db77dc0af7671b162d11be5ccec69339Ray Essick// key for media statistics 70ac4e4189db77dc0af7671b162d11be5ccec69339Ray Essickstatic const char *kKeyRecorder = "recorder"; 71ac4e4189db77dc0af7671b162d11be5ccec69339Ray Essick// attrs for media statistics 72de15b8c160c720c48b93796016801e7ae0b6bd2dRay Essick// NB: these are matched with public Java API constants defined 73de15b8c160c720c48b93796016801e7ae0b6bd2dRay Essick// in frameworks/base/media/java/android/media/MediaRecorder.java 74de15b8c160c720c48b93796016801e7ae0b6bd2dRay Essick// These must be kept synchronized with the constants there. 75afb43f76821e6a63e17e6484289a40430ada6978Ray Essickstatic const char *kRecorderAudioBitrate = "android.media.mediarecorder.audio-bitrate"; 76de15b8c160c720c48b93796016801e7ae0b6bd2dRay Essickstatic const char *kRecorderAudioChannels = "android.media.mediarecorder.audio-channels"; 77de15b8c160c720c48b93796016801e7ae0b6bd2dRay Essickstatic const char *kRecorderAudioSampleRate = "android.media.mediarecorder.audio-samplerate"; 78afb43f76821e6a63e17e6484289a40430ada6978Ray Essickstatic const char *kRecorderAudioTimescale = "android.media.mediarecorder.audio-timescale"; 79afb43f76821e6a63e17e6484289a40430ada6978Ray Essickstatic const char *kRecorderCaptureFps = "android.media.mediarecorder.capture-fps"; 80de15b8c160c720c48b93796016801e7ae0b6bd2dRay Essickstatic const char *kRecorderCaptureFpsEnable = "android.media.mediarecorder.capture-fpsenable"; 81de15b8c160c720c48b93796016801e7ae0b6bd2dRay Essickstatic const char *kRecorderFrameRate = "android.media.mediarecorder.frame-rate"; 82de15b8c160c720c48b93796016801e7ae0b6bd2dRay Essickstatic const char *kRecorderHeight = "android.media.mediarecorder.height"; 83de15b8c160c720c48b93796016801e7ae0b6bd2dRay Essickstatic const char *kRecorderMovieTimescale = "android.media.mediarecorder.movie-timescale"; 84afb43f76821e6a63e17e6484289a40430ada6978Ray Essickstatic const char *kRecorderRotation = "android.media.mediarecorder.rotation"; 85de15b8c160c720c48b93796016801e7ae0b6bd2dRay Essickstatic const char *kRecorderVideoBitrate = "android.media.mediarecorder.video-bitrate"; 86de15b8c160c720c48b93796016801e7ae0b6bd2dRay Essickstatic const char *kRecorderVideoIframeInterval = "android.media.mediarecorder.video-iframe-interval"; 87de15b8c160c720c48b93796016801e7ae0b6bd2dRay Essickstatic const char *kRecorderVideoLevel = "android.media.mediarecorder.video-encoder-level"; 88de15b8c160c720c48b93796016801e7ae0b6bd2dRay Essickstatic const char *kRecorderVideoProfile = "android.media.mediarecorder.video-encoder-profile"; 89de15b8c160c720c48b93796016801e7ae0b6bd2dRay Essickstatic const char *kRecorderVideoTimescale = "android.media.mediarecorder.video-timescale"; 90de15b8c160c720c48b93796016801e7ae0b6bd2dRay Essickstatic const char *kRecorderWidth = "android.media.mediarecorder.width"; 91de15b8c160c720c48b93796016801e7ae0b6bd2dRay Essick 9235cc20b52fdc551b5b0ed1fc32803a56d82e8881Ray Essick// new fields, not yet frozen in the public Java API definitions 9335cc20b52fdc551b5b0ed1fc32803a56d82e8881Ray Essickstatic const char *kRecorderAudioMime = "android.media.mediarecorder.audio.mime"; 9435cc20b52fdc551b5b0ed1fc32803a56d82e8881Ray Essickstatic const char *kRecorderVideoMime = "android.media.mediarecorder.video.mime"; 9535cc20b52fdc551b5b0ed1fc32803a56d82e8881Ray Essickstatic const char *kRecorderDurationMs = "android.media.mediarecorder.durationMs"; 9635cc20b52fdc551b5b0ed1fc32803a56d82e8881Ray Essickstatic const char *kRecorderPaused = "android.media.mediarecorder.pausedMs"; 9735cc20b52fdc551b5b0ed1fc32803a56d82e8881Ray Essickstatic const char *kRecorderNumPauses = "android.media.mediarecorder.NPauses"; 9835cc20b52fdc551b5b0ed1fc32803a56d82e8881Ray Essick 99afb43f76821e6a63e17e6484289a40430ada6978Ray Essick 10075b0b5473c7b43f8c5972db7e6e8930988ead751Gloria Wang// To collect the encoder usage for the battery app 10175b0b5473c7b43f8c5972db7e6e8930988ead751Gloria Wangstatic void addBatteryData(uint32_t params) { 10275b0b5473c7b43f8c5972db7e6e8930988ead751Gloria Wang sp<IBinder> binder = 10375b0b5473c7b43f8c5972db7e6e8930988ead751Gloria Wang defaultServiceManager()->getService(String16("media.player")); 10475b0b5473c7b43f8c5972db7e6e8930988ead751Gloria Wang sp<IMediaPlayerService> service = interface_cast<IMediaPlayerService>(binder); 10575b0b5473c7b43f8c5972db7e6e8930988ead751Gloria Wang CHECK(service.get() != NULL); 10675b0b5473c7b43f8c5972db7e6e8930988ead751Gloria Wang 10775b0b5473c7b43f8c5972db7e6e8930988ead751Gloria Wang service->addBatteryData(params); 10875b0b5473c7b43f8c5972db7e6e8930988ead751Gloria Wang} 10975b0b5473c7b43f8c5972db7e6e8930988ead751Gloria Wang 11075b0b5473c7b43f8c5972db7e6e8930988ead751Gloria Wang 111be71aa29a3c86d2e01cd17839d2a72ab09a1bce5Svet GanovStagefrightRecorder::StagefrightRecorder(const String16 &opPackageName) 112be71aa29a3c86d2e01cd17839d2a72ab09a1bce5Svet Ganov : MediaRecorderBase(opPackageName), 113be71aa29a3c86d2e01cd17839d2a72ab09a1bce5Svet Ganov mWriter(NULL), 1143cecf640c4daf2df616b278bd9986018c8182908James Dong mOutputFd(-1), 115174e1094a41828111c86793232d9492ab8e29395Kevin Rocard mAudioSource((audio_source_t)AUDIO_SOURCE_CNT), // initialize with invalid value 11675b0b5473c7b43f8c5972db7e6e8930988ead751Gloria Wang mVideoSource(VIDEO_SOURCE_LIST_END), 117fec2f93fae282ad10bbb5e3fcce9f60eff2cfb48jiabin mStarted(false), 118fec2f93fae282ad10bbb5e3fcce9f60eff2cfb48jiabin mSelectedDeviceId(AUDIO_PORT_HANDLE_NONE), 119fec2f93fae282ad10bbb5e3fcce9f60eff2cfb48jiabin mDeviceCallbackEnabled(false) { 120d329e21495eda9dbc531fdd0c26c77f1593ac3f4James Dong 1213856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("Constructor"); 122ac4e4189db77dc0af7671b162d11be5ccec69339Ray Essick 123ac4e4189db77dc0af7671b162d11be5ccec69339Ray Essick mAnalyticsDirty = false; 12430ab66297501757d745b9ae10da61adcd891f497Andreas Huber reset(); 12530ab66297501757d745b9ae10da61adcd891f497Andreas Huber} 12630ab66297501757d745b9ae10da61adcd891f497Andreas Huber 12730ab66297501757d745b9ae10da61adcd891f497Andreas HuberStagefrightRecorder::~StagefrightRecorder() { 1283856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("Destructor"); 12930ab66297501757d745b9ae10da61adcd891f497Andreas Huber stop(); 13072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 13172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang if (mLooper != NULL) { 13272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mLooper->stop(); 13372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 134ac4e4189db77dc0af7671b162d11be5ccec69339Ray Essick 135ac4e4189db77dc0af7671b162d11be5ccec69339Ray Essick // log the current record, provided it has some information worth recording 13635cc20b52fdc551b5b0ed1fc32803a56d82e8881Ray Essick // NB: this also reclaims & clears mAnalyticsItem. 13735cc20b52fdc551b5b0ed1fc32803a56d82e8881Ray Essick flushAndResetMetrics(false); 138ac4e4189db77dc0af7671b162d11be5ccec69339Ray Essick} 139ac4e4189db77dc0af7671b162d11be5ccec69339Ray Essick 140ac4e4189db77dc0af7671b162d11be5ccec69339Ray Essickvoid StagefrightRecorder::updateMetrics() { 141ac4e4189db77dc0af7671b162d11be5ccec69339Ray Essick ALOGV("updateMetrics"); 142ac4e4189db77dc0af7671b162d11be5ccec69339Ray Essick 14335cc20b52fdc551b5b0ed1fc32803a56d82e8881Ray Essick // we run as part of the media player service; what we really want to 14435cc20b52fdc551b5b0ed1fc32803a56d82e8881Ray Essick // know is the app which requested the recording. 14535cc20b52fdc551b5b0ed1fc32803a56d82e8881Ray Essick mAnalyticsItem->setUid(mClientUid); 14635cc20b52fdc551b5b0ed1fc32803a56d82e8881Ray Essick 14735cc20b52fdc551b5b0ed1fc32803a56d82e8881Ray Essick // populate the values from the raw fields. 148ac4e4189db77dc0af7671b162d11be5ccec69339Ray Essick 149ac4e4189db77dc0af7671b162d11be5ccec69339Ray Essick // TBD mOutputFormat = OUTPUT_FORMAT_THREE_GPP; 150ac4e4189db77dc0af7671b162d11be5ccec69339Ray Essick // TBD mAudioEncoder = AUDIO_ENCODER_AMR_NB; 151ac4e4189db77dc0af7671b162d11be5ccec69339Ray Essick // TBD mVideoEncoder = VIDEO_ENCODER_DEFAULT; 152afb43f76821e6a63e17e6484289a40430ada6978Ray Essick mAnalyticsItem->setInt32(kRecorderHeight, mVideoHeight); 153afb43f76821e6a63e17e6484289a40430ada6978Ray Essick mAnalyticsItem->setInt32(kRecorderWidth, mVideoWidth); 154afb43f76821e6a63e17e6484289a40430ada6978Ray Essick mAnalyticsItem->setInt32(kRecorderFrameRate, mFrameRate); 155afb43f76821e6a63e17e6484289a40430ada6978Ray Essick mAnalyticsItem->setInt32(kRecorderVideoBitrate, mVideoBitRate); 156afb43f76821e6a63e17e6484289a40430ada6978Ray Essick mAnalyticsItem->setInt32(kRecorderAudioSampleRate, mSampleRate); 157afb43f76821e6a63e17e6484289a40430ada6978Ray Essick mAnalyticsItem->setInt32(kRecorderAudioChannels, mAudioChannels); 158afb43f76821e6a63e17e6484289a40430ada6978Ray Essick mAnalyticsItem->setInt32(kRecorderAudioBitrate, mAudioBitRate); 159ac4e4189db77dc0af7671b162d11be5ccec69339Ray Essick // TBD mInterleaveDurationUs = 0; 160afb43f76821e6a63e17e6484289a40430ada6978Ray Essick mAnalyticsItem->setInt32(kRecorderVideoIframeInterval, mIFramesIntervalSec); 161ac4e4189db77dc0af7671b162d11be5ccec69339Ray Essick // TBD mAudioSourceNode = 0; 162ac4e4189db77dc0af7671b162d11be5ccec69339Ray Essick // TBD mUse64BitFileOffset = false; 163afb43f76821e6a63e17e6484289a40430ada6978Ray Essick mAnalyticsItem->setInt32(kRecorderMovieTimescale, mMovieTimeScale); 164afb43f76821e6a63e17e6484289a40430ada6978Ray Essick mAnalyticsItem->setInt32(kRecorderAudioTimescale, mAudioTimeScale); 165afb43f76821e6a63e17e6484289a40430ada6978Ray Essick mAnalyticsItem->setInt32(kRecorderVideoTimescale, mVideoTimeScale); 166ac4e4189db77dc0af7671b162d11be5ccec69339Ray Essick // TBD mCameraId = 0; 167ac4e4189db77dc0af7671b162d11be5ccec69339Ray Essick // TBD mStartTimeOffsetMs = -1; 168afb43f76821e6a63e17e6484289a40430ada6978Ray Essick mAnalyticsItem->setInt32(kRecorderVideoProfile, mVideoEncoderProfile); 169afb43f76821e6a63e17e6484289a40430ada6978Ray Essick mAnalyticsItem->setInt32(kRecorderVideoLevel, mVideoEncoderLevel); 170ac4e4189db77dc0af7671b162d11be5ccec69339Ray Essick // TBD mMaxFileDurationUs = 0; 171ac4e4189db77dc0af7671b162d11be5ccec69339Ray Essick // TBD mMaxFileSizeBytes = 0; 172ac4e4189db77dc0af7671b162d11be5ccec69339Ray Essick // TBD mTrackEveryTimeDurationUs = 0; 173afb43f76821e6a63e17e6484289a40430ada6978Ray Essick mAnalyticsItem->setInt32(kRecorderCaptureFpsEnable, mCaptureFpsEnable); 174afb43f76821e6a63e17e6484289a40430ada6978Ray Essick mAnalyticsItem->setDouble(kRecorderCaptureFps, mCaptureFps); 175ac4e4189db77dc0af7671b162d11be5ccec69339Ray Essick // TBD mCameraSourceTimeLapse = NULL; 176ac4e4189db77dc0af7671b162d11be5ccec69339Ray Essick // TBD mMetaDataStoredInVideoBuffers = kMetadataBufferTypeInvalid; 177ac4e4189db77dc0af7671b162d11be5ccec69339Ray Essick // TBD mEncoderProfiles = MediaProfiles::getInstance(); 178afb43f76821e6a63e17e6484289a40430ada6978Ray Essick mAnalyticsItem->setInt32(kRecorderRotation, mRotationDegrees); 179ac4e4189db77dc0af7671b162d11be5ccec69339Ray Essick // PII mLatitudex10000 = -3600000; 180ac4e4189db77dc0af7671b162d11be5ccec69339Ray Essick // PII mLongitudex10000 = -3600000; 181ac4e4189db77dc0af7671b162d11be5ccec69339Ray Essick // TBD mTotalBitRate = 0; 182ac4e4189db77dc0af7671b162d11be5ccec69339Ray Essick 18335cc20b52fdc551b5b0ed1fc32803a56d82e8881Ray Essick // duration information (recorded, paused, # of pauses) 18435cc20b52fdc551b5b0ed1fc32803a56d82e8881Ray Essick mAnalyticsItem->setInt64(kRecorderDurationMs, (mDurationRecordedUs+500)/1000 ); 18535cc20b52fdc551b5b0ed1fc32803a56d82e8881Ray Essick if (mNPauses != 0) { 18635cc20b52fdc551b5b0ed1fc32803a56d82e8881Ray Essick mAnalyticsItem->setInt64(kRecorderPaused, (mDurationPausedUs+500)/1000 ); 18735cc20b52fdc551b5b0ed1fc32803a56d82e8881Ray Essick mAnalyticsItem->setInt32(kRecorderNumPauses, mNPauses); 18835cc20b52fdc551b5b0ed1fc32803a56d82e8881Ray Essick } 189ac4e4189db77dc0af7671b162d11be5ccec69339Ray Essick} 190ac4e4189db77dc0af7671b162d11be5ccec69339Ray Essick 19135cc20b52fdc551b5b0ed1fc32803a56d82e8881Ray Essickvoid StagefrightRecorder::flushAndResetMetrics(bool reinitialize) { 19235cc20b52fdc551b5b0ed1fc32803a56d82e8881Ray Essick ALOGV("flushAndResetMetrics"); 19335cc20b52fdc551b5b0ed1fc32803a56d82e8881Ray Essick // flush anything we have, maybe setup a new record 194ac4e4189db77dc0af7671b162d11be5ccec69339Ray Essick if (mAnalyticsDirty && mAnalyticsItem != NULL) { 195ac4e4189db77dc0af7671b162d11be5ccec69339Ray Essick updateMetrics(); 196ac4e4189db77dc0af7671b162d11be5ccec69339Ray Essick if (mAnalyticsItem->count() > 0) { 197ac4e4189db77dc0af7671b162d11be5ccec69339Ray Essick mAnalyticsItem->selfrecord(); 198ac4e4189db77dc0af7671b162d11be5ccec69339Ray Essick } 199ac4e4189db77dc0af7671b162d11be5ccec69339Ray Essick delete mAnalyticsItem; 200ac4e4189db77dc0af7671b162d11be5ccec69339Ray Essick mAnalyticsItem = NULL; 201ac4e4189db77dc0af7671b162d11be5ccec69339Ray Essick } 202ac4e4189db77dc0af7671b162d11be5ccec69339Ray Essick mAnalyticsDirty = false; 20335cc20b52fdc551b5b0ed1fc32803a56d82e8881Ray Essick if (reinitialize) { 20435cc20b52fdc551b5b0ed1fc32803a56d82e8881Ray Essick mAnalyticsItem = new MediaAnalyticsItem(kKeyRecorder); 20535cc20b52fdc551b5b0ed1fc32803a56d82e8881Ray Essick } 20630ab66297501757d745b9ae10da61adcd891f497Andreas Huber} 20730ab66297501757d745b9ae10da61adcd891f497Andreas Huber 20830ab66297501757d745b9ae10da61adcd891f497Andreas Huberstatus_t StagefrightRecorder::init() { 2093856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("init"); 21072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 21172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mLooper = new ALooper; 21272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mLooper->setName("recorder_looper"); 21372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mLooper->start(); 21472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 21530ab66297501757d745b9ae10da61adcd891f497Andreas Huber return OK; 21630ab66297501757d745b9ae10da61adcd891f497Andreas Huber} 21730ab66297501757d745b9ae10da61adcd891f497Andreas Huber 218fec2f93fae282ad10bbb5e3fcce9f60eff2cfb48jiabin// The client side of mediaserver asks it to create a SurfaceMediaSource 219b33f3407bab0970a7f9241680723a1140b177c50Pannag Sanketi// and return a interface reference. The client side will use that 220b33f3407bab0970a7f9241680723a1140b177c50Pannag Sanketi// while encoding GL Frames 2218ba01021b573889802e67e029225a96f0dfa471aAndy McFaddensp<IGraphicBufferProducer> StagefrightRecorder::querySurfaceMediaSource() const { 2223856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("Get SurfaceMediaSource"); 22372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang return mGraphicBufferProducer; 224b33f3407bab0970a7f9241680723a1140b177c50Pannag Sanketi} 225b33f3407bab0970a7f9241680723a1140b177c50Pannag Sanketi 226fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavinstatus_t StagefrightRecorder::setAudioSource(audio_source_t as) { 2273856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("setAudioSource: %d", as); 228d329e21495eda9dbc531fdd0c26c77f1593ac3f4James Dong if (as < AUDIO_SOURCE_DEFAULT || 2290f8f4e681b867dd611d2d916453337cb0770d4daHochi Huang (as >= AUDIO_SOURCE_CNT && as != AUDIO_SOURCE_FM_TUNER)) { 23029357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("Invalid audio source: %d", as); 231d329e21495eda9dbc531fdd0c26c77f1593ac3f4James Dong return BAD_VALUE; 232d329e21495eda9dbc531fdd0c26c77f1593ac3f4James Dong } 233d329e21495eda9dbc531fdd0c26c77f1593ac3f4James Dong 234d329e21495eda9dbc531fdd0c26c77f1593ac3f4James Dong if (as == AUDIO_SOURCE_DEFAULT) { 235d329e21495eda9dbc531fdd0c26c77f1593ac3f4James Dong mAudioSource = AUDIO_SOURCE_MIC; 236d329e21495eda9dbc531fdd0c26c77f1593ac3f4James Dong } else { 237d329e21495eda9dbc531fdd0c26c77f1593ac3f4James Dong mAudioSource = as; 238d329e21495eda9dbc531fdd0c26c77f1593ac3f4James Dong } 23930ab66297501757d745b9ae10da61adcd891f497Andreas Huber 24030ab66297501757d745b9ae10da61adcd891f497Andreas Huber return OK; 24130ab66297501757d745b9ae10da61adcd891f497Andreas Huber} 24230ab66297501757d745b9ae10da61adcd891f497Andreas Huber 24330ab66297501757d745b9ae10da61adcd891f497Andreas Huberstatus_t StagefrightRecorder::setVideoSource(video_source vs) { 2443856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("setVideoSource: %d", vs); 245d329e21495eda9dbc531fdd0c26c77f1593ac3f4James Dong if (vs < VIDEO_SOURCE_DEFAULT || 246d329e21495eda9dbc531fdd0c26c77f1593ac3f4James Dong vs >= VIDEO_SOURCE_LIST_END) { 24729357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("Invalid video source: %d", vs); 248d329e21495eda9dbc531fdd0c26c77f1593ac3f4James Dong return BAD_VALUE; 249d329e21495eda9dbc531fdd0c26c77f1593ac3f4James Dong } 250d329e21495eda9dbc531fdd0c26c77f1593ac3f4James Dong 251d329e21495eda9dbc531fdd0c26c77f1593ac3f4James Dong if (vs == VIDEO_SOURCE_DEFAULT) { 252d329e21495eda9dbc531fdd0c26c77f1593ac3f4James Dong mVideoSource = VIDEO_SOURCE_CAMERA; 253d329e21495eda9dbc531fdd0c26c77f1593ac3f4James Dong } else { 254d329e21495eda9dbc531fdd0c26c77f1593ac3f4James Dong mVideoSource = vs; 255d329e21495eda9dbc531fdd0c26c77f1593ac3f4James Dong } 25630ab66297501757d745b9ae10da61adcd891f497Andreas Huber 25730ab66297501757d745b9ae10da61adcd891f497Andreas Huber return OK; 25830ab66297501757d745b9ae10da61adcd891f497Andreas Huber} 25930ab66297501757d745b9ae10da61adcd891f497Andreas Huber 26030ab66297501757d745b9ae10da61adcd891f497Andreas Huberstatus_t StagefrightRecorder::setOutputFormat(output_format of) { 2613856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("setOutputFormat: %d", of); 262d329e21495eda9dbc531fdd0c26c77f1593ac3f4James Dong if (of < OUTPUT_FORMAT_DEFAULT || 263d329e21495eda9dbc531fdd0c26c77f1593ac3f4James Dong of >= OUTPUT_FORMAT_LIST_END) { 26429357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("Invalid output format: %d", of); 265d329e21495eda9dbc531fdd0c26c77f1593ac3f4James Dong return BAD_VALUE; 266d329e21495eda9dbc531fdd0c26c77f1593ac3f4James Dong } 267d329e21495eda9dbc531fdd0c26c77f1593ac3f4James Dong 268d329e21495eda9dbc531fdd0c26c77f1593ac3f4James Dong if (of == OUTPUT_FORMAT_DEFAULT) { 269d329e21495eda9dbc531fdd0c26c77f1593ac3f4James Dong mOutputFormat = OUTPUT_FORMAT_THREE_GPP; 270d329e21495eda9dbc531fdd0c26c77f1593ac3f4James Dong } else { 271d329e21495eda9dbc531fdd0c26c77f1593ac3f4James Dong mOutputFormat = of; 272d329e21495eda9dbc531fdd0c26c77f1593ac3f4James Dong } 27330ab66297501757d745b9ae10da61adcd891f497Andreas Huber 27430ab66297501757d745b9ae10da61adcd891f497Andreas Huber return OK; 27530ab66297501757d745b9ae10da61adcd891f497Andreas Huber} 27630ab66297501757d745b9ae10da61adcd891f497Andreas Huber 27730ab66297501757d745b9ae10da61adcd891f497Andreas Huberstatus_t StagefrightRecorder::setAudioEncoder(audio_encoder ae) { 2783856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("setAudioEncoder: %d", ae); 279d329e21495eda9dbc531fdd0c26c77f1593ac3f4James Dong if (ae < AUDIO_ENCODER_DEFAULT || 280d329e21495eda9dbc531fdd0c26c77f1593ac3f4James Dong ae >= AUDIO_ENCODER_LIST_END) { 28129357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("Invalid audio encoder: %d", ae); 282d329e21495eda9dbc531fdd0c26c77f1593ac3f4James Dong return BAD_VALUE; 283d329e21495eda9dbc531fdd0c26c77f1593ac3f4James Dong } 284d329e21495eda9dbc531fdd0c26c77f1593ac3f4James Dong 285d329e21495eda9dbc531fdd0c26c77f1593ac3f4James Dong if (ae == AUDIO_ENCODER_DEFAULT) { 286d329e21495eda9dbc531fdd0c26c77f1593ac3f4James Dong mAudioEncoder = AUDIO_ENCODER_AMR_NB; 287d329e21495eda9dbc531fdd0c26c77f1593ac3f4James Dong } else { 288d329e21495eda9dbc531fdd0c26c77f1593ac3f4James Dong mAudioEncoder = ae; 289d329e21495eda9dbc531fdd0c26c77f1593ac3f4James Dong } 29030ab66297501757d745b9ae10da61adcd891f497Andreas Huber 29130ab66297501757d745b9ae10da61adcd891f497Andreas Huber return OK; 29230ab66297501757d745b9ae10da61adcd891f497Andreas Huber} 29330ab66297501757d745b9ae10da61adcd891f497Andreas Huber 29430ab66297501757d745b9ae10da61adcd891f497Andreas Huberstatus_t StagefrightRecorder::setVideoEncoder(video_encoder ve) { 2953856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("setVideoEncoder: %d", ve); 296d329e21495eda9dbc531fdd0c26c77f1593ac3f4James Dong if (ve < VIDEO_ENCODER_DEFAULT || 297d329e21495eda9dbc531fdd0c26c77f1593ac3f4James Dong ve >= VIDEO_ENCODER_LIST_END) { 29829357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("Invalid video encoder: %d", ve); 299d329e21495eda9dbc531fdd0c26c77f1593ac3f4James Dong return BAD_VALUE; 300d329e21495eda9dbc531fdd0c26c77f1593ac3f4James Dong } 301d329e21495eda9dbc531fdd0c26c77f1593ac3f4James Dong 30254ef1bae010f12dfe6a40ff4452695b1b11ff449Chong Zhang mVideoEncoder = ve; 30330ab66297501757d745b9ae10da61adcd891f497Andreas Huber 30430ab66297501757d745b9ae10da61adcd891f497Andreas Huber return OK; 30530ab66297501757d745b9ae10da61adcd891f497Andreas Huber} 30630ab66297501757d745b9ae10da61adcd891f497Andreas Huber 30730ab66297501757d745b9ae10da61adcd891f497Andreas Huberstatus_t StagefrightRecorder::setVideoSize(int width, int height) { 3083856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("setVideoSize: %dx%d", width, height); 309ef9d0cd72e476a4b7556833fb09505a51b626797James Dong if (width <= 0 || height <= 0) { 31029357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("Invalid video size: %dx%d", width, height); 311ef9d0cd72e476a4b7556833fb09505a51b626797James Dong return BAD_VALUE; 312ef9d0cd72e476a4b7556833fb09505a51b626797James Dong } 313ef9d0cd72e476a4b7556833fb09505a51b626797James Dong 314ef9d0cd72e476a4b7556833fb09505a51b626797James Dong // Additional check on the dimension will be performed later 31530ab66297501757d745b9ae10da61adcd891f497Andreas Huber mVideoWidth = width; 31630ab66297501757d745b9ae10da61adcd891f497Andreas Huber mVideoHeight = height; 31730ab66297501757d745b9ae10da61adcd891f497Andreas Huber 31830ab66297501757d745b9ae10da61adcd891f497Andreas Huber return OK; 31930ab66297501757d745b9ae10da61adcd891f497Andreas Huber} 32030ab66297501757d745b9ae10da61adcd891f497Andreas Huber 32130ab66297501757d745b9ae10da61adcd891f497Andreas Huberstatus_t StagefrightRecorder::setVideoFrameRate(int frames_per_second) { 3223856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("setVideoFrameRate: %d", frames_per_second); 323635730831e08c32a5fe7c59125e0919b7e7899cdJames Dong if ((frames_per_second <= 0 && frames_per_second != -1) || 324c9f122d8f32ba6928ac9087448025fa3bed1553dZhijun He frames_per_second > kMaxHighSpeedFps) { 32529357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("Invalid video frame rate: %d", frames_per_second); 326ef9d0cd72e476a4b7556833fb09505a51b626797James Dong return BAD_VALUE; 327ef9d0cd72e476a4b7556833fb09505a51b626797James Dong } 328ef9d0cd72e476a4b7556833fb09505a51b626797James Dong 329ef9d0cd72e476a4b7556833fb09505a51b626797James Dong // Additional check on the frame rate will be performed later 33030ab66297501757d745b9ae10da61adcd891f497Andreas Huber mFrameRate = frames_per_second; 33130ab66297501757d745b9ae10da61adcd891f497Andreas Huber 33230ab66297501757d745b9ae10da61adcd891f497Andreas Huber return OK; 33330ab66297501757d745b9ae10da61adcd891f497Andreas Huber} 33430ab66297501757d745b9ae10da61adcd891f497Andreas Huber 335d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvalastatus_t StagefrightRecorder::setCamera(const sp<hardware::ICamera> &camera, 3364ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li const sp<ICameraRecordingProxy> &proxy) { 3373856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("setCamera"); 338c32cd79d9ad4aba7d959b5b3be7361b4715e6f18James Dong if (camera == 0) { 33929357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("camera is NULL"); 340934da11c4cc598d3dd3b53726c362bcdcc0fd37fJames Dong return BAD_VALUE; 341c32cd79d9ad4aba7d959b5b3be7361b4715e6f18James Dong } 3424ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li if (proxy == 0) { 34329357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("camera proxy is NULL"); 3444ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li return BAD_VALUE; 3454ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li } 346c32cd79d9ad4aba7d959b5b3be7361b4715e6f18James Dong 34754ff19ac69ace7c05ea90d225e26dab3b133f487James Dong mCamera = camera; 3484ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li mCameraProxy = proxy; 34930ab66297501757d745b9ae10da61adcd891f497Andreas Huber return OK; 35030ab66297501757d745b9ae10da61adcd891f497Andreas Huber} 35130ab66297501757d745b9ae10da61adcd891f497Andreas Huber 35299617adda9bc46c43f511f0940bc735c73de61deMathias Agopianstatus_t StagefrightRecorder::setPreviewSurface(const sp<IGraphicBufferProducer> &surface) { 3533856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("setPreviewSurface: %p", surface.get()); 35430ab66297501757d745b9ae10da61adcd891f497Andreas Huber mPreviewSurface = surface; 35530ab66297501757d745b9ae10da61adcd891f497Andreas Huber 35630ab66297501757d745b9ae10da61adcd891f497Andreas Huber return OK; 35730ab66297501757d745b9ae10da61adcd891f497Andreas Huber} 35830ab66297501757d745b9ae10da61adcd891f497Andreas Huber 3598f469e18c307cb9dc0d16ed9225972aa8be4516fChong Zhangstatus_t StagefrightRecorder::setInputSurface( 360addf2cbb120346ae42e78fa739245a353db5edadChong Zhang const sp<PersistentSurface>& surface) { 361e2a2dfcbf0c9d6bb7139263ecf0d8e53b4ca1049Chong Zhang mPersistentSurface = surface; 362e2a2dfcbf0c9d6bb7139263ecf0d8e53b4ca1049Chong Zhang 363e2a2dfcbf0c9d6bb7139263ecf0d8e53b4ca1049Chong Zhang return OK; 364e2a2dfcbf0c9d6bb7139263ecf0d8e53b4ca1049Chong Zhang} 365e2a2dfcbf0c9d6bb7139263ecf0d8e53b4ca1049Chong Zhang 366fe44e4f74fe2582cbf012687059278dbcbdaa6f7Hangyu Kuangstatus_t StagefrightRecorder::setOutputFile(int fd) { 367fe44e4f74fe2582cbf012687059278dbcbdaa6f7Hangyu Kuang ALOGV("setOutputFile: %d", fd); 36830ab66297501757d745b9ae10da61adcd891f497Andreas Huber 369934da11c4cc598d3dd3b53726c362bcdcc0fd37fJames Dong if (fd < 0) { 37029357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("Invalid file descriptor: %d", fd); 371934da11c4cc598d3dd3b53726c362bcdcc0fd37fJames Dong return -EBADF; 372934da11c4cc598d3dd3b53726c362bcdcc0fd37fJames Dong } 373934da11c4cc598d3dd3b53726c362bcdcc0fd37fJames Dong 37469113e8ccc30fbdb8733ca2070bd3491b21e656dMarco Nelissen // start with a clean, empty file 37569113e8ccc30fbdb8733ca2070bd3491b21e656dMarco Nelissen ftruncate(fd, 0); 37669113e8ccc30fbdb8733ca2070bd3491b21e656dMarco Nelissen 37730ab66297501757d745b9ae10da61adcd891f497Andreas Huber if (mOutputFd >= 0) { 37830ab66297501757d745b9ae10da61adcd891f497Andreas Huber ::close(mOutputFd); 37930ab66297501757d745b9ae10da61adcd891f497Andreas Huber } 38030ab66297501757d745b9ae10da61adcd891f497Andreas Huber mOutputFd = dup(fd); 38130ab66297501757d745b9ae10da61adcd891f497Andreas Huber 38230ab66297501757d745b9ae10da61adcd891f497Andreas Huber return OK; 38330ab66297501757d745b9ae10da61adcd891f497Andreas Huber} 38430ab66297501757d745b9ae10da61adcd891f497Andreas Huber 385fe44e4f74fe2582cbf012687059278dbcbdaa6f7Hangyu Kuangstatus_t StagefrightRecorder::setNextOutputFile(int fd) { 386fc079f79d8d4f6ef9f138aa615486c10dda99fb7Hangyu Kuang Mutex::Autolock autolock(mLock); 387fe44e4f74fe2582cbf012687059278dbcbdaa6f7Hangyu Kuang // Only support MPEG4 388fe44e4f74fe2582cbf012687059278dbcbdaa6f7Hangyu Kuang if (mOutputFormat != OUTPUT_FORMAT_MPEG_4) { 389fe44e4f74fe2582cbf012687059278dbcbdaa6f7Hangyu Kuang ALOGE("Only MP4 file format supports setting next output file"); 390fe44e4f74fe2582cbf012687059278dbcbdaa6f7Hangyu Kuang return INVALID_OPERATION; 391fe44e4f74fe2582cbf012687059278dbcbdaa6f7Hangyu Kuang } 392fe44e4f74fe2582cbf012687059278dbcbdaa6f7Hangyu Kuang ALOGV("setNextOutputFile: %d", fd); 393fe44e4f74fe2582cbf012687059278dbcbdaa6f7Hangyu Kuang 394fe44e4f74fe2582cbf012687059278dbcbdaa6f7Hangyu Kuang if (fd < 0) { 395fe44e4f74fe2582cbf012687059278dbcbdaa6f7Hangyu Kuang ALOGE("Invalid file descriptor: %d", fd); 396fe44e4f74fe2582cbf012687059278dbcbdaa6f7Hangyu Kuang return -EBADF; 397fe44e4f74fe2582cbf012687059278dbcbdaa6f7Hangyu Kuang } 398fe44e4f74fe2582cbf012687059278dbcbdaa6f7Hangyu Kuang 399fe44e4f74fe2582cbf012687059278dbcbdaa6f7Hangyu Kuang // start with a clean, empty file 400fe44e4f74fe2582cbf012687059278dbcbdaa6f7Hangyu Kuang ftruncate(fd, 0); 401fe44e4f74fe2582cbf012687059278dbcbdaa6f7Hangyu Kuang int nextFd = dup(fd); 402fc079f79d8d4f6ef9f138aa615486c10dda99fb7Hangyu Kuang if (mWriter == NULL) { 403fc079f79d8d4f6ef9f138aa615486c10dda99fb7Hangyu Kuang ALOGE("setNextOutputFile failed. Writer has been freed"); 404fc079f79d8d4f6ef9f138aa615486c10dda99fb7Hangyu Kuang return INVALID_OPERATION; 405fc079f79d8d4f6ef9f138aa615486c10dda99fb7Hangyu Kuang } 406fe44e4f74fe2582cbf012687059278dbcbdaa6f7Hangyu Kuang return mWriter->setNextFd(nextFd); 407fe44e4f74fe2582cbf012687059278dbcbdaa6f7Hangyu Kuang} 408fe44e4f74fe2582cbf012687059278dbcbdaa6f7Hangyu Kuang 4099ee53a49860e91c2b012883eef09d669a7829e06Chong Zhang// Attempt to parse an float literal optionally surrounded by whitespace, 4109ee53a49860e91c2b012883eef09d669a7829e06Chong Zhang// returns true on success, false otherwise. 41173c3e6363b31fb27882c4666453ad8ef050b3cc1Wonsik Kimstatic bool safe_strtod(const char *s, double *val) { 4129ee53a49860e91c2b012883eef09d669a7829e06Chong Zhang char *end; 4139ee53a49860e91c2b012883eef09d669a7829e06Chong Zhang 4149ee53a49860e91c2b012883eef09d669a7829e06Chong Zhang // It is lame, but according to man page, we have to set errno to 0 41573c3e6363b31fb27882c4666453ad8ef050b3cc1Wonsik Kim // before calling strtod(). 4169ee53a49860e91c2b012883eef09d669a7829e06Chong Zhang errno = 0; 41773c3e6363b31fb27882c4666453ad8ef050b3cc1Wonsik Kim *val = strtod(s, &end); 4189ee53a49860e91c2b012883eef09d669a7829e06Chong Zhang 4199ee53a49860e91c2b012883eef09d669a7829e06Chong Zhang if (end == s || errno == ERANGE) { 4209ee53a49860e91c2b012883eef09d669a7829e06Chong Zhang return false; 4219ee53a49860e91c2b012883eef09d669a7829e06Chong Zhang } 4229ee53a49860e91c2b012883eef09d669a7829e06Chong Zhang 4239ee53a49860e91c2b012883eef09d669a7829e06Chong Zhang // Skip trailing whitespace 4249ee53a49860e91c2b012883eef09d669a7829e06Chong Zhang while (isspace(*end)) { 4259ee53a49860e91c2b012883eef09d669a7829e06Chong Zhang ++end; 4269ee53a49860e91c2b012883eef09d669a7829e06Chong Zhang } 4279ee53a49860e91c2b012883eef09d669a7829e06Chong Zhang 4289ee53a49860e91c2b012883eef09d669a7829e06Chong Zhang // For a successful return, the string must contain nothing but a valid 4299ee53a49860e91c2b012883eef09d669a7829e06Chong Zhang // float literal optionally surrounded by whitespace. 4309ee53a49860e91c2b012883eef09d669a7829e06Chong Zhang 4319ee53a49860e91c2b012883eef09d669a7829e06Chong Zhang return *end == '\0'; 4329ee53a49860e91c2b012883eef09d669a7829e06Chong Zhang} 4339ee53a49860e91c2b012883eef09d669a7829e06Chong Zhang 434050b28a593350047845a45a14cc5026221ac1620James Dong// Attempt to parse an int64 literal optionally surrounded by whitespace, 435050b28a593350047845a45a14cc5026221ac1620James Dong// returns true on success, false otherwise. 436ef9d0cd72e476a4b7556833fb09505a51b626797James Dongstatic bool safe_strtoi64(const char *s, int64_t *val) { 437050b28a593350047845a45a14cc5026221ac1620James Dong char *end; 43827944ef5cd8d0fb476c8c8958986e827c5f8ab83James Dong 43927944ef5cd8d0fb476c8c8958986e827c5f8ab83James Dong // It is lame, but according to man page, we have to set errno to 0 44027944ef5cd8d0fb476c8c8958986e827c5f8ab83James Dong // before calling strtoll(). 44127944ef5cd8d0fb476c8c8958986e827c5f8ab83James Dong errno = 0; 442ef9d0cd72e476a4b7556833fb09505a51b626797James Dong *val = strtoll(s, &end, 10); 443050b28a593350047845a45a14cc5026221ac1620James Dong 444050b28a593350047845a45a14cc5026221ac1620James Dong if (end == s || errno == ERANGE) { 445050b28a593350047845a45a14cc5026221ac1620James Dong return false; 446050b28a593350047845a45a14cc5026221ac1620James Dong } 447050b28a593350047845a45a14cc5026221ac1620James Dong 448050b28a593350047845a45a14cc5026221ac1620James Dong // Skip trailing whitespace 449050b28a593350047845a45a14cc5026221ac1620James Dong while (isspace(*end)) { 450050b28a593350047845a45a14cc5026221ac1620James Dong ++end; 451050b28a593350047845a45a14cc5026221ac1620James Dong } 452050b28a593350047845a45a14cc5026221ac1620James Dong 453050b28a593350047845a45a14cc5026221ac1620James Dong // For a successful return, the string must contain nothing but a valid 454050b28a593350047845a45a14cc5026221ac1620James Dong // int64 literal optionally surrounded by whitespace. 455050b28a593350047845a45a14cc5026221ac1620James Dong 456050b28a593350047845a45a14cc5026221ac1620James Dong return *end == '\0'; 457050b28a593350047845a45a14cc5026221ac1620James Dong} 458050b28a593350047845a45a14cc5026221ac1620James Dong 459ef9d0cd72e476a4b7556833fb09505a51b626797James Dong// Return true if the value is in [0, 0x007FFFFFFF] 460ef9d0cd72e476a4b7556833fb09505a51b626797James Dongstatic bool safe_strtoi32(const char *s, int32_t *val) { 461ef9d0cd72e476a4b7556833fb09505a51b626797James Dong int64_t temp; 462ef9d0cd72e476a4b7556833fb09505a51b626797James Dong if (safe_strtoi64(s, &temp)) { 463ef9d0cd72e476a4b7556833fb09505a51b626797James Dong if (temp >= 0 && temp <= 0x007FFFFFFF) { 464ef9d0cd72e476a4b7556833fb09505a51b626797James Dong *val = static_cast<int32_t>(temp); 465ef9d0cd72e476a4b7556833fb09505a51b626797James Dong return true; 466ef9d0cd72e476a4b7556833fb09505a51b626797James Dong } 467ef9d0cd72e476a4b7556833fb09505a51b626797James Dong } 468ef9d0cd72e476a4b7556833fb09505a51b626797James Dong return false; 469ef9d0cd72e476a4b7556833fb09505a51b626797James Dong} 470ef9d0cd72e476a4b7556833fb09505a51b626797James Dong 471050b28a593350047845a45a14cc5026221ac1620James Dong// Trim both leading and trailing whitespace from the given string. 472050b28a593350047845a45a14cc5026221ac1620James Dongstatic void TrimString(String8 *s) { 473050b28a593350047845a45a14cc5026221ac1620James Dong size_t num_bytes = s->bytes(); 474050b28a593350047845a45a14cc5026221ac1620James Dong const char *data = s->string(); 475050b28a593350047845a45a14cc5026221ac1620James Dong 476050b28a593350047845a45a14cc5026221ac1620James Dong size_t leading_space = 0; 477050b28a593350047845a45a14cc5026221ac1620James Dong while (leading_space < num_bytes && isspace(data[leading_space])) { 478050b28a593350047845a45a14cc5026221ac1620James Dong ++leading_space; 479050b28a593350047845a45a14cc5026221ac1620James Dong } 480050b28a593350047845a45a14cc5026221ac1620James Dong 481050b28a593350047845a45a14cc5026221ac1620James Dong size_t i = num_bytes; 482050b28a593350047845a45a14cc5026221ac1620James Dong while (i > leading_space && isspace(data[i - 1])) { 483050b28a593350047845a45a14cc5026221ac1620James Dong --i; 484050b28a593350047845a45a14cc5026221ac1620James Dong } 485050b28a593350047845a45a14cc5026221ac1620James Dong 486050b28a593350047845a45a14cc5026221ac1620James Dong s->setTo(String8(&data[leading_space], i - leading_space)); 487050b28a593350047845a45a14cc5026221ac1620James Dong} 488050b28a593350047845a45a14cc5026221ac1620James Dong 489050b28a593350047845a45a14cc5026221ac1620James Dongstatus_t StagefrightRecorder::setParamAudioSamplingRate(int32_t sampleRate) { 4903856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("setParamAudioSamplingRate: %d", sampleRate); 491ef9d0cd72e476a4b7556833fb09505a51b626797James Dong if (sampleRate <= 0) { 49229357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("Invalid audio sampling rate: %d", sampleRate); 493ef9d0cd72e476a4b7556833fb09505a51b626797James Dong return BAD_VALUE; 494ef9d0cd72e476a4b7556833fb09505a51b626797James Dong } 495ef9d0cd72e476a4b7556833fb09505a51b626797James Dong 496ef9d0cd72e476a4b7556833fb09505a51b626797James Dong // Additional check on the sample rate will be performed later. 497050b28a593350047845a45a14cc5026221ac1620James Dong mSampleRate = sampleRate; 498ac4e4189db77dc0af7671b162d11be5ccec69339Ray Essick 499050b28a593350047845a45a14cc5026221ac1620James Dong return OK; 500050b28a593350047845a45a14cc5026221ac1620James Dong} 501050b28a593350047845a45a14cc5026221ac1620James Dong 502050b28a593350047845a45a14cc5026221ac1620James Dongstatus_t StagefrightRecorder::setParamAudioNumberOfChannels(int32_t channels) { 5033856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("setParamAudioNumberOfChannels: %d", channels); 504ef9d0cd72e476a4b7556833fb09505a51b626797James Dong if (channels <= 0 || channels >= 3) { 50529357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("Invalid number of audio channels: %d", channels); 506934da11c4cc598d3dd3b53726c362bcdcc0fd37fJames Dong return BAD_VALUE; 507ef9d0cd72e476a4b7556833fb09505a51b626797James Dong } 508ef9d0cd72e476a4b7556833fb09505a51b626797James Dong 509ef9d0cd72e476a4b7556833fb09505a51b626797James Dong // Additional check on the number of channels will be performed later. 510050b28a593350047845a45a14cc5026221ac1620James Dong mAudioChannels = channels; 511ac4e4189db77dc0af7671b162d11be5ccec69339Ray Essick 512050b28a593350047845a45a14cc5026221ac1620James Dong return OK; 513050b28a593350047845a45a14cc5026221ac1620James Dong} 514050b28a593350047845a45a14cc5026221ac1620James Dong 515050b28a593350047845a45a14cc5026221ac1620James Dongstatus_t StagefrightRecorder::setParamAudioEncodingBitRate(int32_t bitRate) { 5163856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("setParamAudioEncodingBitRate: %d", bitRate); 517ef9d0cd72e476a4b7556833fb09505a51b626797James Dong if (bitRate <= 0) { 51829357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("Invalid audio encoding bit rate: %d", bitRate); 519ef9d0cd72e476a4b7556833fb09505a51b626797James Dong return BAD_VALUE; 520ef9d0cd72e476a4b7556833fb09505a51b626797James Dong } 521ef9d0cd72e476a4b7556833fb09505a51b626797James Dong 522ef9d0cd72e476a4b7556833fb09505a51b626797James Dong // The target bit rate may not be exactly the same as the requested. 523ef9d0cd72e476a4b7556833fb09505a51b626797James Dong // It depends on many factors, such as rate control, and the bit rate 524ef9d0cd72e476a4b7556833fb09505a51b626797James Dong // range that a specific encoder supports. The mismatch between the 525ef9d0cd72e476a4b7556833fb09505a51b626797James Dong // the target and requested bit rate will NOT be treated as an error. 526050b28a593350047845a45a14cc5026221ac1620James Dong mAudioBitRate = bitRate; 527050b28a593350047845a45a14cc5026221ac1620James Dong return OK; 528050b28a593350047845a45a14cc5026221ac1620James Dong} 529050b28a593350047845a45a14cc5026221ac1620James Dong 530050b28a593350047845a45a14cc5026221ac1620James Dongstatus_t StagefrightRecorder::setParamVideoEncodingBitRate(int32_t bitRate) { 5313856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("setParamVideoEncodingBitRate: %d", bitRate); 532ef9d0cd72e476a4b7556833fb09505a51b626797James Dong if (bitRate <= 0) { 53329357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("Invalid video encoding bit rate: %d", bitRate); 534ef9d0cd72e476a4b7556833fb09505a51b626797James Dong return BAD_VALUE; 535ef9d0cd72e476a4b7556833fb09505a51b626797James Dong } 536ef9d0cd72e476a4b7556833fb09505a51b626797James Dong 537ef9d0cd72e476a4b7556833fb09505a51b626797James Dong // The target bit rate may not be exactly the same as the requested. 538ef9d0cd72e476a4b7556833fb09505a51b626797James Dong // It depends on many factors, such as rate control, and the bit rate 539ef9d0cd72e476a4b7556833fb09505a51b626797James Dong // range that a specific encoder supports. The mismatch between the 540ef9d0cd72e476a4b7556833fb09505a51b626797James Dong // the target and requested bit rate will NOT be treated as an error. 541050b28a593350047845a45a14cc5026221ac1620James Dong mVideoBitRate = bitRate; 542050b28a593350047845a45a14cc5026221ac1620James Dong return OK; 543050b28a593350047845a45a14cc5026221ac1620James Dong} 544050b28a593350047845a45a14cc5026221ac1620James Dong 54513f6284305e4b27395a23db7882d670bdb1bcae1James Dong// Always rotate clockwise, and only support 0, 90, 180 and 270 for now. 54613f6284305e4b27395a23db7882d670bdb1bcae1James Dongstatus_t StagefrightRecorder::setParamVideoRotation(int32_t degrees) { 5473856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("setParamVideoRotation: %d", degrees); 54813f6284305e4b27395a23db7882d670bdb1bcae1James Dong if (degrees < 0 || degrees % 90 != 0) { 54929357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("Unsupported video rotation angle: %d", degrees); 55013f6284305e4b27395a23db7882d670bdb1bcae1James Dong return BAD_VALUE; 55113f6284305e4b27395a23db7882d670bdb1bcae1James Dong } 55213f6284305e4b27395a23db7882d670bdb1bcae1James Dong mRotationDegrees = degrees % 360; 55313f6284305e4b27395a23db7882d670bdb1bcae1James Dong return OK; 55413f6284305e4b27395a23db7882d670bdb1bcae1James Dong} 55513f6284305e4b27395a23db7882d670bdb1bcae1James Dong 556934da11c4cc598d3dd3b53726c362bcdcc0fd37fJames Dongstatus_t StagefrightRecorder::setParamMaxFileDurationUs(int64_t timeUs) { 557833b47505c513cb5c8f22aa922a7ea20d153b319Andy Hung ALOGV("setParamMaxFileDurationUs: %lld us", (long long)timeUs); 5582d1e5d35be5e6d4b55ac8b39fbfcbeb60fcdd084James Dong 5592d1e5d35be5e6d4b55ac8b39fbfcbeb60fcdd084James Dong // This is meant for backward compatibility for MediaRecorder.java 560be6fd201b9a04fe0f8fd409f10595ddb41832591Nipun Kwatra if (timeUs <= 0) { 561833b47505c513cb5c8f22aa922a7ea20d153b319Andy Hung ALOGW("Max file duration is not positive: %lld us. Disabling duration limit.", 562833b47505c513cb5c8f22aa922a7ea20d153b319Andy Hung (long long)timeUs); 563be6fd201b9a04fe0f8fd409f10595ddb41832591Nipun Kwatra timeUs = 0; // Disable the duration limit for zero or negative values. 564be6fd201b9a04fe0f8fd409f10595ddb41832591Nipun Kwatra } else if (timeUs <= 100000LL) { // XXX: 100 milli-seconds 565833b47505c513cb5c8f22aa922a7ea20d153b319Andy Hung ALOGE("Max file duration is too short: %lld us", (long long)timeUs); 566934da11c4cc598d3dd3b53726c362bcdcc0fd37fJames Dong return BAD_VALUE; 567ef9d0cd72e476a4b7556833fb09505a51b626797James Dong } 568be6fd201b9a04fe0f8fd409f10595ddb41832591Nipun Kwatra 569acd234bba9f048971d66890009eeff9a8db94be3James Dong if (timeUs <= 15 * 1000000LL) { 570833b47505c513cb5c8f22aa922a7ea20d153b319Andy Hung ALOGW("Target duration (%lld us) too short to be respected", (long long)timeUs); 571acd234bba9f048971d66890009eeff9a8db94be3James Dong } 572934da11c4cc598d3dd3b53726c362bcdcc0fd37fJames Dong mMaxFileDurationUs = timeUs; 573934da11c4cc598d3dd3b53726c362bcdcc0fd37fJames Dong return OK; 574934da11c4cc598d3dd3b53726c362bcdcc0fd37fJames Dong} 575934da11c4cc598d3dd3b53726c362bcdcc0fd37fJames Dong 576934da11c4cc598d3dd3b53726c362bcdcc0fd37fJames Dongstatus_t StagefrightRecorder::setParamMaxFileSizeBytes(int64_t bytes) { 577833b47505c513cb5c8f22aa922a7ea20d153b319Andy Hung ALOGV("setParamMaxFileSizeBytes: %lld bytes", (long long)bytes); 5782d1e5d35be5e6d4b55ac8b39fbfcbeb60fcdd084James Dong 5792d1e5d35be5e6d4b55ac8b39fbfcbeb60fcdd084James Dong // This is meant for backward compatibility for MediaRecorder.java 5802d1e5d35be5e6d4b55ac8b39fbfcbeb60fcdd084James Dong if (bytes <= 0) { 5815ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block ALOGW("Max file size is not positive: %lld bytes. " 582833b47505c513cb5c8f22aa922a7ea20d153b319Andy Hung "Disabling file size limit.", (long long)bytes); 5832d1e5d35be5e6d4b55ac8b39fbfcbeb60fcdd084James Dong bytes = 0; // Disable the file size limit for zero or negative values. 5842d1e5d35be5e6d4b55ac8b39fbfcbeb60fcdd084James Dong } else if (bytes <= 1024) { // XXX: 1 kB 585833b47505c513cb5c8f22aa922a7ea20d153b319Andy Hung ALOGE("Max file size is too small: %lld bytes", (long long)bytes); 586934da11c4cc598d3dd3b53726c362bcdcc0fd37fJames Dong return BAD_VALUE; 587934da11c4cc598d3dd3b53726c362bcdcc0fd37fJames Dong } 588acd234bba9f048971d66890009eeff9a8db94be3James Dong 589acd234bba9f048971d66890009eeff9a8db94be3James Dong if (bytes <= 100 * 1024) { 590833b47505c513cb5c8f22aa922a7ea20d153b319Andy Hung ALOGW("Target file size (%lld bytes) is too small to be respected", (long long)bytes); 591acd234bba9f048971d66890009eeff9a8db94be3James Dong } 592acd234bba9f048971d66890009eeff9a8db94be3James Dong 593934da11c4cc598d3dd3b53726c362bcdcc0fd37fJames Dong mMaxFileSizeBytes = bytes; 594050b28a593350047845a45a14cc5026221ac1620James Dong return OK; 595050b28a593350047845a45a14cc5026221ac1620James Dong} 596050b28a593350047845a45a14cc5026221ac1620James Dong 59713aec890216948b0c364f8f92792129d0335f506James Dongstatus_t StagefrightRecorder::setParamInterleaveDuration(int32_t durationUs) { 5983856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("setParamInterleaveDuration: %d", durationUs); 599ddcc4a66d848deef6fb4689e64e30cd9bd2684feJames Dong if (durationUs <= 500000) { // 500 ms 600ddcc4a66d848deef6fb4689e64e30cd9bd2684feJames Dong // If interleave duration is too small, it is very inefficient to do 601ddcc4a66d848deef6fb4689e64e30cd9bd2684feJames Dong // interleaving since the metadata overhead will count for a significant 602ddcc4a66d848deef6fb4689e64e30cd9bd2684feJames Dong // portion of the saved contents 60329357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("Audio/video interleave duration is too small: %d us", durationUs); 604ef9d0cd72e476a4b7556833fb09505a51b626797James Dong return BAD_VALUE; 605ddcc4a66d848deef6fb4689e64e30cd9bd2684feJames Dong } else if (durationUs >= 10000000) { // 10 seconds 606ddcc4a66d848deef6fb4689e64e30cd9bd2684feJames Dong // If interleaving duration is too large, it can cause the recording 607ddcc4a66d848deef6fb4689e64e30cd9bd2684feJames Dong // session to use too much memory since we have to save the output 608ddcc4a66d848deef6fb4689e64e30cd9bd2684feJames Dong // data before we write them out 60929357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("Audio/video interleave duration is too large: %d us", durationUs); 610ddcc4a66d848deef6fb4689e64e30cd9bd2684feJames Dong return BAD_VALUE; 611ef9d0cd72e476a4b7556833fb09505a51b626797James Dong } 61213aec890216948b0c364f8f92792129d0335f506James Dong mInterleaveDurationUs = durationUs; 61313aec890216948b0c364f8f92792129d0335f506James Dong return OK; 61413aec890216948b0c364f8f92792129d0335f506James Dong} 615ef9d0cd72e476a4b7556833fb09505a51b626797James Dong 6168f5f2fcee5c12d08df71d17017410c50951fc2e3James Dong// If seconds < 0, only the first frame is I frame, and rest are all P frames 6178f5f2fcee5c12d08df71d17017410c50951fc2e3James Dong// If seconds == 0, all frames are encoded as I frames. No P frames 6188f5f2fcee5c12d08df71d17017410c50951fc2e3James Dong// If seconds > 0, it is the time spacing (seconds) between 2 neighboring I frames 6198f5f2fcee5c12d08df71d17017410c50951fc2e3James Dongstatus_t StagefrightRecorder::setParamVideoIFramesInterval(int32_t seconds) { 6203856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("setParamVideoIFramesInterval: %d seconds", seconds); 6218f5f2fcee5c12d08df71d17017410c50951fc2e3James Dong mIFramesIntervalSec = seconds; 622ddcc4a66d848deef6fb4689e64e30cd9bd2684feJames Dong return OK; 623ddcc4a66d848deef6fb4689e64e30cd9bd2684feJames Dong} 624ddcc4a66d848deef6fb4689e64e30cd9bd2684feJames Dong 6252dec2b5be2056c6d9428897dc672185872d30d17James Dongstatus_t StagefrightRecorder::setParam64BitFileOffset(bool use64Bit) { 6263856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("setParam64BitFileOffset: %s", 6272dec2b5be2056c6d9428897dc672185872d30d17James Dong use64Bit? "use 64 bit file offset": "use 32 bit file offset"); 6282dec2b5be2056c6d9428897dc672185872d30d17James Dong mUse64BitFileOffset = use64Bit; 6292dec2b5be2056c6d9428897dc672185872d30d17James Dong return OK; 6302dec2b5be2056c6d9428897dc672185872d30d17James Dong} 6312dec2b5be2056c6d9428897dc672185872d30d17James Dong 63293d6b102a13afa23bfa80d74c399d93d542e6ad6James Dongstatus_t StagefrightRecorder::setParamVideoCameraId(int32_t cameraId) { 6333856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("setParamVideoCameraId: %d", cameraId); 63493d6b102a13afa23bfa80d74c399d93d542e6ad6James Dong if (cameraId < 0) { 63593d6b102a13afa23bfa80d74c399d93d542e6ad6James Dong return BAD_VALUE; 63693d6b102a13afa23bfa80d74c399d93d542e6ad6James Dong } 63793d6b102a13afa23bfa80d74c399d93d542e6ad6James Dong mCameraId = cameraId; 63893d6b102a13afa23bfa80d74c399d93d542e6ad6James Dong return OK; 63993d6b102a13afa23bfa80d74c399d93d542e6ad6James Dong} 64093d6b102a13afa23bfa80d74c399d93d542e6ad6James Dong 64193d6b102a13afa23bfa80d74c399d93d542e6ad6James Dongstatus_t StagefrightRecorder::setParamTrackTimeStatus(int64_t timeDurationUs) { 642833b47505c513cb5c8f22aa922a7ea20d153b319Andy Hung ALOGV("setParamTrackTimeStatus: %lld", (long long)timeDurationUs); 64393d6b102a13afa23bfa80d74c399d93d542e6ad6James Dong if (timeDurationUs < 20000) { // Infeasible if shorter than 20 ms? 644833b47505c513cb5c8f22aa922a7ea20d153b319Andy Hung ALOGE("Tracking time duration too short: %lld us", (long long)timeDurationUs); 64593d6b102a13afa23bfa80d74c399d93d542e6ad6James Dong return BAD_VALUE; 64693d6b102a13afa23bfa80d74c399d93d542e6ad6James Dong } 64793d6b102a13afa23bfa80d74c399d93d542e6ad6James Dong mTrackEveryTimeDurationUs = timeDurationUs; 64893d6b102a13afa23bfa80d74c399d93d542e6ad6James Dong return OK; 64993d6b102a13afa23bfa80d74c399d93d542e6ad6James Dong} 65093d6b102a13afa23bfa80d74c399d93d542e6ad6James Dong 651145bfe5eb3e08c9689c28f6bf3287a979438b04bJames Dongstatus_t StagefrightRecorder::setParamVideoEncoderProfile(int32_t profile) { 6523856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("setParamVideoEncoderProfile: %d", profile); 653145bfe5eb3e08c9689c28f6bf3287a979438b04bJames Dong 654145bfe5eb3e08c9689c28f6bf3287a979438b04bJames Dong // Additional check will be done later when we load the encoder. 655145bfe5eb3e08c9689c28f6bf3287a979438b04bJames Dong // For now, we are accepting values defined in OpenMAX IL. 656145bfe5eb3e08c9689c28f6bf3287a979438b04bJames Dong mVideoEncoderProfile = profile; 657145bfe5eb3e08c9689c28f6bf3287a979438b04bJames Dong return OK; 658145bfe5eb3e08c9689c28f6bf3287a979438b04bJames Dong} 659145bfe5eb3e08c9689c28f6bf3287a979438b04bJames Dong 660145bfe5eb3e08c9689c28f6bf3287a979438b04bJames Dongstatus_t StagefrightRecorder::setParamVideoEncoderLevel(int32_t level) { 6613856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("setParamVideoEncoderLevel: %d", level); 662145bfe5eb3e08c9689c28f6bf3287a979438b04bJames Dong 663145bfe5eb3e08c9689c28f6bf3287a979438b04bJames Dong // Additional check will be done later when we load the encoder. 664145bfe5eb3e08c9689c28f6bf3287a979438b04bJames Dong // For now, we are accepting values defined in OpenMAX IL. 665145bfe5eb3e08c9689c28f6bf3287a979438b04bJames Dong mVideoEncoderLevel = level; 666145bfe5eb3e08c9689c28f6bf3287a979438b04bJames Dong return OK; 667145bfe5eb3e08c9689c28f6bf3287a979438b04bJames Dong} 668145bfe5eb3e08c9689c28f6bf3287a979438b04bJames Dong 6698f5f2fcee5c12d08df71d17017410c50951fc2e3James Dongstatus_t StagefrightRecorder::setParamMovieTimeScale(int32_t timeScale) { 6703856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("setParamMovieTimeScale: %d", timeScale); 6718f5f2fcee5c12d08df71d17017410c50951fc2e3James Dong 6728f5f2fcee5c12d08df71d17017410c50951fc2e3James Dong // The range is set to be the same as the audio's time scale range 6738f5f2fcee5c12d08df71d17017410c50951fc2e3James Dong // since audio's time scale has a wider range. 6748f5f2fcee5c12d08df71d17017410c50951fc2e3James Dong if (timeScale < 600 || timeScale > 96000) { 67529357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("Time scale (%d) for movie is out of range [600, 96000]", timeScale); 6768f5f2fcee5c12d08df71d17017410c50951fc2e3James Dong return BAD_VALUE; 6778f5f2fcee5c12d08df71d17017410c50951fc2e3James Dong } 6788f5f2fcee5c12d08df71d17017410c50951fc2e3James Dong mMovieTimeScale = timeScale; 6798f5f2fcee5c12d08df71d17017410c50951fc2e3James Dong return OK; 6808f5f2fcee5c12d08df71d17017410c50951fc2e3James Dong} 6818f5f2fcee5c12d08df71d17017410c50951fc2e3James Dong 6828f5f2fcee5c12d08df71d17017410c50951fc2e3James Dongstatus_t StagefrightRecorder::setParamVideoTimeScale(int32_t timeScale) { 6833856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("setParamVideoTimeScale: %d", timeScale); 6848f5f2fcee5c12d08df71d17017410c50951fc2e3James Dong 6858f5f2fcee5c12d08df71d17017410c50951fc2e3James Dong // 60000 is chosen to make sure that each video frame from a 60-fps 6868f5f2fcee5c12d08df71d17017410c50951fc2e3James Dong // video has 1000 ticks. 6878f5f2fcee5c12d08df71d17017410c50951fc2e3James Dong if (timeScale < 600 || timeScale > 60000) { 68829357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("Time scale (%d) for video is out of range [600, 60000]", timeScale); 6898f5f2fcee5c12d08df71d17017410c50951fc2e3James Dong return BAD_VALUE; 6908f5f2fcee5c12d08df71d17017410c50951fc2e3James Dong } 6918f5f2fcee5c12d08df71d17017410c50951fc2e3James Dong mVideoTimeScale = timeScale; 6928f5f2fcee5c12d08df71d17017410c50951fc2e3James Dong return OK; 6938f5f2fcee5c12d08df71d17017410c50951fc2e3James Dong} 6948f5f2fcee5c12d08df71d17017410c50951fc2e3James Dong 6958f5f2fcee5c12d08df71d17017410c50951fc2e3James Dongstatus_t StagefrightRecorder::setParamAudioTimeScale(int32_t timeScale) { 6963856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("setParamAudioTimeScale: %d", timeScale); 6978f5f2fcee5c12d08df71d17017410c50951fc2e3James Dong 6988f5f2fcee5c12d08df71d17017410c50951fc2e3James Dong // 96000 Hz is the highest sampling rate support in AAC. 6998f5f2fcee5c12d08df71d17017410c50951fc2e3James Dong if (timeScale < 600 || timeScale > 96000) { 70029357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("Time scale (%d) for audio is out of range [600, 96000]", timeScale); 7018f5f2fcee5c12d08df71d17017410c50951fc2e3James Dong return BAD_VALUE; 7028f5f2fcee5c12d08df71d17017410c50951fc2e3James Dong } 7038f5f2fcee5c12d08df71d17017410c50951fc2e3James Dong mAudioTimeScale = timeScale; 7048f5f2fcee5c12d08df71d17017410c50951fc2e3James Dong return OK; 7058f5f2fcee5c12d08df71d17017410c50951fc2e3James Dong} 7068f5f2fcee5c12d08df71d17017410c50951fc2e3James Dong 70746d26dd29195450db15704e84d65740628a821fbChong Zhangstatus_t StagefrightRecorder::setParamCaptureFpsEnable(int32_t captureFpsEnable) { 70846d26dd29195450db15704e84d65740628a821fbChong Zhang ALOGV("setParamCaptureFpsEnable: %d", captureFpsEnable); 709e4e0a6994d39c4a7cba09c5fff442b2dca1df8f8Nipun Kwatra 71046d26dd29195450db15704e84d65740628a821fbChong Zhang if(captureFpsEnable == 0) { 71146d26dd29195450db15704e84d65740628a821fbChong Zhang mCaptureFpsEnable = false; 71246d26dd29195450db15704e84d65740628a821fbChong Zhang } else if (captureFpsEnable == 1) { 71346d26dd29195450db15704e84d65740628a821fbChong Zhang mCaptureFpsEnable = true; 714e4e0a6994d39c4a7cba09c5fff442b2dca1df8f8Nipun Kwatra } else { 715e4e0a6994d39c4a7cba09c5fff442b2dca1df8f8Nipun Kwatra return BAD_VALUE; 716e4e0a6994d39c4a7cba09c5fff442b2dca1df8f8Nipun Kwatra } 717e4e0a6994d39c4a7cba09c5fff442b2dca1df8f8Nipun Kwatra return OK; 718e4e0a6994d39c4a7cba09c5fff442b2dca1df8f8Nipun Kwatra} 719e4e0a6994d39c4a7cba09c5fff442b2dca1df8f8Nipun Kwatra 72073c3e6363b31fb27882c4666453ad8ef050b3cc1Wonsik Kimstatus_t StagefrightRecorder::setParamCaptureFps(double fps) { 72146d26dd29195450db15704e84d65740628a821fbChong Zhang ALOGV("setParamCaptureFps: %.2f", fps); 7229ee53a49860e91c2b012883eef09d669a7829e06Chong Zhang 72322dc508717c7767927064ec7c152def99e54adcbPawin Vongmasa if (!(fps >= 1.0 / 86400)) { 72422dc508717c7767927064ec7c152def99e54adcbPawin Vongmasa ALOGE("FPS is too small"); 725e4e0a6994d39c4a7cba09c5fff442b2dca1df8f8Nipun Kwatra return BAD_VALUE; 726e4e0a6994d39c4a7cba09c5fff442b2dca1df8f8Nipun Kwatra } 7279ee53a49860e91c2b012883eef09d669a7829e06Chong Zhang mCaptureFps = fps; 728e4e0a6994d39c4a7cba09c5fff442b2dca1df8f8Nipun Kwatra return OK; 729e4e0a6994d39c4a7cba09c5fff442b2dca1df8f8Nipun Kwatra} 730e4e0a6994d39c4a7cba09c5fff442b2dca1df8f8Nipun Kwatra 73107b1bb529a1ae76c46a71b01338c166f9490629dJames Dongstatus_t StagefrightRecorder::setParamGeoDataLongitude( 732b832a03d563dd000faa44f2577e92237525edc32James Dong int64_t longitudex10000) { 73307b1bb529a1ae76c46a71b01338c166f9490629dJames Dong 73407b1bb529a1ae76c46a71b01338c166f9490629dJames Dong if (longitudex10000 > 1800000 || longitudex10000 < -1800000) { 73507b1bb529a1ae76c46a71b01338c166f9490629dJames Dong return BAD_VALUE; 73607b1bb529a1ae76c46a71b01338c166f9490629dJames Dong } 73707b1bb529a1ae76c46a71b01338c166f9490629dJames Dong mLongitudex10000 = longitudex10000; 73807b1bb529a1ae76c46a71b01338c166f9490629dJames Dong return OK; 73907b1bb529a1ae76c46a71b01338c166f9490629dJames Dong} 74007b1bb529a1ae76c46a71b01338c166f9490629dJames Dong 74107b1bb529a1ae76c46a71b01338c166f9490629dJames Dongstatus_t StagefrightRecorder::setParamGeoDataLatitude( 742b832a03d563dd000faa44f2577e92237525edc32James Dong int64_t latitudex10000) { 74307b1bb529a1ae76c46a71b01338c166f9490629dJames Dong 74407b1bb529a1ae76c46a71b01338c166f9490629dJames Dong if (latitudex10000 > 900000 || latitudex10000 < -900000) { 74507b1bb529a1ae76c46a71b01338c166f9490629dJames Dong return BAD_VALUE; 74607b1bb529a1ae76c46a71b01338c166f9490629dJames Dong } 74707b1bb529a1ae76c46a71b01338c166f9490629dJames Dong mLatitudex10000 = latitudex10000; 74807b1bb529a1ae76c46a71b01338c166f9490629dJames Dong return OK; 74907b1bb529a1ae76c46a71b01338c166f9490629dJames Dong} 75007b1bb529a1ae76c46a71b01338c166f9490629dJames Dong 751050b28a593350047845a45a14cc5026221ac1620James Dongstatus_t StagefrightRecorder::setParameter( 752050b28a593350047845a45a14cc5026221ac1620James Dong const String8 &key, const String8 &value) { 7533856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("setParameter: key (%s) => value (%s)", key.string(), value.string()); 754050b28a593350047845a45a14cc5026221ac1620James Dong if (key == "max-duration") { 755ef9d0cd72e476a4b7556833fb09505a51b626797James Dong int64_t max_duration_ms; 756050b28a593350047845a45a14cc5026221ac1620James Dong if (safe_strtoi64(value.string(), &max_duration_ms)) { 757934da11c4cc598d3dd3b53726c362bcdcc0fd37fJames Dong return setParamMaxFileDurationUs(1000LL * max_duration_ms); 758050b28a593350047845a45a14cc5026221ac1620James Dong } 759050b28a593350047845a45a14cc5026221ac1620James Dong } else if (key == "max-filesize") { 760ef9d0cd72e476a4b7556833fb09505a51b626797James Dong int64_t max_filesize_bytes; 761050b28a593350047845a45a14cc5026221ac1620James Dong if (safe_strtoi64(value.string(), &max_filesize_bytes)) { 762934da11c4cc598d3dd3b53726c362bcdcc0fd37fJames Dong return setParamMaxFileSizeBytes(max_filesize_bytes); 763050b28a593350047845a45a14cc5026221ac1620James Dong } 76493d6b102a13afa23bfa80d74c399d93d542e6ad6James Dong } else if (key == "interleave-duration-us") { 76593d6b102a13afa23bfa80d74c399d93d542e6ad6James Dong int32_t durationUs; 76693d6b102a13afa23bfa80d74c399d93d542e6ad6James Dong if (safe_strtoi32(value.string(), &durationUs)) { 76793d6b102a13afa23bfa80d74c399d93d542e6ad6James Dong return setParamInterleaveDuration(durationUs); 76893d6b102a13afa23bfa80d74c399d93d542e6ad6James Dong } 7698f5f2fcee5c12d08df71d17017410c50951fc2e3James Dong } else if (key == "param-movie-time-scale") { 7708f5f2fcee5c12d08df71d17017410c50951fc2e3James Dong int32_t timeScale; 7718f5f2fcee5c12d08df71d17017410c50951fc2e3James Dong if (safe_strtoi32(value.string(), &timeScale)) { 7728f5f2fcee5c12d08df71d17017410c50951fc2e3James Dong return setParamMovieTimeScale(timeScale); 7738f5f2fcee5c12d08df71d17017410c50951fc2e3James Dong } 77493d6b102a13afa23bfa80d74c399d93d542e6ad6James Dong } else if (key == "param-use-64bit-offset") { 77593d6b102a13afa23bfa80d74c399d93d542e6ad6James Dong int32_t use64BitOffset; 77693d6b102a13afa23bfa80d74c399d93d542e6ad6James Dong if (safe_strtoi32(value.string(), &use64BitOffset)) { 77793d6b102a13afa23bfa80d74c399d93d542e6ad6James Dong return setParam64BitFileOffset(use64BitOffset != 0); 77893d6b102a13afa23bfa80d74c399d93d542e6ad6James Dong } 77907b1bb529a1ae76c46a71b01338c166f9490629dJames Dong } else if (key == "param-geotag-longitude") { 780b832a03d563dd000faa44f2577e92237525edc32James Dong int64_t longitudex10000; 781b832a03d563dd000faa44f2577e92237525edc32James Dong if (safe_strtoi64(value.string(), &longitudex10000)) { 78207b1bb529a1ae76c46a71b01338c166f9490629dJames Dong return setParamGeoDataLongitude(longitudex10000); 78307b1bb529a1ae76c46a71b01338c166f9490629dJames Dong } 78407b1bb529a1ae76c46a71b01338c166f9490629dJames Dong } else if (key == "param-geotag-latitude") { 785b832a03d563dd000faa44f2577e92237525edc32James Dong int64_t latitudex10000; 786b832a03d563dd000faa44f2577e92237525edc32James Dong if (safe_strtoi64(value.string(), &latitudex10000)) { 78707b1bb529a1ae76c46a71b01338c166f9490629dJames Dong return setParamGeoDataLatitude(latitudex10000); 78807b1bb529a1ae76c46a71b01338c166f9490629dJames Dong } 78993d6b102a13afa23bfa80d74c399d93d542e6ad6James Dong } else if (key == "param-track-time-status") { 79093d6b102a13afa23bfa80d74c399d93d542e6ad6James Dong int64_t timeDurationUs; 79193d6b102a13afa23bfa80d74c399d93d542e6ad6James Dong if (safe_strtoi64(value.string(), &timeDurationUs)) { 79293d6b102a13afa23bfa80d74c399d93d542e6ad6James Dong return setParamTrackTimeStatus(timeDurationUs); 79393d6b102a13afa23bfa80d74c399d93d542e6ad6James Dong } 794050b28a593350047845a45a14cc5026221ac1620James Dong } else if (key == "audio-param-sampling-rate") { 795050b28a593350047845a45a14cc5026221ac1620James Dong int32_t sampling_rate; 796ef9d0cd72e476a4b7556833fb09505a51b626797James Dong if (safe_strtoi32(value.string(), &sampling_rate)) { 797050b28a593350047845a45a14cc5026221ac1620James Dong return setParamAudioSamplingRate(sampling_rate); 798050b28a593350047845a45a14cc5026221ac1620James Dong } 799050b28a593350047845a45a14cc5026221ac1620James Dong } else if (key == "audio-param-number-of-channels") { 800050b28a593350047845a45a14cc5026221ac1620James Dong int32_t number_of_channels; 801ef9d0cd72e476a4b7556833fb09505a51b626797James Dong if (safe_strtoi32(value.string(), &number_of_channels)) { 802050b28a593350047845a45a14cc5026221ac1620James Dong return setParamAudioNumberOfChannels(number_of_channels); 803050b28a593350047845a45a14cc5026221ac1620James Dong } 804050b28a593350047845a45a14cc5026221ac1620James Dong } else if (key == "audio-param-encoding-bitrate") { 805050b28a593350047845a45a14cc5026221ac1620James Dong int32_t audio_bitrate; 806ef9d0cd72e476a4b7556833fb09505a51b626797James Dong if (safe_strtoi32(value.string(), &audio_bitrate)) { 807050b28a593350047845a45a14cc5026221ac1620James Dong return setParamAudioEncodingBitRate(audio_bitrate); 808050b28a593350047845a45a14cc5026221ac1620James Dong } 8098f5f2fcee5c12d08df71d17017410c50951fc2e3James Dong } else if (key == "audio-param-time-scale") { 8108f5f2fcee5c12d08df71d17017410c50951fc2e3James Dong int32_t timeScale; 8118f5f2fcee5c12d08df71d17017410c50951fc2e3James Dong if (safe_strtoi32(value.string(), &timeScale)) { 8128f5f2fcee5c12d08df71d17017410c50951fc2e3James Dong return setParamAudioTimeScale(timeScale); 8138f5f2fcee5c12d08df71d17017410c50951fc2e3James Dong } 814050b28a593350047845a45a14cc5026221ac1620James Dong } else if (key == "video-param-encoding-bitrate") { 815050b28a593350047845a45a14cc5026221ac1620James Dong int32_t video_bitrate; 816ef9d0cd72e476a4b7556833fb09505a51b626797James Dong if (safe_strtoi32(value.string(), &video_bitrate)) { 817050b28a593350047845a45a14cc5026221ac1620James Dong return setParamVideoEncodingBitRate(video_bitrate); 818050b28a593350047845a45a14cc5026221ac1620James Dong } 81913f6284305e4b27395a23db7882d670bdb1bcae1James Dong } else if (key == "video-param-rotation-angle-degrees") { 82013f6284305e4b27395a23db7882d670bdb1bcae1James Dong int32_t degrees; 82113f6284305e4b27395a23db7882d670bdb1bcae1James Dong if (safe_strtoi32(value.string(), °rees)) { 82213f6284305e4b27395a23db7882d670bdb1bcae1James Dong return setParamVideoRotation(degrees); 82313f6284305e4b27395a23db7882d670bdb1bcae1James Dong } 82493d6b102a13afa23bfa80d74c399d93d542e6ad6James Dong } else if (key == "video-param-i-frames-interval") { 8258f5f2fcee5c12d08df71d17017410c50951fc2e3James Dong int32_t seconds; 8268f5f2fcee5c12d08df71d17017410c50951fc2e3James Dong if (safe_strtoi32(value.string(), &seconds)) { 8278f5f2fcee5c12d08df71d17017410c50951fc2e3James Dong return setParamVideoIFramesInterval(seconds); 828ddcc4a66d848deef6fb4689e64e30cd9bd2684feJames Dong } 829145bfe5eb3e08c9689c28f6bf3287a979438b04bJames Dong } else if (key == "video-param-encoder-profile") { 830145bfe5eb3e08c9689c28f6bf3287a979438b04bJames Dong int32_t profile; 831145bfe5eb3e08c9689c28f6bf3287a979438b04bJames Dong if (safe_strtoi32(value.string(), &profile)) { 832145bfe5eb3e08c9689c28f6bf3287a979438b04bJames Dong return setParamVideoEncoderProfile(profile); 833145bfe5eb3e08c9689c28f6bf3287a979438b04bJames Dong } 834145bfe5eb3e08c9689c28f6bf3287a979438b04bJames Dong } else if (key == "video-param-encoder-level") { 835145bfe5eb3e08c9689c28f6bf3287a979438b04bJames Dong int32_t level; 836145bfe5eb3e08c9689c28f6bf3287a979438b04bJames Dong if (safe_strtoi32(value.string(), &level)) { 837145bfe5eb3e08c9689c28f6bf3287a979438b04bJames Dong return setParamVideoEncoderLevel(level); 838145bfe5eb3e08c9689c28f6bf3287a979438b04bJames Dong } 83993d6b102a13afa23bfa80d74c399d93d542e6ad6James Dong } else if (key == "video-param-camera-id") { 84093d6b102a13afa23bfa80d74c399d93d542e6ad6James Dong int32_t cameraId; 84193d6b102a13afa23bfa80d74c399d93d542e6ad6James Dong if (safe_strtoi32(value.string(), &cameraId)) { 84293d6b102a13afa23bfa80d74c399d93d542e6ad6James Dong return setParamVideoCameraId(cameraId); 8432dec2b5be2056c6d9428897dc672185872d30d17James Dong } 8448f5f2fcee5c12d08df71d17017410c50951fc2e3James Dong } else if (key == "video-param-time-scale") { 8458f5f2fcee5c12d08df71d17017410c50951fc2e3James Dong int32_t timeScale; 8468f5f2fcee5c12d08df71d17017410c50951fc2e3James Dong if (safe_strtoi32(value.string(), &timeScale)) { 8478f5f2fcee5c12d08df71d17017410c50951fc2e3James Dong return setParamVideoTimeScale(timeScale); 8488f5f2fcee5c12d08df71d17017410c50951fc2e3James Dong } 849e4e0a6994d39c4a7cba09c5fff442b2dca1df8f8Nipun Kwatra } else if (key == "time-lapse-enable") { 85046d26dd29195450db15704e84d65740628a821fbChong Zhang int32_t captureFpsEnable; 85146d26dd29195450db15704e84d65740628a821fbChong Zhang if (safe_strtoi32(value.string(), &captureFpsEnable)) { 85246d26dd29195450db15704e84d65740628a821fbChong Zhang return setParamCaptureFpsEnable(captureFpsEnable); 853e4e0a6994d39c4a7cba09c5fff442b2dca1df8f8Nipun Kwatra } 8549ee53a49860e91c2b012883eef09d669a7829e06Chong Zhang } else if (key == "time-lapse-fps") { 85573c3e6363b31fb27882c4666453ad8ef050b3cc1Wonsik Kim double fps; 85673c3e6363b31fb27882c4666453ad8ef050b3cc1Wonsik Kim if (safe_strtod(value.string(), &fps)) { 85746d26dd29195450db15704e84d65740628a821fbChong Zhang return setParamCaptureFps(fps); 858e4e0a6994d39c4a7cba09c5fff442b2dca1df8f8Nipun Kwatra } 859050b28a593350047845a45a14cc5026221ac1620James Dong } else { 86029357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("setParameter: failed to find key %s", key.string()); 861050b28a593350047845a45a14cc5026221ac1620James Dong } 862ef9d0cd72e476a4b7556833fb09505a51b626797James Dong return BAD_VALUE; 863050b28a593350047845a45a14cc5026221ac1620James Dong} 86430ab66297501757d745b9ae10da61adcd891f497Andreas Huber 865050b28a593350047845a45a14cc5026221ac1620James Dongstatus_t StagefrightRecorder::setParameters(const String8 ¶ms) { 8663856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("setParameters: %s", params.string()); 867050b28a593350047845a45a14cc5026221ac1620James Dong const char *cparams = params.string(); 868050b28a593350047845a45a14cc5026221ac1620James Dong const char *key_start = cparams; 869050b28a593350047845a45a14cc5026221ac1620James Dong for (;;) { 870050b28a593350047845a45a14cc5026221ac1620James Dong const char *equal_pos = strchr(key_start, '='); 871050b28a593350047845a45a14cc5026221ac1620James Dong if (equal_pos == NULL) { 87229357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("Parameters %s miss a value", cparams); 873050b28a593350047845a45a14cc5026221ac1620James Dong return BAD_VALUE; 874050b28a593350047845a45a14cc5026221ac1620James Dong } 875050b28a593350047845a45a14cc5026221ac1620James Dong String8 key(key_start, equal_pos - key_start); 876050b28a593350047845a45a14cc5026221ac1620James Dong TrimString(&key); 877050b28a593350047845a45a14cc5026221ac1620James Dong if (key.length() == 0) { 87829357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("Parameters %s contains an empty key", cparams); 879050b28a593350047845a45a14cc5026221ac1620James Dong return BAD_VALUE; 880050b28a593350047845a45a14cc5026221ac1620James Dong } 881050b28a593350047845a45a14cc5026221ac1620James Dong const char *value_start = equal_pos + 1; 882050b28a593350047845a45a14cc5026221ac1620James Dong const char *semicolon_pos = strchr(value_start, ';'); 883050b28a593350047845a45a14cc5026221ac1620James Dong String8 value; 884050b28a593350047845a45a14cc5026221ac1620James Dong if (semicolon_pos == NULL) { 885050b28a593350047845a45a14cc5026221ac1620James Dong value.setTo(value_start); 886050b28a593350047845a45a14cc5026221ac1620James Dong } else { 887050b28a593350047845a45a14cc5026221ac1620James Dong value.setTo(value_start, semicolon_pos - value_start); 888050b28a593350047845a45a14cc5026221ac1620James Dong } 889050b28a593350047845a45a14cc5026221ac1620James Dong if (setParameter(key, value) != OK) { 890050b28a593350047845a45a14cc5026221ac1620James Dong return BAD_VALUE; 891050b28a593350047845a45a14cc5026221ac1620James Dong } 892050b28a593350047845a45a14cc5026221ac1620James Dong if (semicolon_pos == NULL) { 893050b28a593350047845a45a14cc5026221ac1620James Dong break; // Reaches the end 894050b28a593350047845a45a14cc5026221ac1620James Dong } 895050b28a593350047845a45a14cc5026221ac1620James Dong key_start = semicolon_pos + 1; 896050b28a593350047845a45a14cc5026221ac1620James Dong } 89730ab66297501757d745b9ae10da61adcd891f497Andreas Huber return OK; 89830ab66297501757d745b9ae10da61adcd891f497Andreas Huber} 89930ab66297501757d745b9ae10da61adcd891f497Andreas Huber 90037047fceba836f341d0108beed0991b0f8dfc543James Dongstatus_t StagefrightRecorder::setListener(const sp<IMediaRecorderClient> &listener) { 90130ab66297501757d745b9ae10da61adcd891f497Andreas Huber mListener = listener; 90230ab66297501757d745b9ae10da61adcd891f497Andreas Huber 90330ab66297501757d745b9ae10da61adcd891f497Andreas Huber return OK; 90430ab66297501757d745b9ae10da61adcd891f497Andreas Huber} 90530ab66297501757d745b9ae10da61adcd891f497Andreas Huber 906ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvalastatus_t StagefrightRecorder::setClientName(const String16& clientName) { 907ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala mClientName = clientName; 908ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala 909ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala return OK; 910ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala} 911ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala 9121a5690652f3f6ee40f15c2f9f6c4b6badf4dbcf5Chong Zhangstatus_t StagefrightRecorder::prepareInternal() { 91372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang ALOGV("prepare"); 91472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang if (mOutputFd < 0) { 91572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang ALOGE("Output file descriptor is invalid"); 91672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang return INVALID_OPERATION; 91772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 918934da11c4cc598d3dd3b53726c362bcdcc0fd37fJames Dong 91998a668f6ea51e4d894d2ebb61a0e18287fb14008Chien-Yu Chen // Get UID and PID here for permission checking 920ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala mClientUid = IPCThreadState::self()->getCallingUid(); 92198a668f6ea51e4d894d2ebb61a0e18287fb14008Chien-Yu Chen mClientPid = IPCThreadState::self()->getCallingPid(); 92230ab66297501757d745b9ae10da61adcd891f497Andreas Huber 92375b0b5473c7b43f8c5972db7e6e8930988ead751Gloria Wang status_t status = OK; 92475b0b5473c7b43f8c5972db7e6e8930988ead751Gloria Wang 9252dce41ad26cb3e9e15c9e456a84bcf5309548ca0Andreas Huber switch (mOutputFormat) { 9262dce41ad26cb3e9e15c9e456a84bcf5309548ca0Andreas Huber case OUTPUT_FORMAT_DEFAULT: 9272dce41ad26cb3e9e15c9e456a84bcf5309548ca0Andreas Huber case OUTPUT_FORMAT_THREE_GPP: 9282dce41ad26cb3e9e15c9e456a84bcf5309548ca0Andreas Huber case OUTPUT_FORMAT_MPEG_4: 929114819633470ebd5b346c13c2a82a0025d2d39c0Robert Shih case OUTPUT_FORMAT_WEBM: 930114819633470ebd5b346c13c2a82a0025d2d39c0Robert Shih status = setupMPEG4orWEBMRecording(); 93175b0b5473c7b43f8c5972db7e6e8930988ead751Gloria Wang break; 9322dce41ad26cb3e9e15c9e456a84bcf5309548ca0Andreas Huber 9332dce41ad26cb3e9e15c9e456a84bcf5309548ca0Andreas Huber case OUTPUT_FORMAT_AMR_NB: 9342dce41ad26cb3e9e15c9e456a84bcf5309548ca0Andreas Huber case OUTPUT_FORMAT_AMR_WB: 93572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang status = setupAMRRecording(); 93675b0b5473c7b43f8c5972db7e6e8930988ead751Gloria Wang break; 9372dce41ad26cb3e9e15c9e456a84bcf5309548ca0Andreas Huber 938ef9d0cd72e476a4b7556833fb09505a51b626797James Dong case OUTPUT_FORMAT_AAC_ADIF: 939ef9d0cd72e476a4b7556833fb09505a51b626797James Dong case OUTPUT_FORMAT_AAC_ADTS: 94072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang status = setupAACRecording(); 94175b0b5473c7b43f8c5972db7e6e8930988ead751Gloria Wang break; 942ef9d0cd72e476a4b7556833fb09505a51b626797James Dong 94339ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber case OUTPUT_FORMAT_RTP_AVP: 94472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang status = setupRTPRecording(); 94575b0b5473c7b43f8c5972db7e6e8930988ead751Gloria Wang break; 94639ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 94759b7dc39ea8332d3418a599e51447d7edb612ac4Andreas Huber case OUTPUT_FORMAT_MPEG2TS: 94872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang status = setupMPEG2TSRecording(); 94975b0b5473c7b43f8c5972db7e6e8930988ead751Gloria Wang break; 95059b7dc39ea8332d3418a599e51447d7edb612ac4Andreas Huber 9512dce41ad26cb3e9e15c9e456a84bcf5309548ca0Andreas Huber default: 95229357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("Unsupported output file format: %d", mOutputFormat); 95375b0b5473c7b43f8c5972db7e6e8930988ead751Gloria Wang status = UNKNOWN_ERROR; 95475b0b5473c7b43f8c5972db7e6e8930988ead751Gloria Wang break; 95575b0b5473c7b43f8c5972db7e6e8930988ead751Gloria Wang } 95675b0b5473c7b43f8c5972db7e6e8930988ead751Gloria Wang 9575a4a0a1e4a44b8e48aff8e74df56d37dc6d7129cHangyu Kuang ALOGV("Recording frameRate: %d captureFps: %f", 9585a4a0a1e4a44b8e48aff8e74df56d37dc6d7129cHangyu Kuang mFrameRate, mCaptureFps); 9595a4a0a1e4a44b8e48aff8e74df56d37dc6d7129cHangyu Kuang 96072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang return status; 96172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang} 96272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 9631a5690652f3f6ee40f15c2f9f6c4b6badf4dbcf5Chong Zhangstatus_t StagefrightRecorder::prepare() { 964fc079f79d8d4f6ef9f138aa615486c10dda99fb7Hangyu Kuang ALOGV("prepare"); 965fc079f79d8d4f6ef9f138aa615486c10dda99fb7Hangyu Kuang Mutex::Autolock autolock(mLock); 9661a5690652f3f6ee40f15c2f9f6c4b6badf4dbcf5Chong Zhang if (mVideoSource == VIDEO_SOURCE_SURFACE) { 9671a5690652f3f6ee40f15c2f9f6c4b6badf4dbcf5Chong Zhang return prepareInternal(); 9681a5690652f3f6ee40f15c2f9f6c4b6badf4dbcf5Chong Zhang } 9691a5690652f3f6ee40f15c2f9f6c4b6badf4dbcf5Chong Zhang return OK; 9701a5690652f3f6ee40f15c2f9f6c4b6badf4dbcf5Chong Zhang} 9711a5690652f3f6ee40f15c2f9f6c4b6badf4dbcf5Chong Zhang 97272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhangstatus_t StagefrightRecorder::start() { 97372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang ALOGV("start"); 974fc079f79d8d4f6ef9f138aa615486c10dda99fb7Hangyu Kuang Mutex::Autolock autolock(mLock); 97572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang if (mOutputFd < 0) { 97672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang ALOGE("Output file descriptor is invalid"); 97772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang return INVALID_OPERATION; 97872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 97972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 9801a5690652f3f6ee40f15c2f9f6c4b6badf4dbcf5Chong Zhang status_t status = OK; 9811a5690652f3f6ee40f15c2f9f6c4b6badf4dbcf5Chong Zhang 9821a5690652f3f6ee40f15c2f9f6c4b6badf4dbcf5Chong Zhang if (mVideoSource != VIDEO_SOURCE_SURFACE) { 9831a5690652f3f6ee40f15c2f9f6c4b6badf4dbcf5Chong Zhang status = prepareInternal(); 9841a5690652f3f6ee40f15c2f9f6c4b6badf4dbcf5Chong Zhang if (status != OK) { 9851a5690652f3f6ee40f15c2f9f6c4b6badf4dbcf5Chong Zhang return status; 9861a5690652f3f6ee40f15c2f9f6c4b6badf4dbcf5Chong Zhang } 9871a5690652f3f6ee40f15c2f9f6c4b6badf4dbcf5Chong Zhang } 9881a5690652f3f6ee40f15c2f9f6c4b6badf4dbcf5Chong Zhang 98972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang if (mWriter == NULL) { 99072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang ALOGE("File writer is not avaialble"); 99172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang return UNKNOWN_ERROR; 99272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 99372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 99472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang switch (mOutputFormat) { 99572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang case OUTPUT_FORMAT_DEFAULT: 99672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang case OUTPUT_FORMAT_THREE_GPP: 99772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang case OUTPUT_FORMAT_MPEG_4: 998114819633470ebd5b346c13c2a82a0025d2d39c0Robert Shih case OUTPUT_FORMAT_WEBM: 99972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang { 1000114819633470ebd5b346c13c2a82a0025d2d39c0Robert Shih bool isMPEG4 = true; 1001114819633470ebd5b346c13c2a82a0025d2d39c0Robert Shih if (mOutputFormat == OUTPUT_FORMAT_WEBM) { 1002114819633470ebd5b346c13c2a82a0025d2d39c0Robert Shih isMPEG4 = false; 1003114819633470ebd5b346c13c2a82a0025d2d39c0Robert Shih } 100472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang sp<MetaData> meta = new MetaData; 1005114819633470ebd5b346c13c2a82a0025d2d39c0Robert Shih setupMPEG4orWEBMMetaData(&meta); 100672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang status = mWriter->start(meta.get()); 100772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang break; 100872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 100972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 101072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang case OUTPUT_FORMAT_AMR_NB: 101172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang case OUTPUT_FORMAT_AMR_WB: 101272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang case OUTPUT_FORMAT_AAC_ADIF: 101372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang case OUTPUT_FORMAT_AAC_ADTS: 101472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang case OUTPUT_FORMAT_RTP_AVP: 101572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang case OUTPUT_FORMAT_MPEG2TS: 101672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang { 10178f889be4754d40f39c9377b055988f58f3ed64a8Hangyu Kuang sp<MetaData> meta = new MetaData; 10188f889be4754d40f39c9377b055988f58f3ed64a8Hangyu Kuang int64_t startTimeUs = systemTime() / 1000; 10198f889be4754d40f39c9377b055988f58f3ed64a8Hangyu Kuang meta->setInt64(kKeyTime, startTimeUs); 10208f889be4754d40f39c9377b055988f58f3ed64a8Hangyu Kuang status = mWriter->start(meta.get()); 102172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang break; 102272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 102372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 102472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang default: 102572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang { 102672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang ALOGE("Unsupported output file format: %d", mOutputFormat); 102772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang status = UNKNOWN_ERROR; 102872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang break; 102972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 103072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 103172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 103272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang if (status != OK) { 103372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mWriter.clear(); 103472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mWriter = NULL; 103572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 103672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 103775b0b5473c7b43f8c5972db7e6e8930988ead751Gloria Wang if ((status == OK) && (!mStarted)) { 1038ac4e4189db77dc0af7671b162d11be5ccec69339Ray Essick mAnalyticsDirty = true; 103975b0b5473c7b43f8c5972db7e6e8930988ead751Gloria Wang mStarted = true; 104075b0b5473c7b43f8c5972db7e6e8930988ead751Gloria Wang 104135cc20b52fdc551b5b0ed1fc32803a56d82e8881Ray Essick mStartedRecordingUs = systemTime() / 1000; 104235cc20b52fdc551b5b0ed1fc32803a56d82e8881Ray Essick 104375b0b5473c7b43f8c5972db7e6e8930988ead751Gloria Wang uint32_t params = IMediaPlayerService::kBatteryDataCodecStarted; 1044fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin if (mAudioSource != AUDIO_SOURCE_CNT) { 104575b0b5473c7b43f8c5972db7e6e8930988ead751Gloria Wang params |= IMediaPlayerService::kBatteryDataTrackAudio; 104675b0b5473c7b43f8c5972db7e6e8930988ead751Gloria Wang } 104775b0b5473c7b43f8c5972db7e6e8930988ead751Gloria Wang if (mVideoSource != VIDEO_SOURCE_LIST_END) { 104875b0b5473c7b43f8c5972db7e6e8930988ead751Gloria Wang params |= IMediaPlayerService::kBatteryDataTrackVideo; 104975b0b5473c7b43f8c5972db7e6e8930988ead751Gloria Wang } 105075b0b5473c7b43f8c5972db7e6e8930988ead751Gloria Wang 105175b0b5473c7b43f8c5972db7e6e8930988ead751Gloria Wang addBatteryData(params); 10522dce41ad26cb3e9e15c9e456a84bcf5309548ca0Andreas Huber } 105375b0b5473c7b43f8c5972db7e6e8930988ead751Gloria Wang 105475b0b5473c7b43f8c5972db7e6e8930988ead751Gloria Wang return status; 10552dce41ad26cb3e9e15c9e456a84bcf5309548ca0Andreas Huber} 10562dce41ad26cb3e9e15c9e456a84bcf5309548ca0Andreas Huber 1057d008275796ac4cccf85fefce53cef733a49bc1faWonsik Kimsp<MediaCodecSource> StagefrightRecorder::createAudioSource() { 105846d26dd29195450db15704e84d65740628a821fbChong Zhang int32_t sourceSampleRate = mSampleRate; 105946d26dd29195450db15704e84d65740628a821fbChong Zhang 106046d26dd29195450db15704e84d65740628a821fbChong Zhang if (mCaptureFpsEnable && mCaptureFps >= mFrameRate) { 106146d26dd29195450db15704e84d65740628a821fbChong Zhang // Upscale the sample rate for slow motion recording. 106246d26dd29195450db15704e84d65740628a821fbChong Zhang // Fail audio source creation if source sample rate is too high, as it could 106346d26dd29195450db15704e84d65740628a821fbChong Zhang // cause out-of-memory due to large input buffer size. And audio recording 106446d26dd29195450db15704e84d65740628a821fbChong Zhang // probably doesn't make sense in the scenario, since the slow-down factor 106546d26dd29195450db15704e84d65740628a821fbChong Zhang // is probably huge (eg. mSampleRate=48K, mCaptureFps=240, mFrameRate=1). 106646d26dd29195450db15704e84d65740628a821fbChong Zhang const static int32_t SAMPLE_RATE_HZ_MAX = 192000; 106746d26dd29195450db15704e84d65740628a821fbChong Zhang sourceSampleRate = 106846d26dd29195450db15704e84d65740628a821fbChong Zhang (mSampleRate * mCaptureFps + mFrameRate / 2) / mFrameRate; 106946d26dd29195450db15704e84d65740628a821fbChong Zhang if (sourceSampleRate < mSampleRate || sourceSampleRate > SAMPLE_RATE_HZ_MAX) { 107046d26dd29195450db15704e84d65740628a821fbChong Zhang ALOGE("source sample rate out of range! " 107146d26dd29195450db15704e84d65740628a821fbChong Zhang "(mSampleRate %d, mCaptureFps %.2f, mFrameRate %d", 107246d26dd29195450db15704e84d65740628a821fbChong Zhang mSampleRate, mCaptureFps, mFrameRate); 107346d26dd29195450db15704e84d65740628a821fbChong Zhang return NULL; 107446d26dd29195450db15704e84d65740628a821fbChong Zhang } 107546d26dd29195450db15704e84d65740628a821fbChong Zhang } 107646d26dd29195450db15704e84d65740628a821fbChong Zhang 10772dce41ad26cb3e9e15c9e456a84bcf5309548ca0Andreas Huber sp<AudioSource> audioSource = 10782dce41ad26cb3e9e15c9e456a84bcf5309548ca0Andreas Huber new AudioSource( 10792dce41ad26cb3e9e15c9e456a84bcf5309548ca0Andreas Huber mAudioSource, 1080be71aa29a3c86d2e01cd17839d2a72ab09a1bce5Svet Ganov mOpPackageName, 108146d26dd29195450db15704e84d65740628a821fbChong Zhang sourceSampleRate, 108246d26dd29195450db15704e84d65740628a821fbChong Zhang mAudioChannels, 1083b2379ba0a32638bae2ea0460644f68cf5a0967ceEric Laurent mSampleRate, 1084b2379ba0a32638bae2ea0460644f68cf5a0967ceEric Laurent mClientUid, 1085fec2f93fae282ad10bbb5e3fcce9f60eff2cfb48jiabin mClientPid, 1086fec2f93fae282ad10bbb5e3fcce9f60eff2cfb48jiabin mSelectedDeviceId); 10872dce41ad26cb3e9e15c9e456a84bcf5309548ca0Andreas Huber 10882dce41ad26cb3e9e15c9e456a84bcf5309548ca0Andreas Huber status_t err = audioSource->initCheck(); 10892dce41ad26cb3e9e15c9e456a84bcf5309548ca0Andreas Huber 10902dce41ad26cb3e9e15c9e456a84bcf5309548ca0Andreas Huber if (err != OK) { 109129357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("audio source is not initialized"); 10922dce41ad26cb3e9e15c9e456a84bcf5309548ca0Andreas Huber return NULL; 10932dce41ad26cb3e9e15c9e456a84bcf5309548ca0Andreas Huber } 10942dce41ad26cb3e9e15c9e456a84bcf5309548ca0Andreas Huber 109572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang sp<AMessage> format = new AMessage; 1096050b28a593350047845a45a14cc5026221ac1620James Dong switch (mAudioEncoder) { 1097050b28a593350047845a45a14cc5026221ac1620James Dong case AUDIO_ENCODER_AMR_NB: 1098050b28a593350047845a45a14cc5026221ac1620James Dong case AUDIO_ENCODER_DEFAULT: 109972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang format->setString("mime", MEDIA_MIMETYPE_AUDIO_AMR_NB); 1100050b28a593350047845a45a14cc5026221ac1620James Dong break; 1101050b28a593350047845a45a14cc5026221ac1620James Dong case AUDIO_ENCODER_AMR_WB: 110272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang format->setString("mime", MEDIA_MIMETYPE_AUDIO_AMR_WB); 1103050b28a593350047845a45a14cc5026221ac1620James Dong break; 1104050b28a593350047845a45a14cc5026221ac1620James Dong case AUDIO_ENCODER_AAC: 110572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang format->setString("mime", MEDIA_MIMETYPE_AUDIO_AAC); 110672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang format->setInt32("aac-profile", OMX_AUDIO_AACObjectLC); 1107aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke break; 1108f60c660f048d5f5e2458cff243c20400d73757a7Dave Burke case AUDIO_ENCODER_HE_AAC: 110972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang format->setString("mime", MEDIA_MIMETYPE_AUDIO_AAC); 111072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang format->setInt32("aac-profile", OMX_AUDIO_AACObjectHE); 1111f60c660f048d5f5e2458cff243c20400d73757a7Dave Burke break; 1112aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke case AUDIO_ENCODER_AAC_ELD: 111372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang format->setString("mime", MEDIA_MIMETYPE_AUDIO_AAC); 111472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang format->setInt32("aac-profile", OMX_AUDIO_AACObjectELD); 1115050b28a593350047845a45a14cc5026221ac1620James Dong break; 1116f60c660f048d5f5e2458cff243c20400d73757a7Dave Burke 1117050b28a593350047845a45a14cc5026221ac1620James Dong default: 111829357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("Unknown audio encoder: %d", mAudioEncoder); 1119050b28a593350047845a45a14cc5026221ac1620James Dong return NULL; 1120050b28a593350047845a45a14cc5026221ac1620James Dong } 11212dce41ad26cb3e9e15c9e456a84bcf5309548ca0Andreas Huber 112235cc20b52fdc551b5b0ed1fc32803a56d82e8881Ray Essick // log audio mime type for media metrics 112335cc20b52fdc551b5b0ed1fc32803a56d82e8881Ray Essick if (mAnalyticsItem != NULL) { 112435cc20b52fdc551b5b0ed1fc32803a56d82e8881Ray Essick AString audiomime; 112535cc20b52fdc551b5b0ed1fc32803a56d82e8881Ray Essick if (format->findString("mime", &audiomime)) { 112635cc20b52fdc551b5b0ed1fc32803a56d82e8881Ray Essick mAnalyticsItem->setCString(kRecorderAudioMime, audiomime.c_str()); 112735cc20b52fdc551b5b0ed1fc32803a56d82e8881Ray Essick } 112835cc20b52fdc551b5b0ed1fc32803a56d82e8881Ray Essick } 112935cc20b52fdc551b5b0ed1fc32803a56d82e8881Ray Essick 1130b45c62c8e9b05c2703bdae18cc298ae55550db8aAndreas Huber int32_t maxInputSize; 1131b45c62c8e9b05c2703bdae18cc298ae55550db8aAndreas Huber CHECK(audioSource->getFormat()->findInt32( 1132b45c62c8e9b05c2703bdae18cc298ae55550db8aAndreas Huber kKeyMaxInputSize, &maxInputSize)); 1133b45c62c8e9b05c2703bdae18cc298ae55550db8aAndreas Huber 113472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang format->setInt32("max-input-size", maxInputSize); 113572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang format->setInt32("channel-count", mAudioChannels); 113672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang format->setInt32("sample-rate", mSampleRate); 113772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang format->setInt32("bitrate", mAudioBitRate); 1138c059860c73678a202bfa33062723e8f82fb779d9James Dong if (mAudioTimeScale > 0) { 113972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang format->setInt32("time-scale", mAudioTimeScale); 1140c059860c73678a202bfa33062723e8f82fb779d9James Dong } 1141fdbc1b3a885f1e8a59b1788e48e24ea4c66acbc8Ronghua Wu format->setInt32("priority", 0 /* realtime */); 11422dce41ad26cb3e9e15c9e456a84bcf5309548ca0Andreas Huber 1143d008275796ac4cccf85fefce53cef733a49bc1faWonsik Kim sp<MediaCodecSource> audioEncoder = 114472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang MediaCodecSource::Create(mLooper, format, audioSource); 1145fec2f93fae282ad10bbb5e3fcce9f60eff2cfb48jiabin sp<AudioSystem::AudioDeviceCallback> callback = mAudioDeviceCallback.promote(); 1146fec2f93fae282ad10bbb5e3fcce9f60eff2cfb48jiabin if (mDeviceCallbackEnabled && callback != 0) { 1147fec2f93fae282ad10bbb5e3fcce9f60eff2cfb48jiabin audioSource->addAudioDeviceCallback(callback); 1148fec2f93fae282ad10bbb5e3fcce9f60eff2cfb48jiabin } 1149d3d4e5069e1af0437c4f5a7b4ba344bda5b937afJames Dong mAudioSourceNode = audioSource; 11502dce41ad26cb3e9e15c9e456a84bcf5309548ca0Andreas Huber 1151ef0cf50343f8a6d74894f96f5ecb5eec4c5f1bc6Chong Zhang if (audioEncoder == NULL) { 1152ef0cf50343f8a6d74894f96f5ecb5eec4c5f1bc6Chong Zhang ALOGE("Failed to create audio encoder"); 1153ef0cf50343f8a6d74894f96f5ecb5eec4c5f1bc6Chong Zhang } 1154ef0cf50343f8a6d74894f96f5ecb5eec4c5f1bc6Chong Zhang 11552dce41ad26cb3e9e15c9e456a84bcf5309548ca0Andreas Huber return audioEncoder; 11562dce41ad26cb3e9e15c9e456a84bcf5309548ca0Andreas Huber} 11572dce41ad26cb3e9e15c9e456a84bcf5309548ca0Andreas Huber 115872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhangstatus_t StagefrightRecorder::setupAACRecording() { 1159760943b5e7a09b602aba04ec451e97662f48b0a4James Dong // FIXME: 1160760943b5e7a09b602aba04ec451e97662f48b0a4James Dong // Add support for OUTPUT_FORMAT_AAC_ADIF 1161f1d5aa162c02a16b7195a43a9bcea4d592600ac4James Dong CHECK_EQ(mOutputFormat, OUTPUT_FORMAT_AAC_ADTS); 1162ef9d0cd72e476a4b7556833fb09505a51b626797James Dong 1163aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke CHECK(mAudioEncoder == AUDIO_ENCODER_AAC || 1164f60c660f048d5f5e2458cff243c20400d73757a7Dave Burke mAudioEncoder == AUDIO_ENCODER_HE_AAC || 1165aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke mAudioEncoder == AUDIO_ENCODER_AAC_ELD); 1166fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin CHECK(mAudioSource != AUDIO_SOURCE_CNT); 1167ef9d0cd72e476a4b7556833fb09505a51b626797James Dong 1168760943b5e7a09b602aba04ec451e97662f48b0a4James Dong mWriter = new AACWriter(mOutputFd); 116972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang return setupRawAudioRecording(); 1170ef9d0cd72e476a4b7556833fb09505a51b626797James Dong} 1171ef9d0cd72e476a4b7556833fb09505a51b626797James Dong 117272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhangstatus_t StagefrightRecorder::setupAMRRecording() { 1173ef9d0cd72e476a4b7556833fb09505a51b626797James Dong CHECK(mOutputFormat == OUTPUT_FORMAT_AMR_NB || 1174ef9d0cd72e476a4b7556833fb09505a51b626797James Dong mOutputFormat == OUTPUT_FORMAT_AMR_WB); 1175ef9d0cd72e476a4b7556833fb09505a51b626797James Dong 1176ef9d0cd72e476a4b7556833fb09505a51b626797James Dong if (mOutputFormat == OUTPUT_FORMAT_AMR_NB) { 1177ef9d0cd72e476a4b7556833fb09505a51b626797James Dong if (mAudioEncoder != AUDIO_ENCODER_DEFAULT && 1178ef9d0cd72e476a4b7556833fb09505a51b626797James Dong mAudioEncoder != AUDIO_ENCODER_AMR_NB) { 117929357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("Invalid encoder %d used for AMRNB recording", 1180ef9d0cd72e476a4b7556833fb09505a51b626797James Dong mAudioEncoder); 1181934da11c4cc598d3dd3b53726c362bcdcc0fd37fJames Dong return BAD_VALUE; 1182ef9d0cd72e476a4b7556833fb09505a51b626797James Dong } 1183ef9d0cd72e476a4b7556833fb09505a51b626797James Dong } else { // mOutputFormat must be OUTPUT_FORMAT_AMR_WB 1184ef9d0cd72e476a4b7556833fb09505a51b626797James Dong if (mAudioEncoder != AUDIO_ENCODER_AMR_WB) { 118529357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("Invlaid encoder %d used for AMRWB recording", 1186ef9d0cd72e476a4b7556833fb09505a51b626797James Dong mAudioEncoder); 1187934da11c4cc598d3dd3b53726c362bcdcc0fd37fJames Dong return BAD_VALUE; 1188ef9d0cd72e476a4b7556833fb09505a51b626797James Dong } 11892dce41ad26cb3e9e15c9e456a84bcf5309548ca0Andreas Huber } 11902dce41ad26cb3e9e15c9e456a84bcf5309548ca0Andreas Huber 1191760943b5e7a09b602aba04ec451e97662f48b0a4James Dong mWriter = new AMRWriter(mOutputFd); 119272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang return setupRawAudioRecording(); 1193760943b5e7a09b602aba04ec451e97662f48b0a4James Dong} 1194760943b5e7a09b602aba04ec451e97662f48b0a4James Dong 119572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhangstatus_t StagefrightRecorder::setupRawAudioRecording() { 11960f8f4e681b867dd611d2d916453337cb0770d4daHochi Huang if (mAudioSource >= AUDIO_SOURCE_CNT && mAudioSource != AUDIO_SOURCE_FM_TUNER) { 119729357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("Invalid audio source: %d", mAudioSource); 1198934da11c4cc598d3dd3b53726c362bcdcc0fd37fJames Dong return BAD_VALUE; 11992dce41ad26cb3e9e15c9e456a84bcf5309548ca0Andreas Huber } 12002dce41ad26cb3e9e15c9e456a84bcf5309548ca0Andreas Huber 120142dd1d5f186252a7f09f8fb1a46ea82e3877b2d3James Dong status_t status = BAD_VALUE; 120242dd1d5f186252a7f09f8fb1a46ea82e3877b2d3James Dong if (OK != (status = checkAudioEncoderCapabilities())) { 120342dd1d5f186252a7f09f8fb1a46ea82e3877b2d3James Dong return status; 120442dd1d5f186252a7f09f8fb1a46ea82e3877b2d3James Dong } 12052dce41ad26cb3e9e15c9e456a84bcf5309548ca0Andreas Huber 1206d008275796ac4cccf85fefce53cef733a49bc1faWonsik Kim sp<MediaCodecSource> audioEncoder = createAudioSource(); 12072dce41ad26cb3e9e15c9e456a84bcf5309548ca0Andreas Huber if (audioEncoder == NULL) { 12082dce41ad26cb3e9e15c9e456a84bcf5309548ca0Andreas Huber return UNKNOWN_ERROR; 12092dce41ad26cb3e9e15c9e456a84bcf5309548ca0Andreas Huber } 12102dce41ad26cb3e9e15c9e456a84bcf5309548ca0Andreas Huber 1211760943b5e7a09b602aba04ec451e97662f48b0a4James Dong CHECK(mWriter != 0); 12122dce41ad26cb3e9e15c9e456a84bcf5309548ca0Andreas Huber mWriter->addSource(audioEncoder); 1213d008275796ac4cccf85fefce53cef733a49bc1faWonsik Kim mAudioEncoderSource = audioEncoder; 1214d599cd4573b5a2d5914c5040e0565ef866749b77James Dong 1215d599cd4573b5a2d5914c5040e0565ef866749b77James Dong if (mMaxFileDurationUs != 0) { 1216d599cd4573b5a2d5914c5040e0565ef866749b77James Dong mWriter->setMaxFileDuration(mMaxFileDurationUs); 1217d599cd4573b5a2d5914c5040e0565ef866749b77James Dong } 1218d599cd4573b5a2d5914c5040e0565ef866749b77James Dong if (mMaxFileSizeBytes != 0) { 1219d599cd4573b5a2d5914c5040e0565ef866749b77James Dong mWriter->setMaxFileSize(mMaxFileSizeBytes); 1220d599cd4573b5a2d5914c5040e0565ef866749b77James Dong } 1221d599cd4573b5a2d5914c5040e0565ef866749b77James Dong mWriter->setListener(mListener); 12222dce41ad26cb3e9e15c9e456a84bcf5309548ca0Andreas Huber 12232dce41ad26cb3e9e15c9e456a84bcf5309548ca0Andreas Huber return OK; 12242dce41ad26cb3e9e15c9e456a84bcf5309548ca0Andreas Huber} 12252dce41ad26cb3e9e15c9e456a84bcf5309548ca0Andreas Huber 122672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhangstatus_t StagefrightRecorder::setupRTPRecording() { 122739ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber CHECK_EQ(mOutputFormat, OUTPUT_FORMAT_RTP_AVP); 122839ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 1229fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin if ((mAudioSource != AUDIO_SOURCE_CNT 123039ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber && mVideoSource != VIDEO_SOURCE_LIST_END) 1231fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin || (mAudioSource == AUDIO_SOURCE_CNT 123239ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber && mVideoSource == VIDEO_SOURCE_LIST_END)) { 123339ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber // Must have exactly one source. 123439ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber return BAD_VALUE; 123539ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber } 123639ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 123739ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber if (mOutputFd < 0) { 123839ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber return BAD_VALUE; 123939ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber } 124039ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 1241d008275796ac4cccf85fefce53cef733a49bc1faWonsik Kim sp<MediaCodecSource> source; 124239ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 1243fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin if (mAudioSource != AUDIO_SOURCE_CNT) { 124439ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber source = createAudioSource(); 1245d008275796ac4cccf85fefce53cef733a49bc1faWonsik Kim mAudioEncoderSource = source; 124639ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber } else { 124754ef1bae010f12dfe6a40ff4452695b1b11ff449Chong Zhang setDefaultVideoEncoderIfNecessary(); 12489c075bca0b75093ca0514a3c8f74d73c8e9e83fdNipun Kwatra 1249b33f3407bab0970a7f9241680723a1140b177c50Pannag Sanketi sp<MediaSource> mediaSource; 1250b33f3407bab0970a7f9241680723a1140b177c50Pannag Sanketi status_t err = setupMediaSource(&mediaSource); 12519c075bca0b75093ca0514a3c8f74d73c8e9e83fdNipun Kwatra if (err != OK) { 12529c075bca0b75093ca0514a3c8f74d73c8e9e83fdNipun Kwatra return err; 12539c075bca0b75093ca0514a3c8f74d73c8e9e83fdNipun Kwatra } 12549c075bca0b75093ca0514a3c8f74d73c8e9e83fdNipun Kwatra 12554db37cedd4db8230f3ec6191d8d7ba2b0036886eRobert Shih err = setupVideoEncoder(mediaSource, &source); 125639ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber if (err != OK) { 125739ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber return err; 125839ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber } 1259d008275796ac4cccf85fefce53cef733a49bc1faWonsik Kim mVideoEncoderSource = source; 126039ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber } 126139ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 1262674ebd0b4e1143e38392a4e3bb38b4679a4577bcJames Dong mWriter = new ARTPWriter(mOutputFd); 126339ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber mWriter->addSource(source); 126439ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber mWriter->setListener(mListener); 126539ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 126672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang return OK; 126739ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber} 126839ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 126972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhangstatus_t StagefrightRecorder::setupMPEG2TSRecording() { 127059b7dc39ea8332d3418a599e51447d7edb612ac4Andreas Huber CHECK_EQ(mOutputFormat, OUTPUT_FORMAT_MPEG2TS); 127159b7dc39ea8332d3418a599e51447d7edb612ac4Andreas Huber 1272674ebd0b4e1143e38392a4e3bb38b4679a4577bcJames Dong sp<MediaWriter> writer = new MPEG2TSWriter(mOutputFd); 127359b7dc39ea8332d3418a599e51447d7edb612ac4Andreas Huber 1274fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin if (mAudioSource != AUDIO_SOURCE_CNT) { 1275f60c660f048d5f5e2458cff243c20400d73757a7Dave Burke if (mAudioEncoder != AUDIO_ENCODER_AAC && 1276f60c660f048d5f5e2458cff243c20400d73757a7Dave Burke mAudioEncoder != AUDIO_ENCODER_HE_AAC && 1277f60c660f048d5f5e2458cff243c20400d73757a7Dave Burke mAudioEncoder != AUDIO_ENCODER_AAC_ELD) { 127859b7dc39ea8332d3418a599e51447d7edb612ac4Andreas Huber return ERROR_UNSUPPORTED; 127959b7dc39ea8332d3418a599e51447d7edb612ac4Andreas Huber } 128059b7dc39ea8332d3418a599e51447d7edb612ac4Andreas Huber 128159b7dc39ea8332d3418a599e51447d7edb612ac4Andreas Huber status_t err = setupAudioEncoder(writer); 128259b7dc39ea8332d3418a599e51447d7edb612ac4Andreas Huber 128359b7dc39ea8332d3418a599e51447d7edb612ac4Andreas Huber if (err != OK) { 128459b7dc39ea8332d3418a599e51447d7edb612ac4Andreas Huber return err; 128559b7dc39ea8332d3418a599e51447d7edb612ac4Andreas Huber } 128659b7dc39ea8332d3418a599e51447d7edb612ac4Andreas Huber } 128759b7dc39ea8332d3418a599e51447d7edb612ac4Andreas Huber 1288b33f3407bab0970a7f9241680723a1140b177c50Pannag Sanketi if (mVideoSource < VIDEO_SOURCE_LIST_END) { 128959b7dc39ea8332d3418a599e51447d7edb612ac4Andreas Huber if (mVideoEncoder != VIDEO_ENCODER_H264) { 129054ef1bae010f12dfe6a40ff4452695b1b11ff449Chong Zhang ALOGE("MPEG2TS recording only supports H.264 encoding!"); 129159b7dc39ea8332d3418a599e51447d7edb612ac4Andreas Huber return ERROR_UNSUPPORTED; 129259b7dc39ea8332d3418a599e51447d7edb612ac4Andreas Huber } 129359b7dc39ea8332d3418a599e51447d7edb612ac4Andreas Huber 1294b33f3407bab0970a7f9241680723a1140b177c50Pannag Sanketi sp<MediaSource> mediaSource; 1295b33f3407bab0970a7f9241680723a1140b177c50Pannag Sanketi status_t err = setupMediaSource(&mediaSource); 1296f9f083e2853740c97588f4db82c24645ae5880e4Kenny Root if (err != OK) { 1297f9f083e2853740c97588f4db82c24645ae5880e4Kenny Root return err; 1298f9f083e2853740c97588f4db82c24645ae5880e4Kenny Root } 1299f9f083e2853740c97588f4db82c24645ae5880e4Kenny Root 1300d008275796ac4cccf85fefce53cef733a49bc1faWonsik Kim sp<MediaCodecSource> encoder; 13014db37cedd4db8230f3ec6191d8d7ba2b0036886eRobert Shih err = setupVideoEncoder(mediaSource, &encoder); 130259b7dc39ea8332d3418a599e51447d7edb612ac4Andreas Huber 130359b7dc39ea8332d3418a599e51447d7edb612ac4Andreas Huber if (err != OK) { 130459b7dc39ea8332d3418a599e51447d7edb612ac4Andreas Huber return err; 130559b7dc39ea8332d3418a599e51447d7edb612ac4Andreas Huber } 130659b7dc39ea8332d3418a599e51447d7edb612ac4Andreas Huber 130759b7dc39ea8332d3418a599e51447d7edb612ac4Andreas Huber writer->addSource(encoder); 1308d008275796ac4cccf85fefce53cef733a49bc1faWonsik Kim mVideoEncoderSource = encoder; 130959b7dc39ea8332d3418a599e51447d7edb612ac4Andreas Huber } 131059b7dc39ea8332d3418a599e51447d7edb612ac4Andreas Huber 131159b7dc39ea8332d3418a599e51447d7edb612ac4Andreas Huber if (mMaxFileDurationUs != 0) { 131259b7dc39ea8332d3418a599e51447d7edb612ac4Andreas Huber writer->setMaxFileDuration(mMaxFileDurationUs); 131359b7dc39ea8332d3418a599e51447d7edb612ac4Andreas Huber } 131459b7dc39ea8332d3418a599e51447d7edb612ac4Andreas Huber 131559b7dc39ea8332d3418a599e51447d7edb612ac4Andreas Huber if (mMaxFileSizeBytes != 0) { 131659b7dc39ea8332d3418a599e51447d7edb612ac4Andreas Huber writer->setMaxFileSize(mMaxFileSizeBytes); 131759b7dc39ea8332d3418a599e51447d7edb612ac4Andreas Huber } 131859b7dc39ea8332d3418a599e51447d7edb612ac4Andreas Huber 131959b7dc39ea8332d3418a599e51447d7edb612ac4Andreas Huber mWriter = writer; 132059b7dc39ea8332d3418a599e51447d7edb612ac4Andreas Huber 132172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang return OK; 132259b7dc39ea8332d3418a599e51447d7edb612ac4Andreas Huber} 132359b7dc39ea8332d3418a599e51447d7edb612ac4Andreas Huber 132499c2a076b4a46762a22bbb4dfbd51d107e0532d9James Dongvoid StagefrightRecorder::clipVideoFrameRate() { 13253856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("clipVideoFrameRate: encoder %d", mVideoEncoder); 132654ef1bae010f12dfe6a40ff4452695b1b11ff449Chong Zhang if (mFrameRate == -1) { 132754ef1bae010f12dfe6a40ff4452695b1b11ff449Chong Zhang mFrameRate = mEncoderProfiles->getCamcorderProfileParamByName( 132854ef1bae010f12dfe6a40ff4452695b1b11ff449Chong Zhang "vid.fps", mCameraId, CAMCORDER_QUALITY_LOW); 132954ef1bae010f12dfe6a40ff4452695b1b11ff449Chong Zhang ALOGW("Using default video fps %d", mFrameRate); 133054ef1bae010f12dfe6a40ff4452695b1b11ff449Chong Zhang } 133154ef1bae010f12dfe6a40ff4452695b1b11ff449Chong Zhang 133299c2a076b4a46762a22bbb4dfbd51d107e0532d9James Dong int minFrameRate = mEncoderProfiles->getVideoEncoderParamByName( 133399c2a076b4a46762a22bbb4dfbd51d107e0532d9James Dong "enc.vid.fps.min", mVideoEncoder); 133499c2a076b4a46762a22bbb4dfbd51d107e0532d9James Dong int maxFrameRate = mEncoderProfiles->getVideoEncoderParamByName( 133599c2a076b4a46762a22bbb4dfbd51d107e0532d9James Dong "enc.vid.fps.max", mVideoEncoder); 1336b4a55269a5b39c73de2cc1d4013d0631ef18c77dJames Dong if (mFrameRate < minFrameRate && minFrameRate != -1) { 13375ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block ALOGW("Intended video encoding frame rate (%d fps) is too small" 133899c2a076b4a46762a22bbb4dfbd51d107e0532d9James Dong " and will be set to (%d fps)", mFrameRate, minFrameRate); 133999c2a076b4a46762a22bbb4dfbd51d107e0532d9James Dong mFrameRate = minFrameRate; 1340b4a55269a5b39c73de2cc1d4013d0631ef18c77dJames Dong } else if (mFrameRate > maxFrameRate && maxFrameRate != -1) { 13415ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block ALOGW("Intended video encoding frame rate (%d fps) is too large" 134299c2a076b4a46762a22bbb4dfbd51d107e0532d9James Dong " and will be set to (%d fps)", mFrameRate, maxFrameRate); 134399c2a076b4a46762a22bbb4dfbd51d107e0532d9James Dong mFrameRate = maxFrameRate; 134499c2a076b4a46762a22bbb4dfbd51d107e0532d9James Dong } 134599c2a076b4a46762a22bbb4dfbd51d107e0532d9James Dong} 134699c2a076b4a46762a22bbb4dfbd51d107e0532d9James Dong 134799c2a076b4a46762a22bbb4dfbd51d107e0532d9James Dongvoid StagefrightRecorder::clipVideoBitRate() { 13483856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("clipVideoBitRate: encoder %d", mVideoEncoder); 134999c2a076b4a46762a22bbb4dfbd51d107e0532d9James Dong int minBitRate = mEncoderProfiles->getVideoEncoderParamByName( 135099c2a076b4a46762a22bbb4dfbd51d107e0532d9James Dong "enc.vid.bps.min", mVideoEncoder); 135199c2a076b4a46762a22bbb4dfbd51d107e0532d9James Dong int maxBitRate = mEncoderProfiles->getVideoEncoderParamByName( 135299c2a076b4a46762a22bbb4dfbd51d107e0532d9James Dong "enc.vid.bps.max", mVideoEncoder); 1353b4a55269a5b39c73de2cc1d4013d0631ef18c77dJames Dong if (mVideoBitRate < minBitRate && minBitRate != -1) { 13545ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block ALOGW("Intended video encoding bit rate (%d bps) is too small" 135599c2a076b4a46762a22bbb4dfbd51d107e0532d9James Dong " and will be set to (%d bps)", mVideoBitRate, minBitRate); 135699c2a076b4a46762a22bbb4dfbd51d107e0532d9James Dong mVideoBitRate = minBitRate; 1357b4a55269a5b39c73de2cc1d4013d0631ef18c77dJames Dong } else if (mVideoBitRate > maxBitRate && maxBitRate != -1) { 13585ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block ALOGW("Intended video encoding bit rate (%d bps) is too large" 135999c2a076b4a46762a22bbb4dfbd51d107e0532d9James Dong " and will be set to (%d bps)", mVideoBitRate, maxBitRate); 136099c2a076b4a46762a22bbb4dfbd51d107e0532d9James Dong mVideoBitRate = maxBitRate; 136199c2a076b4a46762a22bbb4dfbd51d107e0532d9James Dong } 136299c2a076b4a46762a22bbb4dfbd51d107e0532d9James Dong} 136399c2a076b4a46762a22bbb4dfbd51d107e0532d9James Dong 136499c2a076b4a46762a22bbb4dfbd51d107e0532d9James Dongvoid StagefrightRecorder::clipVideoFrameWidth() { 13653856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("clipVideoFrameWidth: encoder %d", mVideoEncoder); 136699c2a076b4a46762a22bbb4dfbd51d107e0532d9James Dong int minFrameWidth = mEncoderProfiles->getVideoEncoderParamByName( 136799c2a076b4a46762a22bbb4dfbd51d107e0532d9James Dong "enc.vid.width.min", mVideoEncoder); 136899c2a076b4a46762a22bbb4dfbd51d107e0532d9James Dong int maxFrameWidth = mEncoderProfiles->getVideoEncoderParamByName( 136999c2a076b4a46762a22bbb4dfbd51d107e0532d9James Dong "enc.vid.width.max", mVideoEncoder); 1370b4a55269a5b39c73de2cc1d4013d0631ef18c77dJames Dong if (mVideoWidth < minFrameWidth && minFrameWidth != -1) { 13715ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block ALOGW("Intended video encoding frame width (%d) is too small" 137299c2a076b4a46762a22bbb4dfbd51d107e0532d9James Dong " and will be set to (%d)", mVideoWidth, minFrameWidth); 137399c2a076b4a46762a22bbb4dfbd51d107e0532d9James Dong mVideoWidth = minFrameWidth; 1374b4a55269a5b39c73de2cc1d4013d0631ef18c77dJames Dong } else if (mVideoWidth > maxFrameWidth && maxFrameWidth != -1) { 13755ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block ALOGW("Intended video encoding frame width (%d) is too large" 137699c2a076b4a46762a22bbb4dfbd51d107e0532d9James Dong " and will be set to (%d)", mVideoWidth, maxFrameWidth); 137799c2a076b4a46762a22bbb4dfbd51d107e0532d9James Dong mVideoWidth = maxFrameWidth; 137899c2a076b4a46762a22bbb4dfbd51d107e0532d9James Dong } 137999c2a076b4a46762a22bbb4dfbd51d107e0532d9James Dong} 138099c2a076b4a46762a22bbb4dfbd51d107e0532d9James Dong 1381d46a6b9fd8b2a4f9098757384711e2cd03a91651Eino-Ville Talvalastatus_t StagefrightRecorder::checkVideoEncoderCapabilities() { 138246d26dd29195450db15704e84d65740628a821fbChong Zhang if (!mCaptureFpsEnable) { 1383e4e0a6994d39c4a7cba09c5fff442b2dca1df8f8Nipun Kwatra // Dont clip for time lapse capture as encoder will have enough 1384e4e0a6994d39c4a7cba09c5fff442b2dca1df8f8Nipun Kwatra // time to encode because of slow capture rate of time lapse. 1385e4e0a6994d39c4a7cba09c5fff442b2dca1df8f8Nipun Kwatra clipVideoBitRate(); 1386e4e0a6994d39c4a7cba09c5fff442b2dca1df8f8Nipun Kwatra clipVideoFrameRate(); 1387e4e0a6994d39c4a7cba09c5fff442b2dca1df8f8Nipun Kwatra clipVideoFrameWidth(); 1388e4e0a6994d39c4a7cba09c5fff442b2dca1df8f8Nipun Kwatra clipVideoFrameHeight(); 1389d552b88515c6ccd18695e5db5e6032a6425d8c63James Dong setDefaultProfileIfNecessary(); 1390e4e0a6994d39c4a7cba09c5fff442b2dca1df8f8Nipun Kwatra } 1391934da11c4cc598d3dd3b53726c362bcdcc0fd37fJames Dong return OK; 1392934da11c4cc598d3dd3b53726c362bcdcc0fd37fJames Dong} 1393934da11c4cc598d3dd3b53726c362bcdcc0fd37fJames Dong 1394d552b88515c6ccd18695e5db5e6032a6425d8c63James Dong// Set to use AVC baseline profile if the encoding parameters matches 1395d552b88515c6ccd18695e5db5e6032a6425d8c63James Dong// CAMCORDER_QUALITY_LOW profile; this is for the sake of MMS service. 1396d552b88515c6ccd18695e5db5e6032a6425d8c63James Dongvoid StagefrightRecorder::setDefaultProfileIfNecessary() { 13973856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("setDefaultProfileIfNecessary"); 1398d552b88515c6ccd18695e5db5e6032a6425d8c63James Dong 1399d552b88515c6ccd18695e5db5e6032a6425d8c63James Dong camcorder_quality quality = CAMCORDER_QUALITY_LOW; 1400d552b88515c6ccd18695e5db5e6032a6425d8c63James Dong 1401d552b88515c6ccd18695e5db5e6032a6425d8c63James Dong int64_t durationUs = mEncoderProfiles->getCamcorderProfileParamByName( 1402d552b88515c6ccd18695e5db5e6032a6425d8c63James Dong "duration", mCameraId, quality) * 1000000LL; 1403d552b88515c6ccd18695e5db5e6032a6425d8c63James Dong 1404d552b88515c6ccd18695e5db5e6032a6425d8c63James Dong int fileFormat = mEncoderProfiles->getCamcorderProfileParamByName( 1405d552b88515c6ccd18695e5db5e6032a6425d8c63James Dong "file.format", mCameraId, quality); 1406d552b88515c6ccd18695e5db5e6032a6425d8c63James Dong 1407d552b88515c6ccd18695e5db5e6032a6425d8c63James Dong int videoCodec = mEncoderProfiles->getCamcorderProfileParamByName( 1408d552b88515c6ccd18695e5db5e6032a6425d8c63James Dong "vid.codec", mCameraId, quality); 1409d552b88515c6ccd18695e5db5e6032a6425d8c63James Dong 1410d552b88515c6ccd18695e5db5e6032a6425d8c63James Dong int videoBitRate = mEncoderProfiles->getCamcorderProfileParamByName( 1411d552b88515c6ccd18695e5db5e6032a6425d8c63James Dong "vid.bps", mCameraId, quality); 1412d552b88515c6ccd18695e5db5e6032a6425d8c63James Dong 1413d552b88515c6ccd18695e5db5e6032a6425d8c63James Dong int videoFrameRate = mEncoderProfiles->getCamcorderProfileParamByName( 1414d552b88515c6ccd18695e5db5e6032a6425d8c63James Dong "vid.fps", mCameraId, quality); 1415d552b88515c6ccd18695e5db5e6032a6425d8c63James Dong 1416d552b88515c6ccd18695e5db5e6032a6425d8c63James Dong int videoFrameWidth = mEncoderProfiles->getCamcorderProfileParamByName( 1417d552b88515c6ccd18695e5db5e6032a6425d8c63James Dong "vid.width", mCameraId, quality); 1418d552b88515c6ccd18695e5db5e6032a6425d8c63James Dong 1419d552b88515c6ccd18695e5db5e6032a6425d8c63James Dong int videoFrameHeight = mEncoderProfiles->getCamcorderProfileParamByName( 1420d552b88515c6ccd18695e5db5e6032a6425d8c63James Dong "vid.height", mCameraId, quality); 1421d552b88515c6ccd18695e5db5e6032a6425d8c63James Dong 1422d552b88515c6ccd18695e5db5e6032a6425d8c63James Dong int audioCodec = mEncoderProfiles->getCamcorderProfileParamByName( 1423d552b88515c6ccd18695e5db5e6032a6425d8c63James Dong "aud.codec", mCameraId, quality); 1424d552b88515c6ccd18695e5db5e6032a6425d8c63James Dong 1425d552b88515c6ccd18695e5db5e6032a6425d8c63James Dong int audioBitRate = mEncoderProfiles->getCamcorderProfileParamByName( 1426d552b88515c6ccd18695e5db5e6032a6425d8c63James Dong "aud.bps", mCameraId, quality); 1427d552b88515c6ccd18695e5db5e6032a6425d8c63James Dong 1428d552b88515c6ccd18695e5db5e6032a6425d8c63James Dong int audioSampleRate = mEncoderProfiles->getCamcorderProfileParamByName( 1429d552b88515c6ccd18695e5db5e6032a6425d8c63James Dong "aud.hz", mCameraId, quality); 1430d552b88515c6ccd18695e5db5e6032a6425d8c63James Dong 1431d552b88515c6ccd18695e5db5e6032a6425d8c63James Dong int audioChannels = mEncoderProfiles->getCamcorderProfileParamByName( 1432d552b88515c6ccd18695e5db5e6032a6425d8c63James Dong "aud.ch", mCameraId, quality); 1433d552b88515c6ccd18695e5db5e6032a6425d8c63James Dong 1434d552b88515c6ccd18695e5db5e6032a6425d8c63James Dong if (durationUs == mMaxFileDurationUs && 1435d552b88515c6ccd18695e5db5e6032a6425d8c63James Dong fileFormat == mOutputFormat && 1436d552b88515c6ccd18695e5db5e6032a6425d8c63James Dong videoCodec == mVideoEncoder && 1437d552b88515c6ccd18695e5db5e6032a6425d8c63James Dong videoBitRate == mVideoBitRate && 1438d552b88515c6ccd18695e5db5e6032a6425d8c63James Dong videoFrameRate == mFrameRate && 1439d552b88515c6ccd18695e5db5e6032a6425d8c63James Dong videoFrameWidth == mVideoWidth && 1440d552b88515c6ccd18695e5db5e6032a6425d8c63James Dong videoFrameHeight == mVideoHeight && 1441d552b88515c6ccd18695e5db5e6032a6425d8c63James Dong audioCodec == mAudioEncoder && 1442d552b88515c6ccd18695e5db5e6032a6425d8c63James Dong audioBitRate == mAudioBitRate && 1443d552b88515c6ccd18695e5db5e6032a6425d8c63James Dong audioSampleRate == mSampleRate && 1444d552b88515c6ccd18695e5db5e6032a6425d8c63James Dong audioChannels == mAudioChannels) { 1445d552b88515c6ccd18695e5db5e6032a6425d8c63James Dong if (videoCodec == VIDEO_ENCODER_H264) { 1446df64d15042bbd5e0e4933ac49bf3c177dd94752cSteve Block ALOGI("Force to use AVC baseline profile"); 1447d552b88515c6ccd18695e5db5e6032a6425d8c63James Dong setParamVideoEncoderProfile(OMX_VIDEO_AVCProfileBaseline); 1448a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar // set 0 for invalid levels - this will be rejected by the 1449a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar // codec if it cannot handle it during configure 1450a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar setParamVideoEncoderLevel(ACodec::getAVCLevelFor( 1451a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar videoFrameWidth, videoFrameHeight, videoFrameRate, videoBitRate)); 1452d552b88515c6ccd18695e5db5e6032a6425d8c63James Dong } 1453d552b88515c6ccd18695e5db5e6032a6425d8c63James Dong } 1454d552b88515c6ccd18695e5db5e6032a6425d8c63James Dong} 1455d552b88515c6ccd18695e5db5e6032a6425d8c63James Dong 145654ef1bae010f12dfe6a40ff4452695b1b11ff449Chong Zhangvoid StagefrightRecorder::setDefaultVideoEncoderIfNecessary() { 145754ef1bae010f12dfe6a40ff4452695b1b11ff449Chong Zhang if (mVideoEncoder == VIDEO_ENCODER_DEFAULT) { 145854ef1bae010f12dfe6a40ff4452695b1b11ff449Chong Zhang if (mOutputFormat == OUTPUT_FORMAT_WEBM) { 145954ef1bae010f12dfe6a40ff4452695b1b11ff449Chong Zhang // default to VP8 for WEBM recording 146054ef1bae010f12dfe6a40ff4452695b1b11ff449Chong Zhang mVideoEncoder = VIDEO_ENCODER_VP8; 146154ef1bae010f12dfe6a40ff4452695b1b11ff449Chong Zhang } else { 146254ef1bae010f12dfe6a40ff4452695b1b11ff449Chong Zhang // pick the default encoder for CAMCORDER_QUALITY_LOW 146354ef1bae010f12dfe6a40ff4452695b1b11ff449Chong Zhang int videoCodec = mEncoderProfiles->getCamcorderProfileParamByName( 146454ef1bae010f12dfe6a40ff4452695b1b11ff449Chong Zhang "vid.codec", mCameraId, CAMCORDER_QUALITY_LOW); 146554ef1bae010f12dfe6a40ff4452695b1b11ff449Chong Zhang 146654ef1bae010f12dfe6a40ff4452695b1b11ff449Chong Zhang if (videoCodec > VIDEO_ENCODER_DEFAULT && 146754ef1bae010f12dfe6a40ff4452695b1b11ff449Chong Zhang videoCodec < VIDEO_ENCODER_LIST_END) { 146854ef1bae010f12dfe6a40ff4452695b1b11ff449Chong Zhang mVideoEncoder = (video_encoder)videoCodec; 146954ef1bae010f12dfe6a40ff4452695b1b11ff449Chong Zhang } else { 147054ef1bae010f12dfe6a40ff4452695b1b11ff449Chong Zhang // default to H.264 if camcorder profile not available 147154ef1bae010f12dfe6a40ff4452695b1b11ff449Chong Zhang mVideoEncoder = VIDEO_ENCODER_H264; 147254ef1bae010f12dfe6a40ff4452695b1b11ff449Chong Zhang } 147354ef1bae010f12dfe6a40ff4452695b1b11ff449Chong Zhang } 147454ef1bae010f12dfe6a40ff4452695b1b11ff449Chong Zhang } 147554ef1bae010f12dfe6a40ff4452695b1b11ff449Chong Zhang} 147654ef1bae010f12dfe6a40ff4452695b1b11ff449Chong Zhang 147742dd1d5f186252a7f09f8fb1a46ea82e3877b2d3James Dongstatus_t StagefrightRecorder::checkAudioEncoderCapabilities() { 147842dd1d5f186252a7f09f8fb1a46ea82e3877b2d3James Dong clipAudioBitRate(); 147942dd1d5f186252a7f09f8fb1a46ea82e3877b2d3James Dong clipAudioSampleRate(); 148042dd1d5f186252a7f09f8fb1a46ea82e3877b2d3James Dong clipNumberOfAudioChannels(); 148142dd1d5f186252a7f09f8fb1a46ea82e3877b2d3James Dong return OK; 148242dd1d5f186252a7f09f8fb1a46ea82e3877b2d3James Dong} 148342dd1d5f186252a7f09f8fb1a46ea82e3877b2d3James Dong 148442dd1d5f186252a7f09f8fb1a46ea82e3877b2d3James Dongvoid StagefrightRecorder::clipAudioBitRate() { 14853856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("clipAudioBitRate: encoder %d", mAudioEncoder); 148642dd1d5f186252a7f09f8fb1a46ea82e3877b2d3James Dong 148742dd1d5f186252a7f09f8fb1a46ea82e3877b2d3James Dong int minAudioBitRate = 148842dd1d5f186252a7f09f8fb1a46ea82e3877b2d3James Dong mEncoderProfiles->getAudioEncoderParamByName( 148942dd1d5f186252a7f09f8fb1a46ea82e3877b2d3James Dong "enc.aud.bps.min", mAudioEncoder); 1490b4a55269a5b39c73de2cc1d4013d0631ef18c77dJames Dong if (minAudioBitRate != -1 && mAudioBitRate < minAudioBitRate) { 14915ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block ALOGW("Intended audio encoding bit rate (%d) is too small" 149242dd1d5f186252a7f09f8fb1a46ea82e3877b2d3James Dong " and will be set to (%d)", mAudioBitRate, minAudioBitRate); 149342dd1d5f186252a7f09f8fb1a46ea82e3877b2d3James Dong mAudioBitRate = minAudioBitRate; 149442dd1d5f186252a7f09f8fb1a46ea82e3877b2d3James Dong } 149542dd1d5f186252a7f09f8fb1a46ea82e3877b2d3James Dong 149642dd1d5f186252a7f09f8fb1a46ea82e3877b2d3James Dong int maxAudioBitRate = 149742dd1d5f186252a7f09f8fb1a46ea82e3877b2d3James Dong mEncoderProfiles->getAudioEncoderParamByName( 149842dd1d5f186252a7f09f8fb1a46ea82e3877b2d3James Dong "enc.aud.bps.max", mAudioEncoder); 1499b4a55269a5b39c73de2cc1d4013d0631ef18c77dJames Dong if (maxAudioBitRate != -1 && mAudioBitRate > maxAudioBitRate) { 15005ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block ALOGW("Intended audio encoding bit rate (%d) is too large" 150142dd1d5f186252a7f09f8fb1a46ea82e3877b2d3James Dong " and will be set to (%d)", mAudioBitRate, maxAudioBitRate); 150242dd1d5f186252a7f09f8fb1a46ea82e3877b2d3James Dong mAudioBitRate = maxAudioBitRate; 150342dd1d5f186252a7f09f8fb1a46ea82e3877b2d3James Dong } 150442dd1d5f186252a7f09f8fb1a46ea82e3877b2d3James Dong} 150542dd1d5f186252a7f09f8fb1a46ea82e3877b2d3James Dong 150642dd1d5f186252a7f09f8fb1a46ea82e3877b2d3James Dongvoid StagefrightRecorder::clipAudioSampleRate() { 15073856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("clipAudioSampleRate: encoder %d", mAudioEncoder); 150842dd1d5f186252a7f09f8fb1a46ea82e3877b2d3James Dong 150942dd1d5f186252a7f09f8fb1a46ea82e3877b2d3James Dong int minSampleRate = 151042dd1d5f186252a7f09f8fb1a46ea82e3877b2d3James Dong mEncoderProfiles->getAudioEncoderParamByName( 151142dd1d5f186252a7f09f8fb1a46ea82e3877b2d3James Dong "enc.aud.hz.min", mAudioEncoder); 1512b4a55269a5b39c73de2cc1d4013d0631ef18c77dJames Dong if (minSampleRate != -1 && mSampleRate < minSampleRate) { 15135ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block ALOGW("Intended audio sample rate (%d) is too small" 151442dd1d5f186252a7f09f8fb1a46ea82e3877b2d3James Dong " and will be set to (%d)", mSampleRate, minSampleRate); 151542dd1d5f186252a7f09f8fb1a46ea82e3877b2d3James Dong mSampleRate = minSampleRate; 151642dd1d5f186252a7f09f8fb1a46ea82e3877b2d3James Dong } 151742dd1d5f186252a7f09f8fb1a46ea82e3877b2d3James Dong 151842dd1d5f186252a7f09f8fb1a46ea82e3877b2d3James Dong int maxSampleRate = 151942dd1d5f186252a7f09f8fb1a46ea82e3877b2d3James Dong mEncoderProfiles->getAudioEncoderParamByName( 152042dd1d5f186252a7f09f8fb1a46ea82e3877b2d3James Dong "enc.aud.hz.max", mAudioEncoder); 1521b4a55269a5b39c73de2cc1d4013d0631ef18c77dJames Dong if (maxSampleRate != -1 && mSampleRate > maxSampleRate) { 15225ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block ALOGW("Intended audio sample rate (%d) is too large" 152342dd1d5f186252a7f09f8fb1a46ea82e3877b2d3James Dong " and will be set to (%d)", mSampleRate, maxSampleRate); 152442dd1d5f186252a7f09f8fb1a46ea82e3877b2d3James Dong mSampleRate = maxSampleRate; 152542dd1d5f186252a7f09f8fb1a46ea82e3877b2d3James Dong } 152642dd1d5f186252a7f09f8fb1a46ea82e3877b2d3James Dong} 152742dd1d5f186252a7f09f8fb1a46ea82e3877b2d3James Dong 152842dd1d5f186252a7f09f8fb1a46ea82e3877b2d3James Dongvoid StagefrightRecorder::clipNumberOfAudioChannels() { 15293856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("clipNumberOfAudioChannels: encoder %d", mAudioEncoder); 153042dd1d5f186252a7f09f8fb1a46ea82e3877b2d3James Dong 153142dd1d5f186252a7f09f8fb1a46ea82e3877b2d3James Dong int minChannels = 153242dd1d5f186252a7f09f8fb1a46ea82e3877b2d3James Dong mEncoderProfiles->getAudioEncoderParamByName( 153342dd1d5f186252a7f09f8fb1a46ea82e3877b2d3James Dong "enc.aud.ch.min", mAudioEncoder); 1534b4a55269a5b39c73de2cc1d4013d0631ef18c77dJames Dong if (minChannels != -1 && mAudioChannels < minChannels) { 15355ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block ALOGW("Intended number of audio channels (%d) is too small" 153642dd1d5f186252a7f09f8fb1a46ea82e3877b2d3James Dong " and will be set to (%d)", mAudioChannels, minChannels); 153742dd1d5f186252a7f09f8fb1a46ea82e3877b2d3James Dong mAudioChannels = minChannels; 153842dd1d5f186252a7f09f8fb1a46ea82e3877b2d3James Dong } 153942dd1d5f186252a7f09f8fb1a46ea82e3877b2d3James Dong 154042dd1d5f186252a7f09f8fb1a46ea82e3877b2d3James Dong int maxChannels = 154142dd1d5f186252a7f09f8fb1a46ea82e3877b2d3James Dong mEncoderProfiles->getAudioEncoderParamByName( 154242dd1d5f186252a7f09f8fb1a46ea82e3877b2d3James Dong "enc.aud.ch.max", mAudioEncoder); 1543b4a55269a5b39c73de2cc1d4013d0631ef18c77dJames Dong if (maxChannels != -1 && mAudioChannels > maxChannels) { 15445ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block ALOGW("Intended number of audio channels (%d) is too large" 154542dd1d5f186252a7f09f8fb1a46ea82e3877b2d3James Dong " and will be set to (%d)", mAudioChannels, maxChannels); 154642dd1d5f186252a7f09f8fb1a46ea82e3877b2d3James Dong mAudioChannels = maxChannels; 154742dd1d5f186252a7f09f8fb1a46ea82e3877b2d3James Dong } 154842dd1d5f186252a7f09f8fb1a46ea82e3877b2d3James Dong} 154942dd1d5f186252a7f09f8fb1a46ea82e3877b2d3James Dong 155099c2a076b4a46762a22bbb4dfbd51d107e0532d9James Dongvoid StagefrightRecorder::clipVideoFrameHeight() { 15513856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("clipVideoFrameHeight: encoder %d", mVideoEncoder); 155299c2a076b4a46762a22bbb4dfbd51d107e0532d9James Dong int minFrameHeight = mEncoderProfiles->getVideoEncoderParamByName( 155399c2a076b4a46762a22bbb4dfbd51d107e0532d9James Dong "enc.vid.height.min", mVideoEncoder); 155499c2a076b4a46762a22bbb4dfbd51d107e0532d9James Dong int maxFrameHeight = mEncoderProfiles->getVideoEncoderParamByName( 155599c2a076b4a46762a22bbb4dfbd51d107e0532d9James Dong "enc.vid.height.max", mVideoEncoder); 1556b4a55269a5b39c73de2cc1d4013d0631ef18c77dJames Dong if (minFrameHeight != -1 && mVideoHeight < minFrameHeight) { 15575ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block ALOGW("Intended video encoding frame height (%d) is too small" 155899c2a076b4a46762a22bbb4dfbd51d107e0532d9James Dong " and will be set to (%d)", mVideoHeight, minFrameHeight); 155999c2a076b4a46762a22bbb4dfbd51d107e0532d9James Dong mVideoHeight = minFrameHeight; 1560b4a55269a5b39c73de2cc1d4013d0631ef18c77dJames Dong } else if (maxFrameHeight != -1 && mVideoHeight > maxFrameHeight) { 15615ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block ALOGW("Intended video encoding frame height (%d) is too large" 156299c2a076b4a46762a22bbb4dfbd51d107e0532d9James Dong " and will be set to (%d)", mVideoHeight, maxFrameHeight); 156399c2a076b4a46762a22bbb4dfbd51d107e0532d9James Dong mVideoHeight = maxFrameHeight; 156499c2a076b4a46762a22bbb4dfbd51d107e0532d9James Dong } 156599c2a076b4a46762a22bbb4dfbd51d107e0532d9James Dong} 156699c2a076b4a46762a22bbb4dfbd51d107e0532d9James Dong 1567b33f3407bab0970a7f9241680723a1140b177c50Pannag Sanketi// Set up the appropriate MediaSource depending on the chosen option 1568b33f3407bab0970a7f9241680723a1140b177c50Pannag Sanketistatus_t StagefrightRecorder::setupMediaSource( 1569b33f3407bab0970a7f9241680723a1140b177c50Pannag Sanketi sp<MediaSource> *mediaSource) { 1570b33f3407bab0970a7f9241680723a1140b177c50Pannag Sanketi if (mVideoSource == VIDEO_SOURCE_DEFAULT 1571b33f3407bab0970a7f9241680723a1140b177c50Pannag Sanketi || mVideoSource == VIDEO_SOURCE_CAMERA) { 1572b33f3407bab0970a7f9241680723a1140b177c50Pannag Sanketi sp<CameraSource> cameraSource; 1573b33f3407bab0970a7f9241680723a1140b177c50Pannag Sanketi status_t err = setupCameraSource(&cameraSource); 1574b33f3407bab0970a7f9241680723a1140b177c50Pannag Sanketi if (err != OK) { 1575b33f3407bab0970a7f9241680723a1140b177c50Pannag Sanketi return err; 1576b33f3407bab0970a7f9241680723a1140b177c50Pannag Sanketi } 1577b33f3407bab0970a7f9241680723a1140b177c50Pannag Sanketi *mediaSource = cameraSource; 157872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } else if (mVideoSource == VIDEO_SOURCE_SURFACE) { 157972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang *mediaSource = NULL; 1580b33f3407bab0970a7f9241680723a1140b177c50Pannag Sanketi } else { 1581b33f3407bab0970a7f9241680723a1140b177c50Pannag Sanketi return INVALID_OPERATION; 1582b33f3407bab0970a7f9241680723a1140b177c50Pannag Sanketi } 1583b33f3407bab0970a7f9241680723a1140b177c50Pannag Sanketi return OK; 1584b33f3407bab0970a7f9241680723a1140b177c50Pannag Sanketi} 1585b33f3407bab0970a7f9241680723a1140b177c50Pannag Sanketi 15868480835b4bc1350646376aa7f3ae33742a7adeb1James Dongstatus_t StagefrightRecorder::setupCameraSource( 15878480835b4bc1350646376aa7f3ae33742a7adeb1James Dong sp<CameraSource> *cameraSource) { 1588635730831e08c32a5fe7c59125e0919b7e7899cdJames Dong status_t err = OK; 1589d46a6b9fd8b2a4f9098757384711e2cd03a91651Eino-Ville Talvala if ((err = checkVideoEncoderCapabilities()) != OK) { 1590635730831e08c32a5fe7c59125e0919b7e7899cdJames Dong return err; 1591635730831e08c32a5fe7c59125e0919b7e7899cdJames Dong } 159254ff19ac69ace7c05ea90d225e26dab3b133f487James Dong Size videoSize; 159354ff19ac69ace7c05ea90d225e26dab3b133f487James Dong videoSize.width = mVideoWidth; 159454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong videoSize.height = mVideoHeight; 159546d26dd29195450db15704e84d65740628a821fbChong Zhang if (mCaptureFpsEnable) { 159622dc508717c7767927064ec7c152def99e54adcbPawin Vongmasa if (!(mCaptureFps > 0.)) { 159722dc508717c7767927064ec7c152def99e54adcbPawin Vongmasa ALOGE("Invalid mCaptureFps value: %lf", mCaptureFps); 15982e77ad2a9f7afb57b6f9127dd7c229e774baa9c8James Dong return BAD_VALUE; 15992e77ad2a9f7afb57b6f9127dd7c229e774baa9c8James Dong } 16002e77ad2a9f7afb57b6f9127dd7c229e774baa9c8James Dong 160154ff19ac69ace7c05ea90d225e26dab3b133f487James Dong mCameraSourceTimeLapse = CameraSourceTimeLapse::CreateFromCamera( 160298a668f6ea51e4d894d2ebb61a0e18287fb14008Chien-Yu Chen mCamera, mCameraProxy, mCameraId, mClientName, mClientUid, mClientPid, 160354ff19ac69ace7c05ea90d225e26dab3b133f487James Dong videoSize, mFrameRate, mPreviewSurface, 160422dc508717c7767927064ec7c152def99e54adcbPawin Vongmasa std::llround(1e6 / mCaptureFps)); 160578eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra *cameraSource = mCameraSourceTimeLapse; 160678eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra } else { 160754ff19ac69ace7c05ea90d225e26dab3b133f487James Dong *cameraSource = CameraSource::CreateFromCamera( 160898a668f6ea51e4d894d2ebb61a0e18287fb14008Chien-Yu Chen mCamera, mCameraProxy, mCameraId, mClientName, mClientUid, mClientPid, 1609ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala videoSize, mFrameRate, 1610d46a6b9fd8b2a4f9098757384711e2cd03a91651Eino-Ville Talvala mPreviewSurface); 161178eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra } 16124ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li mCamera.clear(); 16134ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li mCameraProxy.clear(); 1614ea7b485595f8cec6a66668b5c54c8f297d843f77James Dong if (*cameraSource == NULL) { 1615ea7b485595f8cec6a66668b5c54c8f297d843f77James Dong return UNKNOWN_ERROR; 1616ea7b485595f8cec6a66668b5c54c8f297d843f77James Dong } 1617ea7b485595f8cec6a66668b5c54c8f297d843f77James Dong 1618ea7b485595f8cec6a66668b5c54c8f297d843f77James Dong if ((*cameraSource)->initCheck() != OK) { 1619ea7b485595f8cec6a66668b5c54c8f297d843f77James Dong (*cameraSource).clear(); 1620ea7b485595f8cec6a66668b5c54c8f297d843f77James Dong *cameraSource = NULL; 1621ea7b485595f8cec6a66668b5c54c8f297d843f77James Dong return NO_INIT; 1622ea7b485595f8cec6a66668b5c54c8f297d843f77James Dong } 16239c075bca0b75093ca0514a3c8f74d73c8e9e83fdNipun Kwatra 1624635730831e08c32a5fe7c59125e0919b7e7899cdJames Dong // When frame rate is not set, the actual frame rate will be set to 1625635730831e08c32a5fe7c59125e0919b7e7899cdJames Dong // the current frame rate being used. 1626635730831e08c32a5fe7c59125e0919b7e7899cdJames Dong if (mFrameRate == -1) { 1627635730831e08c32a5fe7c59125e0919b7e7899cdJames Dong int32_t frameRate = 0; 1628635730831e08c32a5fe7c59125e0919b7e7899cdJames Dong CHECK ((*cameraSource)->getFormat()->findInt32( 1629393410a441b6d06daf286ed496470e9d6b2b6ca8James Dong kKeyFrameRate, &frameRate)); 1630df64d15042bbd5e0e4933ac49bf3c177dd94752cSteve Block ALOGI("Frame rate is not explicitly set. Use the current frame " 1631635730831e08c32a5fe7c59125e0919b7e7899cdJames Dong "rate (%d fps)", frameRate); 1632635730831e08c32a5fe7c59125e0919b7e7899cdJames Dong mFrameRate = frameRate; 1633635730831e08c32a5fe7c59125e0919b7e7899cdJames Dong } 1634635730831e08c32a5fe7c59125e0919b7e7899cdJames Dong 1635635730831e08c32a5fe7c59125e0919b7e7899cdJames Dong CHECK(mFrameRate != -1); 16368480835b4bc1350646376aa7f3ae33742a7adeb1James Dong 16373e328782f1e1061d08ea0c45b855cc418a2d9ea6Lajos Molnar mMetaDataStoredInVideoBuffers = 16383e328782f1e1061d08ea0c45b855cc418a2d9ea6Lajos Molnar (*cameraSource)->metaDataStoredInVideoBuffers(); 16398480835b4bc1350646376aa7f3ae33742a7adeb1James Dong 16409c075bca0b75093ca0514a3c8f74d73c8e9e83fdNipun Kwatra return OK; 16419c075bca0b75093ca0514a3c8f74d73c8e9e83fdNipun Kwatra} 16429c075bca0b75093ca0514a3c8f74d73c8e9e83fdNipun Kwatra 16439c075bca0b75093ca0514a3c8f74d73c8e9e83fdNipun Kwatrastatus_t StagefrightRecorder::setupVideoEncoder( 16440d1ed381fde5dac12dd84fcf3da66dac46699378Chih-Hung Hsieh const sp<MediaSource> &cameraSource, 1645d008275796ac4cccf85fefce53cef733a49bc1faWonsik Kim sp<MediaCodecSource> *source) { 16469c075bca0b75093ca0514a3c8f74d73c8e9e83fdNipun Kwatra source->clear(); 1647050b28a593350047845a45a14cc5026221ac1620James Dong 164872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang sp<AMessage> format = new AMessage(); 1649ef9d0cd72e476a4b7556833fb09505a51b626797James Dong 1650934da11c4cc598d3dd3b53726c362bcdcc0fd37fJames Dong switch (mVideoEncoder) { 1651934da11c4cc598d3dd3b53726c362bcdcc0fd37fJames Dong case VIDEO_ENCODER_H263: 165272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang format->setString("mime", MEDIA_MIMETYPE_VIDEO_H263); 1653934da11c4cc598d3dd3b53726c362bcdcc0fd37fJames Dong break; 165465ae665befd929efd1a7d1c9addac41c699f04b2James Dong 1655934da11c4cc598d3dd3b53726c362bcdcc0fd37fJames Dong case VIDEO_ENCODER_MPEG_4_SP: 165672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang format->setString("mime", MEDIA_MIMETYPE_VIDEO_MPEG4); 1657934da11c4cc598d3dd3b53726c362bcdcc0fd37fJames Dong break; 165830ab66297501757d745b9ae10da61adcd891f497Andreas Huber 1659934da11c4cc598d3dd3b53726c362bcdcc0fd37fJames Dong case VIDEO_ENCODER_H264: 166072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang format->setString("mime", MEDIA_MIMETYPE_VIDEO_AVC); 1661934da11c4cc598d3dd3b53726c362bcdcc0fd37fJames Dong break; 166230ab66297501757d745b9ae10da61adcd891f497Andreas Huber 166376dc9c5052741bf0910a23a20c9df6018c4979d8Robert Shih case VIDEO_ENCODER_VP8: 166476dc9c5052741bf0910a23a20c9df6018c4979d8Robert Shih format->setString("mime", MEDIA_MIMETYPE_VIDEO_VP8); 166576dc9c5052741bf0910a23a20c9df6018c4979d8Robert Shih break; 166676dc9c5052741bf0910a23a20c9df6018c4979d8Robert Shih 16679aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim case VIDEO_ENCODER_HEVC: 16689aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim format->setString("mime", MEDIA_MIMETYPE_VIDEO_HEVC); 16699aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim break; 16709aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim 1671934da11c4cc598d3dd3b53726c362bcdcc0fd37fJames Dong default: 1672934da11c4cc598d3dd3b53726c362bcdcc0fd37fJames Dong CHECK(!"Should not be here, unsupported video encoding."); 1673934da11c4cc598d3dd3b53726c362bcdcc0fd37fJames Dong break; 1674934da11c4cc598d3dd3b53726c362bcdcc0fd37fJames Dong } 1675ef9d0cd72e476a4b7556833fb09505a51b626797James Dong 167635cc20b52fdc551b5b0ed1fc32803a56d82e8881Ray Essick // log video mime type for media metrics 167735cc20b52fdc551b5b0ed1fc32803a56d82e8881Ray Essick if (mAnalyticsItem != NULL) { 167835cc20b52fdc551b5b0ed1fc32803a56d82e8881Ray Essick AString videomime; 167935cc20b52fdc551b5b0ed1fc32803a56d82e8881Ray Essick if (format->findString("mime", &videomime)) { 168035cc20b52fdc551b5b0ed1fc32803a56d82e8881Ray Essick mAnalyticsItem->setCString(kRecorderVideoMime, videomime.c_str()); 168135cc20b52fdc551b5b0ed1fc32803a56d82e8881Ray Essick } 168235cc20b52fdc551b5b0ed1fc32803a56d82e8881Ray Essick } 168335cc20b52fdc551b5b0ed1fc32803a56d82e8881Ray Essick 168472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang if (cameraSource != NULL) { 168572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang sp<MetaData> meta = cameraSource->getFormat(); 168630ab66297501757d745b9ae10da61adcd891f497Andreas Huber 168772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang int32_t width, height, stride, sliceHeight, colorFormat; 168872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang CHECK(meta->findInt32(kKeyWidth, &width)); 168972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang CHECK(meta->findInt32(kKeyHeight, &height)); 169072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang CHECK(meta->findInt32(kKeyStride, &stride)); 169172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang CHECK(meta->findInt32(kKeySliceHeight, &sliceHeight)); 169272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang CHECK(meta->findInt32(kKeyColorFormat, &colorFormat)); 169372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 169472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang format->setInt32("width", width); 169572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang format->setInt32("height", height); 169672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang format->setInt32("stride", stride); 169772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang format->setInt32("slice-height", sliceHeight); 169872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang format->setInt32("color-format", colorFormat); 169972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } else { 170072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang format->setInt32("width", mVideoWidth); 170172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang format->setInt32("height", mVideoHeight); 170272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang format->setInt32("stride", mVideoWidth); 1703e62ba9cce4631737e38db1b0d8a7a64ee81cc397xrwu format->setInt32("slice-height", mVideoHeight); 170472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang format->setInt32("color-format", OMX_COLOR_FormatAndroidOpaque); 17052c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang 17062c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang // set up time lapse/slow motion for surface source 170746d26dd29195450db15704e84d65740628a821fbChong Zhang if (mCaptureFpsEnable) { 170822dc508717c7767927064ec7c152def99e54adcbPawin Vongmasa if (!(mCaptureFps > 0.)) { 170922dc508717c7767927064ec7c152def99e54adcbPawin Vongmasa ALOGE("Invalid mCaptureFps value: %lf", mCaptureFps); 17102c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang return BAD_VALUE; 17112c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang } 171222dc508717c7767927064ec7c152def99e54adcbPawin Vongmasa format->setDouble("time-lapse-fps", mCaptureFps); 17132c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang } 171472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 171572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 171672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang format->setInt32("bitrate", mVideoBitRate); 171772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang format->setInt32("frame-rate", mFrameRate); 171872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang format->setInt32("i-frame-interval", mIFramesIntervalSec); 171930ab66297501757d745b9ae10da61adcd891f497Andreas Huber 1720c059860c73678a202bfa33062723e8f82fb779d9James Dong if (mVideoTimeScale > 0) { 172172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang format->setInt32("time-scale", mVideoTimeScale); 1722c059860c73678a202bfa33062723e8f82fb779d9James Dong } 1723145bfe5eb3e08c9689c28f6bf3287a979438b04bJames Dong if (mVideoEncoderProfile != -1) { 172472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang format->setInt32("profile", mVideoEncoderProfile); 1725145bfe5eb3e08c9689c28f6bf3287a979438b04bJames Dong } 1726145bfe5eb3e08c9689c28f6bf3287a979438b04bJames Dong if (mVideoEncoderLevel != -1) { 172772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang format->setInt32("level", mVideoEncoderLevel); 1728145bfe5eb3e08c9689c28f6bf3287a979438b04bJames Dong } 172930ab66297501757d745b9ae10da61adcd891f497Andreas Huber 17302da225766572a3d4746b4e21cb231a0243b114abLajos Molnar uint32_t tsLayers = 1; 1731e19f2956de379b9c9a852d50d83d0608ca42bfe9Lajos Molnar bool preferBFrames = true; // we like B-frames as it produces better quality per bitrate 1732fdbc1b3a885f1e8a59b1788e48e24ea4c66acbc8Ronghua Wu format->setInt32("priority", 0 /* realtime */); 17332da225766572a3d4746b4e21cb231a0243b114abLajos Molnar float maxPlaybackFps = mFrameRate; // assume video is only played back at normal speed 17342da225766572a3d4746b4e21cb231a0243b114abLajos Molnar 173546d26dd29195450db15704e84d65740628a821fbChong Zhang if (mCaptureFpsEnable) { 1736fdbc1b3a885f1e8a59b1788e48e24ea4c66acbc8Ronghua Wu format->setFloat("operating-rate", mCaptureFps); 1737c96cfbe66d7bf261c57ff93984bc6a4b3a58f6fcLajos Molnar 1738c96cfbe66d7bf261c57ff93984bc6a4b3a58f6fcLajos Molnar // enable layering for all time lapse and high frame rate recordings 17392da225766572a3d4746b4e21cb231a0243b114abLajos Molnar if (mFrameRate / mCaptureFps >= 1.9) { // time lapse 1740e19f2956de379b9c9a852d50d83d0608ca42bfe9Lajos Molnar preferBFrames = false; 17412da225766572a3d4746b4e21cb231a0243b114abLajos Molnar tsLayers = 2; // use at least two layers as resulting video will likely be sped up 17422da225766572a3d4746b4e21cb231a0243b114abLajos Molnar } else if (mCaptureFps > maxPlaybackFps) { // slow-mo 17432da225766572a3d4746b4e21cb231a0243b114abLajos Molnar maxPlaybackFps = mCaptureFps; // assume video will be played back at full capture speed 1744e19f2956de379b9c9a852d50d83d0608ca42bfe9Lajos Molnar preferBFrames = false; 17452da225766572a3d4746b4e21cb231a0243b114abLajos Molnar } 17462da225766572a3d4746b4e21cb231a0243b114abLajos Molnar } 1747c96cfbe66d7bf261c57ff93984bc6a4b3a58f6fcLajos Molnar 17482da225766572a3d4746b4e21cb231a0243b114abLajos Molnar for (uint32_t tryLayers = 1; tryLayers <= kMaxNumVideoTemporalLayers; ++tryLayers) { 17492da225766572a3d4746b4e21cb231a0243b114abLajos Molnar if (tryLayers > tsLayers) { 17502da225766572a3d4746b4e21cb231a0243b114abLajos Molnar tsLayers = tryLayers; 1751c96cfbe66d7bf261c57ff93984bc6a4b3a58f6fcLajos Molnar } 17522da225766572a3d4746b4e21cb231a0243b114abLajos Molnar // keep going until the base layer fps falls below the typical display refresh rate 17532da225766572a3d4746b4e21cb231a0243b114abLajos Molnar float baseLayerFps = maxPlaybackFps / (1 << (tryLayers - 1)); 17542da225766572a3d4746b4e21cb231a0243b114abLajos Molnar if (baseLayerFps < kMinTypicalDisplayRefreshingRate / 0.9) { 17552da225766572a3d4746b4e21cb231a0243b114abLajos Molnar break; 17562da225766572a3d4746b4e21cb231a0243b114abLajos Molnar } 17572da225766572a3d4746b4e21cb231a0243b114abLajos Molnar } 17582da225766572a3d4746b4e21cb231a0243b114abLajos Molnar 17592da225766572a3d4746b4e21cb231a0243b114abLajos Molnar if (tsLayers > 1) { 17602da225766572a3d4746b4e21cb231a0243b114abLajos Molnar uint32_t bLayers = std::min(2u, tsLayers - 1); // use up-to 2 B-layers 17612da225766572a3d4746b4e21cb231a0243b114abLajos Molnar uint32_t pLayers = tsLayers - bLayers; 17622da225766572a3d4746b4e21cb231a0243b114abLajos Molnar format->setString( 17632da225766572a3d4746b4e21cb231a0243b114abLajos Molnar "ts-schema", AStringPrintf("android.generic.%u+%u", pLayers, bLayers)); 1764e19f2956de379b9c9a852d50d83d0608ca42bfe9Lajos Molnar 1765e19f2956de379b9c9a852d50d83d0608ca42bfe9Lajos Molnar // TODO: some encoders do not support B-frames with temporal layering, and we have a 1766e19f2956de379b9c9a852d50d83d0608ca42bfe9Lajos Molnar // different preference based on use-case. We could move this into camera profiles. 1767e19f2956de379b9c9a852d50d83d0608ca42bfe9Lajos Molnar format->setInt32("android._prefer-b-frames", preferBFrames); 1768fdbc1b3a885f1e8a59b1788e48e24ea4c66acbc8Ronghua Wu } 1769fdbc1b3a885f1e8a59b1788e48e24ea4c66acbc8Ronghua Wu 17703e328782f1e1061d08ea0c45b855cc418a2d9ea6Lajos Molnar if (mMetaDataStoredInVideoBuffers != kMetadataBufferTypeInvalid) { 17713e328782f1e1061d08ea0c45b855cc418a2d9ea6Lajos Molnar format->setInt32("android._input-metadata-buffer-type", mMetaDataStoredInVideoBuffers); 17728480835b4bc1350646376aa7f3ae33742a7adeb1James Dong } 17737757f5010a771fb8824b6fdf9788f588a1577e3fJames Dong 17743e328782f1e1061d08ea0c45b855cc418a2d9ea6Lajos Molnar uint32_t flags = 0; 177572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang if (cameraSource == NULL) { 177672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang flags |= MediaCodecSource::FLAG_USE_SURFACE_INPUT; 1777b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar } else { 1778b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar // require dataspace setup even if not using surface input 1779b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar format->setInt32("android._using-recorder", 1); 17807757f5010a771fb8824b6fdf9788f588a1577e3fJames Dong } 17817757f5010a771fb8824b6fdf9788f588a1577e3fJames Dong 1782e2a2dfcbf0c9d6bb7139263ecf0d8e53b4ca1049Chong Zhang sp<MediaCodecSource> encoder = MediaCodecSource::Create( 1783e2a2dfcbf0c9d6bb7139263ecf0d8e53b4ca1049Chong Zhang mLooper, format, cameraSource, mPersistentSurface, flags); 1784934da11c4cc598d3dd3b53726c362bcdcc0fd37fJames Dong if (encoder == NULL) { 1785ef0cf50343f8a6d74894f96f5ecb5eec4c5f1bc6Chong Zhang ALOGE("Failed to create video encoder"); 17861cc73922339a110d7ffc47e8842f958492dd85bfJames Dong // When the encoder fails to be created, we need 17871cc73922339a110d7ffc47e8842f958492dd85bfJames Dong // release the camera source due to the camera's lock 17881cc73922339a110d7ffc47e8842f958492dd85bfJames Dong // and unlock mechanism. 178972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang if (cameraSource != NULL) { 179072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang cameraSource->stop(); 179172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 1792934da11c4cc598d3dd3b53726c362bcdcc0fd37fJames Dong return UNKNOWN_ERROR; 1793934da11c4cc598d3dd3b53726c362bcdcc0fd37fJames Dong } 179430ab66297501757d745b9ae10da61adcd891f497Andreas Huber 179572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang if (cameraSource == NULL) { 179672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mGraphicBufferProducer = encoder->getGraphicBufferProducer(); 179772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 179872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 179939ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber *source = encoder; 180039ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 1801934da11c4cc598d3dd3b53726c362bcdcc0fd37fJames Dong return OK; 1802934da11c4cc598d3dd3b53726c362bcdcc0fd37fJames Dong} 180330ab66297501757d745b9ae10da61adcd891f497Andreas Huber 1804934da11c4cc598d3dd3b53726c362bcdcc0fd37fJames Dongstatus_t StagefrightRecorder::setupAudioEncoder(const sp<MediaWriter>& writer) { 180542dd1d5f186252a7f09f8fb1a46ea82e3877b2d3James Dong status_t status = BAD_VALUE; 180642dd1d5f186252a7f09f8fb1a46ea82e3877b2d3James Dong if (OK != (status = checkAudioEncoderCapabilities())) { 180742dd1d5f186252a7f09f8fb1a46ea82e3877b2d3James Dong return status; 180842dd1d5f186252a7f09f8fb1a46ea82e3877b2d3James Dong } 180942dd1d5f186252a7f09f8fb1a46ea82e3877b2d3James Dong 1810934da11c4cc598d3dd3b53726c362bcdcc0fd37fJames Dong switch(mAudioEncoder) { 1811934da11c4cc598d3dd3b53726c362bcdcc0fd37fJames Dong case AUDIO_ENCODER_AMR_NB: 1812934da11c4cc598d3dd3b53726c362bcdcc0fd37fJames Dong case AUDIO_ENCODER_AMR_WB: 1813934da11c4cc598d3dd3b53726c362bcdcc0fd37fJames Dong case AUDIO_ENCODER_AAC: 1814f60c660f048d5f5e2458cff243c20400d73757a7Dave Burke case AUDIO_ENCODER_HE_AAC: 1815aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke case AUDIO_ENCODER_AAC_ELD: 1816934da11c4cc598d3dd3b53726c362bcdcc0fd37fJames Dong break; 181742dd1d5f186252a7f09f8fb1a46ea82e3877b2d3James Dong 1818934da11c4cc598d3dd3b53726c362bcdcc0fd37fJames Dong default: 181929357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("Unsupported audio encoder: %d", mAudioEncoder); 1820934da11c4cc598d3dd3b53726c362bcdcc0fd37fJames Dong return UNKNOWN_ERROR; 1821934da11c4cc598d3dd3b53726c362bcdcc0fd37fJames Dong } 182230ab66297501757d745b9ae10da61adcd891f497Andreas Huber 1823d008275796ac4cccf85fefce53cef733a49bc1faWonsik Kim sp<MediaCodecSource> audioEncoder = createAudioSource(); 1824934da11c4cc598d3dd3b53726c362bcdcc0fd37fJames Dong if (audioEncoder == NULL) { 1825934da11c4cc598d3dd3b53726c362bcdcc0fd37fJames Dong return UNKNOWN_ERROR; 1826934da11c4cc598d3dd3b53726c362bcdcc0fd37fJames Dong } 18278f5f2fcee5c12d08df71d17017410c50951fc2e3James Dong 1828934da11c4cc598d3dd3b53726c362bcdcc0fd37fJames Dong writer->addSource(audioEncoder); 1829d008275796ac4cccf85fefce53cef733a49bc1faWonsik Kim mAudioEncoderSource = audioEncoder; 1830934da11c4cc598d3dd3b53726c362bcdcc0fd37fJames Dong return OK; 1831934da11c4cc598d3dd3b53726c362bcdcc0fd37fJames Dong} 183230ab66297501757d745b9ae10da61adcd891f497Andreas Huber 1833114819633470ebd5b346c13c2a82a0025d2d39c0Robert Shihstatus_t StagefrightRecorder::setupMPEG4orWEBMRecording() { 18344db37cedd4db8230f3ec6191d8d7ba2b0036886eRobert Shih mWriter.clear(); 183572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mTotalBitRate = 0; 183672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 1837934da11c4cc598d3dd3b53726c362bcdcc0fd37fJames Dong status_t err = OK; 1838114819633470ebd5b346c13c2a82a0025d2d39c0Robert Shih sp<MediaWriter> writer; 1839e76dba7af9589d9ed7b116eec3a74168a8352925Chong Zhang sp<MPEG4Writer> mp4writer; 184068e97e7388bc9efa03e56c999645002cc3f38df5Robert Shih if (mOutputFormat == OUTPUT_FORMAT_WEBM) { 1841114819633470ebd5b346c13c2a82a0025d2d39c0Robert Shih writer = new WebmWriter(mOutputFd); 184268e97e7388bc9efa03e56c999645002cc3f38df5Robert Shih } else { 1843e76dba7af9589d9ed7b116eec3a74168a8352925Chong Zhang writer = mp4writer = new MPEG4Writer(mOutputFd); 1844114819633470ebd5b346c13c2a82a0025d2d39c0Robert Shih } 184530ab66297501757d745b9ae10da61adcd891f497Andreas Huber 1846b33f3407bab0970a7f9241680723a1140b177c50Pannag Sanketi if (mVideoSource < VIDEO_SOURCE_LIST_END) { 184754ef1bae010f12dfe6a40ff4452695b1b11ff449Chong Zhang setDefaultVideoEncoderIfNecessary(); 18489c075bca0b75093ca0514a3c8f74d73c8e9e83fdNipun Kwatra 1849b33f3407bab0970a7f9241680723a1140b177c50Pannag Sanketi sp<MediaSource> mediaSource; 18503cecf640c4daf2df616b278bd9986018c8182908James Dong err = setupMediaSource(&mediaSource); 18519c075bca0b75093ca0514a3c8f74d73c8e9e83fdNipun Kwatra if (err != OK) { 18529c075bca0b75093ca0514a3c8f74d73c8e9e83fdNipun Kwatra return err; 18539c075bca0b75093ca0514a3c8f74d73c8e9e83fdNipun Kwatra } 18549c075bca0b75093ca0514a3c8f74d73c8e9e83fdNipun Kwatra 1855d008275796ac4cccf85fefce53cef733a49bc1faWonsik Kim sp<MediaCodecSource> encoder; 18564db37cedd4db8230f3ec6191d8d7ba2b0036886eRobert Shih err = setupVideoEncoder(mediaSource, &encoder); 18579c075bca0b75093ca0514a3c8f74d73c8e9e83fdNipun Kwatra if (err != OK) { 18589c075bca0b75093ca0514a3c8f74d73c8e9e83fdNipun Kwatra return err; 18599c075bca0b75093ca0514a3c8f74d73c8e9e83fdNipun Kwatra } 18609c075bca0b75093ca0514a3c8f74d73c8e9e83fdNipun Kwatra 186139ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber writer->addSource(encoder); 1862d008275796ac4cccf85fefce53cef733a49bc1faWonsik Kim mVideoEncoderSource = encoder; 186372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mTotalBitRate += mVideoBitRate; 186430ab66297501757d745b9ae10da61adcd891f497Andreas Huber } 186530ab66297501757d745b9ae10da61adcd891f497Andreas Huber 186668e97e7388bc9efa03e56c999645002cc3f38df5Robert Shih if (mOutputFormat != OUTPUT_FORMAT_WEBM) { 1867114819633470ebd5b346c13c2a82a0025d2d39c0Robert Shih // Audio source is added at the end if it exists. 1868114819633470ebd5b346c13c2a82a0025d2d39c0Robert Shih // This help make sure that the "recoding" sound is suppressed for 1869114819633470ebd5b346c13c2a82a0025d2d39c0Robert Shih // camcorder applications in the recorded files. 1870114819633470ebd5b346c13c2a82a0025d2d39c0Robert Shih // TODO Audio source is currently unsupported for webm output; vorbis encoder needed. 187146d26dd29195450db15704e84d65740628a821fbChong Zhang // disable audio for time lapse recording 187246d26dd29195450db15704e84d65740628a821fbChong Zhang bool disableAudio = mCaptureFpsEnable && mCaptureFps < mFrameRate; 187346d26dd29195450db15704e84d65740628a821fbChong Zhang if (!disableAudio && mAudioSource != AUDIO_SOURCE_CNT) { 1874114819633470ebd5b346c13c2a82a0025d2d39c0Robert Shih err = setupAudioEncoder(writer); 1875114819633470ebd5b346c13c2a82a0025d2d39c0Robert Shih if (err != OK) return err; 1876114819633470ebd5b346c13c2a82a0025d2d39c0Robert Shih mTotalBitRate += mAudioBitRate; 1877114819633470ebd5b346c13c2a82a0025d2d39c0Robert Shih } 18787bd460110b27a979384dda351788eac95d8467f5James Dong 187946d26dd29195450db15704e84d65740628a821fbChong Zhang if (mCaptureFpsEnable) { 18809ee53a49860e91c2b012883eef09d669a7829e06Chong Zhang mp4writer->setCaptureRate(mCaptureFps); 1881e76dba7af9589d9ed7b116eec3a74168a8352925Chong Zhang } 1882e76dba7af9589d9ed7b116eec3a74168a8352925Chong Zhang 1883114819633470ebd5b346c13c2a82a0025d2d39c0Robert Shih if (mInterleaveDurationUs > 0) { 1884e76dba7af9589d9ed7b116eec3a74168a8352925Chong Zhang mp4writer->setInterleaveDuration(mInterleaveDurationUs); 1885114819633470ebd5b346c13c2a82a0025d2d39c0Robert Shih } 1886114819633470ebd5b346c13c2a82a0025d2d39c0Robert Shih if (mLongitudex10000 > -3600000 && mLatitudex10000 > -3600000) { 1887e76dba7af9589d9ed7b116eec3a74168a8352925Chong Zhang mp4writer->setGeoData(mLatitudex10000, mLongitudex10000); 1888114819633470ebd5b346c13c2a82a0025d2d39c0Robert Shih } 188907b1bb529a1ae76c46a71b01338c166f9490629dJames Dong } 1890d599cd4573b5a2d5914c5040e0565ef866749b77James Dong if (mMaxFileDurationUs != 0) { 1891934da11c4cc598d3dd3b53726c362bcdcc0fd37fJames Dong writer->setMaxFileDuration(mMaxFileDurationUs); 1892d599cd4573b5a2d5914c5040e0565ef866749b77James Dong } 1893d599cd4573b5a2d5914c5040e0565ef866749b77James Dong if (mMaxFileSizeBytes != 0) { 1894934da11c4cc598d3dd3b53726c362bcdcc0fd37fJames Dong writer->setMaxFileSize(mMaxFileSizeBytes); 1895d599cd4573b5a2d5914c5040e0565ef866749b77James Dong } 189672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang if (mVideoSource == VIDEO_SOURCE_DEFAULT 189772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang || mVideoSource == VIDEO_SOURCE_CAMERA) { 189872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mStartTimeOffsetMs = mEncoderProfiles->getStartTimeOffsetMs(mCameraId); 189972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } else if (mVideoSource == VIDEO_SOURCE_SURFACE) { 190072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang // surface source doesn't need large initial delay 19013a5d1e8f18f1ec62962fb0e35eab473a6176d004Hangyu Kuang mStartTimeOffsetMs = 100; 190272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 190386b7f47aa7482424cf8fd248f1315311919be3b0James Dong if (mStartTimeOffsetMs > 0) { 1904114819633470ebd5b346c13c2a82a0025d2d39c0Robert Shih writer->setStartTimeOffsetMs(mStartTimeOffsetMs); 190586b7f47aa7482424cf8fd248f1315311919be3b0James Dong } 190686b7f47aa7482424cf8fd248f1315311919be3b0James Dong 19079c075bca0b75093ca0514a3c8f74d73c8e9e83fdNipun Kwatra writer->setListener(mListener); 19084db37cedd4db8230f3ec6191d8d7ba2b0036886eRobert Shih mWriter = writer; 19099c075bca0b75093ca0514a3c8f74d73c8e9e83fdNipun Kwatra return OK; 19109c075bca0b75093ca0514a3c8f74d73c8e9e83fdNipun Kwatra} 19119c075bca0b75093ca0514a3c8f74d73c8e9e83fdNipun Kwatra 1912114819633470ebd5b346c13c2a82a0025d2d39c0Robert Shihvoid StagefrightRecorder::setupMPEG4orWEBMMetaData(sp<MetaData> *meta) { 191372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang int64_t startTimeUs = systemTime() / 1000; 19149c075bca0b75093ca0514a3c8f74d73c8e9e83fdNipun Kwatra (*meta)->setInt64(kKeyTime, startTimeUs); 19159c075bca0b75093ca0514a3c8f74d73c8e9e83fdNipun Kwatra (*meta)->setInt32(kKeyFileType, mOutputFormat); 191672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang (*meta)->setInt32(kKeyBitRate, mTotalBitRate); 1917c059860c73678a202bfa33062723e8f82fb779d9James Dong if (mMovieTimeScale > 0) { 19189c075bca0b75093ca0514a3c8f74d73c8e9e83fdNipun Kwatra (*meta)->setInt32(kKeyTimeScale, mMovieTimeScale); 1919c059860c73678a202bfa33062723e8f82fb779d9James Dong } 192068e97e7388bc9efa03e56c999645002cc3f38df5Robert Shih if (mOutputFormat != OUTPUT_FORMAT_WEBM) { 1921114819633470ebd5b346c13c2a82a0025d2d39c0Robert Shih (*meta)->setInt32(kKey64BitFileOffset, mUse64BitFileOffset); 1922114819633470ebd5b346c13c2a82a0025d2d39c0Robert Shih if (mTrackEveryTimeDurationUs > 0) { 1923114819633470ebd5b346c13c2a82a0025d2d39c0Robert Shih (*meta)->setInt64(kKeyTrackTimeStatus, mTrackEveryTimeDurationUs); 1924114819633470ebd5b346c13c2a82a0025d2d39c0Robert Shih } 1925114819633470ebd5b346c13c2a82a0025d2d39c0Robert Shih if (mRotationDegrees != 0) { 1926114819633470ebd5b346c13c2a82a0025d2d39c0Robert Shih (*meta)->setInt32(kKeyRotation, mRotationDegrees); 1927114819633470ebd5b346c13c2a82a0025d2d39c0Robert Shih } 192813f6284305e4b27395a23db7882d670bdb1bcae1James Dong } 19299c075bca0b75093ca0514a3c8f74d73c8e9e83fdNipun Kwatra} 19309c075bca0b75093ca0514a3c8f74d73c8e9e83fdNipun Kwatra 1931a7d1a2dd776bf356c228785a94ba8e0ff6a2ec7fJames Dongstatus_t StagefrightRecorder::pause() { 19323856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("pause"); 1933d008275796ac4cccf85fefce53cef733a49bc1faWonsik Kim if (!mStarted) { 1934d008275796ac4cccf85fefce53cef733a49bc1faWonsik Kim return INVALID_OPERATION; 1935a7d1a2dd776bf356c228785a94ba8e0ff6a2ec7fJames Dong } 19369c075bca0b75093ca0514a3c8f74d73c8e9e83fdNipun Kwatra 1937d008275796ac4cccf85fefce53cef733a49bc1faWonsik Kim // Already paused --- no-op. 1938d008275796ac4cccf85fefce53cef733a49bc1faWonsik Kim if (mPauseStartTimeUs != 0) { 1939d008275796ac4cccf85fefce53cef733a49bc1faWonsik Kim return OK; 1940d008275796ac4cccf85fefce53cef733a49bc1faWonsik Kim } 194175b0b5473c7b43f8c5972db7e6e8930988ead751Gloria Wang 1942764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang mPauseStartTimeUs = systemTime() / 1000; 1943764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang sp<MetaData> meta = new MetaData; 1944764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang meta->setInt64(kKeyTime, mPauseStartTimeUs); 1945764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang 194635cc20b52fdc551b5b0ed1fc32803a56d82e8881Ray Essick if (mStartedRecordingUs != 0) { 194735cc20b52fdc551b5b0ed1fc32803a56d82e8881Ray Essick // should always be true 194835cc20b52fdc551b5b0ed1fc32803a56d82e8881Ray Essick int64_t recordingUs = mPauseStartTimeUs - mStartedRecordingUs; 194935cc20b52fdc551b5b0ed1fc32803a56d82e8881Ray Essick mDurationRecordedUs += recordingUs; 195035cc20b52fdc551b5b0ed1fc32803a56d82e8881Ray Essick mStartedRecordingUs = 0; 195135cc20b52fdc551b5b0ed1fc32803a56d82e8881Ray Essick } 195235cc20b52fdc551b5b0ed1fc32803a56d82e8881Ray Essick 1953d008275796ac4cccf85fefce53cef733a49bc1faWonsik Kim if (mAudioEncoderSource != NULL) { 1954d008275796ac4cccf85fefce53cef733a49bc1faWonsik Kim mAudioEncoderSource->pause(); 1955d008275796ac4cccf85fefce53cef733a49bc1faWonsik Kim } 1956d008275796ac4cccf85fefce53cef733a49bc1faWonsik Kim if (mVideoEncoderSource != NULL) { 1957764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang mVideoEncoderSource->pause(meta.get()); 1958d008275796ac4cccf85fefce53cef733a49bc1faWonsik Kim } 195975b0b5473c7b43f8c5972db7e6e8930988ead751Gloria Wang 1960d008275796ac4cccf85fefce53cef733a49bc1faWonsik Kim return OK; 1961d008275796ac4cccf85fefce53cef733a49bc1faWonsik Kim} 1962d008275796ac4cccf85fefce53cef733a49bc1faWonsik Kim 1963d008275796ac4cccf85fefce53cef733a49bc1faWonsik Kimstatus_t StagefrightRecorder::resume() { 1964d008275796ac4cccf85fefce53cef733a49bc1faWonsik Kim ALOGV("resume"); 1965d008275796ac4cccf85fefce53cef733a49bc1faWonsik Kim if (!mStarted) { 1966d008275796ac4cccf85fefce53cef733a49bc1faWonsik Kim return INVALID_OPERATION; 1967d008275796ac4cccf85fefce53cef733a49bc1faWonsik Kim } 1968d008275796ac4cccf85fefce53cef733a49bc1faWonsik Kim 1969d008275796ac4cccf85fefce53cef733a49bc1faWonsik Kim // Not paused --- no-op. 1970d008275796ac4cccf85fefce53cef733a49bc1faWonsik Kim if (mPauseStartTimeUs == 0) { 1971d008275796ac4cccf85fefce53cef733a49bc1faWonsik Kim return OK; 197275b0b5473c7b43f8c5972db7e6e8930988ead751Gloria Wang } 197375b0b5473c7b43f8c5972db7e6e8930988ead751Gloria Wang 1974764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang int64_t resumeStartTimeUs = systemTime() / 1000; 1975764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang 1976a5aeb87eabfda3cb385eed405b843bdcb64252beWonsik Kim int64_t bufferStartTimeUs = 0; 1977a5aeb87eabfda3cb385eed405b843bdcb64252beWonsik Kim bool allSourcesStarted = true; 1978a5aeb87eabfda3cb385eed405b843bdcb64252beWonsik Kim for (const auto &source : { mAudioEncoderSource, mVideoEncoderSource }) { 1979a5aeb87eabfda3cb385eed405b843bdcb64252beWonsik Kim if (source == nullptr) { 1980a5aeb87eabfda3cb385eed405b843bdcb64252beWonsik Kim continue; 1981a5aeb87eabfda3cb385eed405b843bdcb64252beWonsik Kim } 1982a5aeb87eabfda3cb385eed405b843bdcb64252beWonsik Kim int64_t timeUs = source->getFirstSampleSystemTimeUs(); 1983a5aeb87eabfda3cb385eed405b843bdcb64252beWonsik Kim if (timeUs < 0) { 1984a5aeb87eabfda3cb385eed405b843bdcb64252beWonsik Kim allSourcesStarted = false; 1985a5aeb87eabfda3cb385eed405b843bdcb64252beWonsik Kim } 1986a5aeb87eabfda3cb385eed405b843bdcb64252beWonsik Kim if (bufferStartTimeUs < timeUs) { 1987a5aeb87eabfda3cb385eed405b843bdcb64252beWonsik Kim bufferStartTimeUs = timeUs; 1988a5aeb87eabfda3cb385eed405b843bdcb64252beWonsik Kim } 1989a5aeb87eabfda3cb385eed405b843bdcb64252beWonsik Kim } 1990a5aeb87eabfda3cb385eed405b843bdcb64252beWonsik Kim 1991a5aeb87eabfda3cb385eed405b843bdcb64252beWonsik Kim if (allSourcesStarted) { 1992a5aeb87eabfda3cb385eed405b843bdcb64252beWonsik Kim if (mPauseStartTimeUs < bufferStartTimeUs) { 1993a5aeb87eabfda3cb385eed405b843bdcb64252beWonsik Kim mPauseStartTimeUs = bufferStartTimeUs; 1994a5aeb87eabfda3cb385eed405b843bdcb64252beWonsik Kim } 1995a5aeb87eabfda3cb385eed405b843bdcb64252beWonsik Kim // 30 ms buffer to avoid timestamp overlap 1996764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang mTotalPausedDurationUs += resumeStartTimeUs - mPauseStartTimeUs - 30000; 1997a5aeb87eabfda3cb385eed405b843bdcb64252beWonsik Kim } 19989f5c692300e02f9f1b4e08b238a76f1428c854d3Wonsik Kim double timeOffset = -mTotalPausedDurationUs; 19999f5c692300e02f9f1b4e08b238a76f1428c854d3Wonsik Kim if (mCaptureFpsEnable) { 20009f5c692300e02f9f1b4e08b238a76f1428c854d3Wonsik Kim timeOffset *= mCaptureFps / mFrameRate; 20019f5c692300e02f9f1b4e08b238a76f1428c854d3Wonsik Kim } 2002764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang sp<MetaData> meta = new MetaData; 2003764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang meta->setInt64(kKeyTime, resumeStartTimeUs); 2004a5aeb87eabfda3cb385eed405b843bdcb64252beWonsik Kim for (const auto &source : { mAudioEncoderSource, mVideoEncoderSource }) { 2005a5aeb87eabfda3cb385eed405b843bdcb64252beWonsik Kim if (source == nullptr) { 2006a5aeb87eabfda3cb385eed405b843bdcb64252beWonsik Kim continue; 2007a5aeb87eabfda3cb385eed405b843bdcb64252beWonsik Kim } 2008a5aeb87eabfda3cb385eed405b843bdcb64252beWonsik Kim source->setInputBufferTimeOffset((int64_t)timeOffset); 2009764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang source->start(meta.get()); 2010d008275796ac4cccf85fefce53cef733a49bc1faWonsik Kim } 201135cc20b52fdc551b5b0ed1fc32803a56d82e8881Ray Essick 201235cc20b52fdc551b5b0ed1fc32803a56d82e8881Ray Essick 201335cc20b52fdc551b5b0ed1fc32803a56d82e8881Ray Essick // sum info on pause duration 201435cc20b52fdc551b5b0ed1fc32803a56d82e8881Ray Essick // (ignore the 30msec of overlap adjustment factored into mTotalPausedDurationUs) 201535cc20b52fdc551b5b0ed1fc32803a56d82e8881Ray Essick int64_t pausedUs = resumeStartTimeUs - mPauseStartTimeUs; 201635cc20b52fdc551b5b0ed1fc32803a56d82e8881Ray Essick mDurationPausedUs += pausedUs; 201735cc20b52fdc551b5b0ed1fc32803a56d82e8881Ray Essick mNPauses++; 201835cc20b52fdc551b5b0ed1fc32803a56d82e8881Ray Essick // and a timestamp marking that we're back to recording.... 201935cc20b52fdc551b5b0ed1fc32803a56d82e8881Ray Essick mStartedRecordingUs = resumeStartTimeUs; 202035cc20b52fdc551b5b0ed1fc32803a56d82e8881Ray Essick 2021d008275796ac4cccf85fefce53cef733a49bc1faWonsik Kim mPauseStartTimeUs = 0; 202275b0b5473c7b43f8c5972db7e6e8930988ead751Gloria Wang 2023a7d1a2dd776bf356c228785a94ba8e0ff6a2ec7fJames Dong return OK; 2024a7d1a2dd776bf356c228785a94ba8e0ff6a2ec7fJames Dong} 2025a7d1a2dd776bf356c228785a94ba8e0ff6a2ec7fJames Dong 202630ab66297501757d745b9ae10da61adcd891f497Andreas Huberstatus_t StagefrightRecorder::stop() { 20273856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("stop"); 2028fc079f79d8d4f6ef9f138aa615486c10dda99fb7Hangyu Kuang Mutex::Autolock autolock(mLock); 202937187916a486504acaf83bea30147eb5fbf46ae5James Dong status_t err = OK; 20309c075bca0b75093ca0514a3c8f74d73c8e9e83fdNipun Kwatra 203146d26dd29195450db15704e84d65740628a821fbChong Zhang if (mCaptureFpsEnable && mCameraSourceTimeLapse != NULL) { 203278eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra mCameraSourceTimeLapse->startQuickReadReturns(); 203378eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra mCameraSourceTimeLapse = NULL; 203478eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra } 203578eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra 2036f8754cc59cdea9026ee4e1c821a6c362c55da7f8Hangyu Kuang int64_t stopTimeUs = systemTime() / 1000; 2037f8754cc59cdea9026ee4e1c821a6c362c55da7f8Hangyu Kuang for (const auto &source : { mAudioEncoderSource, mVideoEncoderSource }) { 2038f8754cc59cdea9026ee4e1c821a6c362c55da7f8Hangyu Kuang if (source != nullptr && OK != source->setStopTimeUs(stopTimeUs)) { 2039f8754cc59cdea9026ee4e1c821a6c362c55da7f8Hangyu Kuang ALOGW("Failed to set stopTime %lld us for %s", 2040f8754cc59cdea9026ee4e1c821a6c362c55da7f8Hangyu Kuang (long long)stopTimeUs, source->isVideo() ? "Video" : "Audio"); 2041f8754cc59cdea9026ee4e1c821a6c362c55da7f8Hangyu Kuang } 2042764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang } 2043764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang 2044d329e21495eda9dbc531fdd0c26c77f1593ac3f4James Dong if (mWriter != NULL) { 204537187916a486504acaf83bea30147eb5fbf46ae5James Dong err = mWriter->stop(); 2046934da11c4cc598d3dd3b53726c362bcdcc0fd37fJames Dong mWriter.clear(); 204730ab66297501757d745b9ae10da61adcd891f497Andreas Huber } 2048ac4e4189db77dc0af7671b162d11be5ccec69339Ray Essick 204935cc20b52fdc551b5b0ed1fc32803a56d82e8881Ray Essick // account for the last 'segment' -- whether paused or recording 205035cc20b52fdc551b5b0ed1fc32803a56d82e8881Ray Essick if (mPauseStartTimeUs != 0) { 205135cc20b52fdc551b5b0ed1fc32803a56d82e8881Ray Essick // we were paused 205235cc20b52fdc551b5b0ed1fc32803a56d82e8881Ray Essick int64_t additive = stopTimeUs - mPauseStartTimeUs; 205335cc20b52fdc551b5b0ed1fc32803a56d82e8881Ray Essick mDurationPausedUs += additive; 205435cc20b52fdc551b5b0ed1fc32803a56d82e8881Ray Essick mNPauses++; 205535cc20b52fdc551b5b0ed1fc32803a56d82e8881Ray Essick } else if (mStartedRecordingUs != 0) { 205635cc20b52fdc551b5b0ed1fc32803a56d82e8881Ray Essick // we were recording 205735cc20b52fdc551b5b0ed1fc32803a56d82e8881Ray Essick int64_t additive = stopTimeUs - mStartedRecordingUs; 205835cc20b52fdc551b5b0ed1fc32803a56d82e8881Ray Essick mDurationRecordedUs += additive; 205935cc20b52fdc551b5b0ed1fc32803a56d82e8881Ray Essick } else { 206035cc20b52fdc551b5b0ed1fc32803a56d82e8881Ray Essick ALOGW("stop while neither recording nor paused"); 206135cc20b52fdc551b5b0ed1fc32803a56d82e8881Ray Essick } 206235cc20b52fdc551b5b0ed1fc32803a56d82e8881Ray Essick 206335cc20b52fdc551b5b0ed1fc32803a56d82e8881Ray Essick flushAndResetMetrics(true); 2064ac4e4189db77dc0af7671b162d11be5ccec69339Ray Essick 206535cc20b52fdc551b5b0ed1fc32803a56d82e8881Ray Essick mDurationRecordedUs = 0; 206635cc20b52fdc551b5b0ed1fc32803a56d82e8881Ray Essick mDurationPausedUs = 0; 206735cc20b52fdc551b5b0ed1fc32803a56d82e8881Ray Essick mNPauses = 0; 2068148c3d67710ca9353f14e5c37a0a38c88d4f0e53Wonsik Kim mTotalPausedDurationUs = 0; 2069e6cab24fa5857eaf48c957988f153b47a52d1b45Wonsik Kim mPauseStartTimeUs = 0; 207035cc20b52fdc551b5b0ed1fc32803a56d82e8881Ray Essick mStartedRecordingUs = 0; 207130ab66297501757d745b9ae10da61adcd891f497Andreas Huber 207272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mGraphicBufferProducer.clear(); 20738f469e18c307cb9dc0d16ed9225972aa8be4516fChong Zhang mPersistentSurface.clear(); 2074d008275796ac4cccf85fefce53cef733a49bc1faWonsik Kim mAudioEncoderSource.clear(); 2075d008275796ac4cccf85fefce53cef733a49bc1faWonsik Kim mVideoEncoderSource.clear(); 207672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 207725d83125cee222993673d3ba261ae1186bcad8c2James Dong if (mOutputFd >= 0) { 207825d83125cee222993673d3ba261ae1186bcad8c2James Dong ::close(mOutputFd); 207925d83125cee222993673d3ba261ae1186bcad8c2James Dong mOutputFd = -1; 208025d83125cee222993673d3ba261ae1186bcad8c2James Dong } 208125d83125cee222993673d3ba261ae1186bcad8c2James Dong 208275b0b5473c7b43f8c5972db7e6e8930988ead751Gloria Wang if (mStarted) { 208375b0b5473c7b43f8c5972db7e6e8930988ead751Gloria Wang mStarted = false; 208475b0b5473c7b43f8c5972db7e6e8930988ead751Gloria Wang 208575b0b5473c7b43f8c5972db7e6e8930988ead751Gloria Wang uint32_t params = 0; 2086fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin if (mAudioSource != AUDIO_SOURCE_CNT) { 208775b0b5473c7b43f8c5972db7e6e8930988ead751Gloria Wang params |= IMediaPlayerService::kBatteryDataTrackAudio; 208875b0b5473c7b43f8c5972db7e6e8930988ead751Gloria Wang } 208975b0b5473c7b43f8c5972db7e6e8930988ead751Gloria Wang if (mVideoSource != VIDEO_SOURCE_LIST_END) { 209075b0b5473c7b43f8c5972db7e6e8930988ead751Gloria Wang params |= IMediaPlayerService::kBatteryDataTrackVideo; 209175b0b5473c7b43f8c5972db7e6e8930988ead751Gloria Wang } 209275b0b5473c7b43f8c5972db7e6e8930988ead751Gloria Wang 209375b0b5473c7b43f8c5972db7e6e8930988ead751Gloria Wang addBatteryData(params); 209475b0b5473c7b43f8c5972db7e6e8930988ead751Gloria Wang } 209575b0b5473c7b43f8c5972db7e6e8930988ead751Gloria Wang 209637187916a486504acaf83bea30147eb5fbf46ae5James Dong return err; 2097d329e21495eda9dbc531fdd0c26c77f1593ac3f4James Dong} 2098d329e21495eda9dbc531fdd0c26c77f1593ac3f4James Dong 2099d329e21495eda9dbc531fdd0c26c77f1593ac3f4James Dongstatus_t StagefrightRecorder::close() { 21003856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("close"); 2101d329e21495eda9dbc531fdd0c26c77f1593ac3f4James Dong stop(); 2102d329e21495eda9dbc531fdd0c26c77f1593ac3f4James Dong 210330ab66297501757d745b9ae10da61adcd891f497Andreas Huber return OK; 210430ab66297501757d745b9ae10da61adcd891f497Andreas Huber} 210530ab66297501757d745b9ae10da61adcd891f497Andreas Huber 210630ab66297501757d745b9ae10da61adcd891f497Andreas Huberstatus_t StagefrightRecorder::reset() { 21073856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("reset"); 210830ab66297501757d745b9ae10da61adcd891f497Andreas Huber stop(); 210930ab66297501757d745b9ae10da61adcd891f497Andreas Huber 2110050b28a593350047845a45a14cc5026221ac1620James Dong // No audio or video source by default 2111174e1094a41828111c86793232d9492ab8e29395Kevin Rocard mAudioSource = (audio_source_t)AUDIO_SOURCE_CNT; // reset to invalid value 211230ab66297501757d745b9ae10da61adcd891f497Andreas Huber mVideoSource = VIDEO_SOURCE_LIST_END; 2113050b28a593350047845a45a14cc5026221ac1620James Dong 2114050b28a593350047845a45a14cc5026221ac1620James Dong // Default parameters 2115050b28a593350047845a45a14cc5026221ac1620James Dong mOutputFormat = OUTPUT_FORMAT_THREE_GPP; 2116050b28a593350047845a45a14cc5026221ac1620James Dong mAudioEncoder = AUDIO_ENCODER_AMR_NB; 211754ef1bae010f12dfe6a40ff4452695b1b11ff449Chong Zhang mVideoEncoder = VIDEO_ENCODER_DEFAULT; 2118050b28a593350047845a45a14cc5026221ac1620James Dong mVideoWidth = 176; 2119050b28a593350047845a45a14cc5026221ac1620James Dong mVideoHeight = 144; 2120635730831e08c32a5fe7c59125e0919b7e7899cdJames Dong mFrameRate = -1; 2121050b28a593350047845a45a14cc5026221ac1620James Dong mVideoBitRate = 192000; 2122050b28a593350047845a45a14cc5026221ac1620James Dong mSampleRate = 8000; 2123050b28a593350047845a45a14cc5026221ac1620James Dong mAudioChannels = 1; 2124050b28a593350047845a45a14cc5026221ac1620James Dong mAudioBitRate = 12200; 2125e136c3bb38e88315bf8797a464ebf2c788296b22James Dong mInterleaveDurationUs = 0; 21268f5f2fcee5c12d08df71d17017410c50951fc2e3James Dong mIFramesIntervalSec = 1; 2127d3d4e5069e1af0437c4f5a7b4ba344bda5b937afJames Dong mAudioSourceNode = 0; 21282dec2b5be2056c6d9428897dc672185872d30d17James Dong mUse64BitFileOffset = false; 2129c059860c73678a202bfa33062723e8f82fb779d9James Dong mMovieTimeScale = -1; 2130c059860c73678a202bfa33062723e8f82fb779d9James Dong mAudioTimeScale = -1; 2131c059860c73678a202bfa33062723e8f82fb779d9James Dong mVideoTimeScale = -1; 213293d6b102a13afa23bfa80d74c399d93d542e6ad6James Dong mCameraId = 0; 213386b7f47aa7482424cf8fd248f1315311919be3b0James Dong mStartTimeOffsetMs = -1; 2134145bfe5eb3e08c9689c28f6bf3287a979438b04bJames Dong mVideoEncoderProfile = -1; 2135145bfe5eb3e08c9689c28f6bf3287a979438b04bJames Dong mVideoEncoderLevel = -1; 2136145bfe5eb3e08c9689c28f6bf3287a979438b04bJames Dong mMaxFileDurationUs = 0; 2137145bfe5eb3e08c9689c28f6bf3287a979438b04bJames Dong mMaxFileSizeBytes = 0; 213893d6b102a13afa23bfa80d74c399d93d542e6ad6James Dong mTrackEveryTimeDurationUs = 0; 213946d26dd29195450db15704e84d65740628a821fbChong Zhang mCaptureFpsEnable = false; 214022dc508717c7767927064ec7c152def99e54adcbPawin Vongmasa mCaptureFps = -1.0; 214178eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra mCameraSourceTimeLapse = NULL; 21423e328782f1e1061d08ea0c45b855cc418a2d9ea6Lajos Molnar mMetaDataStoredInVideoBuffers = kMetadataBufferTypeInvalid; 214399c2a076b4a46762a22bbb4dfbd51d107e0532d9James Dong mEncoderProfiles = MediaProfiles::getInstance(); 214462db7db731c47a00ee1493e94f3e1d953c6e297aJames Dong mRotationDegrees = 0; 214507b1bb529a1ae76c46a71b01338c166f9490629dJames Dong mLatitudex10000 = -3600000; 214607b1bb529a1ae76c46a71b01338c166f9490629dJames Dong mLongitudex10000 = -3600000; 214772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mTotalBitRate = 0; 2148050b28a593350047845a45a14cc5026221ac1620James Dong 214935cc20b52fdc551b5b0ed1fc32803a56d82e8881Ray Essick // tracking how long we recorded. 215035cc20b52fdc551b5b0ed1fc32803a56d82e8881Ray Essick mDurationRecordedUs = 0; 215135cc20b52fdc551b5b0ed1fc32803a56d82e8881Ray Essick mStartedRecordingUs = 0; 215235cc20b52fdc551b5b0ed1fc32803a56d82e8881Ray Essick mDurationPausedUs = 0; 215335cc20b52fdc551b5b0ed1fc32803a56d82e8881Ray Essick mNPauses = 0; 215435cc20b52fdc551b5b0ed1fc32803a56d82e8881Ray Essick 215530ab66297501757d745b9ae10da61adcd891f497Andreas Huber mOutputFd = -1; 215630ab66297501757d745b9ae10da61adcd891f497Andreas Huber 215730ab66297501757d745b9ae10da61adcd891f497Andreas Huber return OK; 215830ab66297501757d745b9ae10da61adcd891f497Andreas Huber} 215930ab66297501757d745b9ae10da61adcd891f497Andreas Huber 216030ab66297501757d745b9ae10da61adcd891f497Andreas Huberstatus_t StagefrightRecorder::getMaxAmplitude(int *max) { 21613856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("getMaxAmplitude"); 2162d329e21495eda9dbc531fdd0c26c77f1593ac3f4James Dong 2163d329e21495eda9dbc531fdd0c26c77f1593ac3f4James Dong if (max == NULL) { 216429357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("Null pointer argument"); 2165d329e21495eda9dbc531fdd0c26c77f1593ac3f4James Dong return BAD_VALUE; 2166d329e21495eda9dbc531fdd0c26c77f1593ac3f4James Dong } 2167d329e21495eda9dbc531fdd0c26c77f1593ac3f4James Dong 2168d3d4e5069e1af0437c4f5a7b4ba344bda5b937afJames Dong if (mAudioSourceNode != 0) { 2169d3d4e5069e1af0437c4f5a7b4ba344bda5b937afJames Dong *max = mAudioSourceNode->getMaxAmplitude(); 2170d3d4e5069e1af0437c4f5a7b4ba344bda5b937afJames Dong } else { 2171d3d4e5069e1af0437c4f5a7b4ba344bda5b937afJames Dong *max = 0; 2172d3d4e5069e1af0437c4f5a7b4ba344bda5b937afJames Dong } 21732dce41ad26cb3e9e15c9e456a84bcf5309548ca0Andreas Huber 21742dce41ad26cb3e9e15c9e456a84bcf5309548ca0Andreas Huber return OK; 217530ab66297501757d745b9ae10da61adcd891f497Andreas Huber} 217630ab66297501757d745b9ae10da61adcd891f497Andreas Huber 2177ac4e4189db77dc0af7671b162d11be5ccec69339Ray Essickstatus_t StagefrightRecorder::getMetrics(Parcel *reply) { 2178ac4e4189db77dc0af7671b162d11be5ccec69339Ray Essick ALOGD("StagefrightRecorder::getMetrics"); 2179ac4e4189db77dc0af7671b162d11be5ccec69339Ray Essick 2180ac4e4189db77dc0af7671b162d11be5ccec69339Ray Essick if (reply == NULL) { 2181ac4e4189db77dc0af7671b162d11be5ccec69339Ray Essick ALOGE("Null pointer argument"); 2182ac4e4189db77dc0af7671b162d11be5ccec69339Ray Essick return BAD_VALUE; 2183ac4e4189db77dc0af7671b162d11be5ccec69339Ray Essick } 2184ac4e4189db77dc0af7671b162d11be5ccec69339Ray Essick 2185ac4e4189db77dc0af7671b162d11be5ccec69339Ray Essick if (mAnalyticsItem == NULL) { 2186ac4e4189db77dc0af7671b162d11be5ccec69339Ray Essick return UNKNOWN_ERROR; 2187ac4e4189db77dc0af7671b162d11be5ccec69339Ray Essick } 2188ac4e4189db77dc0af7671b162d11be5ccec69339Ray Essick 2189ac4e4189db77dc0af7671b162d11be5ccec69339Ray Essick updateMetrics(); 2190ac4e4189db77dc0af7671b162d11be5ccec69339Ray Essick mAnalyticsItem->writeToParcel(reply); 2191ac4e4189db77dc0af7671b162d11be5ccec69339Ray Essick return OK; 2192ac4e4189db77dc0af7671b162d11be5ccec69339Ray Essick} 2193ac4e4189db77dc0af7671b162d11be5ccec69339Ray Essick 2194fec2f93fae282ad10bbb5e3fcce9f60eff2cfb48jiabinstatus_t StagefrightRecorder::setInputDevice(audio_port_handle_t deviceId) { 2195fec2f93fae282ad10bbb5e3fcce9f60eff2cfb48jiabin ALOGV("setInputDevice"); 2196fec2f93fae282ad10bbb5e3fcce9f60eff2cfb48jiabin 2197fec2f93fae282ad10bbb5e3fcce9f60eff2cfb48jiabin if (mSelectedDeviceId != deviceId) { 2198fec2f93fae282ad10bbb5e3fcce9f60eff2cfb48jiabin mSelectedDeviceId = deviceId; 2199fec2f93fae282ad10bbb5e3fcce9f60eff2cfb48jiabin if (mAudioSourceNode != 0) { 2200fec2f93fae282ad10bbb5e3fcce9f60eff2cfb48jiabin return mAudioSourceNode->setInputDevice(deviceId); 2201fec2f93fae282ad10bbb5e3fcce9f60eff2cfb48jiabin } 2202fec2f93fae282ad10bbb5e3fcce9f60eff2cfb48jiabin } 2203fec2f93fae282ad10bbb5e3fcce9f60eff2cfb48jiabin return NO_ERROR; 2204fec2f93fae282ad10bbb5e3fcce9f60eff2cfb48jiabin} 2205fec2f93fae282ad10bbb5e3fcce9f60eff2cfb48jiabin 2206fec2f93fae282ad10bbb5e3fcce9f60eff2cfb48jiabinstatus_t StagefrightRecorder::getRoutedDeviceId(audio_port_handle_t* deviceId) { 2207fec2f93fae282ad10bbb5e3fcce9f60eff2cfb48jiabin ALOGV("getRoutedDeviceId"); 2208fec2f93fae282ad10bbb5e3fcce9f60eff2cfb48jiabin 2209fec2f93fae282ad10bbb5e3fcce9f60eff2cfb48jiabin if (mAudioSourceNode != 0) { 2210fec2f93fae282ad10bbb5e3fcce9f60eff2cfb48jiabin status_t status = mAudioSourceNode->getRoutedDeviceId(deviceId); 2211fec2f93fae282ad10bbb5e3fcce9f60eff2cfb48jiabin return status; 2212fec2f93fae282ad10bbb5e3fcce9f60eff2cfb48jiabin } 2213fec2f93fae282ad10bbb5e3fcce9f60eff2cfb48jiabin return NO_INIT; 2214fec2f93fae282ad10bbb5e3fcce9f60eff2cfb48jiabin} 2215fec2f93fae282ad10bbb5e3fcce9f60eff2cfb48jiabin 2216fec2f93fae282ad10bbb5e3fcce9f60eff2cfb48jiabinvoid StagefrightRecorder::setAudioDeviceCallback( 2217fec2f93fae282ad10bbb5e3fcce9f60eff2cfb48jiabin const sp<AudioSystem::AudioDeviceCallback>& callback) { 2218fec2f93fae282ad10bbb5e3fcce9f60eff2cfb48jiabin mAudioDeviceCallback = callback; 2219fec2f93fae282ad10bbb5e3fcce9f60eff2cfb48jiabin} 2220fec2f93fae282ad10bbb5e3fcce9f60eff2cfb48jiabin 2221fec2f93fae282ad10bbb5e3fcce9f60eff2cfb48jiabinstatus_t StagefrightRecorder::enableAudioDeviceCallback(bool enabled) { 2222fec2f93fae282ad10bbb5e3fcce9f60eff2cfb48jiabin mDeviceCallbackEnabled = enabled; 2223fec2f93fae282ad10bbb5e3fcce9f60eff2cfb48jiabin sp<AudioSystem::AudioDeviceCallback> callback = mAudioDeviceCallback.promote(); 2224fec2f93fae282ad10bbb5e3fcce9f60eff2cfb48jiabin if (mAudioSourceNode != 0 && callback != 0) { 2225fec2f93fae282ad10bbb5e3fcce9f60eff2cfb48jiabin if (enabled) { 2226fec2f93fae282ad10bbb5e3fcce9f60eff2cfb48jiabin return mAudioSourceNode->addAudioDeviceCallback(callback); 2227fec2f93fae282ad10bbb5e3fcce9f60eff2cfb48jiabin } else { 2228fec2f93fae282ad10bbb5e3fcce9f60eff2cfb48jiabin return mAudioSourceNode->removeAudioDeviceCallback(callback); 2229fec2f93fae282ad10bbb5e3fcce9f60eff2cfb48jiabin } 2230fec2f93fae282ad10bbb5e3fcce9f60eff2cfb48jiabin } 2231fec2f93fae282ad10bbb5e3fcce9f60eff2cfb48jiabin return NO_ERROR; 2232fec2f93fae282ad10bbb5e3fcce9f60eff2cfb48jiabin} 2233fec2f93fae282ad10bbb5e3fcce9f60eff2cfb48jiabin 2234609850df59219845a8c4ebe18a2687447ea570ccjiabinstatus_t StagefrightRecorder::getActiveMicrophones( 2235609850df59219845a8c4ebe18a2687447ea570ccjiabin std::vector<media::MicrophoneInfo>* activeMicrophones) { 2236609850df59219845a8c4ebe18a2687447ea570ccjiabin if (mAudioSourceNode != 0) { 2237609850df59219845a8c4ebe18a2687447ea570ccjiabin return mAudioSourceNode->getActiveMicrophones(activeMicrophones); 2238609850df59219845a8c4ebe18a2687447ea570ccjiabin } 2239609850df59219845a8c4ebe18a2687447ea570ccjiabin return NO_INIT; 2240609850df59219845a8c4ebe18a2687447ea570ccjiabin} 2241609850df59219845a8c4ebe18a2687447ea570ccjiabin 2242609850df59219845a8c4ebe18a2687447ea570ccjiabin 2243dedf414d3fe2e79ee0aad0f1c82ca16ebd886ff6James Dongstatus_t StagefrightRecorder::dump( 2244dedf414d3fe2e79ee0aad0f1c82ca16ebd886ff6James Dong int fd, const Vector<String16>& args) const { 22453856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("dump"); 2246fc079f79d8d4f6ef9f138aa615486c10dda99fb7Hangyu Kuang Mutex::Autolock autolock(mLock); 2247b914122eb9cb54bbeae4ec03bfebb194aecdccbdJames Dong const size_t SIZE = 256; 2248b914122eb9cb54bbeae4ec03bfebb194aecdccbdJames Dong char buffer[SIZE]; 2249b914122eb9cb54bbeae4ec03bfebb194aecdccbdJames Dong String8 result; 2250dedf414d3fe2e79ee0aad0f1c82ca16ebd886ff6James Dong if (mWriter != 0) { 2251dedf414d3fe2e79ee0aad0f1c82ca16ebd886ff6James Dong mWriter->dump(fd, args); 2252dedf414d3fe2e79ee0aad0f1c82ca16ebd886ff6James Dong } else { 2253dedf414d3fe2e79ee0aad0f1c82ca16ebd886ff6James Dong snprintf(buffer, SIZE, " No file writer\n"); 2254dedf414d3fe2e79ee0aad0f1c82ca16ebd886ff6James Dong result.append(buffer); 2255dedf414d3fe2e79ee0aad0f1c82ca16ebd886ff6James Dong } 2256dedf414d3fe2e79ee0aad0f1c82ca16ebd886ff6James Dong snprintf(buffer, SIZE, " Recorder: %p\n", this); 2257b914122eb9cb54bbeae4ec03bfebb194aecdccbdJames Dong snprintf(buffer, SIZE, " Output file (fd %d):\n", mOutputFd); 2258b914122eb9cb54bbeae4ec03bfebb194aecdccbdJames Dong result.append(buffer); 2259b914122eb9cb54bbeae4ec03bfebb194aecdccbdJames Dong snprintf(buffer, SIZE, " File format: %d\n", mOutputFormat); 2260b914122eb9cb54bbeae4ec03bfebb194aecdccbdJames Dong result.append(buffer); 2261377b2ec9a2885f9b6405b07ba900a9e3f4349c38Kévin PETIT snprintf(buffer, SIZE, " Max file size (bytes): %" PRId64 "\n", mMaxFileSizeBytes); 2262b914122eb9cb54bbeae4ec03bfebb194aecdccbdJames Dong result.append(buffer); 2263377b2ec9a2885f9b6405b07ba900a9e3f4349c38Kévin PETIT snprintf(buffer, SIZE, " Max file duration (us): %" PRId64 "\n", mMaxFileDurationUs); 2264b914122eb9cb54bbeae4ec03bfebb194aecdccbdJames Dong result.append(buffer); 2265b914122eb9cb54bbeae4ec03bfebb194aecdccbdJames Dong snprintf(buffer, SIZE, " File offset length (bits): %d\n", mUse64BitFileOffset? 64: 32); 2266b914122eb9cb54bbeae4ec03bfebb194aecdccbdJames Dong result.append(buffer); 2267b914122eb9cb54bbeae4ec03bfebb194aecdccbdJames Dong snprintf(buffer, SIZE, " Interleave duration (us): %d\n", mInterleaveDurationUs); 2268b914122eb9cb54bbeae4ec03bfebb194aecdccbdJames Dong result.append(buffer); 2269377b2ec9a2885f9b6405b07ba900a9e3f4349c38Kévin PETIT snprintf(buffer, SIZE, " Progress notification: %" PRId64 " us\n", mTrackEveryTimeDurationUs); 2270b914122eb9cb54bbeae4ec03bfebb194aecdccbdJames Dong result.append(buffer); 2271b914122eb9cb54bbeae4ec03bfebb194aecdccbdJames Dong snprintf(buffer, SIZE, " Audio\n"); 2272b914122eb9cb54bbeae4ec03bfebb194aecdccbdJames Dong result.append(buffer); 2273b914122eb9cb54bbeae4ec03bfebb194aecdccbdJames Dong snprintf(buffer, SIZE, " Source: %d\n", mAudioSource); 2274b914122eb9cb54bbeae4ec03bfebb194aecdccbdJames Dong result.append(buffer); 2275b914122eb9cb54bbeae4ec03bfebb194aecdccbdJames Dong snprintf(buffer, SIZE, " Encoder: %d\n", mAudioEncoder); 2276b914122eb9cb54bbeae4ec03bfebb194aecdccbdJames Dong result.append(buffer); 2277b914122eb9cb54bbeae4ec03bfebb194aecdccbdJames Dong snprintf(buffer, SIZE, " Bit rate (bps): %d\n", mAudioBitRate); 2278b914122eb9cb54bbeae4ec03bfebb194aecdccbdJames Dong result.append(buffer); 2279b914122eb9cb54bbeae4ec03bfebb194aecdccbdJames Dong snprintf(buffer, SIZE, " Sampling rate (hz): %d\n", mSampleRate); 2280b914122eb9cb54bbeae4ec03bfebb194aecdccbdJames Dong result.append(buffer); 2281b914122eb9cb54bbeae4ec03bfebb194aecdccbdJames Dong snprintf(buffer, SIZE, " Number of channels: %d\n", mAudioChannels); 2282b914122eb9cb54bbeae4ec03bfebb194aecdccbdJames Dong result.append(buffer); 2283b914122eb9cb54bbeae4ec03bfebb194aecdccbdJames Dong snprintf(buffer, SIZE, " Max amplitude: %d\n", mAudioSourceNode == 0? 0: mAudioSourceNode->getMaxAmplitude()); 2284b914122eb9cb54bbeae4ec03bfebb194aecdccbdJames Dong result.append(buffer); 2285b914122eb9cb54bbeae4ec03bfebb194aecdccbdJames Dong snprintf(buffer, SIZE, " Video\n"); 2286b914122eb9cb54bbeae4ec03bfebb194aecdccbdJames Dong result.append(buffer); 2287b914122eb9cb54bbeae4ec03bfebb194aecdccbdJames Dong snprintf(buffer, SIZE, " Source: %d\n", mVideoSource); 2288b914122eb9cb54bbeae4ec03bfebb194aecdccbdJames Dong result.append(buffer); 2289b914122eb9cb54bbeae4ec03bfebb194aecdccbdJames Dong snprintf(buffer, SIZE, " Camera Id: %d\n", mCameraId); 2290b914122eb9cb54bbeae4ec03bfebb194aecdccbdJames Dong result.append(buffer); 229186b7f47aa7482424cf8fd248f1315311919be3b0James Dong snprintf(buffer, SIZE, " Start time offset (ms): %d\n", mStartTimeOffsetMs); 229286b7f47aa7482424cf8fd248f1315311919be3b0James Dong result.append(buffer); 2293b914122eb9cb54bbeae4ec03bfebb194aecdccbdJames Dong snprintf(buffer, SIZE, " Encoder: %d\n", mVideoEncoder); 2294b914122eb9cb54bbeae4ec03bfebb194aecdccbdJames Dong result.append(buffer); 2295b914122eb9cb54bbeae4ec03bfebb194aecdccbdJames Dong snprintf(buffer, SIZE, " Encoder profile: %d\n", mVideoEncoderProfile); 2296b914122eb9cb54bbeae4ec03bfebb194aecdccbdJames Dong result.append(buffer); 2297b914122eb9cb54bbeae4ec03bfebb194aecdccbdJames Dong snprintf(buffer, SIZE, " Encoder level: %d\n", mVideoEncoderLevel); 2298b914122eb9cb54bbeae4ec03bfebb194aecdccbdJames Dong result.append(buffer); 22998f5f2fcee5c12d08df71d17017410c50951fc2e3James Dong snprintf(buffer, SIZE, " I frames interval (s): %d\n", mIFramesIntervalSec); 2300b914122eb9cb54bbeae4ec03bfebb194aecdccbdJames Dong result.append(buffer); 2301b914122eb9cb54bbeae4ec03bfebb194aecdccbdJames Dong snprintf(buffer, SIZE, " Frame size (pixels): %dx%d\n", mVideoWidth, mVideoHeight); 2302b914122eb9cb54bbeae4ec03bfebb194aecdccbdJames Dong result.append(buffer); 2303b914122eb9cb54bbeae4ec03bfebb194aecdccbdJames Dong snprintf(buffer, SIZE, " Frame rate (fps): %d\n", mFrameRate); 2304b914122eb9cb54bbeae4ec03bfebb194aecdccbdJames Dong result.append(buffer); 2305b914122eb9cb54bbeae4ec03bfebb194aecdccbdJames Dong snprintf(buffer, SIZE, " Bit rate (bps): %d\n", mVideoBitRate); 2306b914122eb9cb54bbeae4ec03bfebb194aecdccbdJames Dong result.append(buffer); 2307b914122eb9cb54bbeae4ec03bfebb194aecdccbdJames Dong ::write(fd, result.string(), result.size()); 2308b914122eb9cb54bbeae4ec03bfebb194aecdccbdJames Dong return OK; 2309b914122eb9cb54bbeae4ec03bfebb194aecdccbdJames Dong} 231030ab66297501757d745b9ae10da61adcd891f497Andreas Huber} // namespace android 2311