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" 1930ab66297501757d745b9ae10da61adcd891f497Andreas Huber#include <utils/Log.h> 2030ab66297501757d745b9ae10da61adcd891f497Andreas Huber 2130ab66297501757d745b9ae10da61adcd891f497Andreas Huber#include "StagefrightRecorder.h" 2230ab66297501757d745b9ae10da61adcd891f497Andreas Huber 2375b0b5473c7b43f8c5972db7e6e8930988ead751Gloria Wang#include <binder/IPCThreadState.h> 2475b0b5473c7b43f8c5972db7e6e8930988ead751Gloria Wang#include <binder/IServiceManager.h> 2575b0b5473c7b43f8c5972db7e6e8930988ead751Gloria Wang 2675b0b5473c7b43f8c5972db7e6e8930988ead751Gloria Wang#include <media/IMediaPlayerService.h> 27aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke#include <media/openmax/OMX_Audio.h> 28f1d5aa162c02a16b7195a43a9bcea4d592600ac4James Dong#include <media/stagefright/foundation/ADebug.h> 292dce41ad26cb3e9e15c9e456a84bcf5309548ca0Andreas Huber#include <media/stagefright/AudioSource.h> 302dce41ad26cb3e9e15c9e456a84bcf5309548ca0Andreas Huber#include <media/stagefright/AMRWriter.h> 31760943b5e7a09b602aba04ec451e97662f48b0a4James Dong#include <media/stagefright/AACWriter.h> 3230ab66297501757d745b9ae10da61adcd891f497Andreas Huber#include <media/stagefright/CameraSource.h> 3365e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra#include <media/stagefright/CameraSourceTimeLapse.h> 3459b7dc39ea8332d3418a599e51447d7edb612ac4Andreas Huber#include <media/stagefright/MPEG2TSWriter.h> 3530ab66297501757d745b9ae10da61adcd891f497Andreas Huber#include <media/stagefright/MPEG4Writer.h> 3630ab66297501757d745b9ae10da61adcd891f497Andreas Huber#include <media/stagefright/MediaDefs.h> 3730ab66297501757d745b9ae10da61adcd891f497Andreas Huber#include <media/stagefright/MetaData.h> 3830ab66297501757d745b9ae10da61adcd891f497Andreas Huber#include <media/stagefright/OMXClient.h> 3930ab66297501757d745b9ae10da61adcd891f497Andreas Huber#include <media/stagefright/OMXCodec.h> 40b33f3407bab0970a7f9241680723a1140b177c50Pannag Sanketi#include <media/stagefright/SurfaceMediaSource.h> 4199c2a076b4a46762a22bbb4dfbd51d107e0532d9James Dong#include <media/MediaProfiles.h> 423cf613507f1e2f7bd932d921a6e222e426fd3be4Mathias Agopian#include <camera/ICamera.h> 43ef9d0cd72e476a4b7556833fb09505a51b626797James Dong#include <camera/CameraParameters.h> 44df712ea86e6350f7005a02ab0e1c60c28a343ed0Mathias Agopian#include <gui/Surface.h> 45b33f3407bab0970a7f9241680723a1140b177c50Pannag Sanketi 4630ab66297501757d745b9ae10da61adcd891f497Andreas Huber#include <utils/Errors.h> 47c32cd79d9ad4aba7d959b5b3be7361b4715e6f18James Dong#include <sys/types.h> 48050b28a593350047845a45a14cc5026221ac1620James Dong#include <ctype.h> 49ca2fa61ef03cac008ea86e6fe16b2e5f9f1a2be3Nipun Kwatra#include <unistd.h> 5030ab66297501757d745b9ae10da61adcd891f497Andreas Huber 5164760240f931714858a59c1579f07264d7182ba2Dima Zavin#include <system/audio.h> 52fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin 5339ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber#include "ARTPWriter.h" 5439ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 5530ab66297501757d745b9ae10da61adcd891f497Andreas Hubernamespace android { 5630ab66297501757d745b9ae10da61adcd891f497Andreas Huber 5775b0b5473c7b43f8c5972db7e6e8930988ead751Gloria Wang// To collect the encoder usage for the battery app 5875b0b5473c7b43f8c5972db7e6e8930988ead751Gloria Wangstatic void addBatteryData(uint32_t params) { 5975b0b5473c7b43f8c5972db7e6e8930988ead751Gloria Wang sp<IBinder> binder = 6075b0b5473c7b43f8c5972db7e6e8930988ead751Gloria Wang defaultServiceManager()->getService(String16("media.player")); 6175b0b5473c7b43f8c5972db7e6e8930988ead751Gloria Wang sp<IMediaPlayerService> service = interface_cast<IMediaPlayerService>(binder); 6275b0b5473c7b43f8c5972db7e6e8930988ead751Gloria Wang CHECK(service.get() != NULL); 6375b0b5473c7b43f8c5972db7e6e8930988ead751Gloria Wang 6475b0b5473c7b43f8c5972db7e6e8930988ead751Gloria Wang service->addBatteryData(params); 6575b0b5473c7b43f8c5972db7e6e8930988ead751Gloria Wang} 6675b0b5473c7b43f8c5972db7e6e8930988ead751Gloria Wang 6775b0b5473c7b43f8c5972db7e6e8930988ead751Gloria Wang 68d329e21495eda9dbc531fdd0c26c77f1593ac3f4James DongStagefrightRecorder::StagefrightRecorder() 693cecf640c4daf2df616b278bd9986018c8182908James Dong : mWriter(NULL), 703cecf640c4daf2df616b278bd9986018c8182908James Dong mOutputFd(-1), 71fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin mAudioSource(AUDIO_SOURCE_CNT), 7275b0b5473c7b43f8c5972db7e6e8930988ead751Gloria Wang mVideoSource(VIDEO_SOURCE_LIST_END), 73b33f3407bab0970a7f9241680723a1140b177c50Pannag Sanketi mStarted(false), mSurfaceMediaSource(NULL) { 74d329e21495eda9dbc531fdd0c26c77f1593ac3f4James Dong 753856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("Constructor"); 7630ab66297501757d745b9ae10da61adcd891f497Andreas Huber reset(); 7730ab66297501757d745b9ae10da61adcd891f497Andreas Huber} 7830ab66297501757d745b9ae10da61adcd891f497Andreas Huber 7930ab66297501757d745b9ae10da61adcd891f497Andreas HuberStagefrightRecorder::~StagefrightRecorder() { 803856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("Destructor"); 8130ab66297501757d745b9ae10da61adcd891f497Andreas Huber stop(); 8230ab66297501757d745b9ae10da61adcd891f497Andreas Huber} 8330ab66297501757d745b9ae10da61adcd891f497Andreas Huber 8430ab66297501757d745b9ae10da61adcd891f497Andreas Huberstatus_t StagefrightRecorder::init() { 853856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("init"); 8630ab66297501757d745b9ae10da61adcd891f497Andreas Huber return OK; 8730ab66297501757d745b9ae10da61adcd891f497Andreas Huber} 8830ab66297501757d745b9ae10da61adcd891f497Andreas Huber 89b33f3407bab0970a7f9241680723a1140b177c50Pannag Sanketi// The client side of mediaserver asks it to creat a SurfaceMediaSource 90b33f3407bab0970a7f9241680723a1140b177c50Pannag Sanketi// and return a interface reference. The client side will use that 91b33f3407bab0970a7f9241680723a1140b177c50Pannag Sanketi// while encoding GL Frames 92b33f3407bab0970a7f9241680723a1140b177c50Pannag Sanketisp<ISurfaceTexture> StagefrightRecorder::querySurfaceMediaSource() const { 933856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("Get SurfaceMediaSource"); 94bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam return mSurfaceMediaSource->getBufferQueue(); 95b33f3407bab0970a7f9241680723a1140b177c50Pannag Sanketi} 96b33f3407bab0970a7f9241680723a1140b177c50Pannag Sanketi 97fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavinstatus_t StagefrightRecorder::setAudioSource(audio_source_t as) { 983856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("setAudioSource: %d", as); 99d329e21495eda9dbc531fdd0c26c77f1593ac3f4James Dong if (as < AUDIO_SOURCE_DEFAULT || 100fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin as >= AUDIO_SOURCE_CNT) { 10129357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("Invalid audio source: %d", as); 102d329e21495eda9dbc531fdd0c26c77f1593ac3f4James Dong return BAD_VALUE; 103d329e21495eda9dbc531fdd0c26c77f1593ac3f4James Dong } 104d329e21495eda9dbc531fdd0c26c77f1593ac3f4James Dong 105d329e21495eda9dbc531fdd0c26c77f1593ac3f4James Dong if (as == AUDIO_SOURCE_DEFAULT) { 106d329e21495eda9dbc531fdd0c26c77f1593ac3f4James Dong mAudioSource = AUDIO_SOURCE_MIC; 107d329e21495eda9dbc531fdd0c26c77f1593ac3f4James Dong } else { 108d329e21495eda9dbc531fdd0c26c77f1593ac3f4James Dong mAudioSource = as; 109d329e21495eda9dbc531fdd0c26c77f1593ac3f4James Dong } 11030ab66297501757d745b9ae10da61adcd891f497Andreas Huber 11130ab66297501757d745b9ae10da61adcd891f497Andreas Huber return OK; 11230ab66297501757d745b9ae10da61adcd891f497Andreas Huber} 11330ab66297501757d745b9ae10da61adcd891f497Andreas Huber 11430ab66297501757d745b9ae10da61adcd891f497Andreas Huberstatus_t StagefrightRecorder::setVideoSource(video_source vs) { 1153856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("setVideoSource: %d", vs); 116d329e21495eda9dbc531fdd0c26c77f1593ac3f4James Dong if (vs < VIDEO_SOURCE_DEFAULT || 117d329e21495eda9dbc531fdd0c26c77f1593ac3f4James Dong vs >= VIDEO_SOURCE_LIST_END) { 11829357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("Invalid video source: %d", vs); 119d329e21495eda9dbc531fdd0c26c77f1593ac3f4James Dong return BAD_VALUE; 120d329e21495eda9dbc531fdd0c26c77f1593ac3f4James Dong } 121d329e21495eda9dbc531fdd0c26c77f1593ac3f4James Dong 122d329e21495eda9dbc531fdd0c26c77f1593ac3f4James Dong if (vs == VIDEO_SOURCE_DEFAULT) { 123d329e21495eda9dbc531fdd0c26c77f1593ac3f4James Dong mVideoSource = VIDEO_SOURCE_CAMERA; 124d329e21495eda9dbc531fdd0c26c77f1593ac3f4James Dong } else { 125d329e21495eda9dbc531fdd0c26c77f1593ac3f4James Dong mVideoSource = vs; 126d329e21495eda9dbc531fdd0c26c77f1593ac3f4James Dong } 12730ab66297501757d745b9ae10da61adcd891f497Andreas Huber 12830ab66297501757d745b9ae10da61adcd891f497Andreas Huber return OK; 12930ab66297501757d745b9ae10da61adcd891f497Andreas Huber} 13030ab66297501757d745b9ae10da61adcd891f497Andreas Huber 13130ab66297501757d745b9ae10da61adcd891f497Andreas Huberstatus_t StagefrightRecorder::setOutputFormat(output_format of) { 1323856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("setOutputFormat: %d", of); 133d329e21495eda9dbc531fdd0c26c77f1593ac3f4James Dong if (of < OUTPUT_FORMAT_DEFAULT || 134d329e21495eda9dbc531fdd0c26c77f1593ac3f4James Dong of >= OUTPUT_FORMAT_LIST_END) { 13529357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("Invalid output format: %d", of); 136d329e21495eda9dbc531fdd0c26c77f1593ac3f4James Dong return BAD_VALUE; 137d329e21495eda9dbc531fdd0c26c77f1593ac3f4James Dong } 138d329e21495eda9dbc531fdd0c26c77f1593ac3f4James Dong 139d329e21495eda9dbc531fdd0c26c77f1593ac3f4James Dong if (of == OUTPUT_FORMAT_DEFAULT) { 140d329e21495eda9dbc531fdd0c26c77f1593ac3f4James Dong mOutputFormat = OUTPUT_FORMAT_THREE_GPP; 141d329e21495eda9dbc531fdd0c26c77f1593ac3f4James Dong } else { 142d329e21495eda9dbc531fdd0c26c77f1593ac3f4James Dong mOutputFormat = of; 143d329e21495eda9dbc531fdd0c26c77f1593ac3f4James Dong } 14430ab66297501757d745b9ae10da61adcd891f497Andreas Huber 14530ab66297501757d745b9ae10da61adcd891f497Andreas Huber return OK; 14630ab66297501757d745b9ae10da61adcd891f497Andreas Huber} 14730ab66297501757d745b9ae10da61adcd891f497Andreas Huber 14830ab66297501757d745b9ae10da61adcd891f497Andreas Huberstatus_t StagefrightRecorder::setAudioEncoder(audio_encoder ae) { 1493856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("setAudioEncoder: %d", ae); 150d329e21495eda9dbc531fdd0c26c77f1593ac3f4James Dong if (ae < AUDIO_ENCODER_DEFAULT || 151d329e21495eda9dbc531fdd0c26c77f1593ac3f4James Dong ae >= AUDIO_ENCODER_LIST_END) { 15229357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("Invalid audio encoder: %d", ae); 153d329e21495eda9dbc531fdd0c26c77f1593ac3f4James Dong return BAD_VALUE; 154d329e21495eda9dbc531fdd0c26c77f1593ac3f4James Dong } 155d329e21495eda9dbc531fdd0c26c77f1593ac3f4James Dong 156d329e21495eda9dbc531fdd0c26c77f1593ac3f4James Dong if (ae == AUDIO_ENCODER_DEFAULT) { 157d329e21495eda9dbc531fdd0c26c77f1593ac3f4James Dong mAudioEncoder = AUDIO_ENCODER_AMR_NB; 158d329e21495eda9dbc531fdd0c26c77f1593ac3f4James Dong } else { 159d329e21495eda9dbc531fdd0c26c77f1593ac3f4James Dong mAudioEncoder = ae; 160d329e21495eda9dbc531fdd0c26c77f1593ac3f4James Dong } 16130ab66297501757d745b9ae10da61adcd891f497Andreas Huber 16230ab66297501757d745b9ae10da61adcd891f497Andreas Huber return OK; 16330ab66297501757d745b9ae10da61adcd891f497Andreas Huber} 16430ab66297501757d745b9ae10da61adcd891f497Andreas Huber 16530ab66297501757d745b9ae10da61adcd891f497Andreas Huberstatus_t StagefrightRecorder::setVideoEncoder(video_encoder ve) { 1663856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("setVideoEncoder: %d", ve); 167d329e21495eda9dbc531fdd0c26c77f1593ac3f4James Dong if (ve < VIDEO_ENCODER_DEFAULT || 168d329e21495eda9dbc531fdd0c26c77f1593ac3f4James Dong ve >= VIDEO_ENCODER_LIST_END) { 16929357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("Invalid video encoder: %d", ve); 170d329e21495eda9dbc531fdd0c26c77f1593ac3f4James Dong return BAD_VALUE; 171d329e21495eda9dbc531fdd0c26c77f1593ac3f4James Dong } 172d329e21495eda9dbc531fdd0c26c77f1593ac3f4James Dong 173d329e21495eda9dbc531fdd0c26c77f1593ac3f4James Dong if (ve == VIDEO_ENCODER_DEFAULT) { 174d329e21495eda9dbc531fdd0c26c77f1593ac3f4James Dong mVideoEncoder = VIDEO_ENCODER_H263; 175d329e21495eda9dbc531fdd0c26c77f1593ac3f4James Dong } else { 176d329e21495eda9dbc531fdd0c26c77f1593ac3f4James Dong mVideoEncoder = ve; 177d329e21495eda9dbc531fdd0c26c77f1593ac3f4James Dong } 17830ab66297501757d745b9ae10da61adcd891f497Andreas Huber 17930ab66297501757d745b9ae10da61adcd891f497Andreas Huber return OK; 18030ab66297501757d745b9ae10da61adcd891f497Andreas Huber} 18130ab66297501757d745b9ae10da61adcd891f497Andreas Huber 18230ab66297501757d745b9ae10da61adcd891f497Andreas Huberstatus_t StagefrightRecorder::setVideoSize(int width, int height) { 1833856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("setVideoSize: %dx%d", width, height); 184ef9d0cd72e476a4b7556833fb09505a51b626797James Dong if (width <= 0 || height <= 0) { 18529357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("Invalid video size: %dx%d", width, height); 186ef9d0cd72e476a4b7556833fb09505a51b626797James Dong return BAD_VALUE; 187ef9d0cd72e476a4b7556833fb09505a51b626797James Dong } 188ef9d0cd72e476a4b7556833fb09505a51b626797James Dong 189ef9d0cd72e476a4b7556833fb09505a51b626797James Dong // Additional check on the dimension will be performed later 19030ab66297501757d745b9ae10da61adcd891f497Andreas Huber mVideoWidth = width; 19130ab66297501757d745b9ae10da61adcd891f497Andreas Huber mVideoHeight = height; 19230ab66297501757d745b9ae10da61adcd891f497Andreas Huber 19330ab66297501757d745b9ae10da61adcd891f497Andreas Huber return OK; 19430ab66297501757d745b9ae10da61adcd891f497Andreas Huber} 19530ab66297501757d745b9ae10da61adcd891f497Andreas Huber 19630ab66297501757d745b9ae10da61adcd891f497Andreas Huberstatus_t StagefrightRecorder::setVideoFrameRate(int frames_per_second) { 1973856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("setVideoFrameRate: %d", frames_per_second); 198635730831e08c32a5fe7c59125e0919b7e7899cdJames Dong if ((frames_per_second <= 0 && frames_per_second != -1) || 199635730831e08c32a5fe7c59125e0919b7e7899cdJames Dong frames_per_second > 120) { 20029357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("Invalid video frame rate: %d", frames_per_second); 201ef9d0cd72e476a4b7556833fb09505a51b626797James Dong return BAD_VALUE; 202ef9d0cd72e476a4b7556833fb09505a51b626797James Dong } 203ef9d0cd72e476a4b7556833fb09505a51b626797James Dong 204ef9d0cd72e476a4b7556833fb09505a51b626797James Dong // Additional check on the frame rate will be performed later 20530ab66297501757d745b9ae10da61adcd891f497Andreas Huber mFrameRate = frames_per_second; 20630ab66297501757d745b9ae10da61adcd891f497Andreas Huber 20730ab66297501757d745b9ae10da61adcd891f497Andreas Huber return OK; 20830ab66297501757d745b9ae10da61adcd891f497Andreas Huber} 20930ab66297501757d745b9ae10da61adcd891f497Andreas Huber 2104ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Listatus_t StagefrightRecorder::setCamera(const sp<ICamera> &camera, 2114ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li const sp<ICameraRecordingProxy> &proxy) { 2123856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("setCamera"); 213c32cd79d9ad4aba7d959b5b3be7361b4715e6f18James Dong if (camera == 0) { 21429357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("camera is NULL"); 215934da11c4cc598d3dd3b53726c362bcdcc0fd37fJames Dong return BAD_VALUE; 216c32cd79d9ad4aba7d959b5b3be7361b4715e6f18James Dong } 2174ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li if (proxy == 0) { 21829357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("camera proxy is NULL"); 2194ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li return BAD_VALUE; 2204ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li } 221c32cd79d9ad4aba7d959b5b3be7361b4715e6f18James Dong 22254ff19ac69ace7c05ea90d225e26dab3b133f487James Dong mCamera = camera; 2234ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li mCameraProxy = proxy; 22430ab66297501757d745b9ae10da61adcd891f497Andreas Huber return OK; 22530ab66297501757d745b9ae10da61adcd891f497Andreas Huber} 22630ab66297501757d745b9ae10da61adcd891f497Andreas Huber 2274b79168835965cf0fc41ebe2a367e22b4cb20d08Jamie Gennisstatus_t StagefrightRecorder::setPreviewSurface(const sp<Surface> &surface) { 2283856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("setPreviewSurface: %p", surface.get()); 22930ab66297501757d745b9ae10da61adcd891f497Andreas Huber mPreviewSurface = surface; 23030ab66297501757d745b9ae10da61adcd891f497Andreas Huber 23130ab66297501757d745b9ae10da61adcd891f497Andreas Huber return OK; 23230ab66297501757d745b9ae10da61adcd891f497Andreas Huber} 23330ab66297501757d745b9ae10da61adcd891f497Andreas Huber 23430ab66297501757d745b9ae10da61adcd891f497Andreas Huberstatus_t StagefrightRecorder::setOutputFile(const char *path) { 23529357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("setOutputFile(const char*) must not be called"); 23630ab66297501757d745b9ae10da61adcd891f497Andreas Huber // We don't actually support this at all, as the media_server process 23730ab66297501757d745b9ae10da61adcd891f497Andreas Huber // no longer has permissions to create files. 23830ab66297501757d745b9ae10da61adcd891f497Andreas Huber 239934da11c4cc598d3dd3b53726c362bcdcc0fd37fJames Dong return -EPERM; 24030ab66297501757d745b9ae10da61adcd891f497Andreas Huber} 24130ab66297501757d745b9ae10da61adcd891f497Andreas Huber 24230ab66297501757d745b9ae10da61adcd891f497Andreas Huberstatus_t StagefrightRecorder::setOutputFile(int fd, int64_t offset, int64_t length) { 2433856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("setOutputFile: %d, %lld, %lld", fd, offset, length); 24430ab66297501757d745b9ae10da61adcd891f497Andreas Huber // These don't make any sense, do they? 245f1d5aa162c02a16b7195a43a9bcea4d592600ac4James Dong CHECK_EQ(offset, 0ll); 246f1d5aa162c02a16b7195a43a9bcea4d592600ac4James Dong CHECK_EQ(length, 0ll); 24730ab66297501757d745b9ae10da61adcd891f497Andreas Huber 248934da11c4cc598d3dd3b53726c362bcdcc0fd37fJames Dong if (fd < 0) { 24929357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("Invalid file descriptor: %d", fd); 250934da11c4cc598d3dd3b53726c362bcdcc0fd37fJames Dong return -EBADF; 251934da11c4cc598d3dd3b53726c362bcdcc0fd37fJames Dong } 252934da11c4cc598d3dd3b53726c362bcdcc0fd37fJames Dong 25330ab66297501757d745b9ae10da61adcd891f497Andreas Huber if (mOutputFd >= 0) { 25430ab66297501757d745b9ae10da61adcd891f497Andreas Huber ::close(mOutputFd); 25530ab66297501757d745b9ae10da61adcd891f497Andreas Huber } 25630ab66297501757d745b9ae10da61adcd891f497Andreas Huber mOutputFd = dup(fd); 25730ab66297501757d745b9ae10da61adcd891f497Andreas Huber 25830ab66297501757d745b9ae10da61adcd891f497Andreas Huber return OK; 25930ab66297501757d745b9ae10da61adcd891f497Andreas Huber} 26030ab66297501757d745b9ae10da61adcd891f497Andreas Huber 261050b28a593350047845a45a14cc5026221ac1620James Dong// Attempt to parse an int64 literal optionally surrounded by whitespace, 262050b28a593350047845a45a14cc5026221ac1620James Dong// returns true on success, false otherwise. 263ef9d0cd72e476a4b7556833fb09505a51b626797James Dongstatic bool safe_strtoi64(const char *s, int64_t *val) { 264050b28a593350047845a45a14cc5026221ac1620James Dong char *end; 26527944ef5cd8d0fb476c8c8958986e827c5f8ab83James Dong 26627944ef5cd8d0fb476c8c8958986e827c5f8ab83James Dong // It is lame, but according to man page, we have to set errno to 0 26727944ef5cd8d0fb476c8c8958986e827c5f8ab83James Dong // before calling strtoll(). 26827944ef5cd8d0fb476c8c8958986e827c5f8ab83James Dong errno = 0; 269ef9d0cd72e476a4b7556833fb09505a51b626797James Dong *val = strtoll(s, &end, 10); 270050b28a593350047845a45a14cc5026221ac1620James Dong 271050b28a593350047845a45a14cc5026221ac1620James Dong if (end == s || errno == ERANGE) { 272050b28a593350047845a45a14cc5026221ac1620James Dong return false; 273050b28a593350047845a45a14cc5026221ac1620James Dong } 274050b28a593350047845a45a14cc5026221ac1620James Dong 275050b28a593350047845a45a14cc5026221ac1620James Dong // Skip trailing whitespace 276050b28a593350047845a45a14cc5026221ac1620James Dong while (isspace(*end)) { 277050b28a593350047845a45a14cc5026221ac1620James Dong ++end; 278050b28a593350047845a45a14cc5026221ac1620James Dong } 279050b28a593350047845a45a14cc5026221ac1620James Dong 280050b28a593350047845a45a14cc5026221ac1620James Dong // For a successful return, the string must contain nothing but a valid 281050b28a593350047845a45a14cc5026221ac1620James Dong // int64 literal optionally surrounded by whitespace. 282050b28a593350047845a45a14cc5026221ac1620James Dong 283050b28a593350047845a45a14cc5026221ac1620James Dong return *end == '\0'; 284050b28a593350047845a45a14cc5026221ac1620James Dong} 285050b28a593350047845a45a14cc5026221ac1620James Dong 286ef9d0cd72e476a4b7556833fb09505a51b626797James Dong// Return true if the value is in [0, 0x007FFFFFFF] 287ef9d0cd72e476a4b7556833fb09505a51b626797James Dongstatic bool safe_strtoi32(const char *s, int32_t *val) { 288ef9d0cd72e476a4b7556833fb09505a51b626797James Dong int64_t temp; 289ef9d0cd72e476a4b7556833fb09505a51b626797James Dong if (safe_strtoi64(s, &temp)) { 290ef9d0cd72e476a4b7556833fb09505a51b626797James Dong if (temp >= 0 && temp <= 0x007FFFFFFF) { 291ef9d0cd72e476a4b7556833fb09505a51b626797James Dong *val = static_cast<int32_t>(temp); 292ef9d0cd72e476a4b7556833fb09505a51b626797James Dong return true; 293ef9d0cd72e476a4b7556833fb09505a51b626797James Dong } 294ef9d0cd72e476a4b7556833fb09505a51b626797James Dong } 295ef9d0cd72e476a4b7556833fb09505a51b626797James Dong return false; 296ef9d0cd72e476a4b7556833fb09505a51b626797James Dong} 297ef9d0cd72e476a4b7556833fb09505a51b626797James Dong 298050b28a593350047845a45a14cc5026221ac1620James Dong// Trim both leading and trailing whitespace from the given string. 299050b28a593350047845a45a14cc5026221ac1620James Dongstatic void TrimString(String8 *s) { 300050b28a593350047845a45a14cc5026221ac1620James Dong size_t num_bytes = s->bytes(); 301050b28a593350047845a45a14cc5026221ac1620James Dong const char *data = s->string(); 302050b28a593350047845a45a14cc5026221ac1620James Dong 303050b28a593350047845a45a14cc5026221ac1620James Dong size_t leading_space = 0; 304050b28a593350047845a45a14cc5026221ac1620James Dong while (leading_space < num_bytes && isspace(data[leading_space])) { 305050b28a593350047845a45a14cc5026221ac1620James Dong ++leading_space; 306050b28a593350047845a45a14cc5026221ac1620James Dong } 307050b28a593350047845a45a14cc5026221ac1620James Dong 308050b28a593350047845a45a14cc5026221ac1620James Dong size_t i = num_bytes; 309050b28a593350047845a45a14cc5026221ac1620James Dong while (i > leading_space && isspace(data[i - 1])) { 310050b28a593350047845a45a14cc5026221ac1620James Dong --i; 311050b28a593350047845a45a14cc5026221ac1620James Dong } 312050b28a593350047845a45a14cc5026221ac1620James Dong 313050b28a593350047845a45a14cc5026221ac1620James Dong s->setTo(String8(&data[leading_space], i - leading_space)); 314050b28a593350047845a45a14cc5026221ac1620James Dong} 315050b28a593350047845a45a14cc5026221ac1620James Dong 316050b28a593350047845a45a14cc5026221ac1620James Dongstatus_t StagefrightRecorder::setParamAudioSamplingRate(int32_t sampleRate) { 3173856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("setParamAudioSamplingRate: %d", sampleRate); 318ef9d0cd72e476a4b7556833fb09505a51b626797James Dong if (sampleRate <= 0) { 31929357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("Invalid audio sampling rate: %d", sampleRate); 320ef9d0cd72e476a4b7556833fb09505a51b626797James Dong return BAD_VALUE; 321ef9d0cd72e476a4b7556833fb09505a51b626797James Dong } 322ef9d0cd72e476a4b7556833fb09505a51b626797James Dong 323ef9d0cd72e476a4b7556833fb09505a51b626797James Dong // Additional check on the sample rate will be performed later. 324050b28a593350047845a45a14cc5026221ac1620James Dong mSampleRate = sampleRate; 325050b28a593350047845a45a14cc5026221ac1620James Dong return OK; 326050b28a593350047845a45a14cc5026221ac1620James Dong} 327050b28a593350047845a45a14cc5026221ac1620James Dong 328050b28a593350047845a45a14cc5026221ac1620James Dongstatus_t StagefrightRecorder::setParamAudioNumberOfChannels(int32_t channels) { 3293856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("setParamAudioNumberOfChannels: %d", channels); 330ef9d0cd72e476a4b7556833fb09505a51b626797James Dong if (channels <= 0 || channels >= 3) { 33129357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("Invalid number of audio channels: %d", channels); 332934da11c4cc598d3dd3b53726c362bcdcc0fd37fJames Dong return BAD_VALUE; 333ef9d0cd72e476a4b7556833fb09505a51b626797James Dong } 334ef9d0cd72e476a4b7556833fb09505a51b626797James Dong 335ef9d0cd72e476a4b7556833fb09505a51b626797James Dong // Additional check on the number of channels will be performed later. 336050b28a593350047845a45a14cc5026221ac1620James Dong mAudioChannels = channels; 337050b28a593350047845a45a14cc5026221ac1620James Dong return OK; 338050b28a593350047845a45a14cc5026221ac1620James Dong} 339050b28a593350047845a45a14cc5026221ac1620James Dong 340050b28a593350047845a45a14cc5026221ac1620James Dongstatus_t StagefrightRecorder::setParamAudioEncodingBitRate(int32_t bitRate) { 3413856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("setParamAudioEncodingBitRate: %d", bitRate); 342ef9d0cd72e476a4b7556833fb09505a51b626797James Dong if (bitRate <= 0) { 34329357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("Invalid audio encoding bit rate: %d", bitRate); 344ef9d0cd72e476a4b7556833fb09505a51b626797James Dong return BAD_VALUE; 345ef9d0cd72e476a4b7556833fb09505a51b626797James Dong } 346ef9d0cd72e476a4b7556833fb09505a51b626797James Dong 347ef9d0cd72e476a4b7556833fb09505a51b626797James Dong // The target bit rate may not be exactly the same as the requested. 348ef9d0cd72e476a4b7556833fb09505a51b626797James Dong // It depends on many factors, such as rate control, and the bit rate 349ef9d0cd72e476a4b7556833fb09505a51b626797James Dong // range that a specific encoder supports. The mismatch between the 350ef9d0cd72e476a4b7556833fb09505a51b626797James Dong // the target and requested bit rate will NOT be treated as an error. 351050b28a593350047845a45a14cc5026221ac1620James Dong mAudioBitRate = bitRate; 352050b28a593350047845a45a14cc5026221ac1620James Dong return OK; 353050b28a593350047845a45a14cc5026221ac1620James Dong} 354050b28a593350047845a45a14cc5026221ac1620James Dong 355050b28a593350047845a45a14cc5026221ac1620James Dongstatus_t StagefrightRecorder::setParamVideoEncodingBitRate(int32_t bitRate) { 3563856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("setParamVideoEncodingBitRate: %d", bitRate); 357ef9d0cd72e476a4b7556833fb09505a51b626797James Dong if (bitRate <= 0) { 35829357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("Invalid video encoding bit rate: %d", bitRate); 359ef9d0cd72e476a4b7556833fb09505a51b626797James Dong return BAD_VALUE; 360ef9d0cd72e476a4b7556833fb09505a51b626797James Dong } 361ef9d0cd72e476a4b7556833fb09505a51b626797James Dong 362ef9d0cd72e476a4b7556833fb09505a51b626797James Dong // The target bit rate may not be exactly the same as the requested. 363ef9d0cd72e476a4b7556833fb09505a51b626797James Dong // It depends on many factors, such as rate control, and the bit rate 364ef9d0cd72e476a4b7556833fb09505a51b626797James Dong // range that a specific encoder supports. The mismatch between the 365ef9d0cd72e476a4b7556833fb09505a51b626797James Dong // the target and requested bit rate will NOT be treated as an error. 366050b28a593350047845a45a14cc5026221ac1620James Dong mVideoBitRate = bitRate; 367050b28a593350047845a45a14cc5026221ac1620James Dong return OK; 368050b28a593350047845a45a14cc5026221ac1620James Dong} 369050b28a593350047845a45a14cc5026221ac1620James Dong 37013f6284305e4b27395a23db7882d670bdb1bcae1James Dong// Always rotate clockwise, and only support 0, 90, 180 and 270 for now. 37113f6284305e4b27395a23db7882d670bdb1bcae1James Dongstatus_t StagefrightRecorder::setParamVideoRotation(int32_t degrees) { 3723856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("setParamVideoRotation: %d", degrees); 37313f6284305e4b27395a23db7882d670bdb1bcae1James Dong if (degrees < 0 || degrees % 90 != 0) { 37429357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("Unsupported video rotation angle: %d", degrees); 37513f6284305e4b27395a23db7882d670bdb1bcae1James Dong return BAD_VALUE; 37613f6284305e4b27395a23db7882d670bdb1bcae1James Dong } 37713f6284305e4b27395a23db7882d670bdb1bcae1James Dong mRotationDegrees = degrees % 360; 37813f6284305e4b27395a23db7882d670bdb1bcae1James Dong return OK; 37913f6284305e4b27395a23db7882d670bdb1bcae1James Dong} 38013f6284305e4b27395a23db7882d670bdb1bcae1James Dong 381934da11c4cc598d3dd3b53726c362bcdcc0fd37fJames Dongstatus_t StagefrightRecorder::setParamMaxFileDurationUs(int64_t timeUs) { 3823856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("setParamMaxFileDurationUs: %lld us", timeUs); 3832d1e5d35be5e6d4b55ac8b39fbfcbeb60fcdd084James Dong 3842d1e5d35be5e6d4b55ac8b39fbfcbeb60fcdd084James Dong // This is meant for backward compatibility for MediaRecorder.java 385be6fd201b9a04fe0f8fd409f10595ddb41832591Nipun Kwatra if (timeUs <= 0) { 3865ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block ALOGW("Max file duration is not positive: %lld us. Disabling duration limit.", timeUs); 387be6fd201b9a04fe0f8fd409f10595ddb41832591Nipun Kwatra timeUs = 0; // Disable the duration limit for zero or negative values. 388be6fd201b9a04fe0f8fd409f10595ddb41832591Nipun Kwatra } else if (timeUs <= 100000LL) { // XXX: 100 milli-seconds 38929357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("Max file duration is too short: %lld us", timeUs); 390934da11c4cc598d3dd3b53726c362bcdcc0fd37fJames Dong return BAD_VALUE; 391ef9d0cd72e476a4b7556833fb09505a51b626797James Dong } 392be6fd201b9a04fe0f8fd409f10595ddb41832591Nipun Kwatra 393acd234bba9f048971d66890009eeff9a8db94be3James Dong if (timeUs <= 15 * 1000000LL) { 3945ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block ALOGW("Target duration (%lld us) too short to be respected", timeUs); 395acd234bba9f048971d66890009eeff9a8db94be3James Dong } 396934da11c4cc598d3dd3b53726c362bcdcc0fd37fJames Dong mMaxFileDurationUs = timeUs; 397934da11c4cc598d3dd3b53726c362bcdcc0fd37fJames Dong return OK; 398934da11c4cc598d3dd3b53726c362bcdcc0fd37fJames Dong} 399934da11c4cc598d3dd3b53726c362bcdcc0fd37fJames Dong 400934da11c4cc598d3dd3b53726c362bcdcc0fd37fJames Dongstatus_t StagefrightRecorder::setParamMaxFileSizeBytes(int64_t bytes) { 4013856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("setParamMaxFileSizeBytes: %lld bytes", bytes); 4022d1e5d35be5e6d4b55ac8b39fbfcbeb60fcdd084James Dong 4032d1e5d35be5e6d4b55ac8b39fbfcbeb60fcdd084James Dong // This is meant for backward compatibility for MediaRecorder.java 4042d1e5d35be5e6d4b55ac8b39fbfcbeb60fcdd084James Dong if (bytes <= 0) { 4055ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block ALOGW("Max file size is not positive: %lld bytes. " 4062d1e5d35be5e6d4b55ac8b39fbfcbeb60fcdd084James Dong "Disabling file size limit.", bytes); 4072d1e5d35be5e6d4b55ac8b39fbfcbeb60fcdd084James Dong bytes = 0; // Disable the file size limit for zero or negative values. 4082d1e5d35be5e6d4b55ac8b39fbfcbeb60fcdd084James Dong } else if (bytes <= 1024) { // XXX: 1 kB 40929357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("Max file size is too small: %lld bytes", bytes); 410934da11c4cc598d3dd3b53726c362bcdcc0fd37fJames Dong return BAD_VALUE; 411934da11c4cc598d3dd3b53726c362bcdcc0fd37fJames Dong } 412acd234bba9f048971d66890009eeff9a8db94be3James Dong 413acd234bba9f048971d66890009eeff9a8db94be3James Dong if (bytes <= 100 * 1024) { 4145ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block ALOGW("Target file size (%lld bytes) is too small to be respected", bytes); 415acd234bba9f048971d66890009eeff9a8db94be3James Dong } 416acd234bba9f048971d66890009eeff9a8db94be3James Dong 417934da11c4cc598d3dd3b53726c362bcdcc0fd37fJames Dong mMaxFileSizeBytes = bytes; 418050b28a593350047845a45a14cc5026221ac1620James Dong return OK; 419050b28a593350047845a45a14cc5026221ac1620James Dong} 420050b28a593350047845a45a14cc5026221ac1620James Dong 42113aec890216948b0c364f8f92792129d0335f506James Dongstatus_t StagefrightRecorder::setParamInterleaveDuration(int32_t durationUs) { 4223856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("setParamInterleaveDuration: %d", durationUs); 423ddcc4a66d848deef6fb4689e64e30cd9bd2684feJames Dong if (durationUs <= 500000) { // 500 ms 424ddcc4a66d848deef6fb4689e64e30cd9bd2684feJames Dong // If interleave duration is too small, it is very inefficient to do 425ddcc4a66d848deef6fb4689e64e30cd9bd2684feJames Dong // interleaving since the metadata overhead will count for a significant 426ddcc4a66d848deef6fb4689e64e30cd9bd2684feJames Dong // portion of the saved contents 42729357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("Audio/video interleave duration is too small: %d us", durationUs); 428ef9d0cd72e476a4b7556833fb09505a51b626797James Dong return BAD_VALUE; 429ddcc4a66d848deef6fb4689e64e30cd9bd2684feJames Dong } else if (durationUs >= 10000000) { // 10 seconds 430ddcc4a66d848deef6fb4689e64e30cd9bd2684feJames Dong // If interleaving duration is too large, it can cause the recording 431ddcc4a66d848deef6fb4689e64e30cd9bd2684feJames Dong // session to use too much memory since we have to save the output 432ddcc4a66d848deef6fb4689e64e30cd9bd2684feJames Dong // data before we write them out 43329357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("Audio/video interleave duration is too large: %d us", durationUs); 434ddcc4a66d848deef6fb4689e64e30cd9bd2684feJames Dong return BAD_VALUE; 435ef9d0cd72e476a4b7556833fb09505a51b626797James Dong } 43613aec890216948b0c364f8f92792129d0335f506James Dong mInterleaveDurationUs = durationUs; 43713aec890216948b0c364f8f92792129d0335f506James Dong return OK; 43813aec890216948b0c364f8f92792129d0335f506James Dong} 439ef9d0cd72e476a4b7556833fb09505a51b626797James Dong 4408f5f2fcee5c12d08df71d17017410c50951fc2e3James Dong// If seconds < 0, only the first frame is I frame, and rest are all P frames 4418f5f2fcee5c12d08df71d17017410c50951fc2e3James Dong// If seconds == 0, all frames are encoded as I frames. No P frames 4428f5f2fcee5c12d08df71d17017410c50951fc2e3James Dong// If seconds > 0, it is the time spacing (seconds) between 2 neighboring I frames 4438f5f2fcee5c12d08df71d17017410c50951fc2e3James Dongstatus_t StagefrightRecorder::setParamVideoIFramesInterval(int32_t seconds) { 4443856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("setParamVideoIFramesInterval: %d seconds", seconds); 4458f5f2fcee5c12d08df71d17017410c50951fc2e3James Dong mIFramesIntervalSec = seconds; 446ddcc4a66d848deef6fb4689e64e30cd9bd2684feJames Dong return OK; 447ddcc4a66d848deef6fb4689e64e30cd9bd2684feJames Dong} 448ddcc4a66d848deef6fb4689e64e30cd9bd2684feJames Dong 4492dec2b5be2056c6d9428897dc672185872d30d17James Dongstatus_t StagefrightRecorder::setParam64BitFileOffset(bool use64Bit) { 4503856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("setParam64BitFileOffset: %s", 4512dec2b5be2056c6d9428897dc672185872d30d17James Dong use64Bit? "use 64 bit file offset": "use 32 bit file offset"); 4522dec2b5be2056c6d9428897dc672185872d30d17James Dong mUse64BitFileOffset = use64Bit; 4532dec2b5be2056c6d9428897dc672185872d30d17James Dong return OK; 4542dec2b5be2056c6d9428897dc672185872d30d17James Dong} 4552dec2b5be2056c6d9428897dc672185872d30d17James Dong 45693d6b102a13afa23bfa80d74c399d93d542e6ad6James Dongstatus_t StagefrightRecorder::setParamVideoCameraId(int32_t cameraId) { 4573856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("setParamVideoCameraId: %d", cameraId); 45893d6b102a13afa23bfa80d74c399d93d542e6ad6James Dong if (cameraId < 0) { 45993d6b102a13afa23bfa80d74c399d93d542e6ad6James Dong return BAD_VALUE; 46093d6b102a13afa23bfa80d74c399d93d542e6ad6James Dong } 46193d6b102a13afa23bfa80d74c399d93d542e6ad6James Dong mCameraId = cameraId; 46293d6b102a13afa23bfa80d74c399d93d542e6ad6James Dong return OK; 46393d6b102a13afa23bfa80d74c399d93d542e6ad6James Dong} 46493d6b102a13afa23bfa80d74c399d93d542e6ad6James Dong 46593d6b102a13afa23bfa80d74c399d93d542e6ad6James Dongstatus_t StagefrightRecorder::setParamTrackTimeStatus(int64_t timeDurationUs) { 4663856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("setParamTrackTimeStatus: %lld", timeDurationUs); 46793d6b102a13afa23bfa80d74c399d93d542e6ad6James Dong if (timeDurationUs < 20000) { // Infeasible if shorter than 20 ms? 46829357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("Tracking time duration too short: %lld us", timeDurationUs); 46993d6b102a13afa23bfa80d74c399d93d542e6ad6James Dong return BAD_VALUE; 47093d6b102a13afa23bfa80d74c399d93d542e6ad6James Dong } 47193d6b102a13afa23bfa80d74c399d93d542e6ad6James Dong mTrackEveryTimeDurationUs = timeDurationUs; 47293d6b102a13afa23bfa80d74c399d93d542e6ad6James Dong return OK; 47393d6b102a13afa23bfa80d74c399d93d542e6ad6James Dong} 47493d6b102a13afa23bfa80d74c399d93d542e6ad6James Dong 475145bfe5eb3e08c9689c28f6bf3287a979438b04bJames Dongstatus_t StagefrightRecorder::setParamVideoEncoderProfile(int32_t profile) { 4763856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("setParamVideoEncoderProfile: %d", profile); 477145bfe5eb3e08c9689c28f6bf3287a979438b04bJames Dong 478145bfe5eb3e08c9689c28f6bf3287a979438b04bJames Dong // Additional check will be done later when we load the encoder. 479145bfe5eb3e08c9689c28f6bf3287a979438b04bJames Dong // For now, we are accepting values defined in OpenMAX IL. 480145bfe5eb3e08c9689c28f6bf3287a979438b04bJames Dong mVideoEncoderProfile = profile; 481145bfe5eb3e08c9689c28f6bf3287a979438b04bJames Dong return OK; 482145bfe5eb3e08c9689c28f6bf3287a979438b04bJames Dong} 483145bfe5eb3e08c9689c28f6bf3287a979438b04bJames Dong 484145bfe5eb3e08c9689c28f6bf3287a979438b04bJames Dongstatus_t StagefrightRecorder::setParamVideoEncoderLevel(int32_t level) { 4853856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("setParamVideoEncoderLevel: %d", level); 486145bfe5eb3e08c9689c28f6bf3287a979438b04bJames Dong 487145bfe5eb3e08c9689c28f6bf3287a979438b04bJames Dong // Additional check will be done later when we load the encoder. 488145bfe5eb3e08c9689c28f6bf3287a979438b04bJames Dong // For now, we are accepting values defined in OpenMAX IL. 489145bfe5eb3e08c9689c28f6bf3287a979438b04bJames Dong mVideoEncoderLevel = level; 490145bfe5eb3e08c9689c28f6bf3287a979438b04bJames Dong return OK; 491145bfe5eb3e08c9689c28f6bf3287a979438b04bJames Dong} 492145bfe5eb3e08c9689c28f6bf3287a979438b04bJames Dong 4938f5f2fcee5c12d08df71d17017410c50951fc2e3James Dongstatus_t StagefrightRecorder::setParamMovieTimeScale(int32_t timeScale) { 4943856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("setParamMovieTimeScale: %d", timeScale); 4958f5f2fcee5c12d08df71d17017410c50951fc2e3James Dong 4968f5f2fcee5c12d08df71d17017410c50951fc2e3James Dong // The range is set to be the same as the audio's time scale range 4978f5f2fcee5c12d08df71d17017410c50951fc2e3James Dong // since audio's time scale has a wider range. 4988f5f2fcee5c12d08df71d17017410c50951fc2e3James Dong if (timeScale < 600 || timeScale > 96000) { 49929357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("Time scale (%d) for movie is out of range [600, 96000]", timeScale); 5008f5f2fcee5c12d08df71d17017410c50951fc2e3James Dong return BAD_VALUE; 5018f5f2fcee5c12d08df71d17017410c50951fc2e3James Dong } 5028f5f2fcee5c12d08df71d17017410c50951fc2e3James Dong mMovieTimeScale = timeScale; 5038f5f2fcee5c12d08df71d17017410c50951fc2e3James Dong return OK; 5048f5f2fcee5c12d08df71d17017410c50951fc2e3James Dong} 5058f5f2fcee5c12d08df71d17017410c50951fc2e3James Dong 5068f5f2fcee5c12d08df71d17017410c50951fc2e3James Dongstatus_t StagefrightRecorder::setParamVideoTimeScale(int32_t timeScale) { 5073856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("setParamVideoTimeScale: %d", timeScale); 5088f5f2fcee5c12d08df71d17017410c50951fc2e3James Dong 5098f5f2fcee5c12d08df71d17017410c50951fc2e3James Dong // 60000 is chosen to make sure that each video frame from a 60-fps 5108f5f2fcee5c12d08df71d17017410c50951fc2e3James Dong // video has 1000 ticks. 5118f5f2fcee5c12d08df71d17017410c50951fc2e3James Dong if (timeScale < 600 || timeScale > 60000) { 51229357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("Time scale (%d) for video is out of range [600, 60000]", timeScale); 5138f5f2fcee5c12d08df71d17017410c50951fc2e3James Dong return BAD_VALUE; 5148f5f2fcee5c12d08df71d17017410c50951fc2e3James Dong } 5158f5f2fcee5c12d08df71d17017410c50951fc2e3James Dong mVideoTimeScale = timeScale; 5168f5f2fcee5c12d08df71d17017410c50951fc2e3James Dong return OK; 5178f5f2fcee5c12d08df71d17017410c50951fc2e3James Dong} 5188f5f2fcee5c12d08df71d17017410c50951fc2e3James Dong 5198f5f2fcee5c12d08df71d17017410c50951fc2e3James Dongstatus_t StagefrightRecorder::setParamAudioTimeScale(int32_t timeScale) { 5203856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("setParamAudioTimeScale: %d", timeScale); 5218f5f2fcee5c12d08df71d17017410c50951fc2e3James Dong 5228f5f2fcee5c12d08df71d17017410c50951fc2e3James Dong // 96000 Hz is the highest sampling rate support in AAC. 5238f5f2fcee5c12d08df71d17017410c50951fc2e3James Dong if (timeScale < 600 || timeScale > 96000) { 52429357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("Time scale (%d) for audio is out of range [600, 96000]", timeScale); 5258f5f2fcee5c12d08df71d17017410c50951fc2e3James Dong return BAD_VALUE; 5268f5f2fcee5c12d08df71d17017410c50951fc2e3James Dong } 5278f5f2fcee5c12d08df71d17017410c50951fc2e3James Dong mAudioTimeScale = timeScale; 5288f5f2fcee5c12d08df71d17017410c50951fc2e3James Dong return OK; 5298f5f2fcee5c12d08df71d17017410c50951fc2e3James Dong} 5308f5f2fcee5c12d08df71d17017410c50951fc2e3James Dong 531e4e0a6994d39c4a7cba09c5fff442b2dca1df8f8Nipun Kwatrastatus_t StagefrightRecorder::setParamTimeLapseEnable(int32_t timeLapseEnable) { 5323856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("setParamTimeLapseEnable: %d", timeLapseEnable); 533e4e0a6994d39c4a7cba09c5fff442b2dca1df8f8Nipun Kwatra 534e4e0a6994d39c4a7cba09c5fff442b2dca1df8f8Nipun Kwatra if(timeLapseEnable == 0) { 535e4e0a6994d39c4a7cba09c5fff442b2dca1df8f8Nipun Kwatra mCaptureTimeLapse = false; 536e4e0a6994d39c4a7cba09c5fff442b2dca1df8f8Nipun Kwatra } else if (timeLapseEnable == 1) { 537e4e0a6994d39c4a7cba09c5fff442b2dca1df8f8Nipun Kwatra mCaptureTimeLapse = true; 538e4e0a6994d39c4a7cba09c5fff442b2dca1df8f8Nipun Kwatra } else { 539e4e0a6994d39c4a7cba09c5fff442b2dca1df8f8Nipun Kwatra return BAD_VALUE; 540e4e0a6994d39c4a7cba09c5fff442b2dca1df8f8Nipun Kwatra } 541e4e0a6994d39c4a7cba09c5fff442b2dca1df8f8Nipun Kwatra return OK; 542e4e0a6994d39c4a7cba09c5fff442b2dca1df8f8Nipun Kwatra} 543e4e0a6994d39c4a7cba09c5fff442b2dca1df8f8Nipun Kwatra 544e4e0a6994d39c4a7cba09c5fff442b2dca1df8f8Nipun Kwatrastatus_t StagefrightRecorder::setParamTimeBetweenTimeLapseFrameCapture(int64_t timeUs) { 5453856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("setParamTimeBetweenTimeLapseFrameCapture: %lld us", timeUs); 546e4e0a6994d39c4a7cba09c5fff442b2dca1df8f8Nipun Kwatra 547e4e0a6994d39c4a7cba09c5fff442b2dca1df8f8Nipun Kwatra // Not allowing time more than a day 548e4e0a6994d39c4a7cba09c5fff442b2dca1df8f8Nipun Kwatra if (timeUs <= 0 || timeUs > 86400*1E6) { 54929357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("Time between time lapse frame capture (%lld) is out of range [0, 1 Day]", timeUs); 550e4e0a6994d39c4a7cba09c5fff442b2dca1df8f8Nipun Kwatra return BAD_VALUE; 551e4e0a6994d39c4a7cba09c5fff442b2dca1df8f8Nipun Kwatra } 552e4e0a6994d39c4a7cba09c5fff442b2dca1df8f8Nipun Kwatra 553e4e0a6994d39c4a7cba09c5fff442b2dca1df8f8Nipun Kwatra mTimeBetweenTimeLapseFrameCaptureUs = timeUs; 554e4e0a6994d39c4a7cba09c5fff442b2dca1df8f8Nipun Kwatra return OK; 555e4e0a6994d39c4a7cba09c5fff442b2dca1df8f8Nipun Kwatra} 556e4e0a6994d39c4a7cba09c5fff442b2dca1df8f8Nipun Kwatra 55707b1bb529a1ae76c46a71b01338c166f9490629dJames Dongstatus_t StagefrightRecorder::setParamGeoDataLongitude( 558b832a03d563dd000faa44f2577e92237525edc32James Dong int64_t longitudex10000) { 55907b1bb529a1ae76c46a71b01338c166f9490629dJames Dong 56007b1bb529a1ae76c46a71b01338c166f9490629dJames Dong if (longitudex10000 > 1800000 || longitudex10000 < -1800000) { 56107b1bb529a1ae76c46a71b01338c166f9490629dJames Dong return BAD_VALUE; 56207b1bb529a1ae76c46a71b01338c166f9490629dJames Dong } 56307b1bb529a1ae76c46a71b01338c166f9490629dJames Dong mLongitudex10000 = longitudex10000; 56407b1bb529a1ae76c46a71b01338c166f9490629dJames Dong return OK; 56507b1bb529a1ae76c46a71b01338c166f9490629dJames Dong} 56607b1bb529a1ae76c46a71b01338c166f9490629dJames Dong 56707b1bb529a1ae76c46a71b01338c166f9490629dJames Dongstatus_t StagefrightRecorder::setParamGeoDataLatitude( 568b832a03d563dd000faa44f2577e92237525edc32James Dong int64_t latitudex10000) { 56907b1bb529a1ae76c46a71b01338c166f9490629dJames Dong 57007b1bb529a1ae76c46a71b01338c166f9490629dJames Dong if (latitudex10000 > 900000 || latitudex10000 < -900000) { 57107b1bb529a1ae76c46a71b01338c166f9490629dJames Dong return BAD_VALUE; 57207b1bb529a1ae76c46a71b01338c166f9490629dJames Dong } 57307b1bb529a1ae76c46a71b01338c166f9490629dJames Dong mLatitudex10000 = latitudex10000; 57407b1bb529a1ae76c46a71b01338c166f9490629dJames Dong return OK; 57507b1bb529a1ae76c46a71b01338c166f9490629dJames Dong} 57607b1bb529a1ae76c46a71b01338c166f9490629dJames Dong 577050b28a593350047845a45a14cc5026221ac1620James Dongstatus_t StagefrightRecorder::setParameter( 578050b28a593350047845a45a14cc5026221ac1620James Dong const String8 &key, const String8 &value) { 5793856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("setParameter: key (%s) => value (%s)", key.string(), value.string()); 580050b28a593350047845a45a14cc5026221ac1620James Dong if (key == "max-duration") { 581ef9d0cd72e476a4b7556833fb09505a51b626797James Dong int64_t max_duration_ms; 582050b28a593350047845a45a14cc5026221ac1620James Dong if (safe_strtoi64(value.string(), &max_duration_ms)) { 583934da11c4cc598d3dd3b53726c362bcdcc0fd37fJames Dong return setParamMaxFileDurationUs(1000LL * max_duration_ms); 584050b28a593350047845a45a14cc5026221ac1620James Dong } 585050b28a593350047845a45a14cc5026221ac1620James Dong } else if (key == "max-filesize") { 586ef9d0cd72e476a4b7556833fb09505a51b626797James Dong int64_t max_filesize_bytes; 587050b28a593350047845a45a14cc5026221ac1620James Dong if (safe_strtoi64(value.string(), &max_filesize_bytes)) { 588934da11c4cc598d3dd3b53726c362bcdcc0fd37fJames Dong return setParamMaxFileSizeBytes(max_filesize_bytes); 589050b28a593350047845a45a14cc5026221ac1620James Dong } 59093d6b102a13afa23bfa80d74c399d93d542e6ad6James Dong } else if (key == "interleave-duration-us") { 59193d6b102a13afa23bfa80d74c399d93d542e6ad6James Dong int32_t durationUs; 59293d6b102a13afa23bfa80d74c399d93d542e6ad6James Dong if (safe_strtoi32(value.string(), &durationUs)) { 59393d6b102a13afa23bfa80d74c399d93d542e6ad6James Dong return setParamInterleaveDuration(durationUs); 59493d6b102a13afa23bfa80d74c399d93d542e6ad6James Dong } 5958f5f2fcee5c12d08df71d17017410c50951fc2e3James Dong } else if (key == "param-movie-time-scale") { 5968f5f2fcee5c12d08df71d17017410c50951fc2e3James Dong int32_t timeScale; 5978f5f2fcee5c12d08df71d17017410c50951fc2e3James Dong if (safe_strtoi32(value.string(), &timeScale)) { 5988f5f2fcee5c12d08df71d17017410c50951fc2e3James Dong return setParamMovieTimeScale(timeScale); 5998f5f2fcee5c12d08df71d17017410c50951fc2e3James Dong } 60093d6b102a13afa23bfa80d74c399d93d542e6ad6James Dong } else if (key == "param-use-64bit-offset") { 60193d6b102a13afa23bfa80d74c399d93d542e6ad6James Dong int32_t use64BitOffset; 60293d6b102a13afa23bfa80d74c399d93d542e6ad6James Dong if (safe_strtoi32(value.string(), &use64BitOffset)) { 60393d6b102a13afa23bfa80d74c399d93d542e6ad6James Dong return setParam64BitFileOffset(use64BitOffset != 0); 60493d6b102a13afa23bfa80d74c399d93d542e6ad6James Dong } 60507b1bb529a1ae76c46a71b01338c166f9490629dJames Dong } else if (key == "param-geotag-longitude") { 606b832a03d563dd000faa44f2577e92237525edc32James Dong int64_t longitudex10000; 607b832a03d563dd000faa44f2577e92237525edc32James Dong if (safe_strtoi64(value.string(), &longitudex10000)) { 60807b1bb529a1ae76c46a71b01338c166f9490629dJames Dong return setParamGeoDataLongitude(longitudex10000); 60907b1bb529a1ae76c46a71b01338c166f9490629dJames Dong } 61007b1bb529a1ae76c46a71b01338c166f9490629dJames Dong } else if (key == "param-geotag-latitude") { 611b832a03d563dd000faa44f2577e92237525edc32James Dong int64_t latitudex10000; 612b832a03d563dd000faa44f2577e92237525edc32James Dong if (safe_strtoi64(value.string(), &latitudex10000)) { 61307b1bb529a1ae76c46a71b01338c166f9490629dJames Dong return setParamGeoDataLatitude(latitudex10000); 61407b1bb529a1ae76c46a71b01338c166f9490629dJames Dong } 61593d6b102a13afa23bfa80d74c399d93d542e6ad6James Dong } else if (key == "param-track-time-status") { 61693d6b102a13afa23bfa80d74c399d93d542e6ad6James Dong int64_t timeDurationUs; 61793d6b102a13afa23bfa80d74c399d93d542e6ad6James Dong if (safe_strtoi64(value.string(), &timeDurationUs)) { 61893d6b102a13afa23bfa80d74c399d93d542e6ad6James Dong return setParamTrackTimeStatus(timeDurationUs); 61993d6b102a13afa23bfa80d74c399d93d542e6ad6James Dong } 620050b28a593350047845a45a14cc5026221ac1620James Dong } else if (key == "audio-param-sampling-rate") { 621050b28a593350047845a45a14cc5026221ac1620James Dong int32_t sampling_rate; 622ef9d0cd72e476a4b7556833fb09505a51b626797James Dong if (safe_strtoi32(value.string(), &sampling_rate)) { 623050b28a593350047845a45a14cc5026221ac1620James Dong return setParamAudioSamplingRate(sampling_rate); 624050b28a593350047845a45a14cc5026221ac1620James Dong } 625050b28a593350047845a45a14cc5026221ac1620James Dong } else if (key == "audio-param-number-of-channels") { 626050b28a593350047845a45a14cc5026221ac1620James Dong int32_t number_of_channels; 627ef9d0cd72e476a4b7556833fb09505a51b626797James Dong if (safe_strtoi32(value.string(), &number_of_channels)) { 628050b28a593350047845a45a14cc5026221ac1620James Dong return setParamAudioNumberOfChannels(number_of_channels); 629050b28a593350047845a45a14cc5026221ac1620James Dong } 630050b28a593350047845a45a14cc5026221ac1620James Dong } else if (key == "audio-param-encoding-bitrate") { 631050b28a593350047845a45a14cc5026221ac1620James Dong int32_t audio_bitrate; 632ef9d0cd72e476a4b7556833fb09505a51b626797James Dong if (safe_strtoi32(value.string(), &audio_bitrate)) { 633050b28a593350047845a45a14cc5026221ac1620James Dong return setParamAudioEncodingBitRate(audio_bitrate); 634050b28a593350047845a45a14cc5026221ac1620James Dong } 6358f5f2fcee5c12d08df71d17017410c50951fc2e3James Dong } else if (key == "audio-param-time-scale") { 6368f5f2fcee5c12d08df71d17017410c50951fc2e3James Dong int32_t timeScale; 6378f5f2fcee5c12d08df71d17017410c50951fc2e3James Dong if (safe_strtoi32(value.string(), &timeScale)) { 6388f5f2fcee5c12d08df71d17017410c50951fc2e3James Dong return setParamAudioTimeScale(timeScale); 6398f5f2fcee5c12d08df71d17017410c50951fc2e3James Dong } 640050b28a593350047845a45a14cc5026221ac1620James Dong } else if (key == "video-param-encoding-bitrate") { 641050b28a593350047845a45a14cc5026221ac1620James Dong int32_t video_bitrate; 642ef9d0cd72e476a4b7556833fb09505a51b626797James Dong if (safe_strtoi32(value.string(), &video_bitrate)) { 643050b28a593350047845a45a14cc5026221ac1620James Dong return setParamVideoEncodingBitRate(video_bitrate); 644050b28a593350047845a45a14cc5026221ac1620James Dong } 64513f6284305e4b27395a23db7882d670bdb1bcae1James Dong } else if (key == "video-param-rotation-angle-degrees") { 64613f6284305e4b27395a23db7882d670bdb1bcae1James Dong int32_t degrees; 64713f6284305e4b27395a23db7882d670bdb1bcae1James Dong if (safe_strtoi32(value.string(), °rees)) { 64813f6284305e4b27395a23db7882d670bdb1bcae1James Dong return setParamVideoRotation(degrees); 64913f6284305e4b27395a23db7882d670bdb1bcae1James Dong } 65093d6b102a13afa23bfa80d74c399d93d542e6ad6James Dong } else if (key == "video-param-i-frames-interval") { 6518f5f2fcee5c12d08df71d17017410c50951fc2e3James Dong int32_t seconds; 6528f5f2fcee5c12d08df71d17017410c50951fc2e3James Dong if (safe_strtoi32(value.string(), &seconds)) { 6538f5f2fcee5c12d08df71d17017410c50951fc2e3James Dong return setParamVideoIFramesInterval(seconds); 654ddcc4a66d848deef6fb4689e64e30cd9bd2684feJames Dong } 655145bfe5eb3e08c9689c28f6bf3287a979438b04bJames Dong } else if (key == "video-param-encoder-profile") { 656145bfe5eb3e08c9689c28f6bf3287a979438b04bJames Dong int32_t profile; 657145bfe5eb3e08c9689c28f6bf3287a979438b04bJames Dong if (safe_strtoi32(value.string(), &profile)) { 658145bfe5eb3e08c9689c28f6bf3287a979438b04bJames Dong return setParamVideoEncoderProfile(profile); 659145bfe5eb3e08c9689c28f6bf3287a979438b04bJames Dong } 660145bfe5eb3e08c9689c28f6bf3287a979438b04bJames Dong } else if (key == "video-param-encoder-level") { 661145bfe5eb3e08c9689c28f6bf3287a979438b04bJames Dong int32_t level; 662145bfe5eb3e08c9689c28f6bf3287a979438b04bJames Dong if (safe_strtoi32(value.string(), &level)) { 663145bfe5eb3e08c9689c28f6bf3287a979438b04bJames Dong return setParamVideoEncoderLevel(level); 664145bfe5eb3e08c9689c28f6bf3287a979438b04bJames Dong } 66593d6b102a13afa23bfa80d74c399d93d542e6ad6James Dong } else if (key == "video-param-camera-id") { 66693d6b102a13afa23bfa80d74c399d93d542e6ad6James Dong int32_t cameraId; 66793d6b102a13afa23bfa80d74c399d93d542e6ad6James Dong if (safe_strtoi32(value.string(), &cameraId)) { 66893d6b102a13afa23bfa80d74c399d93d542e6ad6James Dong return setParamVideoCameraId(cameraId); 6692dec2b5be2056c6d9428897dc672185872d30d17James Dong } 6708f5f2fcee5c12d08df71d17017410c50951fc2e3James Dong } else if (key == "video-param-time-scale") { 6718f5f2fcee5c12d08df71d17017410c50951fc2e3James Dong int32_t timeScale; 6728f5f2fcee5c12d08df71d17017410c50951fc2e3James Dong if (safe_strtoi32(value.string(), &timeScale)) { 6738f5f2fcee5c12d08df71d17017410c50951fc2e3James Dong return setParamVideoTimeScale(timeScale); 6748f5f2fcee5c12d08df71d17017410c50951fc2e3James Dong } 675e4e0a6994d39c4a7cba09c5fff442b2dca1df8f8Nipun Kwatra } else if (key == "time-lapse-enable") { 676e4e0a6994d39c4a7cba09c5fff442b2dca1df8f8Nipun Kwatra int32_t timeLapseEnable; 677e4e0a6994d39c4a7cba09c5fff442b2dca1df8f8Nipun Kwatra if (safe_strtoi32(value.string(), &timeLapseEnable)) { 678e4e0a6994d39c4a7cba09c5fff442b2dca1df8f8Nipun Kwatra return setParamTimeLapseEnable(timeLapseEnable); 679e4e0a6994d39c4a7cba09c5fff442b2dca1df8f8Nipun Kwatra } 680e4e0a6994d39c4a7cba09c5fff442b2dca1df8f8Nipun Kwatra } else if (key == "time-between-time-lapse-frame-capture") { 681e4e0a6994d39c4a7cba09c5fff442b2dca1df8f8Nipun Kwatra int64_t timeBetweenTimeLapseFrameCaptureMs; 682e4e0a6994d39c4a7cba09c5fff442b2dca1df8f8Nipun Kwatra if (safe_strtoi64(value.string(), &timeBetweenTimeLapseFrameCaptureMs)) { 683e4e0a6994d39c4a7cba09c5fff442b2dca1df8f8Nipun Kwatra return setParamTimeBetweenTimeLapseFrameCapture( 684e4e0a6994d39c4a7cba09c5fff442b2dca1df8f8Nipun Kwatra 1000LL * timeBetweenTimeLapseFrameCaptureMs); 685e4e0a6994d39c4a7cba09c5fff442b2dca1df8f8Nipun Kwatra } 686050b28a593350047845a45a14cc5026221ac1620James Dong } else { 68729357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("setParameter: failed to find key %s", key.string()); 688050b28a593350047845a45a14cc5026221ac1620James Dong } 689ef9d0cd72e476a4b7556833fb09505a51b626797James Dong return BAD_VALUE; 690050b28a593350047845a45a14cc5026221ac1620James Dong} 69130ab66297501757d745b9ae10da61adcd891f497Andreas Huber 692050b28a593350047845a45a14cc5026221ac1620James Dongstatus_t StagefrightRecorder::setParameters(const String8 ¶ms) { 6933856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("setParameters: %s", params.string()); 694050b28a593350047845a45a14cc5026221ac1620James Dong const char *cparams = params.string(); 695050b28a593350047845a45a14cc5026221ac1620James Dong const char *key_start = cparams; 696050b28a593350047845a45a14cc5026221ac1620James Dong for (;;) { 697050b28a593350047845a45a14cc5026221ac1620James Dong const char *equal_pos = strchr(key_start, '='); 698050b28a593350047845a45a14cc5026221ac1620James Dong if (equal_pos == NULL) { 69929357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("Parameters %s miss a value", cparams); 700050b28a593350047845a45a14cc5026221ac1620James Dong return BAD_VALUE; 701050b28a593350047845a45a14cc5026221ac1620James Dong } 702050b28a593350047845a45a14cc5026221ac1620James Dong String8 key(key_start, equal_pos - key_start); 703050b28a593350047845a45a14cc5026221ac1620James Dong TrimString(&key); 704050b28a593350047845a45a14cc5026221ac1620James Dong if (key.length() == 0) { 70529357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("Parameters %s contains an empty key", cparams); 706050b28a593350047845a45a14cc5026221ac1620James Dong return BAD_VALUE; 707050b28a593350047845a45a14cc5026221ac1620James Dong } 708050b28a593350047845a45a14cc5026221ac1620James Dong const char *value_start = equal_pos + 1; 709050b28a593350047845a45a14cc5026221ac1620James Dong const char *semicolon_pos = strchr(value_start, ';'); 710050b28a593350047845a45a14cc5026221ac1620James Dong String8 value; 711050b28a593350047845a45a14cc5026221ac1620James Dong if (semicolon_pos == NULL) { 712050b28a593350047845a45a14cc5026221ac1620James Dong value.setTo(value_start); 713050b28a593350047845a45a14cc5026221ac1620James Dong } else { 714050b28a593350047845a45a14cc5026221ac1620James Dong value.setTo(value_start, semicolon_pos - value_start); 715050b28a593350047845a45a14cc5026221ac1620James Dong } 716050b28a593350047845a45a14cc5026221ac1620James Dong if (setParameter(key, value) != OK) { 717050b28a593350047845a45a14cc5026221ac1620James Dong return BAD_VALUE; 718050b28a593350047845a45a14cc5026221ac1620James Dong } 719050b28a593350047845a45a14cc5026221ac1620James Dong if (semicolon_pos == NULL) { 720050b28a593350047845a45a14cc5026221ac1620James Dong break; // Reaches the end 721050b28a593350047845a45a14cc5026221ac1620James Dong } 722050b28a593350047845a45a14cc5026221ac1620James Dong key_start = semicolon_pos + 1; 723050b28a593350047845a45a14cc5026221ac1620James Dong } 72430ab66297501757d745b9ae10da61adcd891f497Andreas Huber return OK; 72530ab66297501757d745b9ae10da61adcd891f497Andreas Huber} 72630ab66297501757d745b9ae10da61adcd891f497Andreas Huber 72737047fceba836f341d0108beed0991b0f8dfc543James Dongstatus_t StagefrightRecorder::setListener(const sp<IMediaRecorderClient> &listener) { 72830ab66297501757d745b9ae10da61adcd891f497Andreas Huber mListener = listener; 72930ab66297501757d745b9ae10da61adcd891f497Andreas Huber 73030ab66297501757d745b9ae10da61adcd891f497Andreas Huber return OK; 73130ab66297501757d745b9ae10da61adcd891f497Andreas Huber} 73230ab66297501757d745b9ae10da61adcd891f497Andreas Huber 73330ab66297501757d745b9ae10da61adcd891f497Andreas Huberstatus_t StagefrightRecorder::prepare() { 73430ab66297501757d745b9ae10da61adcd891f497Andreas Huber return OK; 73530ab66297501757d745b9ae10da61adcd891f497Andreas Huber} 73630ab66297501757d745b9ae10da61adcd891f497Andreas Huber 73730ab66297501757d745b9ae10da61adcd891f497Andreas Huberstatus_t StagefrightRecorder::start() { 738f1d5aa162c02a16b7195a43a9bcea4d592600ac4James Dong CHECK_GE(mOutputFd, 0); 739934da11c4cc598d3dd3b53726c362bcdcc0fd37fJames Dong 74030ab66297501757d745b9ae10da61adcd891f497Andreas Huber if (mWriter != NULL) { 74129357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("File writer is not avaialble"); 74230ab66297501757d745b9ae10da61adcd891f497Andreas Huber return UNKNOWN_ERROR; 74330ab66297501757d745b9ae10da61adcd891f497Andreas Huber } 74430ab66297501757d745b9ae10da61adcd891f497Andreas Huber 74575b0b5473c7b43f8c5972db7e6e8930988ead751Gloria Wang status_t status = OK; 74675b0b5473c7b43f8c5972db7e6e8930988ead751Gloria Wang 7472dce41ad26cb3e9e15c9e456a84bcf5309548ca0Andreas Huber switch (mOutputFormat) { 7482dce41ad26cb3e9e15c9e456a84bcf5309548ca0Andreas Huber case OUTPUT_FORMAT_DEFAULT: 7492dce41ad26cb3e9e15c9e456a84bcf5309548ca0Andreas Huber case OUTPUT_FORMAT_THREE_GPP: 7502dce41ad26cb3e9e15c9e456a84bcf5309548ca0Andreas Huber case OUTPUT_FORMAT_MPEG_4: 75175b0b5473c7b43f8c5972db7e6e8930988ead751Gloria Wang status = startMPEG4Recording(); 75275b0b5473c7b43f8c5972db7e6e8930988ead751Gloria Wang break; 7532dce41ad26cb3e9e15c9e456a84bcf5309548ca0Andreas Huber 7542dce41ad26cb3e9e15c9e456a84bcf5309548ca0Andreas Huber case OUTPUT_FORMAT_AMR_NB: 7552dce41ad26cb3e9e15c9e456a84bcf5309548ca0Andreas Huber case OUTPUT_FORMAT_AMR_WB: 75675b0b5473c7b43f8c5972db7e6e8930988ead751Gloria Wang status = startAMRRecording(); 75775b0b5473c7b43f8c5972db7e6e8930988ead751Gloria Wang break; 7582dce41ad26cb3e9e15c9e456a84bcf5309548ca0Andreas Huber 759ef9d0cd72e476a4b7556833fb09505a51b626797James Dong case OUTPUT_FORMAT_AAC_ADIF: 760ef9d0cd72e476a4b7556833fb09505a51b626797James Dong case OUTPUT_FORMAT_AAC_ADTS: 76175b0b5473c7b43f8c5972db7e6e8930988ead751Gloria Wang status = startAACRecording(); 76275b0b5473c7b43f8c5972db7e6e8930988ead751Gloria Wang break; 763ef9d0cd72e476a4b7556833fb09505a51b626797James Dong 76439ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber case OUTPUT_FORMAT_RTP_AVP: 76575b0b5473c7b43f8c5972db7e6e8930988ead751Gloria Wang status = startRTPRecording(); 76675b0b5473c7b43f8c5972db7e6e8930988ead751Gloria Wang break; 76739ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 76859b7dc39ea8332d3418a599e51447d7edb612ac4Andreas Huber case OUTPUT_FORMAT_MPEG2TS: 76975b0b5473c7b43f8c5972db7e6e8930988ead751Gloria Wang status = startMPEG2TSRecording(); 77075b0b5473c7b43f8c5972db7e6e8930988ead751Gloria Wang break; 77159b7dc39ea8332d3418a599e51447d7edb612ac4Andreas Huber 7722dce41ad26cb3e9e15c9e456a84bcf5309548ca0Andreas Huber default: 77329357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("Unsupported output file format: %d", mOutputFormat); 77475b0b5473c7b43f8c5972db7e6e8930988ead751Gloria Wang status = UNKNOWN_ERROR; 77575b0b5473c7b43f8c5972db7e6e8930988ead751Gloria Wang break; 77675b0b5473c7b43f8c5972db7e6e8930988ead751Gloria Wang } 77775b0b5473c7b43f8c5972db7e6e8930988ead751Gloria Wang 77875b0b5473c7b43f8c5972db7e6e8930988ead751Gloria Wang if ((status == OK) && (!mStarted)) { 77975b0b5473c7b43f8c5972db7e6e8930988ead751Gloria Wang mStarted = true; 78075b0b5473c7b43f8c5972db7e6e8930988ead751Gloria Wang 78175b0b5473c7b43f8c5972db7e6e8930988ead751Gloria Wang uint32_t params = IMediaPlayerService::kBatteryDataCodecStarted; 782fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin if (mAudioSource != AUDIO_SOURCE_CNT) { 78375b0b5473c7b43f8c5972db7e6e8930988ead751Gloria Wang params |= IMediaPlayerService::kBatteryDataTrackAudio; 78475b0b5473c7b43f8c5972db7e6e8930988ead751Gloria Wang } 78575b0b5473c7b43f8c5972db7e6e8930988ead751Gloria Wang if (mVideoSource != VIDEO_SOURCE_LIST_END) { 78675b0b5473c7b43f8c5972db7e6e8930988ead751Gloria Wang params |= IMediaPlayerService::kBatteryDataTrackVideo; 78775b0b5473c7b43f8c5972db7e6e8930988ead751Gloria Wang } 78875b0b5473c7b43f8c5972db7e6e8930988ead751Gloria Wang 78975b0b5473c7b43f8c5972db7e6e8930988ead751Gloria Wang addBatteryData(params); 7902dce41ad26cb3e9e15c9e456a84bcf5309548ca0Andreas Huber } 79175b0b5473c7b43f8c5972db7e6e8930988ead751Gloria Wang 79275b0b5473c7b43f8c5972db7e6e8930988ead751Gloria Wang return status; 7932dce41ad26cb3e9e15c9e456a84bcf5309548ca0Andreas Huber} 7942dce41ad26cb3e9e15c9e456a84bcf5309548ca0Andreas Huber 795050b28a593350047845a45a14cc5026221ac1620James Dongsp<MediaSource> StagefrightRecorder::createAudioSource() { 7962dce41ad26cb3e9e15c9e456a84bcf5309548ca0Andreas Huber sp<AudioSource> audioSource = 7972dce41ad26cb3e9e15c9e456a84bcf5309548ca0Andreas Huber new AudioSource( 7982dce41ad26cb3e9e15c9e456a84bcf5309548ca0Andreas Huber mAudioSource, 799050b28a593350047845a45a14cc5026221ac1620James Dong mSampleRate, 800be6ec71af2d12e2a55f2f0b1b77d3fa5d593a1c7James Dong mAudioChannels); 8012dce41ad26cb3e9e15c9e456a84bcf5309548ca0Andreas Huber 8022dce41ad26cb3e9e15c9e456a84bcf5309548ca0Andreas Huber status_t err = audioSource->initCheck(); 8032dce41ad26cb3e9e15c9e456a84bcf5309548ca0Andreas Huber 8042dce41ad26cb3e9e15c9e456a84bcf5309548ca0Andreas Huber if (err != OK) { 80529357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("audio source is not initialized"); 8062dce41ad26cb3e9e15c9e456a84bcf5309548ca0Andreas Huber return NULL; 8072dce41ad26cb3e9e15c9e456a84bcf5309548ca0Andreas Huber } 8082dce41ad26cb3e9e15c9e456a84bcf5309548ca0Andreas Huber 8092dce41ad26cb3e9e15c9e456a84bcf5309548ca0Andreas Huber sp<MetaData> encMeta = new MetaData; 810050b28a593350047845a45a14cc5026221ac1620James Dong const char *mime; 811050b28a593350047845a45a14cc5026221ac1620James Dong switch (mAudioEncoder) { 812050b28a593350047845a45a14cc5026221ac1620James Dong case AUDIO_ENCODER_AMR_NB: 813050b28a593350047845a45a14cc5026221ac1620James Dong case AUDIO_ENCODER_DEFAULT: 814050b28a593350047845a45a14cc5026221ac1620James Dong mime = MEDIA_MIMETYPE_AUDIO_AMR_NB; 815050b28a593350047845a45a14cc5026221ac1620James Dong break; 816050b28a593350047845a45a14cc5026221ac1620James Dong case AUDIO_ENCODER_AMR_WB: 817050b28a593350047845a45a14cc5026221ac1620James Dong mime = MEDIA_MIMETYPE_AUDIO_AMR_WB; 818050b28a593350047845a45a14cc5026221ac1620James Dong break; 819050b28a593350047845a45a14cc5026221ac1620James Dong case AUDIO_ENCODER_AAC: 820050b28a593350047845a45a14cc5026221ac1620James Dong mime = MEDIA_MIMETYPE_AUDIO_AAC; 821aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke encMeta->setInt32(kKeyAACProfile, OMX_AUDIO_AACObjectLC); 822aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke break; 823f60c660f048d5f5e2458cff243c20400d73757a7Dave Burke case AUDIO_ENCODER_HE_AAC: 824f60c660f048d5f5e2458cff243c20400d73757a7Dave Burke mime = MEDIA_MIMETYPE_AUDIO_AAC; 825f60c660f048d5f5e2458cff243c20400d73757a7Dave Burke encMeta->setInt32(kKeyAACProfile, OMX_AUDIO_AACObjectHE); 826f60c660f048d5f5e2458cff243c20400d73757a7Dave Burke break; 827aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke case AUDIO_ENCODER_AAC_ELD: 828aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke mime = MEDIA_MIMETYPE_AUDIO_AAC; 829aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke encMeta->setInt32(kKeyAACProfile, OMX_AUDIO_AACObjectELD); 830050b28a593350047845a45a14cc5026221ac1620James Dong break; 831f60c660f048d5f5e2458cff243c20400d73757a7Dave Burke 832050b28a593350047845a45a14cc5026221ac1620James Dong default: 83329357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("Unknown audio encoder: %d", mAudioEncoder); 834050b28a593350047845a45a14cc5026221ac1620James Dong return NULL; 835050b28a593350047845a45a14cc5026221ac1620James Dong } 836050b28a593350047845a45a14cc5026221ac1620James Dong encMeta->setCString(kKeyMIMEType, mime); 8372dce41ad26cb3e9e15c9e456a84bcf5309548ca0Andreas Huber 838b45c62c8e9b05c2703bdae18cc298ae55550db8aAndreas Huber int32_t maxInputSize; 839b45c62c8e9b05c2703bdae18cc298ae55550db8aAndreas Huber CHECK(audioSource->getFormat()->findInt32( 840b45c62c8e9b05c2703bdae18cc298ae55550db8aAndreas Huber kKeyMaxInputSize, &maxInputSize)); 841b45c62c8e9b05c2703bdae18cc298ae55550db8aAndreas Huber 842b45c62c8e9b05c2703bdae18cc298ae55550db8aAndreas Huber encMeta->setInt32(kKeyMaxInputSize, maxInputSize); 843050b28a593350047845a45a14cc5026221ac1620James Dong encMeta->setInt32(kKeyChannelCount, mAudioChannels); 844050b28a593350047845a45a14cc5026221ac1620James Dong encMeta->setInt32(kKeySampleRate, mSampleRate); 845ef9d0cd72e476a4b7556833fb09505a51b626797James Dong encMeta->setInt32(kKeyBitRate, mAudioBitRate); 846c059860c73678a202bfa33062723e8f82fb779d9James Dong if (mAudioTimeScale > 0) { 847c059860c73678a202bfa33062723e8f82fb779d9James Dong encMeta->setInt32(kKeyTimeScale, mAudioTimeScale); 848c059860c73678a202bfa33062723e8f82fb779d9James Dong } 8492dce41ad26cb3e9e15c9e456a84bcf5309548ca0Andreas Huber 8502dce41ad26cb3e9e15c9e456a84bcf5309548ca0Andreas Huber OMXClient client; 851f1d5aa162c02a16b7195a43a9bcea4d592600ac4James Dong CHECK_EQ(client.connect(), (status_t)OK); 8522dce41ad26cb3e9e15c9e456a84bcf5309548ca0Andreas Huber sp<MediaSource> audioEncoder = 8532dce41ad26cb3e9e15c9e456a84bcf5309548ca0Andreas Huber OMXCodec::Create(client.interface(), encMeta, 8542dce41ad26cb3e9e15c9e456a84bcf5309548ca0Andreas Huber true /* createEncoder */, audioSource); 855d3d4e5069e1af0437c4f5a7b4ba344bda5b937afJames Dong mAudioSourceNode = audioSource; 8562dce41ad26cb3e9e15c9e456a84bcf5309548ca0Andreas Huber 8572dce41ad26cb3e9e15c9e456a84bcf5309548ca0Andreas Huber return audioEncoder; 8582dce41ad26cb3e9e15c9e456a84bcf5309548ca0Andreas Huber} 8592dce41ad26cb3e9e15c9e456a84bcf5309548ca0Andreas Huber 860ef9d0cd72e476a4b7556833fb09505a51b626797James Dongstatus_t StagefrightRecorder::startAACRecording() { 861760943b5e7a09b602aba04ec451e97662f48b0a4James Dong // FIXME: 862760943b5e7a09b602aba04ec451e97662f48b0a4James Dong // Add support for OUTPUT_FORMAT_AAC_ADIF 863f1d5aa162c02a16b7195a43a9bcea4d592600ac4James Dong CHECK_EQ(mOutputFormat, OUTPUT_FORMAT_AAC_ADTS); 864ef9d0cd72e476a4b7556833fb09505a51b626797James Dong 865aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke CHECK(mAudioEncoder == AUDIO_ENCODER_AAC || 866f60c660f048d5f5e2458cff243c20400d73757a7Dave Burke mAudioEncoder == AUDIO_ENCODER_HE_AAC || 867aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke mAudioEncoder == AUDIO_ENCODER_AAC_ELD); 868fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin CHECK(mAudioSource != AUDIO_SOURCE_CNT); 869ef9d0cd72e476a4b7556833fb09505a51b626797James Dong 870760943b5e7a09b602aba04ec451e97662f48b0a4James Dong mWriter = new AACWriter(mOutputFd); 871760943b5e7a09b602aba04ec451e97662f48b0a4James Dong status_t status = startRawAudioRecording(); 872760943b5e7a09b602aba04ec451e97662f48b0a4James Dong if (status != OK) { 873760943b5e7a09b602aba04ec451e97662f48b0a4James Dong mWriter.clear(); 874760943b5e7a09b602aba04ec451e97662f48b0a4James Dong mWriter = NULL; 875760943b5e7a09b602aba04ec451e97662f48b0a4James Dong } 876ef9d0cd72e476a4b7556833fb09505a51b626797James Dong 877760943b5e7a09b602aba04ec451e97662f48b0a4James Dong return status; 878ef9d0cd72e476a4b7556833fb09505a51b626797James Dong} 879ef9d0cd72e476a4b7556833fb09505a51b626797James Dong 8802dce41ad26cb3e9e15c9e456a84bcf5309548ca0Andreas Huberstatus_t StagefrightRecorder::startAMRRecording() { 881ef9d0cd72e476a4b7556833fb09505a51b626797James Dong CHECK(mOutputFormat == OUTPUT_FORMAT_AMR_NB || 882ef9d0cd72e476a4b7556833fb09505a51b626797James Dong mOutputFormat == OUTPUT_FORMAT_AMR_WB); 883ef9d0cd72e476a4b7556833fb09505a51b626797James Dong 884ef9d0cd72e476a4b7556833fb09505a51b626797James Dong if (mOutputFormat == OUTPUT_FORMAT_AMR_NB) { 885ef9d0cd72e476a4b7556833fb09505a51b626797James Dong if (mAudioEncoder != AUDIO_ENCODER_DEFAULT && 886ef9d0cd72e476a4b7556833fb09505a51b626797James Dong mAudioEncoder != AUDIO_ENCODER_AMR_NB) { 88729357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("Invalid encoder %d used for AMRNB recording", 888ef9d0cd72e476a4b7556833fb09505a51b626797James Dong mAudioEncoder); 889934da11c4cc598d3dd3b53726c362bcdcc0fd37fJames Dong return BAD_VALUE; 890ef9d0cd72e476a4b7556833fb09505a51b626797James Dong } 891ef9d0cd72e476a4b7556833fb09505a51b626797James Dong } else { // mOutputFormat must be OUTPUT_FORMAT_AMR_WB 892ef9d0cd72e476a4b7556833fb09505a51b626797James Dong if (mAudioEncoder != AUDIO_ENCODER_AMR_WB) { 89329357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("Invlaid encoder %d used for AMRWB recording", 894ef9d0cd72e476a4b7556833fb09505a51b626797James Dong mAudioEncoder); 895934da11c4cc598d3dd3b53726c362bcdcc0fd37fJames Dong return BAD_VALUE; 896ef9d0cd72e476a4b7556833fb09505a51b626797James Dong } 8972dce41ad26cb3e9e15c9e456a84bcf5309548ca0Andreas Huber } 8982dce41ad26cb3e9e15c9e456a84bcf5309548ca0Andreas Huber 899760943b5e7a09b602aba04ec451e97662f48b0a4James Dong mWriter = new AMRWriter(mOutputFd); 900760943b5e7a09b602aba04ec451e97662f48b0a4James Dong status_t status = startRawAudioRecording(); 901760943b5e7a09b602aba04ec451e97662f48b0a4James Dong if (status != OK) { 902760943b5e7a09b602aba04ec451e97662f48b0a4James Dong mWriter.clear(); 903760943b5e7a09b602aba04ec451e97662f48b0a4James Dong mWriter = NULL; 904760943b5e7a09b602aba04ec451e97662f48b0a4James Dong } 905760943b5e7a09b602aba04ec451e97662f48b0a4James Dong return status; 906760943b5e7a09b602aba04ec451e97662f48b0a4James Dong} 907760943b5e7a09b602aba04ec451e97662f48b0a4James Dong 908760943b5e7a09b602aba04ec451e97662f48b0a4James Dongstatus_t StagefrightRecorder::startRawAudioRecording() { 909fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin if (mAudioSource >= AUDIO_SOURCE_CNT) { 91029357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("Invalid audio source: %d", mAudioSource); 911934da11c4cc598d3dd3b53726c362bcdcc0fd37fJames Dong return BAD_VALUE; 9122dce41ad26cb3e9e15c9e456a84bcf5309548ca0Andreas Huber } 9132dce41ad26cb3e9e15c9e456a84bcf5309548ca0Andreas Huber 91442dd1d5f186252a7f09f8fb1a46ea82e3877b2d3James Dong status_t status = BAD_VALUE; 91542dd1d5f186252a7f09f8fb1a46ea82e3877b2d3James Dong if (OK != (status = checkAudioEncoderCapabilities())) { 91642dd1d5f186252a7f09f8fb1a46ea82e3877b2d3James Dong return status; 91742dd1d5f186252a7f09f8fb1a46ea82e3877b2d3James Dong } 9182dce41ad26cb3e9e15c9e456a84bcf5309548ca0Andreas Huber 91942dd1d5f186252a7f09f8fb1a46ea82e3877b2d3James Dong sp<MediaSource> audioEncoder = createAudioSource(); 9202dce41ad26cb3e9e15c9e456a84bcf5309548ca0Andreas Huber if (audioEncoder == NULL) { 9212dce41ad26cb3e9e15c9e456a84bcf5309548ca0Andreas Huber return UNKNOWN_ERROR; 9222dce41ad26cb3e9e15c9e456a84bcf5309548ca0Andreas Huber } 9232dce41ad26cb3e9e15c9e456a84bcf5309548ca0Andreas Huber 924760943b5e7a09b602aba04ec451e97662f48b0a4James Dong CHECK(mWriter != 0); 9252dce41ad26cb3e9e15c9e456a84bcf5309548ca0Andreas Huber mWriter->addSource(audioEncoder); 926d599cd4573b5a2d5914c5040e0565ef866749b77James Dong 927d599cd4573b5a2d5914c5040e0565ef866749b77James Dong if (mMaxFileDurationUs != 0) { 928d599cd4573b5a2d5914c5040e0565ef866749b77James Dong mWriter->setMaxFileDuration(mMaxFileDurationUs); 929d599cd4573b5a2d5914c5040e0565ef866749b77James Dong } 930d599cd4573b5a2d5914c5040e0565ef866749b77James Dong if (mMaxFileSizeBytes != 0) { 931d599cd4573b5a2d5914c5040e0565ef866749b77James Dong mWriter->setMaxFileSize(mMaxFileSizeBytes); 932d599cd4573b5a2d5914c5040e0565ef866749b77James Dong } 933d599cd4573b5a2d5914c5040e0565ef866749b77James Dong mWriter->setListener(mListener); 9342dce41ad26cb3e9e15c9e456a84bcf5309548ca0Andreas Huber mWriter->start(); 9352dce41ad26cb3e9e15c9e456a84bcf5309548ca0Andreas Huber 9362dce41ad26cb3e9e15c9e456a84bcf5309548ca0Andreas Huber return OK; 9372dce41ad26cb3e9e15c9e456a84bcf5309548ca0Andreas Huber} 9382dce41ad26cb3e9e15c9e456a84bcf5309548ca0Andreas Huber 93939ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huberstatus_t StagefrightRecorder::startRTPRecording() { 94039ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber CHECK_EQ(mOutputFormat, OUTPUT_FORMAT_RTP_AVP); 94139ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 942fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin if ((mAudioSource != AUDIO_SOURCE_CNT 94339ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber && mVideoSource != VIDEO_SOURCE_LIST_END) 944fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin || (mAudioSource == AUDIO_SOURCE_CNT 94539ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber && mVideoSource == VIDEO_SOURCE_LIST_END)) { 94639ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber // Must have exactly one source. 94739ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber return BAD_VALUE; 94839ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber } 94939ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 95039ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber if (mOutputFd < 0) { 95139ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber return BAD_VALUE; 95239ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber } 95339ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 95439ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber sp<MediaSource> source; 95539ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 956fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin if (mAudioSource != AUDIO_SOURCE_CNT) { 95739ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber source = createAudioSource(); 95839ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber } else { 9599c075bca0b75093ca0514a3c8f74d73c8e9e83fdNipun Kwatra 960b33f3407bab0970a7f9241680723a1140b177c50Pannag Sanketi sp<MediaSource> mediaSource; 961b33f3407bab0970a7f9241680723a1140b177c50Pannag Sanketi status_t err = setupMediaSource(&mediaSource); 9629c075bca0b75093ca0514a3c8f74d73c8e9e83fdNipun Kwatra if (err != OK) { 9639c075bca0b75093ca0514a3c8f74d73c8e9e83fdNipun Kwatra return err; 9649c075bca0b75093ca0514a3c8f74d73c8e9e83fdNipun Kwatra } 9659c075bca0b75093ca0514a3c8f74d73c8e9e83fdNipun Kwatra 966b33f3407bab0970a7f9241680723a1140b177c50Pannag Sanketi err = setupVideoEncoder(mediaSource, mVideoBitRate, &source); 96739ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber if (err != OK) { 96839ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber return err; 96939ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber } 97039ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber } 97139ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 972674ebd0b4e1143e38392a4e3bb38b4679a4577bcJames Dong mWriter = new ARTPWriter(mOutputFd); 97339ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber mWriter->addSource(source); 97439ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber mWriter->setListener(mListener); 97539ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 97639ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber return mWriter->start(); 97739ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber} 97839ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 97959b7dc39ea8332d3418a599e51447d7edb612ac4Andreas Huberstatus_t StagefrightRecorder::startMPEG2TSRecording() { 98059b7dc39ea8332d3418a599e51447d7edb612ac4Andreas Huber CHECK_EQ(mOutputFormat, OUTPUT_FORMAT_MPEG2TS); 98159b7dc39ea8332d3418a599e51447d7edb612ac4Andreas Huber 982674ebd0b4e1143e38392a4e3bb38b4679a4577bcJames Dong sp<MediaWriter> writer = new MPEG2TSWriter(mOutputFd); 98359b7dc39ea8332d3418a599e51447d7edb612ac4Andreas Huber 984fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin if (mAudioSource != AUDIO_SOURCE_CNT) { 985f60c660f048d5f5e2458cff243c20400d73757a7Dave Burke if (mAudioEncoder != AUDIO_ENCODER_AAC && 986f60c660f048d5f5e2458cff243c20400d73757a7Dave Burke mAudioEncoder != AUDIO_ENCODER_HE_AAC && 987f60c660f048d5f5e2458cff243c20400d73757a7Dave Burke mAudioEncoder != AUDIO_ENCODER_AAC_ELD) { 98859b7dc39ea8332d3418a599e51447d7edb612ac4Andreas Huber return ERROR_UNSUPPORTED; 98959b7dc39ea8332d3418a599e51447d7edb612ac4Andreas Huber } 99059b7dc39ea8332d3418a599e51447d7edb612ac4Andreas Huber 99159b7dc39ea8332d3418a599e51447d7edb612ac4Andreas Huber status_t err = setupAudioEncoder(writer); 99259b7dc39ea8332d3418a599e51447d7edb612ac4Andreas Huber 99359b7dc39ea8332d3418a599e51447d7edb612ac4Andreas Huber if (err != OK) { 99459b7dc39ea8332d3418a599e51447d7edb612ac4Andreas Huber return err; 99559b7dc39ea8332d3418a599e51447d7edb612ac4Andreas Huber } 99659b7dc39ea8332d3418a599e51447d7edb612ac4Andreas Huber } 99759b7dc39ea8332d3418a599e51447d7edb612ac4Andreas Huber 998b33f3407bab0970a7f9241680723a1140b177c50Pannag Sanketi if (mVideoSource < VIDEO_SOURCE_LIST_END) { 99959b7dc39ea8332d3418a599e51447d7edb612ac4Andreas Huber if (mVideoEncoder != VIDEO_ENCODER_H264) { 100059b7dc39ea8332d3418a599e51447d7edb612ac4Andreas Huber return ERROR_UNSUPPORTED; 100159b7dc39ea8332d3418a599e51447d7edb612ac4Andreas Huber } 100259b7dc39ea8332d3418a599e51447d7edb612ac4Andreas Huber 1003b33f3407bab0970a7f9241680723a1140b177c50Pannag Sanketi sp<MediaSource> mediaSource; 1004b33f3407bab0970a7f9241680723a1140b177c50Pannag Sanketi status_t err = setupMediaSource(&mediaSource); 1005f9f083e2853740c97588f4db82c24645ae5880e4Kenny Root if (err != OK) { 1006f9f083e2853740c97588f4db82c24645ae5880e4Kenny Root return err; 1007f9f083e2853740c97588f4db82c24645ae5880e4Kenny Root } 1008f9f083e2853740c97588f4db82c24645ae5880e4Kenny Root 100959b7dc39ea8332d3418a599e51447d7edb612ac4Andreas Huber sp<MediaSource> encoder; 1010b33f3407bab0970a7f9241680723a1140b177c50Pannag Sanketi err = setupVideoEncoder(mediaSource, mVideoBitRate, &encoder); 101159b7dc39ea8332d3418a599e51447d7edb612ac4Andreas Huber 101259b7dc39ea8332d3418a599e51447d7edb612ac4Andreas Huber if (err != OK) { 101359b7dc39ea8332d3418a599e51447d7edb612ac4Andreas Huber return err; 101459b7dc39ea8332d3418a599e51447d7edb612ac4Andreas Huber } 101559b7dc39ea8332d3418a599e51447d7edb612ac4Andreas Huber 101659b7dc39ea8332d3418a599e51447d7edb612ac4Andreas Huber writer->addSource(encoder); 101759b7dc39ea8332d3418a599e51447d7edb612ac4Andreas Huber } 101859b7dc39ea8332d3418a599e51447d7edb612ac4Andreas Huber 101959b7dc39ea8332d3418a599e51447d7edb612ac4Andreas Huber if (mMaxFileDurationUs != 0) { 102059b7dc39ea8332d3418a599e51447d7edb612ac4Andreas Huber writer->setMaxFileDuration(mMaxFileDurationUs); 102159b7dc39ea8332d3418a599e51447d7edb612ac4Andreas Huber } 102259b7dc39ea8332d3418a599e51447d7edb612ac4Andreas Huber 102359b7dc39ea8332d3418a599e51447d7edb612ac4Andreas Huber if (mMaxFileSizeBytes != 0) { 102459b7dc39ea8332d3418a599e51447d7edb612ac4Andreas Huber writer->setMaxFileSize(mMaxFileSizeBytes); 102559b7dc39ea8332d3418a599e51447d7edb612ac4Andreas Huber } 102659b7dc39ea8332d3418a599e51447d7edb612ac4Andreas Huber 102759b7dc39ea8332d3418a599e51447d7edb612ac4Andreas Huber mWriter = writer; 102859b7dc39ea8332d3418a599e51447d7edb612ac4Andreas Huber 102959b7dc39ea8332d3418a599e51447d7edb612ac4Andreas Huber return mWriter->start(); 103059b7dc39ea8332d3418a599e51447d7edb612ac4Andreas Huber} 103159b7dc39ea8332d3418a599e51447d7edb612ac4Andreas Huber 103299c2a076b4a46762a22bbb4dfbd51d107e0532d9James Dongvoid StagefrightRecorder::clipVideoFrameRate() { 10333856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("clipVideoFrameRate: encoder %d", mVideoEncoder); 103499c2a076b4a46762a22bbb4dfbd51d107e0532d9James Dong int minFrameRate = mEncoderProfiles->getVideoEncoderParamByName( 103599c2a076b4a46762a22bbb4dfbd51d107e0532d9James Dong "enc.vid.fps.min", mVideoEncoder); 103699c2a076b4a46762a22bbb4dfbd51d107e0532d9James Dong int maxFrameRate = mEncoderProfiles->getVideoEncoderParamByName( 103799c2a076b4a46762a22bbb4dfbd51d107e0532d9James Dong "enc.vid.fps.max", mVideoEncoder); 1038b4a55269a5b39c73de2cc1d4013d0631ef18c77dJames Dong if (mFrameRate < minFrameRate && minFrameRate != -1) { 10395ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block ALOGW("Intended video encoding frame rate (%d fps) is too small" 104099c2a076b4a46762a22bbb4dfbd51d107e0532d9James Dong " and will be set to (%d fps)", mFrameRate, minFrameRate); 104199c2a076b4a46762a22bbb4dfbd51d107e0532d9James Dong mFrameRate = minFrameRate; 1042b4a55269a5b39c73de2cc1d4013d0631ef18c77dJames Dong } else if (mFrameRate > maxFrameRate && maxFrameRate != -1) { 10435ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block ALOGW("Intended video encoding frame rate (%d fps) is too large" 104499c2a076b4a46762a22bbb4dfbd51d107e0532d9James Dong " and will be set to (%d fps)", mFrameRate, maxFrameRate); 104599c2a076b4a46762a22bbb4dfbd51d107e0532d9James Dong mFrameRate = maxFrameRate; 104699c2a076b4a46762a22bbb4dfbd51d107e0532d9James Dong } 104799c2a076b4a46762a22bbb4dfbd51d107e0532d9James Dong} 104899c2a076b4a46762a22bbb4dfbd51d107e0532d9James Dong 104999c2a076b4a46762a22bbb4dfbd51d107e0532d9James Dongvoid StagefrightRecorder::clipVideoBitRate() { 10503856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("clipVideoBitRate: encoder %d", mVideoEncoder); 105199c2a076b4a46762a22bbb4dfbd51d107e0532d9James Dong int minBitRate = mEncoderProfiles->getVideoEncoderParamByName( 105299c2a076b4a46762a22bbb4dfbd51d107e0532d9James Dong "enc.vid.bps.min", mVideoEncoder); 105399c2a076b4a46762a22bbb4dfbd51d107e0532d9James Dong int maxBitRate = mEncoderProfiles->getVideoEncoderParamByName( 105499c2a076b4a46762a22bbb4dfbd51d107e0532d9James Dong "enc.vid.bps.max", mVideoEncoder); 1055b4a55269a5b39c73de2cc1d4013d0631ef18c77dJames Dong if (mVideoBitRate < minBitRate && minBitRate != -1) { 10565ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block ALOGW("Intended video encoding bit rate (%d bps) is too small" 105799c2a076b4a46762a22bbb4dfbd51d107e0532d9James Dong " and will be set to (%d bps)", mVideoBitRate, minBitRate); 105899c2a076b4a46762a22bbb4dfbd51d107e0532d9James Dong mVideoBitRate = minBitRate; 1059b4a55269a5b39c73de2cc1d4013d0631ef18c77dJames Dong } else if (mVideoBitRate > maxBitRate && maxBitRate != -1) { 10605ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block ALOGW("Intended video encoding bit rate (%d bps) is too large" 106199c2a076b4a46762a22bbb4dfbd51d107e0532d9James Dong " and will be set to (%d bps)", mVideoBitRate, maxBitRate); 106299c2a076b4a46762a22bbb4dfbd51d107e0532d9James Dong mVideoBitRate = maxBitRate; 106399c2a076b4a46762a22bbb4dfbd51d107e0532d9James Dong } 106499c2a076b4a46762a22bbb4dfbd51d107e0532d9James Dong} 106599c2a076b4a46762a22bbb4dfbd51d107e0532d9James Dong 106699c2a076b4a46762a22bbb4dfbd51d107e0532d9James Dongvoid StagefrightRecorder::clipVideoFrameWidth() { 10673856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("clipVideoFrameWidth: encoder %d", mVideoEncoder); 106899c2a076b4a46762a22bbb4dfbd51d107e0532d9James Dong int minFrameWidth = mEncoderProfiles->getVideoEncoderParamByName( 106999c2a076b4a46762a22bbb4dfbd51d107e0532d9James Dong "enc.vid.width.min", mVideoEncoder); 107099c2a076b4a46762a22bbb4dfbd51d107e0532d9James Dong int maxFrameWidth = mEncoderProfiles->getVideoEncoderParamByName( 107199c2a076b4a46762a22bbb4dfbd51d107e0532d9James Dong "enc.vid.width.max", mVideoEncoder); 1072b4a55269a5b39c73de2cc1d4013d0631ef18c77dJames Dong if (mVideoWidth < minFrameWidth && minFrameWidth != -1) { 10735ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block ALOGW("Intended video encoding frame width (%d) is too small" 107499c2a076b4a46762a22bbb4dfbd51d107e0532d9James Dong " and will be set to (%d)", mVideoWidth, minFrameWidth); 107599c2a076b4a46762a22bbb4dfbd51d107e0532d9James Dong mVideoWidth = minFrameWidth; 1076b4a55269a5b39c73de2cc1d4013d0631ef18c77dJames Dong } else if (mVideoWidth > maxFrameWidth && maxFrameWidth != -1) { 10775ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block ALOGW("Intended video encoding frame width (%d) is too large" 107899c2a076b4a46762a22bbb4dfbd51d107e0532d9James Dong " and will be set to (%d)", mVideoWidth, maxFrameWidth); 107999c2a076b4a46762a22bbb4dfbd51d107e0532d9James Dong mVideoWidth = maxFrameWidth; 108099c2a076b4a46762a22bbb4dfbd51d107e0532d9James Dong } 108199c2a076b4a46762a22bbb4dfbd51d107e0532d9James Dong} 108299c2a076b4a46762a22bbb4dfbd51d107e0532d9James Dong 108354ff19ac69ace7c05ea90d225e26dab3b133f487James Dongstatus_t StagefrightRecorder::checkVideoEncoderCapabilities() { 1084ca2fa61ef03cac008ea86e6fe16b2e5f9f1a2be3Nipun Kwatra if (!mCaptureTimeLapse) { 1085e4e0a6994d39c4a7cba09c5fff442b2dca1df8f8Nipun Kwatra // Dont clip for time lapse capture as encoder will have enough 1086e4e0a6994d39c4a7cba09c5fff442b2dca1df8f8Nipun Kwatra // time to encode because of slow capture rate of time lapse. 1087e4e0a6994d39c4a7cba09c5fff442b2dca1df8f8Nipun Kwatra clipVideoBitRate(); 1088e4e0a6994d39c4a7cba09c5fff442b2dca1df8f8Nipun Kwatra clipVideoFrameRate(); 1089e4e0a6994d39c4a7cba09c5fff442b2dca1df8f8Nipun Kwatra clipVideoFrameWidth(); 1090e4e0a6994d39c4a7cba09c5fff442b2dca1df8f8Nipun Kwatra clipVideoFrameHeight(); 1091d552b88515c6ccd18695e5db5e6032a6425d8c63James Dong setDefaultProfileIfNecessary(); 1092e4e0a6994d39c4a7cba09c5fff442b2dca1df8f8Nipun Kwatra } 1093934da11c4cc598d3dd3b53726c362bcdcc0fd37fJames Dong return OK; 1094934da11c4cc598d3dd3b53726c362bcdcc0fd37fJames Dong} 1095934da11c4cc598d3dd3b53726c362bcdcc0fd37fJames Dong 1096d552b88515c6ccd18695e5db5e6032a6425d8c63James Dong// Set to use AVC baseline profile if the encoding parameters matches 1097d552b88515c6ccd18695e5db5e6032a6425d8c63James Dong// CAMCORDER_QUALITY_LOW profile; this is for the sake of MMS service. 1098d552b88515c6ccd18695e5db5e6032a6425d8c63James Dongvoid StagefrightRecorder::setDefaultProfileIfNecessary() { 10993856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("setDefaultProfileIfNecessary"); 1100d552b88515c6ccd18695e5db5e6032a6425d8c63James Dong 1101d552b88515c6ccd18695e5db5e6032a6425d8c63James Dong camcorder_quality quality = CAMCORDER_QUALITY_LOW; 1102d552b88515c6ccd18695e5db5e6032a6425d8c63James Dong 1103d552b88515c6ccd18695e5db5e6032a6425d8c63James Dong int64_t durationUs = mEncoderProfiles->getCamcorderProfileParamByName( 1104d552b88515c6ccd18695e5db5e6032a6425d8c63James Dong "duration", mCameraId, quality) * 1000000LL; 1105d552b88515c6ccd18695e5db5e6032a6425d8c63James Dong 1106d552b88515c6ccd18695e5db5e6032a6425d8c63James Dong int fileFormat = mEncoderProfiles->getCamcorderProfileParamByName( 1107d552b88515c6ccd18695e5db5e6032a6425d8c63James Dong "file.format", mCameraId, quality); 1108d552b88515c6ccd18695e5db5e6032a6425d8c63James Dong 1109d552b88515c6ccd18695e5db5e6032a6425d8c63James Dong int videoCodec = mEncoderProfiles->getCamcorderProfileParamByName( 1110d552b88515c6ccd18695e5db5e6032a6425d8c63James Dong "vid.codec", mCameraId, quality); 1111d552b88515c6ccd18695e5db5e6032a6425d8c63James Dong 1112d552b88515c6ccd18695e5db5e6032a6425d8c63James Dong int videoBitRate = mEncoderProfiles->getCamcorderProfileParamByName( 1113d552b88515c6ccd18695e5db5e6032a6425d8c63James Dong "vid.bps", mCameraId, quality); 1114d552b88515c6ccd18695e5db5e6032a6425d8c63James Dong 1115d552b88515c6ccd18695e5db5e6032a6425d8c63James Dong int videoFrameRate = mEncoderProfiles->getCamcorderProfileParamByName( 1116d552b88515c6ccd18695e5db5e6032a6425d8c63James Dong "vid.fps", mCameraId, quality); 1117d552b88515c6ccd18695e5db5e6032a6425d8c63James Dong 1118d552b88515c6ccd18695e5db5e6032a6425d8c63James Dong int videoFrameWidth = mEncoderProfiles->getCamcorderProfileParamByName( 1119d552b88515c6ccd18695e5db5e6032a6425d8c63James Dong "vid.width", mCameraId, quality); 1120d552b88515c6ccd18695e5db5e6032a6425d8c63James Dong 1121d552b88515c6ccd18695e5db5e6032a6425d8c63James Dong int videoFrameHeight = mEncoderProfiles->getCamcorderProfileParamByName( 1122d552b88515c6ccd18695e5db5e6032a6425d8c63James Dong "vid.height", mCameraId, quality); 1123d552b88515c6ccd18695e5db5e6032a6425d8c63James Dong 1124d552b88515c6ccd18695e5db5e6032a6425d8c63James Dong int audioCodec = mEncoderProfiles->getCamcorderProfileParamByName( 1125d552b88515c6ccd18695e5db5e6032a6425d8c63James Dong "aud.codec", mCameraId, quality); 1126d552b88515c6ccd18695e5db5e6032a6425d8c63James Dong 1127d552b88515c6ccd18695e5db5e6032a6425d8c63James Dong int audioBitRate = mEncoderProfiles->getCamcorderProfileParamByName( 1128d552b88515c6ccd18695e5db5e6032a6425d8c63James Dong "aud.bps", mCameraId, quality); 1129d552b88515c6ccd18695e5db5e6032a6425d8c63James Dong 1130d552b88515c6ccd18695e5db5e6032a6425d8c63James Dong int audioSampleRate = mEncoderProfiles->getCamcorderProfileParamByName( 1131d552b88515c6ccd18695e5db5e6032a6425d8c63James Dong "aud.hz", mCameraId, quality); 1132d552b88515c6ccd18695e5db5e6032a6425d8c63James Dong 1133d552b88515c6ccd18695e5db5e6032a6425d8c63James Dong int audioChannels = mEncoderProfiles->getCamcorderProfileParamByName( 1134d552b88515c6ccd18695e5db5e6032a6425d8c63James Dong "aud.ch", mCameraId, quality); 1135d552b88515c6ccd18695e5db5e6032a6425d8c63James Dong 1136d552b88515c6ccd18695e5db5e6032a6425d8c63James Dong if (durationUs == mMaxFileDurationUs && 1137d552b88515c6ccd18695e5db5e6032a6425d8c63James Dong fileFormat == mOutputFormat && 1138d552b88515c6ccd18695e5db5e6032a6425d8c63James Dong videoCodec == mVideoEncoder && 1139d552b88515c6ccd18695e5db5e6032a6425d8c63James Dong videoBitRate == mVideoBitRate && 1140d552b88515c6ccd18695e5db5e6032a6425d8c63James Dong videoFrameRate == mFrameRate && 1141d552b88515c6ccd18695e5db5e6032a6425d8c63James Dong videoFrameWidth == mVideoWidth && 1142d552b88515c6ccd18695e5db5e6032a6425d8c63James Dong videoFrameHeight == mVideoHeight && 1143d552b88515c6ccd18695e5db5e6032a6425d8c63James Dong audioCodec == mAudioEncoder && 1144d552b88515c6ccd18695e5db5e6032a6425d8c63James Dong audioBitRate == mAudioBitRate && 1145d552b88515c6ccd18695e5db5e6032a6425d8c63James Dong audioSampleRate == mSampleRate && 1146d552b88515c6ccd18695e5db5e6032a6425d8c63James Dong audioChannels == mAudioChannels) { 1147d552b88515c6ccd18695e5db5e6032a6425d8c63James Dong if (videoCodec == VIDEO_ENCODER_H264) { 1148df64d15042bbd5e0e4933ac49bf3c177dd94752cSteve Block ALOGI("Force to use AVC baseline profile"); 1149d552b88515c6ccd18695e5db5e6032a6425d8c63James Dong setParamVideoEncoderProfile(OMX_VIDEO_AVCProfileBaseline); 1150d552b88515c6ccd18695e5db5e6032a6425d8c63James Dong } 1151d552b88515c6ccd18695e5db5e6032a6425d8c63James Dong } 1152d552b88515c6ccd18695e5db5e6032a6425d8c63James Dong} 1153d552b88515c6ccd18695e5db5e6032a6425d8c63James Dong 115442dd1d5f186252a7f09f8fb1a46ea82e3877b2d3James Dongstatus_t StagefrightRecorder::checkAudioEncoderCapabilities() { 115542dd1d5f186252a7f09f8fb1a46ea82e3877b2d3James Dong clipAudioBitRate(); 115642dd1d5f186252a7f09f8fb1a46ea82e3877b2d3James Dong clipAudioSampleRate(); 115742dd1d5f186252a7f09f8fb1a46ea82e3877b2d3James Dong clipNumberOfAudioChannels(); 115842dd1d5f186252a7f09f8fb1a46ea82e3877b2d3James Dong return OK; 115942dd1d5f186252a7f09f8fb1a46ea82e3877b2d3James Dong} 116042dd1d5f186252a7f09f8fb1a46ea82e3877b2d3James Dong 116142dd1d5f186252a7f09f8fb1a46ea82e3877b2d3James Dongvoid StagefrightRecorder::clipAudioBitRate() { 11623856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("clipAudioBitRate: encoder %d", mAudioEncoder); 116342dd1d5f186252a7f09f8fb1a46ea82e3877b2d3James Dong 116442dd1d5f186252a7f09f8fb1a46ea82e3877b2d3James Dong int minAudioBitRate = 116542dd1d5f186252a7f09f8fb1a46ea82e3877b2d3James Dong mEncoderProfiles->getAudioEncoderParamByName( 116642dd1d5f186252a7f09f8fb1a46ea82e3877b2d3James Dong "enc.aud.bps.min", mAudioEncoder); 1167b4a55269a5b39c73de2cc1d4013d0631ef18c77dJames Dong if (minAudioBitRate != -1 && mAudioBitRate < minAudioBitRate) { 11685ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block ALOGW("Intended audio encoding bit rate (%d) is too small" 116942dd1d5f186252a7f09f8fb1a46ea82e3877b2d3James Dong " and will be set to (%d)", mAudioBitRate, minAudioBitRate); 117042dd1d5f186252a7f09f8fb1a46ea82e3877b2d3James Dong mAudioBitRate = minAudioBitRate; 117142dd1d5f186252a7f09f8fb1a46ea82e3877b2d3James Dong } 117242dd1d5f186252a7f09f8fb1a46ea82e3877b2d3James Dong 117342dd1d5f186252a7f09f8fb1a46ea82e3877b2d3James Dong int maxAudioBitRate = 117442dd1d5f186252a7f09f8fb1a46ea82e3877b2d3James Dong mEncoderProfiles->getAudioEncoderParamByName( 117542dd1d5f186252a7f09f8fb1a46ea82e3877b2d3James Dong "enc.aud.bps.max", mAudioEncoder); 1176b4a55269a5b39c73de2cc1d4013d0631ef18c77dJames Dong if (maxAudioBitRate != -1 && mAudioBitRate > maxAudioBitRate) { 11775ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block ALOGW("Intended audio encoding bit rate (%d) is too large" 117842dd1d5f186252a7f09f8fb1a46ea82e3877b2d3James Dong " and will be set to (%d)", mAudioBitRate, maxAudioBitRate); 117942dd1d5f186252a7f09f8fb1a46ea82e3877b2d3James Dong mAudioBitRate = maxAudioBitRate; 118042dd1d5f186252a7f09f8fb1a46ea82e3877b2d3James Dong } 118142dd1d5f186252a7f09f8fb1a46ea82e3877b2d3James Dong} 118242dd1d5f186252a7f09f8fb1a46ea82e3877b2d3James Dong 118342dd1d5f186252a7f09f8fb1a46ea82e3877b2d3James Dongvoid StagefrightRecorder::clipAudioSampleRate() { 11843856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("clipAudioSampleRate: encoder %d", mAudioEncoder); 118542dd1d5f186252a7f09f8fb1a46ea82e3877b2d3James Dong 118642dd1d5f186252a7f09f8fb1a46ea82e3877b2d3James Dong int minSampleRate = 118742dd1d5f186252a7f09f8fb1a46ea82e3877b2d3James Dong mEncoderProfiles->getAudioEncoderParamByName( 118842dd1d5f186252a7f09f8fb1a46ea82e3877b2d3James Dong "enc.aud.hz.min", mAudioEncoder); 1189b4a55269a5b39c73de2cc1d4013d0631ef18c77dJames Dong if (minSampleRate != -1 && mSampleRate < minSampleRate) { 11905ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block ALOGW("Intended audio sample rate (%d) is too small" 119142dd1d5f186252a7f09f8fb1a46ea82e3877b2d3James Dong " and will be set to (%d)", mSampleRate, minSampleRate); 119242dd1d5f186252a7f09f8fb1a46ea82e3877b2d3James Dong mSampleRate = minSampleRate; 119342dd1d5f186252a7f09f8fb1a46ea82e3877b2d3James Dong } 119442dd1d5f186252a7f09f8fb1a46ea82e3877b2d3James Dong 119542dd1d5f186252a7f09f8fb1a46ea82e3877b2d3James Dong int maxSampleRate = 119642dd1d5f186252a7f09f8fb1a46ea82e3877b2d3James Dong mEncoderProfiles->getAudioEncoderParamByName( 119742dd1d5f186252a7f09f8fb1a46ea82e3877b2d3James Dong "enc.aud.hz.max", mAudioEncoder); 1198b4a55269a5b39c73de2cc1d4013d0631ef18c77dJames Dong if (maxSampleRate != -1 && mSampleRate > maxSampleRate) { 11995ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block ALOGW("Intended audio sample rate (%d) is too large" 120042dd1d5f186252a7f09f8fb1a46ea82e3877b2d3James Dong " and will be set to (%d)", mSampleRate, maxSampleRate); 120142dd1d5f186252a7f09f8fb1a46ea82e3877b2d3James Dong mSampleRate = maxSampleRate; 120242dd1d5f186252a7f09f8fb1a46ea82e3877b2d3James Dong } 120342dd1d5f186252a7f09f8fb1a46ea82e3877b2d3James Dong} 120442dd1d5f186252a7f09f8fb1a46ea82e3877b2d3James Dong 120542dd1d5f186252a7f09f8fb1a46ea82e3877b2d3James Dongvoid StagefrightRecorder::clipNumberOfAudioChannels() { 12063856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("clipNumberOfAudioChannels: encoder %d", mAudioEncoder); 120742dd1d5f186252a7f09f8fb1a46ea82e3877b2d3James Dong 120842dd1d5f186252a7f09f8fb1a46ea82e3877b2d3James Dong int minChannels = 120942dd1d5f186252a7f09f8fb1a46ea82e3877b2d3James Dong mEncoderProfiles->getAudioEncoderParamByName( 121042dd1d5f186252a7f09f8fb1a46ea82e3877b2d3James Dong "enc.aud.ch.min", mAudioEncoder); 1211b4a55269a5b39c73de2cc1d4013d0631ef18c77dJames Dong if (minChannels != -1 && mAudioChannels < minChannels) { 12125ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block ALOGW("Intended number of audio channels (%d) is too small" 121342dd1d5f186252a7f09f8fb1a46ea82e3877b2d3James Dong " and will be set to (%d)", mAudioChannels, minChannels); 121442dd1d5f186252a7f09f8fb1a46ea82e3877b2d3James Dong mAudioChannels = minChannels; 121542dd1d5f186252a7f09f8fb1a46ea82e3877b2d3James Dong } 121642dd1d5f186252a7f09f8fb1a46ea82e3877b2d3James Dong 121742dd1d5f186252a7f09f8fb1a46ea82e3877b2d3James Dong int maxChannels = 121842dd1d5f186252a7f09f8fb1a46ea82e3877b2d3James Dong mEncoderProfiles->getAudioEncoderParamByName( 121942dd1d5f186252a7f09f8fb1a46ea82e3877b2d3James Dong "enc.aud.ch.max", mAudioEncoder); 1220b4a55269a5b39c73de2cc1d4013d0631ef18c77dJames Dong if (maxChannels != -1 && mAudioChannels > maxChannels) { 12215ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block ALOGW("Intended number of audio channels (%d) is too large" 122242dd1d5f186252a7f09f8fb1a46ea82e3877b2d3James Dong " and will be set to (%d)", mAudioChannels, maxChannels); 122342dd1d5f186252a7f09f8fb1a46ea82e3877b2d3James Dong mAudioChannels = maxChannels; 122442dd1d5f186252a7f09f8fb1a46ea82e3877b2d3James Dong } 122542dd1d5f186252a7f09f8fb1a46ea82e3877b2d3James Dong} 122642dd1d5f186252a7f09f8fb1a46ea82e3877b2d3James Dong 122799c2a076b4a46762a22bbb4dfbd51d107e0532d9James Dongvoid StagefrightRecorder::clipVideoFrameHeight() { 12283856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("clipVideoFrameHeight: encoder %d", mVideoEncoder); 122999c2a076b4a46762a22bbb4dfbd51d107e0532d9James Dong int minFrameHeight = mEncoderProfiles->getVideoEncoderParamByName( 123099c2a076b4a46762a22bbb4dfbd51d107e0532d9James Dong "enc.vid.height.min", mVideoEncoder); 123199c2a076b4a46762a22bbb4dfbd51d107e0532d9James Dong int maxFrameHeight = mEncoderProfiles->getVideoEncoderParamByName( 123299c2a076b4a46762a22bbb4dfbd51d107e0532d9James Dong "enc.vid.height.max", mVideoEncoder); 1233b4a55269a5b39c73de2cc1d4013d0631ef18c77dJames Dong if (minFrameHeight != -1 && mVideoHeight < minFrameHeight) { 12345ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block ALOGW("Intended video encoding frame height (%d) is too small" 123599c2a076b4a46762a22bbb4dfbd51d107e0532d9James Dong " and will be set to (%d)", mVideoHeight, minFrameHeight); 123699c2a076b4a46762a22bbb4dfbd51d107e0532d9James Dong mVideoHeight = minFrameHeight; 1237b4a55269a5b39c73de2cc1d4013d0631ef18c77dJames Dong } else if (maxFrameHeight != -1 && mVideoHeight > maxFrameHeight) { 12385ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block ALOGW("Intended video encoding frame height (%d) is too large" 123999c2a076b4a46762a22bbb4dfbd51d107e0532d9James Dong " and will be set to (%d)", mVideoHeight, maxFrameHeight); 124099c2a076b4a46762a22bbb4dfbd51d107e0532d9James Dong mVideoHeight = maxFrameHeight; 124199c2a076b4a46762a22bbb4dfbd51d107e0532d9James Dong } 124299c2a076b4a46762a22bbb4dfbd51d107e0532d9James Dong} 124399c2a076b4a46762a22bbb4dfbd51d107e0532d9James Dong 1244b33f3407bab0970a7f9241680723a1140b177c50Pannag Sanketi// Set up the appropriate MediaSource depending on the chosen option 1245b33f3407bab0970a7f9241680723a1140b177c50Pannag Sanketistatus_t StagefrightRecorder::setupMediaSource( 1246b33f3407bab0970a7f9241680723a1140b177c50Pannag Sanketi sp<MediaSource> *mediaSource) { 1247b33f3407bab0970a7f9241680723a1140b177c50Pannag Sanketi if (mVideoSource == VIDEO_SOURCE_DEFAULT 1248b33f3407bab0970a7f9241680723a1140b177c50Pannag Sanketi || mVideoSource == VIDEO_SOURCE_CAMERA) { 1249b33f3407bab0970a7f9241680723a1140b177c50Pannag Sanketi sp<CameraSource> cameraSource; 1250b33f3407bab0970a7f9241680723a1140b177c50Pannag Sanketi status_t err = setupCameraSource(&cameraSource); 1251b33f3407bab0970a7f9241680723a1140b177c50Pannag Sanketi if (err != OK) { 1252b33f3407bab0970a7f9241680723a1140b177c50Pannag Sanketi return err; 1253b33f3407bab0970a7f9241680723a1140b177c50Pannag Sanketi } 1254b33f3407bab0970a7f9241680723a1140b177c50Pannag Sanketi *mediaSource = cameraSource; 1255b33f3407bab0970a7f9241680723a1140b177c50Pannag Sanketi } else if (mVideoSource == VIDEO_SOURCE_GRALLOC_BUFFER) { 1256b33f3407bab0970a7f9241680723a1140b177c50Pannag Sanketi // If using GRAlloc buffers, setup surfacemediasource. 1257b33f3407bab0970a7f9241680723a1140b177c50Pannag Sanketi // Later a handle to that will be passed 1258b33f3407bab0970a7f9241680723a1140b177c50Pannag Sanketi // to the client side when queried 1259b33f3407bab0970a7f9241680723a1140b177c50Pannag Sanketi status_t err = setupSurfaceMediaSource(); 1260b33f3407bab0970a7f9241680723a1140b177c50Pannag Sanketi if (err != OK) { 1261b33f3407bab0970a7f9241680723a1140b177c50Pannag Sanketi return err; 1262b33f3407bab0970a7f9241680723a1140b177c50Pannag Sanketi } 1263b33f3407bab0970a7f9241680723a1140b177c50Pannag Sanketi *mediaSource = mSurfaceMediaSource; 1264b33f3407bab0970a7f9241680723a1140b177c50Pannag Sanketi } else { 1265b33f3407bab0970a7f9241680723a1140b177c50Pannag Sanketi return INVALID_OPERATION; 1266b33f3407bab0970a7f9241680723a1140b177c50Pannag Sanketi } 1267b33f3407bab0970a7f9241680723a1140b177c50Pannag Sanketi return OK; 1268b33f3407bab0970a7f9241680723a1140b177c50Pannag Sanketi} 1269b33f3407bab0970a7f9241680723a1140b177c50Pannag Sanketi 1270b33f3407bab0970a7f9241680723a1140b177c50Pannag Sanketi// setupSurfaceMediaSource creates a source with the given 1271b33f3407bab0970a7f9241680723a1140b177c50Pannag Sanketi// width and height and framerate. 1272b33f3407bab0970a7f9241680723a1140b177c50Pannag Sanketi// TODO: This could go in a static function inside SurfaceMediaSource 1273b33f3407bab0970a7f9241680723a1140b177c50Pannag Sanketi// similar to that in CameraSource 1274b33f3407bab0970a7f9241680723a1140b177c50Pannag Sanketistatus_t StagefrightRecorder::setupSurfaceMediaSource() { 1275b33f3407bab0970a7f9241680723a1140b177c50Pannag Sanketi status_t err = OK; 1276b33f3407bab0970a7f9241680723a1140b177c50Pannag Sanketi mSurfaceMediaSource = new SurfaceMediaSource(mVideoWidth, mVideoHeight); 1277b33f3407bab0970a7f9241680723a1140b177c50Pannag Sanketi if (mSurfaceMediaSource == NULL) { 1278b33f3407bab0970a7f9241680723a1140b177c50Pannag Sanketi return NO_INIT; 1279b33f3407bab0970a7f9241680723a1140b177c50Pannag Sanketi } 1280b33f3407bab0970a7f9241680723a1140b177c50Pannag Sanketi 1281b33f3407bab0970a7f9241680723a1140b177c50Pannag Sanketi if (mFrameRate == -1) { 1282b33f3407bab0970a7f9241680723a1140b177c50Pannag Sanketi int32_t frameRate = 0; 1283b33f3407bab0970a7f9241680723a1140b177c50Pannag Sanketi CHECK (mSurfaceMediaSource->getFormat()->findInt32( 1284b33f3407bab0970a7f9241680723a1140b177c50Pannag Sanketi kKeyFrameRate, &frameRate)); 1285df64d15042bbd5e0e4933ac49bf3c177dd94752cSteve Block ALOGI("Frame rate is not explicitly set. Use the current frame " 1286b33f3407bab0970a7f9241680723a1140b177c50Pannag Sanketi "rate (%d fps)", frameRate); 1287b33f3407bab0970a7f9241680723a1140b177c50Pannag Sanketi mFrameRate = frameRate; 1288b33f3407bab0970a7f9241680723a1140b177c50Pannag Sanketi } else { 1289b33f3407bab0970a7f9241680723a1140b177c50Pannag Sanketi err = mSurfaceMediaSource->setFrameRate(mFrameRate); 1290b33f3407bab0970a7f9241680723a1140b177c50Pannag Sanketi } 1291b33f3407bab0970a7f9241680723a1140b177c50Pannag Sanketi CHECK(mFrameRate != -1); 1292b33f3407bab0970a7f9241680723a1140b177c50Pannag Sanketi 1293b33f3407bab0970a7f9241680723a1140b177c50Pannag Sanketi mIsMetaDataStoredInVideoBuffers = 1294b33f3407bab0970a7f9241680723a1140b177c50Pannag Sanketi mSurfaceMediaSource->isMetaDataStoredInVideoBuffers(); 1295b33f3407bab0970a7f9241680723a1140b177c50Pannag Sanketi return err; 1296b33f3407bab0970a7f9241680723a1140b177c50Pannag Sanketi} 1297b33f3407bab0970a7f9241680723a1140b177c50Pannag Sanketi 12988480835b4bc1350646376aa7f3ae33742a7adeb1James Dongstatus_t StagefrightRecorder::setupCameraSource( 12998480835b4bc1350646376aa7f3ae33742a7adeb1James Dong sp<CameraSource> *cameraSource) { 1300635730831e08c32a5fe7c59125e0919b7e7899cdJames Dong status_t err = OK; 1301635730831e08c32a5fe7c59125e0919b7e7899cdJames Dong if ((err = checkVideoEncoderCapabilities()) != OK) { 1302635730831e08c32a5fe7c59125e0919b7e7899cdJames Dong return err; 1303635730831e08c32a5fe7c59125e0919b7e7899cdJames Dong } 130454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong Size videoSize; 130554ff19ac69ace7c05ea90d225e26dab3b133f487James Dong videoSize.width = mVideoWidth; 130654ff19ac69ace7c05ea90d225e26dab3b133f487James Dong videoSize.height = mVideoHeight; 130778eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra if (mCaptureTimeLapse) { 13082e77ad2a9f7afb57b6f9127dd7c229e774baa9c8James Dong if (mTimeBetweenTimeLapseFrameCaptureUs < 0) { 13092e77ad2a9f7afb57b6f9127dd7c229e774baa9c8James Dong ALOGE("Invalid mTimeBetweenTimeLapseFrameCaptureUs value: %lld", 13102e77ad2a9f7afb57b6f9127dd7c229e774baa9c8James Dong mTimeBetweenTimeLapseFrameCaptureUs); 13112e77ad2a9f7afb57b6f9127dd7c229e774baa9c8James Dong return BAD_VALUE; 13122e77ad2a9f7afb57b6f9127dd7c229e774baa9c8James Dong } 13132e77ad2a9f7afb57b6f9127dd7c229e774baa9c8James Dong 131454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong mCameraSourceTimeLapse = CameraSourceTimeLapse::CreateFromCamera( 13154ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li mCamera, mCameraProxy, mCameraId, 131654ff19ac69ace7c05ea90d225e26dab3b133f487James Dong videoSize, mFrameRate, mPreviewSurface, 131754ff19ac69ace7c05ea90d225e26dab3b133f487James Dong mTimeBetweenTimeLapseFrameCaptureUs); 131878eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra *cameraSource = mCameraSourceTimeLapse; 131978eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra } else { 132054ff19ac69ace7c05ea90d225e26dab3b133f487James Dong *cameraSource = CameraSource::CreateFromCamera( 13214ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li mCamera, mCameraProxy, mCameraId, videoSize, mFrameRate, 13228480835b4bc1350646376aa7f3ae33742a7adeb1James Dong mPreviewSurface, true /*storeMetaDataInVideoBuffers*/); 132378eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra } 13244ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li mCamera.clear(); 13254ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li mCameraProxy.clear(); 1326ea7b485595f8cec6a66668b5c54c8f297d843f77James Dong if (*cameraSource == NULL) { 1327ea7b485595f8cec6a66668b5c54c8f297d843f77James Dong return UNKNOWN_ERROR; 1328ea7b485595f8cec6a66668b5c54c8f297d843f77James Dong } 1329ea7b485595f8cec6a66668b5c54c8f297d843f77James Dong 1330ea7b485595f8cec6a66668b5c54c8f297d843f77James Dong if ((*cameraSource)->initCheck() != OK) { 1331ea7b485595f8cec6a66668b5c54c8f297d843f77James Dong (*cameraSource).clear(); 1332ea7b485595f8cec6a66668b5c54c8f297d843f77James Dong *cameraSource = NULL; 1333ea7b485595f8cec6a66668b5c54c8f297d843f77James Dong return NO_INIT; 1334ea7b485595f8cec6a66668b5c54c8f297d843f77James Dong } 13359c075bca0b75093ca0514a3c8f74d73c8e9e83fdNipun Kwatra 1336635730831e08c32a5fe7c59125e0919b7e7899cdJames Dong // When frame rate is not set, the actual frame rate will be set to 1337635730831e08c32a5fe7c59125e0919b7e7899cdJames Dong // the current frame rate being used. 1338635730831e08c32a5fe7c59125e0919b7e7899cdJames Dong if (mFrameRate == -1) { 1339635730831e08c32a5fe7c59125e0919b7e7899cdJames Dong int32_t frameRate = 0; 1340635730831e08c32a5fe7c59125e0919b7e7899cdJames Dong CHECK ((*cameraSource)->getFormat()->findInt32( 1341393410a441b6d06daf286ed496470e9d6b2b6ca8James Dong kKeyFrameRate, &frameRate)); 1342df64d15042bbd5e0e4933ac49bf3c177dd94752cSteve Block ALOGI("Frame rate is not explicitly set. Use the current frame " 1343635730831e08c32a5fe7c59125e0919b7e7899cdJames Dong "rate (%d fps)", frameRate); 1344635730831e08c32a5fe7c59125e0919b7e7899cdJames Dong mFrameRate = frameRate; 1345635730831e08c32a5fe7c59125e0919b7e7899cdJames Dong } 1346635730831e08c32a5fe7c59125e0919b7e7899cdJames Dong 1347635730831e08c32a5fe7c59125e0919b7e7899cdJames Dong CHECK(mFrameRate != -1); 13488480835b4bc1350646376aa7f3ae33742a7adeb1James Dong 13498480835b4bc1350646376aa7f3ae33742a7adeb1James Dong mIsMetaDataStoredInVideoBuffers = 13508480835b4bc1350646376aa7f3ae33742a7adeb1James Dong (*cameraSource)->isMetaDataStoredInVideoBuffers(); 13518480835b4bc1350646376aa7f3ae33742a7adeb1James Dong 13529c075bca0b75093ca0514a3c8f74d73c8e9e83fdNipun Kwatra return OK; 13539c075bca0b75093ca0514a3c8f74d73c8e9e83fdNipun Kwatra} 13549c075bca0b75093ca0514a3c8f74d73c8e9e83fdNipun Kwatra 13559c075bca0b75093ca0514a3c8f74d73c8e9e83fdNipun Kwatrastatus_t StagefrightRecorder::setupVideoEncoder( 13569c075bca0b75093ca0514a3c8f74d73c8e9e83fdNipun Kwatra sp<MediaSource> cameraSource, 13579c075bca0b75093ca0514a3c8f74d73c8e9e83fdNipun Kwatra int32_t videoBitRate, 13589c075bca0b75093ca0514a3c8f74d73c8e9e83fdNipun Kwatra sp<MediaSource> *source) { 13599c075bca0b75093ca0514a3c8f74d73c8e9e83fdNipun Kwatra source->clear(); 1360050b28a593350047845a45a14cc5026221ac1620James Dong 1361934da11c4cc598d3dd3b53726c362bcdcc0fd37fJames Dong sp<MetaData> enc_meta = new MetaData; 13629c075bca0b75093ca0514a3c8f74d73c8e9e83fdNipun Kwatra enc_meta->setInt32(kKeyBitRate, videoBitRate); 1363393410a441b6d06daf286ed496470e9d6b2b6ca8James Dong enc_meta->setInt32(kKeyFrameRate, mFrameRate); 1364ef9d0cd72e476a4b7556833fb09505a51b626797James Dong 1365934da11c4cc598d3dd3b53726c362bcdcc0fd37fJames Dong switch (mVideoEncoder) { 1366934da11c4cc598d3dd3b53726c362bcdcc0fd37fJames Dong case VIDEO_ENCODER_H263: 1367934da11c4cc598d3dd3b53726c362bcdcc0fd37fJames Dong enc_meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_H263); 1368934da11c4cc598d3dd3b53726c362bcdcc0fd37fJames Dong break; 136965ae665befd929efd1a7d1c9addac41c699f04b2James Dong 1370934da11c4cc598d3dd3b53726c362bcdcc0fd37fJames Dong case VIDEO_ENCODER_MPEG_4_SP: 1371934da11c4cc598d3dd3b53726c362bcdcc0fd37fJames Dong enc_meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_MPEG4); 1372934da11c4cc598d3dd3b53726c362bcdcc0fd37fJames Dong break; 137330ab66297501757d745b9ae10da61adcd891f497Andreas Huber 1374934da11c4cc598d3dd3b53726c362bcdcc0fd37fJames Dong case VIDEO_ENCODER_H264: 1375934da11c4cc598d3dd3b53726c362bcdcc0fd37fJames Dong enc_meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_AVC); 1376934da11c4cc598d3dd3b53726c362bcdcc0fd37fJames Dong break; 137730ab66297501757d745b9ae10da61adcd891f497Andreas Huber 1378934da11c4cc598d3dd3b53726c362bcdcc0fd37fJames Dong default: 1379934da11c4cc598d3dd3b53726c362bcdcc0fd37fJames Dong CHECK(!"Should not be here, unsupported video encoding."); 1380934da11c4cc598d3dd3b53726c362bcdcc0fd37fJames Dong break; 1381934da11c4cc598d3dd3b53726c362bcdcc0fd37fJames Dong } 1382ef9d0cd72e476a4b7556833fb09505a51b626797James Dong 1383934da11c4cc598d3dd3b53726c362bcdcc0fd37fJames Dong sp<MetaData> meta = cameraSource->getFormat(); 138430ab66297501757d745b9ae10da61adcd891f497Andreas Huber 138529a84457aed4c45bc900998b5e11c03023264208James Dong int32_t width, height, stride, sliceHeight, colorFormat; 1386934da11c4cc598d3dd3b53726c362bcdcc0fd37fJames Dong CHECK(meta->findInt32(kKeyWidth, &width)); 1387934da11c4cc598d3dd3b53726c362bcdcc0fd37fJames Dong CHECK(meta->findInt32(kKeyHeight, &height)); 1388934da11c4cc598d3dd3b53726c362bcdcc0fd37fJames Dong CHECK(meta->findInt32(kKeyStride, &stride)); 1389934da11c4cc598d3dd3b53726c362bcdcc0fd37fJames Dong CHECK(meta->findInt32(kKeySliceHeight, &sliceHeight)); 139029a84457aed4c45bc900998b5e11c03023264208James Dong CHECK(meta->findInt32(kKeyColorFormat, &colorFormat)); 139130ab66297501757d745b9ae10da61adcd891f497Andreas Huber 1392934da11c4cc598d3dd3b53726c362bcdcc0fd37fJames Dong enc_meta->setInt32(kKeyWidth, width); 1393934da11c4cc598d3dd3b53726c362bcdcc0fd37fJames Dong enc_meta->setInt32(kKeyHeight, height); 13948f5f2fcee5c12d08df71d17017410c50951fc2e3James Dong enc_meta->setInt32(kKeyIFramesInterval, mIFramesIntervalSec); 1395934da11c4cc598d3dd3b53726c362bcdcc0fd37fJames Dong enc_meta->setInt32(kKeyStride, stride); 1396934da11c4cc598d3dd3b53726c362bcdcc0fd37fJames Dong enc_meta->setInt32(kKeySliceHeight, sliceHeight); 139729a84457aed4c45bc900998b5e11c03023264208James Dong enc_meta->setInt32(kKeyColorFormat, colorFormat); 1398c059860c73678a202bfa33062723e8f82fb779d9James Dong if (mVideoTimeScale > 0) { 1399c059860c73678a202bfa33062723e8f82fb779d9James Dong enc_meta->setInt32(kKeyTimeScale, mVideoTimeScale); 1400c059860c73678a202bfa33062723e8f82fb779d9James Dong } 1401145bfe5eb3e08c9689c28f6bf3287a979438b04bJames Dong if (mVideoEncoderProfile != -1) { 1402145bfe5eb3e08c9689c28f6bf3287a979438b04bJames Dong enc_meta->setInt32(kKeyVideoProfile, mVideoEncoderProfile); 1403145bfe5eb3e08c9689c28f6bf3287a979438b04bJames Dong } 1404145bfe5eb3e08c9689c28f6bf3287a979438b04bJames Dong if (mVideoEncoderLevel != -1) { 1405145bfe5eb3e08c9689c28f6bf3287a979438b04bJames Dong enc_meta->setInt32(kKeyVideoLevel, mVideoEncoderLevel); 1406145bfe5eb3e08c9689c28f6bf3287a979438b04bJames Dong } 140730ab66297501757d745b9ae10da61adcd891f497Andreas Huber 1408934da11c4cc598d3dd3b53726c362bcdcc0fd37fJames Dong OMXClient client; 1409f1d5aa162c02a16b7195a43a9bcea4d592600ac4James Dong CHECK_EQ(client.connect(), (status_t)OK); 141030ab66297501757d745b9ae10da61adcd891f497Andreas Huber 14111cc73922339a110d7ffc47e8842f958492dd85bfJames Dong uint32_t encoder_flags = 0; 14122b4883641e324c50a2ee24c5bd15170c7d31e57dJames Dong if (mIsMetaDataStoredInVideoBuffers) { 14138480835b4bc1350646376aa7f3ae33742a7adeb1James Dong encoder_flags |= OMXCodec::kStoreMetaDataInVideoBuffers; 14148480835b4bc1350646376aa7f3ae33742a7adeb1James Dong } 14157757f5010a771fb8824b6fdf9788f588a1577e3fJames Dong 14167757f5010a771fb8824b6fdf9788f588a1577e3fJames Dong // Do not wait for all the input buffers to become available. 14177757f5010a771fb8824b6fdf9788f588a1577e3fJames Dong // This give timelapse video recording faster response in 14187757f5010a771fb8824b6fdf9788f588a1577e3fJames Dong // receiving output from video encoder component. 14197757f5010a771fb8824b6fdf9788f588a1577e3fJames Dong if (mCaptureTimeLapse) { 14207757f5010a771fb8824b6fdf9788f588a1577e3fJames Dong encoder_flags |= OMXCodec::kOnlySubmitOneInputBufferAtOneTime; 14217757f5010a771fb8824b6fdf9788f588a1577e3fJames Dong } 14227757f5010a771fb8824b6fdf9788f588a1577e3fJames Dong 1423934da11c4cc598d3dd3b53726c362bcdcc0fd37fJames Dong sp<MediaSource> encoder = OMXCodec::Create( 1424934da11c4cc598d3dd3b53726c362bcdcc0fd37fJames Dong client.interface(), enc_meta, 14257a42770f47225483a885b168d05e81b6a81189c0Nipun Kwatra true /* createEncoder */, cameraSource, 14267a42770f47225483a885b168d05e81b6a81189c0Nipun Kwatra NULL, encoder_flags); 1427934da11c4cc598d3dd3b53726c362bcdcc0fd37fJames Dong if (encoder == NULL) { 14285ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block ALOGW("Failed to create the encoder"); 14291cc73922339a110d7ffc47e8842f958492dd85bfJames Dong // When the encoder fails to be created, we need 14301cc73922339a110d7ffc47e8842f958492dd85bfJames Dong // release the camera source due to the camera's lock 14311cc73922339a110d7ffc47e8842f958492dd85bfJames Dong // and unlock mechanism. 14321cc73922339a110d7ffc47e8842f958492dd85bfJames Dong cameraSource->stop(); 1433934da11c4cc598d3dd3b53726c362bcdcc0fd37fJames Dong return UNKNOWN_ERROR; 1434934da11c4cc598d3dd3b53726c362bcdcc0fd37fJames Dong } 143530ab66297501757d745b9ae10da61adcd891f497Andreas Huber 143639ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber *source = encoder; 143739ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 1438934da11c4cc598d3dd3b53726c362bcdcc0fd37fJames Dong return OK; 1439934da11c4cc598d3dd3b53726c362bcdcc0fd37fJames Dong} 144030ab66297501757d745b9ae10da61adcd891f497Andreas Huber 1441934da11c4cc598d3dd3b53726c362bcdcc0fd37fJames Dongstatus_t StagefrightRecorder::setupAudioEncoder(const sp<MediaWriter>& writer) { 144242dd1d5f186252a7f09f8fb1a46ea82e3877b2d3James Dong status_t status = BAD_VALUE; 144342dd1d5f186252a7f09f8fb1a46ea82e3877b2d3James Dong if (OK != (status = checkAudioEncoderCapabilities())) { 144442dd1d5f186252a7f09f8fb1a46ea82e3877b2d3James Dong return status; 144542dd1d5f186252a7f09f8fb1a46ea82e3877b2d3James Dong } 144642dd1d5f186252a7f09f8fb1a46ea82e3877b2d3James Dong 1447934da11c4cc598d3dd3b53726c362bcdcc0fd37fJames Dong switch(mAudioEncoder) { 1448934da11c4cc598d3dd3b53726c362bcdcc0fd37fJames Dong case AUDIO_ENCODER_AMR_NB: 1449934da11c4cc598d3dd3b53726c362bcdcc0fd37fJames Dong case AUDIO_ENCODER_AMR_WB: 1450934da11c4cc598d3dd3b53726c362bcdcc0fd37fJames Dong case AUDIO_ENCODER_AAC: 1451f60c660f048d5f5e2458cff243c20400d73757a7Dave Burke case AUDIO_ENCODER_HE_AAC: 1452aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke case AUDIO_ENCODER_AAC_ELD: 1453934da11c4cc598d3dd3b53726c362bcdcc0fd37fJames Dong break; 145442dd1d5f186252a7f09f8fb1a46ea82e3877b2d3James Dong 1455934da11c4cc598d3dd3b53726c362bcdcc0fd37fJames Dong default: 145629357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("Unsupported audio encoder: %d", mAudioEncoder); 1457934da11c4cc598d3dd3b53726c362bcdcc0fd37fJames Dong return UNKNOWN_ERROR; 1458934da11c4cc598d3dd3b53726c362bcdcc0fd37fJames Dong } 145930ab66297501757d745b9ae10da61adcd891f497Andreas Huber 146042dd1d5f186252a7f09f8fb1a46ea82e3877b2d3James Dong sp<MediaSource> audioEncoder = createAudioSource(); 1461934da11c4cc598d3dd3b53726c362bcdcc0fd37fJames Dong if (audioEncoder == NULL) { 1462934da11c4cc598d3dd3b53726c362bcdcc0fd37fJames Dong return UNKNOWN_ERROR; 1463934da11c4cc598d3dd3b53726c362bcdcc0fd37fJames Dong } 14648f5f2fcee5c12d08df71d17017410c50951fc2e3James Dong 1465934da11c4cc598d3dd3b53726c362bcdcc0fd37fJames Dong writer->addSource(audioEncoder); 1466934da11c4cc598d3dd3b53726c362bcdcc0fd37fJames Dong return OK; 1467934da11c4cc598d3dd3b53726c362bcdcc0fd37fJames Dong} 146830ab66297501757d745b9ae10da61adcd891f497Andreas Huber 14699c075bca0b75093ca0514a3c8f74d73c8e9e83fdNipun Kwatrastatus_t StagefrightRecorder::setupMPEG4Recording( 1470cfe88a20345dad981842b2c8092e4c704d3f98b4Nipun Kwatra int outputFd, 1471cfe88a20345dad981842b2c8092e4c704d3f98b4Nipun Kwatra int32_t videoWidth, int32_t videoHeight, 1472cfe88a20345dad981842b2c8092e4c704d3f98b4Nipun Kwatra int32_t videoBitRate, 14739c075bca0b75093ca0514a3c8f74d73c8e9e83fdNipun Kwatra int32_t *totalBitRate, 14749c075bca0b75093ca0514a3c8f74d73c8e9e83fdNipun Kwatra sp<MediaWriter> *mediaWriter) { 14759c075bca0b75093ca0514a3c8f74d73c8e9e83fdNipun Kwatra mediaWriter->clear(); 14769c075bca0b75093ca0514a3c8f74d73c8e9e83fdNipun Kwatra *totalBitRate = 0; 1477934da11c4cc598d3dd3b53726c362bcdcc0fd37fJames Dong status_t err = OK; 1478674ebd0b4e1143e38392a4e3bb38b4679a4577bcJames Dong sp<MediaWriter> writer = new MPEG4Writer(outputFd); 147930ab66297501757d745b9ae10da61adcd891f497Andreas Huber 1480b33f3407bab0970a7f9241680723a1140b177c50Pannag Sanketi if (mVideoSource < VIDEO_SOURCE_LIST_END) { 14819c075bca0b75093ca0514a3c8f74d73c8e9e83fdNipun Kwatra 1482b33f3407bab0970a7f9241680723a1140b177c50Pannag Sanketi sp<MediaSource> mediaSource; 14833cecf640c4daf2df616b278bd9986018c8182908James Dong err = setupMediaSource(&mediaSource); 14849c075bca0b75093ca0514a3c8f74d73c8e9e83fdNipun Kwatra if (err != OK) { 14859c075bca0b75093ca0514a3c8f74d73c8e9e83fdNipun Kwatra return err; 14869c075bca0b75093ca0514a3c8f74d73c8e9e83fdNipun Kwatra } 14879c075bca0b75093ca0514a3c8f74d73c8e9e83fdNipun Kwatra 148839ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber sp<MediaSource> encoder; 1489b33f3407bab0970a7f9241680723a1140b177c50Pannag Sanketi err = setupVideoEncoder(mediaSource, videoBitRate, &encoder); 14909c075bca0b75093ca0514a3c8f74d73c8e9e83fdNipun Kwatra if (err != OK) { 14919c075bca0b75093ca0514a3c8f74d73c8e9e83fdNipun Kwatra return err; 14929c075bca0b75093ca0514a3c8f74d73c8e9e83fdNipun Kwatra } 14939c075bca0b75093ca0514a3c8f74d73c8e9e83fdNipun Kwatra 149439ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber writer->addSource(encoder); 14959c075bca0b75093ca0514a3c8f74d73c8e9e83fdNipun Kwatra *totalBitRate += videoBitRate; 149630ab66297501757d745b9ae10da61adcd891f497Andreas Huber } 149730ab66297501757d745b9ae10da61adcd891f497Andreas Huber 14987bd460110b27a979384dda351788eac95d8467f5James Dong // Audio source is added at the end if it exists. 14997bd460110b27a979384dda351788eac95d8467f5James Dong // This help make sure that the "recoding" sound is suppressed for 15007bd460110b27a979384dda351788eac95d8467f5James Dong // camcorder applications in the recorded files. 1501fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin if (!mCaptureTimeLapse && (mAudioSource != AUDIO_SOURCE_CNT)) { 15027bd460110b27a979384dda351788eac95d8467f5James Dong err = setupAudioEncoder(writer); 15037bd460110b27a979384dda351788eac95d8467f5James Dong if (err != OK) return err; 15047bd460110b27a979384dda351788eac95d8467f5James Dong *totalBitRate += mAudioBitRate; 15057bd460110b27a979384dda351788eac95d8467f5James Dong } 15067bd460110b27a979384dda351788eac95d8467f5James Dong 1507f01528f435e6b1f02d118fcd8305a148c27a89f1James Dong if (mInterleaveDurationUs > 0) { 1508f01528f435e6b1f02d118fcd8305a148c27a89f1James Dong reinterpret_cast<MPEG4Writer *>(writer.get())-> 1509f01528f435e6b1f02d118fcd8305a148c27a89f1James Dong setInterleaveDuration(mInterleaveDurationUs); 1510f01528f435e6b1f02d118fcd8305a148c27a89f1James Dong } 151107b1bb529a1ae76c46a71b01338c166f9490629dJames Dong if (mLongitudex10000 > -3600000 && mLatitudex10000 > -3600000) { 151207b1bb529a1ae76c46a71b01338c166f9490629dJames Dong reinterpret_cast<MPEG4Writer *>(writer.get())-> 151307b1bb529a1ae76c46a71b01338c166f9490629dJames Dong setGeoData(mLatitudex10000, mLongitudex10000); 151407b1bb529a1ae76c46a71b01338c166f9490629dJames Dong } 1515d599cd4573b5a2d5914c5040e0565ef866749b77James Dong if (mMaxFileDurationUs != 0) { 1516934da11c4cc598d3dd3b53726c362bcdcc0fd37fJames Dong writer->setMaxFileDuration(mMaxFileDurationUs); 1517d599cd4573b5a2d5914c5040e0565ef866749b77James Dong } 1518d599cd4573b5a2d5914c5040e0565ef866749b77James Dong if (mMaxFileSizeBytes != 0) { 1519934da11c4cc598d3dd3b53726c362bcdcc0fd37fJames Dong writer->setMaxFileSize(mMaxFileSizeBytes); 1520d599cd4573b5a2d5914c5040e0565ef866749b77James Dong } 15219c075bca0b75093ca0514a3c8f74d73c8e9e83fdNipun Kwatra 152286b7f47aa7482424cf8fd248f1315311919be3b0James Dong mStartTimeOffsetMs = mEncoderProfiles->getStartTimeOffsetMs(mCameraId); 152386b7f47aa7482424cf8fd248f1315311919be3b0James Dong if (mStartTimeOffsetMs > 0) { 152486b7f47aa7482424cf8fd248f1315311919be3b0James Dong reinterpret_cast<MPEG4Writer *>(writer.get())-> 152586b7f47aa7482424cf8fd248f1315311919be3b0James Dong setStartTimeOffsetMs(mStartTimeOffsetMs); 152686b7f47aa7482424cf8fd248f1315311919be3b0James Dong } 152786b7f47aa7482424cf8fd248f1315311919be3b0James Dong 15289c075bca0b75093ca0514a3c8f74d73c8e9e83fdNipun Kwatra writer->setListener(mListener); 15299c075bca0b75093ca0514a3c8f74d73c8e9e83fdNipun Kwatra *mediaWriter = writer; 15309c075bca0b75093ca0514a3c8f74d73c8e9e83fdNipun Kwatra return OK; 15319c075bca0b75093ca0514a3c8f74d73c8e9e83fdNipun Kwatra} 15329c075bca0b75093ca0514a3c8f74d73c8e9e83fdNipun Kwatra 15339c075bca0b75093ca0514a3c8f74d73c8e9e83fdNipun Kwatravoid StagefrightRecorder::setupMPEG4MetaData(int64_t startTimeUs, int32_t totalBitRate, 15349c075bca0b75093ca0514a3c8f74d73c8e9e83fdNipun Kwatra sp<MetaData> *meta) { 15359c075bca0b75093ca0514a3c8f74d73c8e9e83fdNipun Kwatra (*meta)->setInt64(kKeyTime, startTimeUs); 15369c075bca0b75093ca0514a3c8f74d73c8e9e83fdNipun Kwatra (*meta)->setInt32(kKeyFileType, mOutputFormat); 15379c075bca0b75093ca0514a3c8f74d73c8e9e83fdNipun Kwatra (*meta)->setInt32(kKeyBitRate, totalBitRate); 15389c075bca0b75093ca0514a3c8f74d73c8e9e83fdNipun Kwatra (*meta)->setInt32(kKey64BitFileOffset, mUse64BitFileOffset); 1539c059860c73678a202bfa33062723e8f82fb779d9James Dong if (mMovieTimeScale > 0) { 15409c075bca0b75093ca0514a3c8f74d73c8e9e83fdNipun Kwatra (*meta)->setInt32(kKeyTimeScale, mMovieTimeScale); 1541c059860c73678a202bfa33062723e8f82fb779d9James Dong } 154293d6b102a13afa23bfa80d74c399d93d542e6ad6James Dong if (mTrackEveryTimeDurationUs > 0) { 15439c075bca0b75093ca0514a3c8f74d73c8e9e83fdNipun Kwatra (*meta)->setInt64(kKeyTrackTimeStatus, mTrackEveryTimeDurationUs); 154493d6b102a13afa23bfa80d74c399d93d542e6ad6James Dong } 154513f6284305e4b27395a23db7882d670bdb1bcae1James Dong if (mRotationDegrees != 0) { 154613f6284305e4b27395a23db7882d670bdb1bcae1James Dong (*meta)->setInt32(kKeyRotation, mRotationDegrees); 154713f6284305e4b27395a23db7882d670bdb1bcae1James Dong } 15489c075bca0b75093ca0514a3c8f74d73c8e9e83fdNipun Kwatra} 15499c075bca0b75093ca0514a3c8f74d73c8e9e83fdNipun Kwatra 15509c075bca0b75093ca0514a3c8f74d73c8e9e83fdNipun Kwatrastatus_t StagefrightRecorder::startMPEG4Recording() { 15519c075bca0b75093ca0514a3c8f74d73c8e9e83fdNipun Kwatra int32_t totalBitRate; 15523cecf640c4daf2df616b278bd9986018c8182908James Dong status_t err = setupMPEG4Recording( 1553cfe88a20345dad981842b2c8092e4c704d3f98b4Nipun Kwatra mOutputFd, mVideoWidth, mVideoHeight, 1554cfe88a20345dad981842b2c8092e4c704d3f98b4Nipun Kwatra mVideoBitRate, &totalBitRate, &mWriter); 15559c075bca0b75093ca0514a3c8f74d73c8e9e83fdNipun Kwatra if (err != OK) { 15569c075bca0b75093ca0514a3c8f74d73c8e9e83fdNipun Kwatra return err; 15579c075bca0b75093ca0514a3c8f74d73c8e9e83fdNipun Kwatra } 15589c075bca0b75093ca0514a3c8f74d73c8e9e83fdNipun Kwatra 15599c075bca0b75093ca0514a3c8f74d73c8e9e83fdNipun Kwatra int64_t startTimeUs = systemTime() / 1000; 15609c075bca0b75093ca0514a3c8f74d73c8e9e83fdNipun Kwatra sp<MetaData> meta = new MetaData; 15619c075bca0b75093ca0514a3c8f74d73c8e9e83fdNipun Kwatra setupMPEG4MetaData(startTimeUs, totalBitRate, &meta); 15629c075bca0b75093ca0514a3c8f74d73c8e9e83fdNipun Kwatra 15639c075bca0b75093ca0514a3c8f74d73c8e9e83fdNipun Kwatra err = mWriter->start(meta.get()); 15649c075bca0b75093ca0514a3c8f74d73c8e9e83fdNipun Kwatra if (err != OK) { 15659c075bca0b75093ca0514a3c8f74d73c8e9e83fdNipun Kwatra return err; 15669c075bca0b75093ca0514a3c8f74d73c8e9e83fdNipun Kwatra } 15679c075bca0b75093ca0514a3c8f74d73c8e9e83fdNipun Kwatra 15689c075bca0b75093ca0514a3c8f74d73c8e9e83fdNipun Kwatra return OK; 156930ab66297501757d745b9ae10da61adcd891f497Andreas Huber} 157030ab66297501757d745b9ae10da61adcd891f497Andreas Huber 1571a7d1a2dd776bf356c228785a94ba8e0ff6a2ec7fJames Dongstatus_t StagefrightRecorder::pause() { 15723856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("pause"); 1573a7d1a2dd776bf356c228785a94ba8e0ff6a2ec7fJames Dong if (mWriter == NULL) { 1574a7d1a2dd776bf356c228785a94ba8e0ff6a2ec7fJames Dong return UNKNOWN_ERROR; 1575a7d1a2dd776bf356c228785a94ba8e0ff6a2ec7fJames Dong } 1576a7d1a2dd776bf356c228785a94ba8e0ff6a2ec7fJames Dong mWriter->pause(); 15779c075bca0b75093ca0514a3c8f74d73c8e9e83fdNipun Kwatra 157875b0b5473c7b43f8c5972db7e6e8930988ead751Gloria Wang if (mStarted) { 157975b0b5473c7b43f8c5972db7e6e8930988ead751Gloria Wang mStarted = false; 158075b0b5473c7b43f8c5972db7e6e8930988ead751Gloria Wang 158175b0b5473c7b43f8c5972db7e6e8930988ead751Gloria Wang uint32_t params = 0; 1582fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin if (mAudioSource != AUDIO_SOURCE_CNT) { 158375b0b5473c7b43f8c5972db7e6e8930988ead751Gloria Wang params |= IMediaPlayerService::kBatteryDataTrackAudio; 158475b0b5473c7b43f8c5972db7e6e8930988ead751Gloria Wang } 158575b0b5473c7b43f8c5972db7e6e8930988ead751Gloria Wang if (mVideoSource != VIDEO_SOURCE_LIST_END) { 158675b0b5473c7b43f8c5972db7e6e8930988ead751Gloria Wang params |= IMediaPlayerService::kBatteryDataTrackVideo; 158775b0b5473c7b43f8c5972db7e6e8930988ead751Gloria Wang } 158875b0b5473c7b43f8c5972db7e6e8930988ead751Gloria Wang 158975b0b5473c7b43f8c5972db7e6e8930988ead751Gloria Wang addBatteryData(params); 159075b0b5473c7b43f8c5972db7e6e8930988ead751Gloria Wang } 159175b0b5473c7b43f8c5972db7e6e8930988ead751Gloria Wang 159275b0b5473c7b43f8c5972db7e6e8930988ead751Gloria Wang 1593a7d1a2dd776bf356c228785a94ba8e0ff6a2ec7fJames Dong return OK; 1594a7d1a2dd776bf356c228785a94ba8e0ff6a2ec7fJames Dong} 1595a7d1a2dd776bf356c228785a94ba8e0ff6a2ec7fJames Dong 159630ab66297501757d745b9ae10da61adcd891f497Andreas Huberstatus_t StagefrightRecorder::stop() { 15973856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("stop"); 159837187916a486504acaf83bea30147eb5fbf46ae5James Dong status_t err = OK; 15999c075bca0b75093ca0514a3c8f74d73c8e9e83fdNipun Kwatra 160078eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra if (mCaptureTimeLapse && mCameraSourceTimeLapse != NULL) { 160178eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra mCameraSourceTimeLapse->startQuickReadReturns(); 160278eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra mCameraSourceTimeLapse = NULL; 160378eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra } 160478eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra 1605d329e21495eda9dbc531fdd0c26c77f1593ac3f4James Dong if (mWriter != NULL) { 160637187916a486504acaf83bea30147eb5fbf46ae5James Dong err = mWriter->stop(); 1607934da11c4cc598d3dd3b53726c362bcdcc0fd37fJames Dong mWriter.clear(); 160830ab66297501757d745b9ae10da61adcd891f497Andreas Huber } 160930ab66297501757d745b9ae10da61adcd891f497Andreas Huber 161025d83125cee222993673d3ba261ae1186bcad8c2James Dong if (mOutputFd >= 0) { 161125d83125cee222993673d3ba261ae1186bcad8c2James Dong ::close(mOutputFd); 161225d83125cee222993673d3ba261ae1186bcad8c2James Dong mOutputFd = -1; 161325d83125cee222993673d3ba261ae1186bcad8c2James Dong } 161425d83125cee222993673d3ba261ae1186bcad8c2James Dong 161575b0b5473c7b43f8c5972db7e6e8930988ead751Gloria Wang if (mStarted) { 161675b0b5473c7b43f8c5972db7e6e8930988ead751Gloria Wang mStarted = false; 161775b0b5473c7b43f8c5972db7e6e8930988ead751Gloria Wang 161875b0b5473c7b43f8c5972db7e6e8930988ead751Gloria Wang uint32_t params = 0; 1619fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin if (mAudioSource != AUDIO_SOURCE_CNT) { 162075b0b5473c7b43f8c5972db7e6e8930988ead751Gloria Wang params |= IMediaPlayerService::kBatteryDataTrackAudio; 162175b0b5473c7b43f8c5972db7e6e8930988ead751Gloria Wang } 162275b0b5473c7b43f8c5972db7e6e8930988ead751Gloria Wang if (mVideoSource != VIDEO_SOURCE_LIST_END) { 162375b0b5473c7b43f8c5972db7e6e8930988ead751Gloria Wang params |= IMediaPlayerService::kBatteryDataTrackVideo; 162475b0b5473c7b43f8c5972db7e6e8930988ead751Gloria Wang } 162575b0b5473c7b43f8c5972db7e6e8930988ead751Gloria Wang 162675b0b5473c7b43f8c5972db7e6e8930988ead751Gloria Wang addBatteryData(params); 162775b0b5473c7b43f8c5972db7e6e8930988ead751Gloria Wang } 162875b0b5473c7b43f8c5972db7e6e8930988ead751Gloria Wang 162975b0b5473c7b43f8c5972db7e6e8930988ead751Gloria Wang 163037187916a486504acaf83bea30147eb5fbf46ae5James Dong return err; 1631d329e21495eda9dbc531fdd0c26c77f1593ac3f4James Dong} 1632d329e21495eda9dbc531fdd0c26c77f1593ac3f4James Dong 1633d329e21495eda9dbc531fdd0c26c77f1593ac3f4James Dongstatus_t StagefrightRecorder::close() { 16343856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("close"); 1635d329e21495eda9dbc531fdd0c26c77f1593ac3f4James Dong stop(); 1636d329e21495eda9dbc531fdd0c26c77f1593ac3f4James Dong 163730ab66297501757d745b9ae10da61adcd891f497Andreas Huber return OK; 163830ab66297501757d745b9ae10da61adcd891f497Andreas Huber} 163930ab66297501757d745b9ae10da61adcd891f497Andreas Huber 164030ab66297501757d745b9ae10da61adcd891f497Andreas Huberstatus_t StagefrightRecorder::reset() { 16413856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("reset"); 164230ab66297501757d745b9ae10da61adcd891f497Andreas Huber stop(); 164330ab66297501757d745b9ae10da61adcd891f497Andreas Huber 1644050b28a593350047845a45a14cc5026221ac1620James Dong // No audio or video source by default 1645fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin mAudioSource = AUDIO_SOURCE_CNT; 164630ab66297501757d745b9ae10da61adcd891f497Andreas Huber mVideoSource = VIDEO_SOURCE_LIST_END; 1647050b28a593350047845a45a14cc5026221ac1620James Dong 1648050b28a593350047845a45a14cc5026221ac1620James Dong // Default parameters 1649050b28a593350047845a45a14cc5026221ac1620James Dong mOutputFormat = OUTPUT_FORMAT_THREE_GPP; 1650050b28a593350047845a45a14cc5026221ac1620James Dong mAudioEncoder = AUDIO_ENCODER_AMR_NB; 1651050b28a593350047845a45a14cc5026221ac1620James Dong mVideoEncoder = VIDEO_ENCODER_H263; 1652050b28a593350047845a45a14cc5026221ac1620James Dong mVideoWidth = 176; 1653050b28a593350047845a45a14cc5026221ac1620James Dong mVideoHeight = 144; 1654635730831e08c32a5fe7c59125e0919b7e7899cdJames Dong mFrameRate = -1; 1655050b28a593350047845a45a14cc5026221ac1620James Dong mVideoBitRate = 192000; 1656050b28a593350047845a45a14cc5026221ac1620James Dong mSampleRate = 8000; 1657050b28a593350047845a45a14cc5026221ac1620James Dong mAudioChannels = 1; 1658050b28a593350047845a45a14cc5026221ac1620James Dong mAudioBitRate = 12200; 1659e136c3bb38e88315bf8797a464ebf2c788296b22James Dong mInterleaveDurationUs = 0; 16608f5f2fcee5c12d08df71d17017410c50951fc2e3James Dong mIFramesIntervalSec = 1; 1661d3d4e5069e1af0437c4f5a7b4ba344bda5b937afJames Dong mAudioSourceNode = 0; 16622dec2b5be2056c6d9428897dc672185872d30d17James Dong mUse64BitFileOffset = false; 1663c059860c73678a202bfa33062723e8f82fb779d9James Dong mMovieTimeScale = -1; 1664c059860c73678a202bfa33062723e8f82fb779d9James Dong mAudioTimeScale = -1; 1665c059860c73678a202bfa33062723e8f82fb779d9James Dong mVideoTimeScale = -1; 166693d6b102a13afa23bfa80d74c399d93d542e6ad6James Dong mCameraId = 0; 166786b7f47aa7482424cf8fd248f1315311919be3b0James Dong mStartTimeOffsetMs = -1; 1668145bfe5eb3e08c9689c28f6bf3287a979438b04bJames Dong mVideoEncoderProfile = -1; 1669145bfe5eb3e08c9689c28f6bf3287a979438b04bJames Dong mVideoEncoderLevel = -1; 1670145bfe5eb3e08c9689c28f6bf3287a979438b04bJames Dong mMaxFileDurationUs = 0; 1671145bfe5eb3e08c9689c28f6bf3287a979438b04bJames Dong mMaxFileSizeBytes = 0; 167293d6b102a13afa23bfa80d74c399d93d542e6ad6James Dong mTrackEveryTimeDurationUs = 0; 1673fc20aab463f527ab3b0664986f0381a86b375884Nipun Kwatra mCaptureTimeLapse = false; 1674e4e0a6994d39c4a7cba09c5fff442b2dca1df8f8Nipun Kwatra mTimeBetweenTimeLapseFrameCaptureUs = -1; 167578eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra mCameraSourceTimeLapse = NULL; 16768480835b4bc1350646376aa7f3ae33742a7adeb1James Dong mIsMetaDataStoredInVideoBuffers = false; 167799c2a076b4a46762a22bbb4dfbd51d107e0532d9James Dong mEncoderProfiles = MediaProfiles::getInstance(); 167862db7db731c47a00ee1493e94f3e1d953c6e297aJames Dong mRotationDegrees = 0; 167907b1bb529a1ae76c46a71b01338c166f9490629dJames Dong mLatitudex10000 = -3600000; 168007b1bb529a1ae76c46a71b01338c166f9490629dJames Dong mLongitudex10000 = -3600000; 1681050b28a593350047845a45a14cc5026221ac1620James Dong 168230ab66297501757d745b9ae10da61adcd891f497Andreas Huber mOutputFd = -1; 168330ab66297501757d745b9ae10da61adcd891f497Andreas Huber 168430ab66297501757d745b9ae10da61adcd891f497Andreas Huber return OK; 168530ab66297501757d745b9ae10da61adcd891f497Andreas Huber} 168630ab66297501757d745b9ae10da61adcd891f497Andreas Huber 168730ab66297501757d745b9ae10da61adcd891f497Andreas Huberstatus_t StagefrightRecorder::getMaxAmplitude(int *max) { 16883856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("getMaxAmplitude"); 1689d329e21495eda9dbc531fdd0c26c77f1593ac3f4James Dong 1690d329e21495eda9dbc531fdd0c26c77f1593ac3f4James Dong if (max == NULL) { 169129357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("Null pointer argument"); 1692d329e21495eda9dbc531fdd0c26c77f1593ac3f4James Dong return BAD_VALUE; 1693d329e21495eda9dbc531fdd0c26c77f1593ac3f4James Dong } 1694d329e21495eda9dbc531fdd0c26c77f1593ac3f4James Dong 1695d3d4e5069e1af0437c4f5a7b4ba344bda5b937afJames Dong if (mAudioSourceNode != 0) { 1696d3d4e5069e1af0437c4f5a7b4ba344bda5b937afJames Dong *max = mAudioSourceNode->getMaxAmplitude(); 1697d3d4e5069e1af0437c4f5a7b4ba344bda5b937afJames Dong } else { 1698d3d4e5069e1af0437c4f5a7b4ba344bda5b937afJames Dong *max = 0; 1699d3d4e5069e1af0437c4f5a7b4ba344bda5b937afJames Dong } 17002dce41ad26cb3e9e15c9e456a84bcf5309548ca0Andreas Huber 17012dce41ad26cb3e9e15c9e456a84bcf5309548ca0Andreas Huber return OK; 170230ab66297501757d745b9ae10da61adcd891f497Andreas Huber} 170330ab66297501757d745b9ae10da61adcd891f497Andreas Huber 1704dedf414d3fe2e79ee0aad0f1c82ca16ebd886ff6James Dongstatus_t StagefrightRecorder::dump( 1705dedf414d3fe2e79ee0aad0f1c82ca16ebd886ff6James Dong int fd, const Vector<String16>& args) const { 17063856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("dump"); 1707b914122eb9cb54bbeae4ec03bfebb194aecdccbdJames Dong const size_t SIZE = 256; 1708b914122eb9cb54bbeae4ec03bfebb194aecdccbdJames Dong char buffer[SIZE]; 1709b914122eb9cb54bbeae4ec03bfebb194aecdccbdJames Dong String8 result; 1710dedf414d3fe2e79ee0aad0f1c82ca16ebd886ff6James Dong if (mWriter != 0) { 1711dedf414d3fe2e79ee0aad0f1c82ca16ebd886ff6James Dong mWriter->dump(fd, args); 1712dedf414d3fe2e79ee0aad0f1c82ca16ebd886ff6James Dong } else { 1713dedf414d3fe2e79ee0aad0f1c82ca16ebd886ff6James Dong snprintf(buffer, SIZE, " No file writer\n"); 1714dedf414d3fe2e79ee0aad0f1c82ca16ebd886ff6James Dong result.append(buffer); 1715dedf414d3fe2e79ee0aad0f1c82ca16ebd886ff6James Dong } 1716dedf414d3fe2e79ee0aad0f1c82ca16ebd886ff6James Dong snprintf(buffer, SIZE, " Recorder: %p\n", this); 1717b914122eb9cb54bbeae4ec03bfebb194aecdccbdJames Dong snprintf(buffer, SIZE, " Output file (fd %d):\n", mOutputFd); 1718b914122eb9cb54bbeae4ec03bfebb194aecdccbdJames Dong result.append(buffer); 1719b914122eb9cb54bbeae4ec03bfebb194aecdccbdJames Dong snprintf(buffer, SIZE, " File format: %d\n", mOutputFormat); 1720b914122eb9cb54bbeae4ec03bfebb194aecdccbdJames Dong result.append(buffer); 1721b914122eb9cb54bbeae4ec03bfebb194aecdccbdJames Dong snprintf(buffer, SIZE, " Max file size (bytes): %lld\n", mMaxFileSizeBytes); 1722b914122eb9cb54bbeae4ec03bfebb194aecdccbdJames Dong result.append(buffer); 1723b914122eb9cb54bbeae4ec03bfebb194aecdccbdJames Dong snprintf(buffer, SIZE, " Max file duration (us): %lld\n", mMaxFileDurationUs); 1724b914122eb9cb54bbeae4ec03bfebb194aecdccbdJames Dong result.append(buffer); 1725b914122eb9cb54bbeae4ec03bfebb194aecdccbdJames Dong snprintf(buffer, SIZE, " File offset length (bits): %d\n", mUse64BitFileOffset? 64: 32); 1726b914122eb9cb54bbeae4ec03bfebb194aecdccbdJames Dong result.append(buffer); 1727b914122eb9cb54bbeae4ec03bfebb194aecdccbdJames Dong snprintf(buffer, SIZE, " Interleave duration (us): %d\n", mInterleaveDurationUs); 1728b914122eb9cb54bbeae4ec03bfebb194aecdccbdJames Dong result.append(buffer); 1729b914122eb9cb54bbeae4ec03bfebb194aecdccbdJames Dong snprintf(buffer, SIZE, " Progress notification: %lld us\n", mTrackEveryTimeDurationUs); 1730b914122eb9cb54bbeae4ec03bfebb194aecdccbdJames Dong result.append(buffer); 1731b914122eb9cb54bbeae4ec03bfebb194aecdccbdJames Dong snprintf(buffer, SIZE, " Audio\n"); 1732b914122eb9cb54bbeae4ec03bfebb194aecdccbdJames Dong result.append(buffer); 1733b914122eb9cb54bbeae4ec03bfebb194aecdccbdJames Dong snprintf(buffer, SIZE, " Source: %d\n", mAudioSource); 1734b914122eb9cb54bbeae4ec03bfebb194aecdccbdJames Dong result.append(buffer); 1735b914122eb9cb54bbeae4ec03bfebb194aecdccbdJames Dong snprintf(buffer, SIZE, " Encoder: %d\n", mAudioEncoder); 1736b914122eb9cb54bbeae4ec03bfebb194aecdccbdJames Dong result.append(buffer); 1737b914122eb9cb54bbeae4ec03bfebb194aecdccbdJames Dong snprintf(buffer, SIZE, " Bit rate (bps): %d\n", mAudioBitRate); 1738b914122eb9cb54bbeae4ec03bfebb194aecdccbdJames Dong result.append(buffer); 1739b914122eb9cb54bbeae4ec03bfebb194aecdccbdJames Dong snprintf(buffer, SIZE, " Sampling rate (hz): %d\n", mSampleRate); 1740b914122eb9cb54bbeae4ec03bfebb194aecdccbdJames Dong result.append(buffer); 1741b914122eb9cb54bbeae4ec03bfebb194aecdccbdJames Dong snprintf(buffer, SIZE, " Number of channels: %d\n", mAudioChannels); 1742b914122eb9cb54bbeae4ec03bfebb194aecdccbdJames Dong result.append(buffer); 1743b914122eb9cb54bbeae4ec03bfebb194aecdccbdJames Dong snprintf(buffer, SIZE, " Max amplitude: %d\n", mAudioSourceNode == 0? 0: mAudioSourceNode->getMaxAmplitude()); 1744b914122eb9cb54bbeae4ec03bfebb194aecdccbdJames Dong result.append(buffer); 1745b914122eb9cb54bbeae4ec03bfebb194aecdccbdJames Dong snprintf(buffer, SIZE, " Video\n"); 1746b914122eb9cb54bbeae4ec03bfebb194aecdccbdJames Dong result.append(buffer); 1747b914122eb9cb54bbeae4ec03bfebb194aecdccbdJames Dong snprintf(buffer, SIZE, " Source: %d\n", mVideoSource); 1748b914122eb9cb54bbeae4ec03bfebb194aecdccbdJames Dong result.append(buffer); 1749b914122eb9cb54bbeae4ec03bfebb194aecdccbdJames Dong snprintf(buffer, SIZE, " Camera Id: %d\n", mCameraId); 1750b914122eb9cb54bbeae4ec03bfebb194aecdccbdJames Dong result.append(buffer); 175186b7f47aa7482424cf8fd248f1315311919be3b0James Dong snprintf(buffer, SIZE, " Start time offset (ms): %d\n", mStartTimeOffsetMs); 175286b7f47aa7482424cf8fd248f1315311919be3b0James Dong result.append(buffer); 1753b914122eb9cb54bbeae4ec03bfebb194aecdccbdJames Dong snprintf(buffer, SIZE, " Encoder: %d\n", mVideoEncoder); 1754b914122eb9cb54bbeae4ec03bfebb194aecdccbdJames Dong result.append(buffer); 1755b914122eb9cb54bbeae4ec03bfebb194aecdccbdJames Dong snprintf(buffer, SIZE, " Encoder profile: %d\n", mVideoEncoderProfile); 1756b914122eb9cb54bbeae4ec03bfebb194aecdccbdJames Dong result.append(buffer); 1757b914122eb9cb54bbeae4ec03bfebb194aecdccbdJames Dong snprintf(buffer, SIZE, " Encoder level: %d\n", mVideoEncoderLevel); 1758b914122eb9cb54bbeae4ec03bfebb194aecdccbdJames Dong result.append(buffer); 17598f5f2fcee5c12d08df71d17017410c50951fc2e3James Dong snprintf(buffer, SIZE, " I frames interval (s): %d\n", mIFramesIntervalSec); 1760b914122eb9cb54bbeae4ec03bfebb194aecdccbdJames Dong result.append(buffer); 1761b914122eb9cb54bbeae4ec03bfebb194aecdccbdJames Dong snprintf(buffer, SIZE, " Frame size (pixels): %dx%d\n", mVideoWidth, mVideoHeight); 1762b914122eb9cb54bbeae4ec03bfebb194aecdccbdJames Dong result.append(buffer); 1763b914122eb9cb54bbeae4ec03bfebb194aecdccbdJames Dong snprintf(buffer, SIZE, " Frame rate (fps): %d\n", mFrameRate); 1764b914122eb9cb54bbeae4ec03bfebb194aecdccbdJames Dong result.append(buffer); 1765b914122eb9cb54bbeae4ec03bfebb194aecdccbdJames Dong snprintf(buffer, SIZE, " Bit rate (bps): %d\n", mVideoBitRate); 1766b914122eb9cb54bbeae4ec03bfebb194aecdccbdJames Dong result.append(buffer); 1767b914122eb9cb54bbeae4ec03bfebb194aecdccbdJames Dong ::write(fd, result.string(), result.size()); 1768b914122eb9cb54bbeae4ec03bfebb194aecdccbdJames Dong return OK; 1769b914122eb9cb54bbeae4ec03bfebb194aecdccbdJames Dong} 177030ab66297501757d745b9ae10da61adcd891f497Andreas Huber} // namespace android 1771