StagefrightRecorder.cpp revision b4a55269a5b39c73de2cc1d4013d0631ef18c77d
127c174483a8ae9688d5d4897c19074f62c7f1701James Dong/* 227c174483a8ae9688d5d4897c19074f62c7f1701James Dong * Copyright (C) 2009 The Android Open Source Project 327c174483a8ae9688d5d4897c19074f62c7f1701James Dong * 427c174483a8ae9688d5d4897c19074f62c7f1701James Dong * Licensed under the Apache License, Version 2.0 (the "License"); 527c174483a8ae9688d5d4897c19074f62c7f1701James Dong * you may not use this file except in compliance with the License. 627c174483a8ae9688d5d4897c19074f62c7f1701James Dong * You may obtain a copy of the License at 727c174483a8ae9688d5d4897c19074f62c7f1701James Dong * 827c174483a8ae9688d5d4897c19074f62c7f1701James Dong * http://www.apache.org/licenses/LICENSE-2.0 927c174483a8ae9688d5d4897c19074f62c7f1701James Dong * 1027c174483a8ae9688d5d4897c19074f62c7f1701James Dong * Unless required by applicable law or agreed to in writing, software 1127c174483a8ae9688d5d4897c19074f62c7f1701James Dong * distributed under the License is distributed on an "AS IS" BASIS, 1227c174483a8ae9688d5d4897c19074f62c7f1701James Dong * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1327c174483a8ae9688d5d4897c19074f62c7f1701James Dong * See the License for the specific language governing permissions and 1427c174483a8ae9688d5d4897c19074f62c7f1701James Dong * limitations under the License. 1527c174483a8ae9688d5d4897c19074f62c7f1701James Dong */ 1627c174483a8ae9688d5d4897c19074f62c7f1701James Dong 17f933441648ef6a71dee783d733aac17b9508b452Andreas Huber//#define LOG_NDEBUG 0 18f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#define LOG_TAG "StagefrightRecorder" 19f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <utils/Log.h> 20f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 21f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include "StagefrightRecorder.h" 22f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 23f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <binder/IPCThreadState.h> 24f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <binder/IServiceManager.h> 25f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 26f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/IMediaPlayerService.h> 27f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/openmax/OMX_Audio.h> 28f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/foundation/ADebug.h> 297cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden#include <media/stagefright/AudioSource.h> 30afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber#include <media/stagefright/AMRWriter.h> 31f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/AACWriter.h> 321173118eace0e9e347cb007f0da817cee87579edGlenn Kasten#include <media/stagefright/CameraSource.h> 33f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/CameraSourceTimeLapse.h> 341065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber#include <media/stagefright/MPEG2TSWriter.h> 35f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/MPEG4Writer.h> 363a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber#include <media/stagefright/MediaDefs.h> 373a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber#include <media/stagefright/MetaData.h> 3897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu#include <media/stagefright/OMXClient.h> 39f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/OMXCodec.h> 4097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu#include <media/stagefright/SurfaceMediaSource.h> 41f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/MediaProfiles.h> 42496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber#include <camera/ICamera.h> 43496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber#include <camera/CameraParameters.h> 44f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <gui/Surface.h> 45f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 46f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <utils/Errors.h> 47f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <sys/types.h> 48f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <ctype.h> 49f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <unistd.h> 50f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 51f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <system/audio.h> 52f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 53f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include "ARTPWriter.h" 54f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 55f933441648ef6a71dee783d733aac17b9508b452Andreas Hubernamespace android { 56f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 57f933441648ef6a71dee783d733aac17b9508b452Andreas Huber// To collect the encoder usage for the battery app 58f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatic void addBatteryData(uint32_t params) { 59f933441648ef6a71dee783d733aac17b9508b452Andreas Huber sp<IBinder> binder = 60f933441648ef6a71dee783d733aac17b9508b452Andreas Huber defaultServiceManager()->getService(String16("media.player")); 61f933441648ef6a71dee783d733aac17b9508b452Andreas Huber sp<IMediaPlayerService> service = interface_cast<IMediaPlayerService>(binder); 62f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK(service.get() != NULL); 63f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 64f933441648ef6a71dee783d733aac17b9508b452Andreas Huber service->addBatteryData(params); 65f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 66f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 67f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 68f933441648ef6a71dee783d733aac17b9508b452Andreas HuberStagefrightRecorder::StagefrightRecorder() 69f933441648ef6a71dee783d733aac17b9508b452Andreas Huber : mWriter(NULL), 70f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mOutputFd(-1), 71f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mAudioSource(AUDIO_SOURCE_CNT), 72f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mVideoSource(VIDEO_SOURCE_LIST_END), 73f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mStarted(false), mSurfaceMediaSource(NULL) { 74f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 75f933441648ef6a71dee783d733aac17b9508b452Andreas Huber ALOGV("Constructor"); 76f933441648ef6a71dee783d733aac17b9508b452Andreas Huber reset(); 77f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 78f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 79f933441648ef6a71dee783d733aac17b9508b452Andreas HuberStagefrightRecorder::~StagefrightRecorder() { 80f933441648ef6a71dee783d733aac17b9508b452Andreas Huber ALOGV("Destructor"); 81f933441648ef6a71dee783d733aac17b9508b452Andreas Huber stop(); 82f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 83f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 84f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t StagefrightRecorder::init() { 85f933441648ef6a71dee783d733aac17b9508b452Andreas Huber ALOGV("init"); 86f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return OK; 87f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 88f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 89f933441648ef6a71dee783d733aac17b9508b452Andreas Huber// The client side of mediaserver asks it to creat a SurfaceMediaSource 90f933441648ef6a71dee783d733aac17b9508b452Andreas Huber// and return a interface reference. The client side will use that 91f933441648ef6a71dee783d733aac17b9508b452Andreas Huber// while encoding GL Frames 92f933441648ef6a71dee783d733aac17b9508b452Andreas Hubersp<ISurfaceTexture> StagefrightRecorder::querySurfaceMediaSource() const { 93f933441648ef6a71dee783d733aac17b9508b452Andreas Huber ALOGV("Get SurfaceMediaSource"); 94f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return mSurfaceMediaSource->getBufferQueue(); 95f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 96f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 97f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t StagefrightRecorder::setAudioSource(audio_source_t as) { 98f933441648ef6a71dee783d733aac17b9508b452Andreas Huber ALOGV("setAudioSource: %d", as); 99f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (as < AUDIO_SOURCE_DEFAULT || 100f933441648ef6a71dee783d733aac17b9508b452Andreas Huber as >= AUDIO_SOURCE_CNT) { 101f933441648ef6a71dee783d733aac17b9508b452Andreas Huber ALOGE("Invalid audio source: %d", as); 102f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return BAD_VALUE; 103f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 104f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 105f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (as == AUDIO_SOURCE_DEFAULT) { 106f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mAudioSource = AUDIO_SOURCE_MIC; 107f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } else { 108f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mAudioSource = as; 109f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 110f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 111f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return OK; 112f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 113f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 114f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t StagefrightRecorder::setVideoSource(video_source vs) { 115f933441648ef6a71dee783d733aac17b9508b452Andreas Huber ALOGV("setVideoSource: %d", vs); 116f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (vs < VIDEO_SOURCE_DEFAULT || 117f933441648ef6a71dee783d733aac17b9508b452Andreas Huber vs >= VIDEO_SOURCE_LIST_END) { 118f933441648ef6a71dee783d733aac17b9508b452Andreas Huber ALOGE("Invalid video source: %d", vs); 119f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return BAD_VALUE; 120f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 121f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 122f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (vs == VIDEO_SOURCE_DEFAULT) { 123f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mVideoSource = VIDEO_SOURCE_CAMERA; 124f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } else { 125f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mVideoSource = vs; 126f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 127f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 128f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return OK; 129f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 130f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 131f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t StagefrightRecorder::setOutputFormat(output_format of) { 132f933441648ef6a71dee783d733aac17b9508b452Andreas Huber ALOGV("setOutputFormat: %d", of); 133f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (of < OUTPUT_FORMAT_DEFAULT || 134f933441648ef6a71dee783d733aac17b9508b452Andreas Huber of >= OUTPUT_FORMAT_LIST_END) { 135f933441648ef6a71dee783d733aac17b9508b452Andreas Huber ALOGE("Invalid output format: %d", of); 136f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return BAD_VALUE; 137f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 138f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 139f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (of == OUTPUT_FORMAT_DEFAULT) { 140f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mOutputFormat = OUTPUT_FORMAT_THREE_GPP; 141f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } else { 142f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mOutputFormat = of; 143f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 144f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 145f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return OK; 146f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 147f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 148f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t StagefrightRecorder::setAudioEncoder(audio_encoder ae) { 149f933441648ef6a71dee783d733aac17b9508b452Andreas Huber ALOGV("setAudioEncoder: %d", ae); 150f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (ae < AUDIO_ENCODER_DEFAULT || 151f933441648ef6a71dee783d733aac17b9508b452Andreas Huber ae >= AUDIO_ENCODER_LIST_END) { 152f933441648ef6a71dee783d733aac17b9508b452Andreas Huber ALOGE("Invalid audio encoder: %d", ae); 153f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return BAD_VALUE; 154f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 155f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 156f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (ae == AUDIO_ENCODER_DEFAULT) { 157f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mAudioEncoder = AUDIO_ENCODER_AMR_NB; 158f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } else { 159f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mAudioEncoder = ae; 160f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 161f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 162f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return OK; 163f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 164f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 165f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t StagefrightRecorder::setVideoEncoder(video_encoder ve) { 166f933441648ef6a71dee783d733aac17b9508b452Andreas Huber ALOGV("setVideoEncoder: %d", ve); 167f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (ve < VIDEO_ENCODER_DEFAULT || 168f933441648ef6a71dee783d733aac17b9508b452Andreas Huber ve >= VIDEO_ENCODER_LIST_END) { 169f933441648ef6a71dee783d733aac17b9508b452Andreas Huber ALOGE("Invalid video encoder: %d", ve); 170f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return BAD_VALUE; 171ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber } 172ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber 173ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber if (ve == VIDEO_ENCODER_DEFAULT) { 174ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber mVideoEncoder = VIDEO_ENCODER_H263; 175ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber } else { 176ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber mVideoEncoder = ve; 177ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber } 178ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber 179ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber return OK; 180ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber} 181ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber 182ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huberstatus_t StagefrightRecorder::setVideoSize(int width, int height) { 183ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber ALOGV("setVideoSize: %dx%d", width, height); 184ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber if (width <= 0 || height <= 0) { 185ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber ALOGE("Invalid video size: %dx%d", width, height); 186ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber return BAD_VALUE; 187ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber } 188ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber 189f933441648ef6a71dee783d733aac17b9508b452Andreas Huber // Additional check on the dimension will be performed later 190f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mVideoWidth = width; 191f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mVideoHeight = height; 192f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 193f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return OK; 194c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber} 195f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 196f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t StagefrightRecorder::setVideoFrameRate(int frames_per_second) { 197f933441648ef6a71dee783d733aac17b9508b452Andreas Huber ALOGV("setVideoFrameRate: %d", frames_per_second); 198c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber if ((frames_per_second <= 0 && frames_per_second != -1) || 199f933441648ef6a71dee783d733aac17b9508b452Andreas Huber frames_per_second > 120) { 200ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber ALOGE("Invalid video frame rate: %d", frames_per_second); 201ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber return BAD_VALUE; 202f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 203f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 204f933441648ef6a71dee783d733aac17b9508b452Andreas Huber // Additional check on the frame rate will be performed later 205f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mFrameRate = frames_per_second; 206f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 207c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber return OK; 208c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber} 209c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber 210c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberstatus_t StagefrightRecorder::setCamera(const sp<ICamera> &camera, 211c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber const sp<ICameraRecordingProxy> &proxy) { 212c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber ALOGV("setCamera"); 213c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber if (camera == 0) { 214c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber ALOGE("camera is NULL"); 215c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber return BAD_VALUE; 216c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber } 217c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber if (proxy == 0) { 2187cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden ALOGE("camera proxy is NULL"); 219c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber return BAD_VALUE; 220c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber } 221c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber 222c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber mCamera = camera; 223c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber mCameraProxy = proxy; 224c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber return OK; 225c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber} 226c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber 227f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t StagefrightRecorder::setPreviewSurface(const sp<Surface> &surface) { 228f933441648ef6a71dee783d733aac17b9508b452Andreas Huber ALOGV("setPreviewSurface: %p", surface.get()); 229f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mPreviewSurface = surface; 230f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 231f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return OK; 232f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 233f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 234f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t StagefrightRecorder::setOutputFile(const char *path) { 235f933441648ef6a71dee783d733aac17b9508b452Andreas Huber ALOGE("setOutputFile(const char*) must not be called"); 236f933441648ef6a71dee783d733aac17b9508b452Andreas Huber // We don't actually support this at all, as the media_server process 237f933441648ef6a71dee783d733aac17b9508b452Andreas Huber // no longer has permissions to create files. 238f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 239f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return -EPERM; 240f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 241f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 242f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t StagefrightRecorder::setOutputFile(int fd, int64_t offset, int64_t length) { 243f933441648ef6a71dee783d733aac17b9508b452Andreas Huber ALOGV("setOutputFile: %d, %lld, %lld", fd, offset, length); 244f933441648ef6a71dee783d733aac17b9508b452Andreas Huber // These don't make any sense, do they? 245f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK_EQ(offset, 0ll); 246f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK_EQ(length, 0ll); 247f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 248f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (fd < 0) { 249f933441648ef6a71dee783d733aac17b9508b452Andreas Huber ALOGE("Invalid file descriptor: %d", fd); 250f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return -EBADF; 251f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 252f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 253f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (mOutputFd >= 0) { 254f933441648ef6a71dee783d733aac17b9508b452Andreas Huber ::close(mOutputFd); 255f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 256f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mOutputFd = dup(fd); 257f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 258f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return OK; 259f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 260054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar 261054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar// Attempt to parse an int64 literal optionally surrounded by whitespace, 262f933441648ef6a71dee783d733aac17b9508b452Andreas Huber// returns true on success, false otherwise. 263f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatic bool safe_strtoi64(const char *s, int64_t *val) { 264f933441648ef6a71dee783d733aac17b9508b452Andreas Huber char *end; 265f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 266f933441648ef6a71dee783d733aac17b9508b452Andreas Huber // It is lame, but according to man page, we have to set errno to 0 267f933441648ef6a71dee783d733aac17b9508b452Andreas Huber // before calling strtoll(). 268349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber errno = 0; 269349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber *val = strtoll(s, &end, 10); 270349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber 271f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (end == s || errno == ERANGE) { 272f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return false; 273f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 274f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 275f933441648ef6a71dee783d733aac17b9508b452Andreas Huber // Skip trailing whitespace 276f933441648ef6a71dee783d733aac17b9508b452Andreas Huber while (isspace(*end)) { 277f933441648ef6a71dee783d733aac17b9508b452Andreas Huber ++end; 278f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 279349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber 280349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber // For a successful return, the string must contain nothing but a valid 281f933441648ef6a71dee783d733aac17b9508b452Andreas Huber // int64 literal optionally surrounded by whitespace. 282f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 283f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return *end == '\0'; 284f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 285f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 286f933441648ef6a71dee783d733aac17b9508b452Andreas Huber// Return true if the value is in [0, 0x007FFFFFFF] 287f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatic bool safe_strtoi32(const char *s, int32_t *val) { 288f933441648ef6a71dee783d733aac17b9508b452Andreas Huber int64_t temp; 289f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (safe_strtoi64(s, &temp)) { 290f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (temp >= 0 && temp <= 0x007FFFFFFF) { 291f933441648ef6a71dee783d733aac17b9508b452Andreas Huber *val = static_cast<int32_t>(temp); 292f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return true; 293f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 294f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 295f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return false; 296f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 297f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 298f933441648ef6a71dee783d733aac17b9508b452Andreas Huber// Trim both leading and trailing whitespace from the given string. 299f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatic void TrimString(String8 *s) { 300f933441648ef6a71dee783d733aac17b9508b452Andreas Huber size_t num_bytes = s->bytes(); 301f933441648ef6a71dee783d733aac17b9508b452Andreas Huber const char *data = s->string(); 302f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 303f933441648ef6a71dee783d733aac17b9508b452Andreas Huber size_t leading_space = 0; 304f933441648ef6a71dee783d733aac17b9508b452Andreas Huber while (leading_space < num_bytes && isspace(data[leading_space])) { 305f933441648ef6a71dee783d733aac17b9508b452Andreas Huber ++leading_space; 306f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 307f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 308f933441648ef6a71dee783d733aac17b9508b452Andreas Huber size_t i = num_bytes; 309f933441648ef6a71dee783d733aac17b9508b452Andreas Huber while (i > leading_space && isspace(data[i - 1])) { 310f933441648ef6a71dee783d733aac17b9508b452Andreas Huber --i; 311f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 312f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 313f933441648ef6a71dee783d733aac17b9508b452Andreas Huber s->setTo(String8(&data[leading_space], i - leading_space)); 314f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 315f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 316f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t StagefrightRecorder::setParamAudioSamplingRate(int32_t sampleRate) { 3175778822d86b0337407514b9372562b86edfa91cdAndreas Huber ALOGV("setParamAudioSamplingRate: %d", sampleRate); 3185778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (sampleRate <= 0) { 319f933441648ef6a71dee783d733aac17b9508b452Andreas Huber ALOGE("Invalid audio sampling rate: %d", sampleRate); 320f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return BAD_VALUE; 321f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 322f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 323f933441648ef6a71dee783d733aac17b9508b452Andreas Huber // Additional check on the sample rate will be performed later. 324f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mSampleRate = sampleRate; 325f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return OK; 326f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 327f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 328f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t StagefrightRecorder::setParamAudioNumberOfChannels(int32_t channels) { 329f933441648ef6a71dee783d733aac17b9508b452Andreas Huber ALOGV("setParamAudioNumberOfChannels: %d", channels); 330f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (channels <= 0 || channels >= 3) { 331f933441648ef6a71dee783d733aac17b9508b452Andreas Huber ALOGE("Invalid number of audio channels: %d", channels); 332f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return BAD_VALUE; 333f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 334f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 335f933441648ef6a71dee783d733aac17b9508b452Andreas Huber // Additional check on the number of channels will be performed later. 336f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mAudioChannels = channels; 337f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return OK; 338f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 339f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 340f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t StagefrightRecorder::setParamAudioEncodingBitRate(int32_t bitRate) { 341f933441648ef6a71dee783d733aac17b9508b452Andreas Huber ALOGV("setParamAudioEncodingBitRate: %d", bitRate); 342f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (bitRate <= 0) { 343f933441648ef6a71dee783d733aac17b9508b452Andreas Huber ALOGE("Invalid audio encoding bit rate: %d", bitRate); 344f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return BAD_VALUE; 345f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 346f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 347f933441648ef6a71dee783d733aac17b9508b452Andreas Huber // The target bit rate may not be exactly the same as the requested. 348f933441648ef6a71dee783d733aac17b9508b452Andreas Huber // It depends on many factors, such as rate control, and the bit rate 349f933441648ef6a71dee783d733aac17b9508b452Andreas Huber // range that a specific encoder supports. The mismatch between the 350f933441648ef6a71dee783d733aac17b9508b452Andreas Huber // the target and requested bit rate will NOT be treated as an error. 351f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mAudioBitRate = bitRate; 352f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return OK; 353f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 354f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 355f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t StagefrightRecorder::setParamVideoEncodingBitRate(int32_t bitRate) { 356f933441648ef6a71dee783d733aac17b9508b452Andreas Huber ALOGV("setParamVideoEncodingBitRate: %d", bitRate); 357f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (bitRate <= 0) { 358f933441648ef6a71dee783d733aac17b9508b452Andreas Huber ALOGE("Invalid video encoding bit rate: %d", bitRate); 359f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return BAD_VALUE; 360f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 361f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 362afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber // The target bit rate may not be exactly the same as the requested. 363afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber // It depends on many factors, such as rate control, and the bit rate 3645778822d86b0337407514b9372562b86edfa91cdAndreas Huber // range that a specific encoder supports. The mismatch between the 365c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber // the target and requested bit rate will NOT be treated as an error. 366308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang mVideoBitRate = bitRate; 3679806555d3930be43e11106281dee354820ac1c88Andreas Huber return OK; 3689806555d3930be43e11106281dee354820ac1c88Andreas Huber} 3699806555d3930be43e11106281dee354820ac1c88Andreas Huber 3709806555d3930be43e11106281dee354820ac1c88Andreas Huber// Always rotate clockwise, and only support 0, 90, 180 and 270 for now. 371054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarstatus_t StagefrightRecorder::setParamVideoRotation(int32_t degrees) { 372054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar ALOGV("setParamVideoRotation: %d", degrees); 373054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar if (degrees < 0 || degrees % 90 != 0) { 374a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber ALOGE("Unsupported video rotation angle: %d", degrees); 375a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber return BAD_VALUE; 376f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 377c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber mRotationDegrees = degrees % 360; 378f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return OK; 379f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 380f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 381f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t StagefrightRecorder::setParamMaxFileDurationUs(int64_t timeUs) { 382f933441648ef6a71dee783d733aac17b9508b452Andreas Huber ALOGV("setParamMaxFileDurationUs: %lld us", timeUs); 383f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 384f933441648ef6a71dee783d733aac17b9508b452Andreas Huber // This is meant for backward compatibility for MediaRecorder.java 385f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (timeUs <= 0) { 386f933441648ef6a71dee783d733aac17b9508b452Andreas Huber ALOGW("Max file duration is not positive: %lld us. Disabling duration limit.", timeUs); 387f933441648ef6a71dee783d733aac17b9508b452Andreas Huber timeUs = 0; // Disable the duration limit for zero or negative values. 388f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } else if (timeUs <= 100000LL) { // XXX: 100 milli-seconds 389f933441648ef6a71dee783d733aac17b9508b452Andreas Huber ALOGE("Max file duration is too short: %lld us", timeUs); 390dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber return BAD_VALUE; 391f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 392f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 393f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (timeUs <= 15 * 1000000LL) { 394f933441648ef6a71dee783d733aac17b9508b452Andreas Huber ALOGW("Target duration (%lld us) too short to be respected", timeUs); 395f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 396f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mMaxFileDurationUs = timeUs; 397f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return OK; 398f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 399f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 400f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t StagefrightRecorder::setParamMaxFileSizeBytes(int64_t bytes) { 401f933441648ef6a71dee783d733aac17b9508b452Andreas Huber ALOGV("setParamMaxFileSizeBytes: %lld bytes", bytes); 402f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 403f933441648ef6a71dee783d733aac17b9508b452Andreas Huber // This is meant for backward compatibility for MediaRecorder.java 404f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (bytes <= 0) { 405f933441648ef6a71dee783d733aac17b9508b452Andreas Huber ALOGW("Max file size is not positive: %lld bytes. " 406f933441648ef6a71dee783d733aac17b9508b452Andreas Huber "Disabling file size limit.", bytes); 407f933441648ef6a71dee783d733aac17b9508b452Andreas Huber bytes = 0; // Disable the file size limit for zero or negative values. 408a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber } else if (bytes <= 1024) { // XXX: 1 kB 409a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber ALOGE("Max file size is too small: %lld bytes", bytes); 410a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber return BAD_VALUE; 411a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber } 412a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber 413a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber if (bytes <= 100 * 1024) { 4145778822d86b0337407514b9372562b86edfa91cdAndreas Huber ALOGW("Target file size (%lld bytes) is too small to be respected", bytes); 4155778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 4165778822d86b0337407514b9372562b86edfa91cdAndreas Huber 4175778822d86b0337407514b9372562b86edfa91cdAndreas Huber mMaxFileSizeBytes = bytes; 4185778822d86b0337407514b9372562b86edfa91cdAndreas Huber return OK; 4195778822d86b0337407514b9372562b86edfa91cdAndreas Huber} 4205778822d86b0337407514b9372562b86edfa91cdAndreas Huber 4215778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t StagefrightRecorder::setParamInterleaveDuration(int32_t durationUs) { 4225778822d86b0337407514b9372562b86edfa91cdAndreas Huber ALOGV("setParamInterleaveDuration: %d", durationUs); 4235778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (durationUs <= 500000) { // 500 ms 4245778822d86b0337407514b9372562b86edfa91cdAndreas Huber // If interleave duration is too small, it is very inefficient to do 4255778822d86b0337407514b9372562b86edfa91cdAndreas Huber // interleaving since the metadata overhead will count for a significant 4267cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden // portion of the saved contents 4277cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden ALOGE("Audio/video interleave duration is too small: %d us", durationUs); 4287cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden return BAD_VALUE; 4297cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden } else if (durationUs >= 10000000) { // 10 seconds 4307cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden // If interleaving duration is too large, it can cause the recording 4317cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden // session to use too much memory since we have to save the output 4327cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden // data before we write them out 4337cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden ALOGE("Audio/video interleave duration is too large: %d us", durationUs); 4345778822d86b0337407514b9372562b86edfa91cdAndreas Huber return BAD_VALUE; 4355778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 4365778822d86b0337407514b9372562b86edfa91cdAndreas Huber mInterleaveDurationUs = durationUs; 4375778822d86b0337407514b9372562b86edfa91cdAndreas Huber return OK; 438f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 4397a3a2b2f9bb9421dcf83fbd47276e57917078aefJames Dong 440f933441648ef6a71dee783d733aac17b9508b452Andreas Huber// If seconds < 0, only the first frame is I frame, and rest are all P frames 441f933441648ef6a71dee783d733aac17b9508b452Andreas Huber// If seconds == 0, all frames are encoded as I frames. No P frames 442f933441648ef6a71dee783d733aac17b9508b452Andreas Huber// If seconds > 0, it is the time spacing (seconds) between 2 neighboring I frames 443f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t StagefrightRecorder::setParamVideoIFramesInterval(int32_t seconds) { 444f933441648ef6a71dee783d733aac17b9508b452Andreas Huber ALOGV("setParamVideoIFramesInterval: %d seconds", seconds); 445f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mIFramesIntervalSec = seconds; 446f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return OK; 447c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber} 448c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber 449c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberstatus_t StagefrightRecorder::setParam64BitFileOffset(bool use64Bit) { 450c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber ALOGV("setParam64BitFileOffset: %s", 451f933441648ef6a71dee783d733aac17b9508b452Andreas Huber use64Bit? "use 64 bit file offset": "use 32 bit file offset"); 452f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mUse64BitFileOffset = use64Bit; 453496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber return OK; 454496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber} 455496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber 456496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huberstatus_t StagefrightRecorder::setParamVideoCameraId(int32_t cameraId) { 4574dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar ALOGV("setParamVideoCameraId: %d", cameraId); 4584dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar if (cameraId < 0) { 4594dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar return BAD_VALUE; 4604dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar } 4614dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar mCameraId = cameraId; 4624dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar return OK; 4634dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar} 4644dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar 4654dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnarstatus_t StagefrightRecorder::setParamTrackTimeStatus(int64_t timeDurationUs) { 4664dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar ALOGV("setParamTrackTimeStatus: %lld", timeDurationUs); 4674dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar if (timeDurationUs < 20000) { // Infeasible if shorter than 20 ms? 4684dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar ALOGE("Tracking time duration too short: %lld us", timeDurationUs); 469f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return BAD_VALUE; 470f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 471f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mTrackEveryTimeDurationUs = timeDurationUs; 472f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return OK; 473f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 474f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 4755778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t StagefrightRecorder::setParamVideoEncoderProfile(int32_t profile) { 476f933441648ef6a71dee783d733aac17b9508b452Andreas Huber ALOGV("setParamVideoEncoderProfile: %d", profile); 477054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar 478054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar // Additional check will be done later when we load the encoder. 479054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar // For now, we are accepting values defined in OpenMAX IL. 480054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar mVideoEncoderProfile = profile; 481054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar return OK; 4825778822d86b0337407514b9372562b86edfa91cdAndreas Huber} 4835778822d86b0337407514b9372562b86edfa91cdAndreas Huber 4845778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t StagefrightRecorder::setParamVideoEncoderLevel(int32_t level) { 4855778822d86b0337407514b9372562b86edfa91cdAndreas Huber ALOGV("setParamVideoEncoderLevel: %d", level); 486f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 4875778822d86b0337407514b9372562b86edfa91cdAndreas Huber // Additional check will be done later when we load the encoder. 4885778822d86b0337407514b9372562b86edfa91cdAndreas Huber // For now, we are accepting values defined in OpenMAX IL. 489f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mVideoEncoderLevel = level; 4905778822d86b0337407514b9372562b86edfa91cdAndreas Huber return OK; 4915778822d86b0337407514b9372562b86edfa91cdAndreas Huber} 4925778822d86b0337407514b9372562b86edfa91cdAndreas Huber 4935778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t StagefrightRecorder::setParamMovieTimeScale(int32_t timeScale) { 4945778822d86b0337407514b9372562b86edfa91cdAndreas Huber ALOGV("setParamMovieTimeScale: %d", timeScale); 495f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 4965778822d86b0337407514b9372562b86edfa91cdAndreas Huber // The range is set to be the same as the audio's time scale range 4975778822d86b0337407514b9372562b86edfa91cdAndreas Huber // since audio's time scale has a wider range. 498f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (timeScale < 600 || timeScale > 96000) { 4995778822d86b0337407514b9372562b86edfa91cdAndreas Huber ALOGE("Time scale (%d) for movie is out of range [600, 96000]", timeScale); 5005778822d86b0337407514b9372562b86edfa91cdAndreas Huber return BAD_VALUE; 5015778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 502f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mMovieTimeScale = timeScale; 503ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber return OK; 504ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber} 505f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 506afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huberstatus_t StagefrightRecorder::setParamVideoTimeScale(int32_t timeScale) { 507afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber ALOGV("setParamVideoTimeScale: %d", timeScale); 508afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber 509afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber // 60000 is chosen to make sure that each video frame from a 60-fps 5101065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber // video has 1000 ticks. 511308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang if (timeScale < 600 || timeScale > 60000) { 512308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang ALOGE("Time scale (%d) for video is out of range [600, 60000]", timeScale); 513ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber return BAD_VALUE; 514ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber } 515ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber mVideoTimeScale = timeScale; 516ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber return OK; 517ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber} 518ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber 519ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huberstatus_t StagefrightRecorder::setParamAudioTimeScale(int32_t timeScale) { 520308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang ALOGV("setParamAudioTimeScale: %d", timeScale); 521308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang 522308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang // 96000 Hz is the highest sampling rate support in AAC. 523308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang if (timeScale < 600 || timeScale > 96000) { 524ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber ALOGE("Time scale (%d) for audio is out of range [600, 96000]", timeScale); 5255778822d86b0337407514b9372562b86edfa91cdAndreas Huber return BAD_VALUE; 526ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber } 5275778822d86b0337407514b9372562b86edfa91cdAndreas Huber mAudioTimeScale = timeScale; 528ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber return OK; 529ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber} 530ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber 531ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huberstatus_t StagefrightRecorder::setParamTimeLapseEnable(int32_t timeLapseEnable) { 532ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber ALOGV("setParamTimeLapseEnable: %d", timeLapseEnable); 5335778822d86b0337407514b9372562b86edfa91cdAndreas Huber 5341065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber if(timeLapseEnable == 0) { 5355778822d86b0337407514b9372562b86edfa91cdAndreas Huber mCaptureTimeLapse = false; 5361065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber } else if (timeLapseEnable == 1) { 5371065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber mCaptureTimeLapse = true; 5385778822d86b0337407514b9372562b86edfa91cdAndreas Huber } else { 539f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return BAD_VALUE; 5405778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 5415778822d86b0337407514b9372562b86edfa91cdAndreas Huber return OK; 5425778822d86b0337407514b9372562b86edfa91cdAndreas Huber} 543f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 5445778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t StagefrightRecorder::setParamTimeBetweenTimeLapseFrameCapture(int64_t timeUs) { 5455778822d86b0337407514b9372562b86edfa91cdAndreas Huber ALOGV("setParamTimeBetweenTimeLapseFrameCapture: %lld us", timeUs); 5465778822d86b0337407514b9372562b86edfa91cdAndreas Huber 5475778822d86b0337407514b9372562b86edfa91cdAndreas Huber // Not allowing time more than a day 548eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber if (timeUs <= 0 || timeUs > 86400*1E6) { 549eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber ALOGE("Time between time lapse frame capture (%lld) is out of range [0, 1 Day]", timeUs); 550eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber return BAD_VALUE; 5515778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 552eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber 5535778822d86b0337407514b9372562b86edfa91cdAndreas Huber mTimeBetweenTimeLapseFrameCaptureUs = timeUs; 554eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber return OK; 555f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 556f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 557eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huberstatus_t StagefrightRecorder::setParamGeoDataLongitude( 5585778822d86b0337407514b9372562b86edfa91cdAndreas Huber int64_t longitudex10000) { 5595778822d86b0337407514b9372562b86edfa91cdAndreas Huber 560f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (longitudex10000 > 1800000 || longitudex10000 < -1800000) { 561f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return BAD_VALUE; 562f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 563054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar mLongitudex10000 = longitudex10000; 564054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar return OK; 565054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar} 566f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 567f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t StagefrightRecorder::setParamGeoDataLatitude( 568f933441648ef6a71dee783d733aac17b9508b452Andreas Huber int64_t latitudex10000) { 569f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 570f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (latitudex10000 > 900000 || latitudex10000 < -900000) { 571f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return BAD_VALUE; 572f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 573f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mLatitudex10000 = latitudex10000; 574f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return OK; 575f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 576f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 577f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t StagefrightRecorder::setParameter( 578f933441648ef6a71dee783d733aac17b9508b452Andreas Huber const String8 &key, const String8 &value) { 579f933441648ef6a71dee783d733aac17b9508b452Andreas Huber ALOGV("setParameter: key (%s) => value (%s)", key.string(), value.string()); 580f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (key == "max-duration") { 581f933441648ef6a71dee783d733aac17b9508b452Andreas Huber int64_t max_duration_ms; 582f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (safe_strtoi64(value.string(), &max_duration_ms)) { 583f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return setParamMaxFileDurationUs(1000LL * max_duration_ms); 58429357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block } 585f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } else if (key == "max-filesize") { 586f933441648ef6a71dee783d733aac17b9508b452Andreas Huber int64_t max_filesize_bytes; 587f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (safe_strtoi64(value.string(), &max_filesize_bytes)) { 588f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return setParamMaxFileSizeBytes(max_filesize_bytes); 589f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 5903c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis } else if (key == "interleave-duration-us") { 5913c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis int32_t durationUs; 5923c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis if (safe_strtoi32(value.string(), &durationUs)) { 5935ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block return setParamInterleaveDuration(durationUs); 5943c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis } 5953c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis } else if (key == "param-movie-time-scale") { 5963c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis int32_t timeScale; 5973c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis if (safe_strtoi32(value.string(), &timeScale)) { 598bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber return setParamMovieTimeScale(timeScale); 599bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber } 600bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber } else if (key == "param-use-64bit-offset") { 601bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber int32_t use64BitOffset; 602bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber if (safe_strtoi32(value.string(), &use64BitOffset)) { 603bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber return setParam64BitFileOffset(use64BitOffset != 0); 604bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber } 605bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber } else if (key == "param-geotag-longitude") { 606bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber int64_t longitudex10000; 607bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber if (safe_strtoi64(value.string(), &longitudex10000)) { 608bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber return setParamGeoDataLongitude(longitudex10000); 609bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber } 610bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber } else if (key == "param-geotag-latitude") { 611bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber int64_t latitudex10000; 612bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber if (safe_strtoi64(value.string(), &latitudex10000)) { 613bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber return setParamGeoDataLatitude(latitudex10000); 614bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber } 615bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber } else if (key == "param-track-time-status") { 616bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber int64_t timeDurationUs; 617bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber if (safe_strtoi64(value.string(), &timeDurationUs)) { 618bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber return setParamTrackTimeStatus(timeDurationUs); 619bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber } 620bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber } else if (key == "audio-param-sampling-rate") { 621f933441648ef6a71dee783d733aac17b9508b452Andreas Huber int32_t sampling_rate; 622f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (safe_strtoi32(value.string(), &sampling_rate)) { 6233c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis return setParamAudioSamplingRate(sampling_rate); 624f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 625f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } else if (key == "audio-param-number-of-channels") { 62629357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block int32_t number_of_channels; 627f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (safe_strtoi32(value.string(), &number_of_channels)) { 628f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return setParamAudioNumberOfChannels(number_of_channels); 629f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 630054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar } else if (key == "audio-param-encoding-bitrate") { 631258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis int32_t audio_bitrate; 632258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis if (safe_strtoi32(value.string(), &audio_bitrate)) { 633054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar return setParamAudioEncodingBitRate(audio_bitrate); 634258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis } 635258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis } else if (key == "audio-param-time-scale") { 63629357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block int32_t timeScale; 637258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis if (safe_strtoi32(value.string(), &timeScale)) { 638258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis return setParamAudioTimeScale(timeScale); 639258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis } 640258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis } else if (key == "video-param-encoding-bitrate") { 641258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis int32_t video_bitrate; 642258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis if (safe_strtoi32(value.string(), &video_bitrate)) { 643258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis return setParamVideoEncodingBitRate(video_bitrate); 644054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar } 645054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar } else if (key == "video-param-rotation-angle-degrees") { 646258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis int32_t degrees; 647258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis if (safe_strtoi32(value.string(), °rees)) { 648258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis return setParamVideoRotation(degrees); 649258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis } 650258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis } else if (key == "video-param-i-frames-interval") { 65129357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block int32_t seconds; 652258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis if (safe_strtoi32(value.string(), &seconds)) { 653258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis return setParamVideoIFramesInterval(seconds); 654258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis } 655258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis } else if (key == "video-param-encoder-profile") { 656258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis int32_t profile; 657f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (safe_strtoi32(value.string(), &profile)) { 658f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return setParamVideoEncoderProfile(profile); 659f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 660f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } else if (key == "video-param-encoder-level") { 66129357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block int32_t level; 662f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (safe_strtoi32(value.string(), &level)) { 663f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return setParamVideoEncoderLevel(level); 664f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 665f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } else if (key == "video-param-camera-id") { 666054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar int32_t cameraId; 667054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar if (safe_strtoi32(value.string(), &cameraId)) { 668054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar return setParamVideoCameraId(cameraId); 669054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar } 670054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar } else if (key == "video-param-time-scale") { 671054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar int32_t timeScale; 672054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar if (safe_strtoi32(value.string(), &timeScale)) { 673054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar return setParamVideoTimeScale(timeScale); 674054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar } 675054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar } else if (key == "time-lapse-enable") { 676054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar int32_t timeLapseEnable; 677054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar if (safe_strtoi32(value.string(), &timeLapseEnable)) { 6783856b090cd04ba5dd4a59a12430ed724d5995909Steve Block return setParamTimeLapseEnable(timeLapseEnable); 679f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 680054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar } else if (key == "time-between-time-lapse-frame-capture") { 681f933441648ef6a71dee783d733aac17b9508b452Andreas Huber int64_t timeBetweenTimeLapseFrameCaptureMs; 682f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (safe_strtoi64(value.string(), &timeBetweenTimeLapseFrameCaptureMs)) { 683054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar return setParamTimeBetweenTimeLapseFrameCapture( 6848ce2364512f7c32c824f5ec5719688830ba72427Iliyan Malchev 1000LL * timeBetweenTimeLapseFrameCaptureMs); 6851e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis } 686f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } else { 68729357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("setParameter: failed to find key %s", key.string()); 688f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 689f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return BAD_VALUE; 690f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 691f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 69274006804065941841883c4b46ee785070164023fJamie Gennisstatus_t StagefrightRecorder::setParameters(const String8 ¶ms) { 69374006804065941841883c4b46ee785070164023fJamie Gennis ALOGV("setParameters: %s", params.string()); 694054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar const char *cparams = params.string(); 69574006804065941841883c4b46ee785070164023fJamie Gennis const char *key_start = cparams; 69674006804065941841883c4b46ee785070164023fJamie Gennis for (;;) { 69774006804065941841883c4b46ee785070164023fJamie Gennis const char *equal_pos = strchr(key_start, '='); 698f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (equal_pos == NULL) { 699f933441648ef6a71dee783d733aac17b9508b452Andreas Huber ALOGE("Parameters %s miss a value", cparams); 700f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return BAD_VALUE; 701f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 70229357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block String8 key(key_start, equal_pos - key_start); 70374006804065941841883c4b46ee785070164023fJamie Gennis TrimString(&key); 704f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (key.length() == 0) { 705f933441648ef6a71dee783d733aac17b9508b452Andreas Huber ALOGE("Parameters %s contains an empty key", cparams); 706f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return BAD_VALUE; 70774006804065941841883c4b46ee785070164023fJamie Gennis } 70874006804065941841883c4b46ee785070164023fJamie Gennis const char *value_start = equal_pos + 1; 7093856b090cd04ba5dd4a59a12430ed724d5995909Steve Block const char *semicolon_pos = strchr(value_start, ';'); 710f933441648ef6a71dee783d733aac17b9508b452Andreas Huber String8 value; 711f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (semicolon_pos == NULL) { 712f933441648ef6a71dee783d733aac17b9508b452Andreas Huber value.setTo(value_start); 713f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } else { 714f933441648ef6a71dee783d733aac17b9508b452Andreas Huber value.setTo(value_start, semicolon_pos - value_start); 715f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 716f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (setParameter(key, value) != OK) { 717f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return BAD_VALUE; 718f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 719f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (semicolon_pos == NULL) { 720f933441648ef6a71dee783d733aac17b9508b452Andreas Huber break; // Reaches the end 72174006804065941841883c4b46ee785070164023fJamie Gennis } 722f933441648ef6a71dee783d733aac17b9508b452Andreas Huber key_start = semicolon_pos + 1; 723054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar } 724054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar return OK; 725054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar} 726f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 727f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t StagefrightRecorder::setListener(const sp<IMediaRecorderClient> &listener) { 728f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mListener = listener; 729f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 730f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return OK; 731f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 732f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 733f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t StagefrightRecorder::prepare() { 734f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return OK; 735f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 736054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar 737054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarstatus_t StagefrightRecorder::start() { 738054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar CHECK_GE(mOutputFd, 0); 739054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar 740054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar if (mWriter != NULL) { 741054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar ALOGE("File writer is not avaialble"); 742054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar return UNKNOWN_ERROR; 743054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar } 744054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar 745054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar status_t status = OK; 746054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar 747054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar switch (mOutputFormat) { 748054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar case OUTPUT_FORMAT_DEFAULT: 749054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar case OUTPUT_FORMAT_THREE_GPP: 750054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar case OUTPUT_FORMAT_MPEG_4: 751054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar status = startMPEG4Recording(); 752054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar break; 753054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar 754054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar case OUTPUT_FORMAT_AMR_NB: 755054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar case OUTPUT_FORMAT_AMR_WB: 756054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar status = startAMRRecording(); 757054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar break; 758054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar 759054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar case OUTPUT_FORMAT_AAC_ADIF: 760054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar case OUTPUT_FORMAT_AAC_ADTS: 761054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar status = startAACRecording(); 762054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar break; 763054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar 764054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar case OUTPUT_FORMAT_RTP_AVP: 765054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar status = startRTPRecording(); 766054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar break; 767054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar 768054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar case OUTPUT_FORMAT_MPEG2TS: 769054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar status = startMPEG2TSRecording(); 770054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar break; 771054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar 772054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar default: 773054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar ALOGE("Unsupported output file format: %d", mOutputFormat); 774054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar status = UNKNOWN_ERROR; 775054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar break; 776054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar } 777054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar 778054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar if ((status == OK) && (!mStarted)) { 779054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar mStarted = true; 780054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar 781054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar uint32_t params = IMediaPlayerService::kBatteryDataCodecStarted; 782054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar if (mAudioSource != AUDIO_SOURCE_CNT) { 783054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar params |= IMediaPlayerService::kBatteryDataTrackAudio; 784054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar } 785054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar if (mVideoSource != VIDEO_SOURCE_LIST_END) { 786054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar params |= IMediaPlayerService::kBatteryDataTrackVideo; 787054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar } 788054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar 789054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar addBatteryData(params); 790054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar } 791054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar 792054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar return status; 793054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar} 794054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar 795f933441648ef6a71dee783d733aac17b9508b452Andreas Hubersp<MediaSource> StagefrightRecorder::createAudioSource() { 796f933441648ef6a71dee783d733aac17b9508b452Andreas Huber sp<AudioSource> audioSource = 797f933441648ef6a71dee783d733aac17b9508b452Andreas Huber new AudioSource( 7983856b090cd04ba5dd4a59a12430ed724d5995909Steve Block mAudioSource, 799f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mSampleRate, 800f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mAudioChannels); 801f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 8021e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis status_t err = audioSource->initCheck(); 803f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 804f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (err != OK) { 805f933441648ef6a71dee783d733aac17b9508b452Andreas Huber ALOGE("audio source is not initialized"); 806f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return NULL; 807f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 808f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 809f933441648ef6a71dee783d733aac17b9508b452Andreas Huber sp<MetaData> encMeta = new MetaData; 810f933441648ef6a71dee783d733aac17b9508b452Andreas Huber const char *mime; 811f933441648ef6a71dee783d733aac17b9508b452Andreas Huber switch (mAudioEncoder) { 8128ce2364512f7c32c824f5ec5719688830ba72427Iliyan Malchev case AUDIO_ENCODER_AMR_NB: 8131e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis case AUDIO_ENCODER_DEFAULT: 814054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar mime = MEDIA_MIMETYPE_AUDIO_AMR_NB; 8151e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis break; 81629357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block case AUDIO_ENCODER_AMR_WB: 817c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber mime = MEDIA_MIMETYPE_AUDIO_AMR_WB; 818c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber break; 819f933441648ef6a71dee783d733aac17b9508b452Andreas Huber case AUDIO_ENCODER_AAC: 820054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar mime = MEDIA_MIMETYPE_AUDIO_AAC; 821f933441648ef6a71dee783d733aac17b9508b452Andreas Huber encMeta->setInt32(kKeyAACProfile, OMX_AUDIO_AACObjectLC); 822f933441648ef6a71dee783d733aac17b9508b452Andreas Huber break; 823f933441648ef6a71dee783d733aac17b9508b452Andreas Huber case AUDIO_ENCODER_HE_AAC: 824f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mime = MEDIA_MIMETYPE_AUDIO_AAC; 825054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar encMeta->setInt32(kKeyAACProfile, OMX_AUDIO_AACObjectHE); 826054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar break; 827f933441648ef6a71dee783d733aac17b9508b452Andreas Huber case AUDIO_ENCODER_AAC_ELD: 828f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mime = MEDIA_MIMETYPE_AUDIO_AAC; 829f933441648ef6a71dee783d733aac17b9508b452Andreas Huber encMeta->setInt32(kKeyAACProfile, OMX_AUDIO_AACObjectELD); 830f933441648ef6a71dee783d733aac17b9508b452Andreas Huber break; 831f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 832f933441648ef6a71dee783d733aac17b9508b452Andreas Huber default: 833f933441648ef6a71dee783d733aac17b9508b452Andreas Huber ALOGE("Unknown audio encoder: %d", mAudioEncoder); 834054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar return NULL; 835054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar } 836054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar encMeta->setCString(kKeyMIMEType, mime); 837054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar 838054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar int32_t maxInputSize; 839054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar CHECK(audioSource->getFormat()->findInt32( 840054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar kKeyMaxInputSize, &maxInputSize)); 841054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar 842054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar encMeta->setInt32(kKeyMaxInputSize, maxInputSize); 843054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar encMeta->setInt32(kKeyChannelCount, mAudioChannels); 844054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar encMeta->setInt32(kKeySampleRate, mSampleRate); 845054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar encMeta->setInt32(kKeyBitRate, mAudioBitRate); 846054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar if (mAudioTimeScale > 0) { 847054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar encMeta->setInt32(kKeyTimeScale, mAudioTimeScale); 848054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar } 849054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar 850054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar OMXClient client; 851d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar CHECK_EQ(client.connect(), (status_t)OK); 852d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar sp<MediaSource> audioEncoder = 853d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar OMXCodec::Create(client.interface(), encMeta, 854054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar true /* createEncoder */, audioSource); 855d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar mAudioSourceNode = audioSource; 856d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar 857d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar return audioEncoder; 858d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar} 859d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar 860d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnarstatus_t StagefrightRecorder::startAACRecording() { 861054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar // FIXME: 862054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar // Add support for OUTPUT_FORMAT_AAC_ADIF 863d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar CHECK_EQ(mOutputFormat, OUTPUT_FORMAT_AAC_ADTS); 864d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar 865054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar CHECK(mAudioEncoder == AUDIO_ENCODER_AAC || 866054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar mAudioEncoder == AUDIO_ENCODER_HE_AAC || 867f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mAudioEncoder == AUDIO_ENCODER_AAC_ELD); 868f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK(mAudioSource != AUDIO_SOURCE_CNT); 869f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 870f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mWriter = new AACWriter(mOutputFd); 871f933441648ef6a71dee783d733aac17b9508b452Andreas Huber status_t status = startRawAudioRecording(); 872f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (status != OK) { 873f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mWriter.clear(); 874f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mWriter = NULL; 875f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 876f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 877f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return status; 878f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 879f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 880f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t StagefrightRecorder::startAMRRecording() { 881f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK(mOutputFormat == OUTPUT_FORMAT_AMR_NB || 882f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mOutputFormat == OUTPUT_FORMAT_AMR_WB); 883f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 884349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber if (mOutputFormat == OUTPUT_FORMAT_AMR_NB) { 885f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (mAudioEncoder != AUDIO_ENCODER_DEFAULT && 886f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mAudioEncoder != AUDIO_ENCODER_AMR_NB) { 887f933441648ef6a71dee783d733aac17b9508b452Andreas Huber ALOGE("Invalid encoder %d used for AMRNB recording", 888f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mAudioEncoder); 8892ded8b53014602d25b20bade8ce46db95a8da4b5Lajos Molnar return BAD_VALUE; 8902ded8b53014602d25b20bade8ce46db95a8da4b5Lajos Molnar } 8912ded8b53014602d25b20bade8ce46db95a8da4b5Lajos Molnar } else { // mOutputFormat must be OUTPUT_FORMAT_AMR_WB 8922ded8b53014602d25b20bade8ce46db95a8da4b5Lajos Molnar if (mAudioEncoder != AUDIO_ENCODER_AMR_WB) { 893f933441648ef6a71dee783d733aac17b9508b452Andreas Huber ALOGE("Invlaid encoder %d used for AMRWB recording", 894f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mAudioEncoder); 895f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return BAD_VALUE; 896f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 897f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 898f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 899f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mWriter = new AMRWriter(mOutputFd); 900f933441648ef6a71dee783d733aac17b9508b452Andreas Huber status_t status = startRawAudioRecording(); 901f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (status != OK) { 902f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mWriter.clear(); 903f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mWriter = NULL; 904f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 905f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return status; 906f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 907f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 908f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t StagefrightRecorder::startRawAudioRecording() { 909f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (mAudioSource >= AUDIO_SOURCE_CNT) { 910f933441648ef6a71dee783d733aac17b9508b452Andreas Huber ALOGE("Invalid audio source: %d", mAudioSource); 911f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return BAD_VALUE; 912f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 913f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 914f933441648ef6a71dee783d733aac17b9508b452Andreas Huber status_t status = BAD_VALUE; 915f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (OK != (status = checkAudioEncoderCapabilities())) { 916f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return status; 917f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 918f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 919f933441648ef6a71dee783d733aac17b9508b452Andreas Huber sp<MediaSource> audioEncoder = createAudioSource(); 920f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (audioEncoder == NULL) { 921f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return UNKNOWN_ERROR; 922f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 923f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 924f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK(mWriter != 0); 925f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mWriter->addSource(audioEncoder); 926f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 927f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (mMaxFileDurationUs != 0) { 928f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mWriter->setMaxFileDuration(mMaxFileDurationUs); 929f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 930f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (mMaxFileSizeBytes != 0) { 931f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mWriter->setMaxFileSize(mMaxFileSizeBytes); 932f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 933f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mWriter->setListener(mListener); 934f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mWriter->start(); 935f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 936f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return OK; 937f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 938f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 9395778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t StagefrightRecorder::startRTPRecording() { 940f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK_EQ(mOutputFormat, OUTPUT_FORMAT_RTP_AVP); 941f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 942f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if ((mAudioSource != AUDIO_SOURCE_CNT 943f933441648ef6a71dee783d733aac17b9508b452Andreas Huber && mVideoSource != VIDEO_SOURCE_LIST_END) 944f933441648ef6a71dee783d733aac17b9508b452Andreas Huber || (mAudioSource == AUDIO_SOURCE_CNT 945f933441648ef6a71dee783d733aac17b9508b452Andreas Huber && mVideoSource == VIDEO_SOURCE_LIST_END)) { 946f933441648ef6a71dee783d733aac17b9508b452Andreas Huber // Must have exactly one source. 947f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return BAD_VALUE; 948f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 949f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 9502944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber if (mOutputFd < 0) { 9512944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber return BAD_VALUE; 9522944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber } 9532944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber 954f933441648ef6a71dee783d733aac17b9508b452Andreas Huber sp<MediaSource> source; 955f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 956f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (mAudioSource != AUDIO_SOURCE_CNT) { 957f933441648ef6a71dee783d733aac17b9508b452Andreas Huber source = createAudioSource(); 958f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } else { 959f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 960729de186450f78c099637e1fce743fe531862c52Andreas Huber sp<MediaSource> mediaSource; 961729de186450f78c099637e1fce743fe531862c52Andreas Huber status_t err = setupMediaSource(&mediaSource); 962c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber if (err != OK) { 963c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber return err; 964c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber } 965c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber 966f933441648ef6a71dee783d733aac17b9508b452Andreas Huber err = setupVideoEncoder(mediaSource, mVideoBitRate, &source); 967f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (err != OK) { 968f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return err; 969f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 970f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 971f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 97294705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang mWriter = new ARTPWriter(mOutputFd); 97394705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang mWriter->addSource(source); 97494705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang mWriter->setListener(mListener); 97594705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang 976ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber return mWriter->start(); 977ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber} 9782f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi 9792f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivistatus_t StagefrightRecorder::startMPEG2TSRecording() { 980ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen CHECK_EQ(mOutputFormat, OUTPUT_FORMAT_MPEG2TS); 981ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen 982774eb18c40c3a7da0bc1636a9779f02315ddbad8Changwan Ryu sp<MediaWriter> writer = new MPEG2TSWriter(mOutputFd); 983774eb18c40c3a7da0bc1636a9779f02315ddbad8Changwan Ryu 98497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu if (mAudioSource != AUDIO_SOURCE_CNT) { 98597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu if (mAudioEncoder != AUDIO_ENCODER_AAC && 986f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mAudioEncoder != AUDIO_ENCODER_HE_AAC && 987f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mAudioEncoder != AUDIO_ENCODER_AAC_ELD) { 988f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return ERROR_UNSUPPORTED; 989f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 990f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 991f933441648ef6a71dee783d733aac17b9508b452Andreas Huber status_t err = setupAudioEncoder(writer); 992f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 993f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (err != OK) { 994f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return err; 995f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 996f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 997f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 998f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (mVideoSource < VIDEO_SOURCE_LIST_END) { 9995778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (mVideoEncoder != VIDEO_ENCODER_H264) { 1000f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return ERROR_UNSUPPORTED; 1001f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 1002f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1003f933441648ef6a71dee783d733aac17b9508b452Andreas Huber sp<MediaSource> mediaSource; 1004f933441648ef6a71dee783d733aac17b9508b452Andreas Huber status_t err = setupMediaSource(&mediaSource); 1005f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (err != OK) { 1006f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return err; 1007f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 1008f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1009f933441648ef6a71dee783d733aac17b9508b452Andreas Huber sp<MediaSource> encoder; 1010f933441648ef6a71dee783d733aac17b9508b452Andreas Huber err = setupVideoEncoder(mediaSource, mVideoBitRate, &encoder); 1011f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1012f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (err != OK) { 1013f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return err; 1014f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 1015f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1016f933441648ef6a71dee783d733aac17b9508b452Andreas Huber writer->addSource(encoder); 1017f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 1018f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1019f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (mMaxFileDurationUs != 0) { 10205ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block writer->setMaxFileDuration(mMaxFileDurationUs); 1021f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 10225778822d86b0337407514b9372562b86edfa91cdAndreas Huber 10235778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (mMaxFileSizeBytes != 0) { 1024f933441648ef6a71dee783d733aac17b9508b452Andreas Huber writer->setMaxFileSize(mMaxFileSizeBytes); 1025f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 10265778822d86b0337407514b9372562b86edfa91cdAndreas Huber 10275778822d86b0337407514b9372562b86edfa91cdAndreas Huber mWriter = writer; 1028f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1029f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return mWriter->start(); 10305778822d86b0337407514b9372562b86edfa91cdAndreas Huber} 1031f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 10325778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid StagefrightRecorder::clipVideoFrameRate() { 10335778822d86b0337407514b9372562b86edfa91cdAndreas Huber ALOGV("clipVideoFrameRate: encoder %d", mVideoEncoder); 10345778822d86b0337407514b9372562b86edfa91cdAndreas Huber int minFrameRate = mEncoderProfiles->getVideoEncoderParamByName( 10355778822d86b0337407514b9372562b86edfa91cdAndreas Huber "enc.vid.fps.min", mVideoEncoder); 1036f933441648ef6a71dee783d733aac17b9508b452Andreas Huber int maxFrameRate = mEncoderProfiles->getVideoEncoderParamByName( 10375778822d86b0337407514b9372562b86edfa91cdAndreas Huber "enc.vid.fps.max", mVideoEncoder); 1038f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (mFrameRate < minFrameRate && minFrameRate != -1) { 10395778822d86b0337407514b9372562b86edfa91cdAndreas Huber ALOGW("Intended video encoding frame rate (%d fps) is too small" 10405778822d86b0337407514b9372562b86edfa91cdAndreas Huber " and will be set to (%d fps)", mFrameRate, minFrameRate); 10415778822d86b0337407514b9372562b86edfa91cdAndreas Huber mFrameRate = minFrameRate; 10425778822d86b0337407514b9372562b86edfa91cdAndreas Huber } else if (mFrameRate > maxFrameRate && maxFrameRate != -1) { 10435778822d86b0337407514b9372562b86edfa91cdAndreas Huber ALOGW("Intended video encoding frame rate (%d fps) is too large" 10445778822d86b0337407514b9372562b86edfa91cdAndreas Huber " and will be set to (%d fps)", mFrameRate, maxFrameRate); 10455778822d86b0337407514b9372562b86edfa91cdAndreas Huber mFrameRate = maxFrameRate; 10462f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi } 10472f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi} 10482f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi 10495778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid StagefrightRecorder::clipVideoBitRate() { 10505778822d86b0337407514b9372562b86edfa91cdAndreas Huber ALOGV("clipVideoBitRate: encoder %d", mVideoEncoder); 10515778822d86b0337407514b9372562b86edfa91cdAndreas Huber int minBitRate = mEncoderProfiles->getVideoEncoderParamByName( 1052d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber "enc.vid.bps.min", mVideoEncoder); 1053d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber int maxBitRate = mEncoderProfiles->getVideoEncoderParamByName( 1054d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber "enc.vid.bps.max", mVideoEncoder); 1055d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber if (mVideoBitRate < minBitRate && minBitRate != -1) { 1056d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber ALOGW("Intended video encoding bit rate (%d bps) is too small" 1057d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber " and will be set to (%d bps)", mVideoBitRate, minBitRate); 1058d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber mVideoBitRate = minBitRate; 1059308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang } else if (mVideoBitRate > maxBitRate && maxBitRate != -1) { 1060308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang ALOGW("Intended video encoding bit rate (%d bps) is too large" 1061d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber " and will be set to (%d bps)", mVideoBitRate, maxBitRate); 1062308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang mVideoBitRate = maxBitRate; 1063308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang } 1064308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang} 1065d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 1066308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhangvoid StagefrightRecorder::clipVideoFrameWidth() { 10673a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber ALOGV("clipVideoFrameWidth: encoder %d", mVideoEncoder); 10683a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber int minFrameWidth = mEncoderProfiles->getVideoEncoderParamByName( 10693a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber "enc.vid.width.min", mVideoEncoder); 10703a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber int maxFrameWidth = mEncoderProfiles->getVideoEncoderParamByName( 10713a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber "enc.vid.width.max", mVideoEncoder); 10723a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber if (mVideoWidth < minFrameWidth && minFrameWidth != -1) { 10733a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber ALOGW("Intended video encoding frame width (%d) is too small" 10743a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber " and will be set to (%d)", mVideoWidth, minFrameWidth); 10753a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber mVideoWidth = minFrameWidth; 10763a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber } else if (mVideoWidth > maxFrameWidth && maxFrameWidth != -1) { 10773a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber ALOGW("Intended video encoding frame width (%d) is too large" 10783a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber " and will be set to (%d)", mVideoWidth, maxFrameWidth); 10793a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber mVideoWidth = maxFrameWidth; 10803a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber } 10813a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber} 10823a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber 10833a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huberstatus_t StagefrightRecorder::checkVideoEncoderCapabilities() { 10843a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber if (!mCaptureTimeLapse) { 10853a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber // Dont clip for time lapse capture as encoder will have enough 10863a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber // time to encode because of slow capture rate of time lapse. 10873a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber clipVideoBitRate(); 10883a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber clipVideoFrameRate(); 10893a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber clipVideoFrameWidth(); 10903a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber clipVideoFrameHeight(); 10913a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber setDefaultProfileIfNecessary(); 10923a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber } 1093308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang return OK; 1094308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang} 1095308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang 1096308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang// Set to use AVC baseline profile if the encoding parameters matches 1097308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang// CAMCORDER_QUALITY_LOW profile; this is for the sake of MMS service. 1098308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhangvoid StagefrightRecorder::setDefaultProfileIfNecessary() { 1099308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang ALOGV("setDefaultProfileIfNecessary"); 1100308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang 1101308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang camcorder_quality quality = CAMCORDER_QUALITY_LOW; 1102308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang 1103308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang int64_t durationUs = mEncoderProfiles->getCamcorderProfileParamByName( 1104308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang "duration", mCameraId, quality) * 1000000LL; 1105308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang 1106308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang int fileFormat = mEncoderProfiles->getCamcorderProfileParamByName( 1107308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang "file.format", mCameraId, quality); 1108308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang 1109308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang int videoCodec = mEncoderProfiles->getCamcorderProfileParamByName( 1110308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang "vid.codec", mCameraId, quality); 1111a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber 1112a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber int videoBitRate = mEncoderProfiles->getCamcorderProfileParamByName( 1113a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber "vid.bps", mCameraId, quality); 1114a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber 1115a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber int videoFrameRate = mEncoderProfiles->getCamcorderProfileParamByName( 1116a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber "vid.fps", mCameraId, quality); 1117308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang 1118308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang int videoFrameWidth = mEncoderProfiles->getCamcorderProfileParamByName( 1119054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar "vid.width", mCameraId, quality); 1120054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar 1121054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar int videoFrameHeight = mEncoderProfiles->getCamcorderProfileParamByName( 1122054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar "vid.height", mCameraId, quality); 1123054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar 1124054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar int audioCodec = mEncoderProfiles->getCamcorderProfileParamByName( 1125054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar "aud.codec", mCameraId, quality); 1126054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar 1127054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar int audioBitRate = mEncoderProfiles->getCamcorderProfileParamByName( 1128054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar "aud.bps", mCameraId, quality); 1129fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar 1130fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar int audioSampleRate = mEncoderProfiles->getCamcorderProfileParamByName( 1131fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar "aud.hz", mCameraId, quality); 1132fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar 1133fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar int audioChannels = mEncoderProfiles->getCamcorderProfileParamByName( 1134fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar "aud.ch", mCameraId, quality); 1135fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar 1136fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar if (durationUs == mMaxFileDurationUs && 1137fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar fileFormat == mOutputFormat && 1138fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar videoCodec == mVideoEncoder && 1139fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar videoBitRate == mVideoBitRate && 1140fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar videoFrameRate == mFrameRate && 1141fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar videoFrameWidth == mVideoWidth && 1142fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar videoFrameHeight == mVideoHeight && 1143fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar audioCodec == mAudioEncoder && 1144fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar audioBitRate == mAudioBitRate && 1145fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar audioSampleRate == mSampleRate && 1146fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar audioChannels == mAudioChannels) { 1147fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar if (videoCodec == VIDEO_ENCODER_H264) { 1148fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar ALOGI("Force to use AVC baseline profile"); 1149fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar setParamVideoEncoderProfile(OMX_VIDEO_AVCProfileBaseline); 1150fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar } 1151fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar } 1152fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar} 1153fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar 1154fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnarstatus_t StagefrightRecorder::checkAudioEncoderCapabilities() { 1155fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar clipAudioBitRate(); 1156fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar clipAudioSampleRate(); 1157fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar clipNumberOfAudioChannels(); 1158fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar return OK; 1159fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar} 1160fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar 1161fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnarvoid StagefrightRecorder::clipAudioBitRate() { 1162fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar ALOGV("clipAudioBitRate: encoder %d", mAudioEncoder); 1163fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar 1164fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar int minAudioBitRate = 1165fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar mEncoderProfiles->getAudioEncoderParamByName( 1166fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar "enc.aud.bps.min", mAudioEncoder); 1167fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar if (minAudioBitRate != -1 && mAudioBitRate < minAudioBitRate) { 1168fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar ALOGW("Intended audio encoding bit rate (%d) is too small" 1169fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar " and will be set to (%d)", mAudioBitRate, minAudioBitRate); 1170054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar mAudioBitRate = minAudioBitRate; 1171054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar } 1172054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar 1173054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar int maxAudioBitRate = 1174054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar mEncoderProfiles->getAudioEncoderParamByName( 11750167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber "enc.aud.bps.max", mAudioEncoder); 11760167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber if (maxAudioBitRate != -1 && mAudioBitRate > maxAudioBitRate) { 11770167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber ALOGW("Intended audio encoding bit rate (%d) is too large" 11780167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber " and will be set to (%d)", mAudioBitRate, maxAudioBitRate); 11790167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber mAudioBitRate = maxAudioBitRate; 11800167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber } 1181054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar} 1182054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar 1183308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhangvoid StagefrightRecorder::clipAudioSampleRate() { 11845778822d86b0337407514b9372562b86edfa91cdAndreas Huber ALOGV("clipAudioSampleRate: encoder %d", mAudioEncoder); 11855778822d86b0337407514b9372562b86edfa91cdAndreas Huber 11865778822d86b0337407514b9372562b86edfa91cdAndreas Huber int minSampleRate = 11875778822d86b0337407514b9372562b86edfa91cdAndreas Huber mEncoderProfiles->getAudioEncoderParamByName( 11885778822d86b0337407514b9372562b86edfa91cdAndreas Huber "enc.aud.hz.min", mAudioEncoder); 11895778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (minSampleRate != -1 && mSampleRate < minSampleRate) { 11905778822d86b0337407514b9372562b86edfa91cdAndreas Huber ALOGW("Intended audio sample rate (%d) is too small" 11915778822d86b0337407514b9372562b86edfa91cdAndreas Huber " and will be set to (%d)", mSampleRate, minSampleRate); 11925778822d86b0337407514b9372562b86edfa91cdAndreas Huber mSampleRate = minSampleRate; 11935778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 11945778822d86b0337407514b9372562b86edfa91cdAndreas Huber 119542392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber int maxSampleRate = 119642392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber mEncoderProfiles->getAudioEncoderParamByName( 119742392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber "enc.aud.hz.max", mAudioEncoder); 119842392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber if (maxSampleRate != -1 && mSampleRate > maxSampleRate) { 119942392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber ALOGW("Intended audio sample rate (%d) is too large" 120042392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber " and will be set to (%d)", mSampleRate, maxSampleRate); 120142392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber mSampleRate = maxSampleRate; 120242392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber } 120342392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber} 120442392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber 120542392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Hubervoid StagefrightRecorder::clipNumberOfAudioChannels() { 120642392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber ALOGV("clipNumberOfAudioChannels: encoder %d", mAudioEncoder); 120742392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber 1208f933441648ef6a71dee783d733aac17b9508b452Andreas Huber int minChannels = 1209f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mEncoderProfiles->getAudioEncoderParamByName( 12105778822d86b0337407514b9372562b86edfa91cdAndreas Huber "enc.aud.ch.min", mAudioEncoder); 12115778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (minChannels != -1 && mAudioChannels < minChannels) { 12125778822d86b0337407514b9372562b86edfa91cdAndreas Huber ALOGW("Intended number of audio channels (%d) is too small" 12135778822d86b0337407514b9372562b86edfa91cdAndreas Huber " and will be set to (%d)", mAudioChannels, minChannels); 1214aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke mAudioChannels = minChannels; 1215ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber } 1216ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber 1217ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber int maxChannels = 1218aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke mEncoderProfiles->getAudioEncoderParamByName( 1219aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke "enc.aud.ch.max", mAudioEncoder); 1220aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke if (maxChannels != -1 && mAudioChannels > maxChannels) { 1221ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber ALOGW("Intended number of audio channels (%d) is too large" 1222ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber " and will be set to (%d)", mAudioChannels, maxChannels); 12234471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber mAudioChannels = maxChannels; 12244471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber } 12255778822d86b0337407514b9372562b86edfa91cdAndreas Huber} 1226729de186450f78c099637e1fce743fe531862c52Andreas Huber 12275778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid StagefrightRecorder::clipVideoFrameHeight() { 1228729de186450f78c099637e1fce743fe531862c52Andreas Huber ALOGV("clipVideoFrameHeight: encoder %d", mVideoEncoder); 12295778822d86b0337407514b9372562b86edfa91cdAndreas Huber int minFrameHeight = mEncoderProfiles->getVideoEncoderParamByName( 1230729de186450f78c099637e1fce743fe531862c52Andreas Huber "enc.vid.height.min", mVideoEncoder); 1231729de186450f78c099637e1fce743fe531862c52Andreas Huber int maxFrameHeight = mEncoderProfiles->getVideoEncoderParamByName( 1232729de186450f78c099637e1fce743fe531862c52Andreas Huber "enc.vid.height.max", mVideoEncoder); 1233729de186450f78c099637e1fce743fe531862c52Andreas Huber if (minFrameHeight != -1 && mVideoHeight < minFrameHeight) { 1234729de186450f78c099637e1fce743fe531862c52Andreas Huber ALOGW("Intended video encoding frame height (%d) is too small" 1235729de186450f78c099637e1fce743fe531862c52Andreas Huber " and will be set to (%d)", mVideoHeight, minFrameHeight); 12365778822d86b0337407514b9372562b86edfa91cdAndreas Huber mVideoHeight = minFrameHeight; 12375778822d86b0337407514b9372562b86edfa91cdAndreas Huber } else if (maxFrameHeight != -1 && mVideoHeight > maxFrameHeight) { 12385778822d86b0337407514b9372562b86edfa91cdAndreas Huber ALOGW("Intended video encoding frame height (%d) is too large" 12395778822d86b0337407514b9372562b86edfa91cdAndreas Huber " and will be set to (%d)", mVideoHeight, maxFrameHeight); 12405778822d86b0337407514b9372562b86edfa91cdAndreas Huber mVideoHeight = maxFrameHeight; 12412f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi } 12422f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi} 12432f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi 12442f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi// Set up the appropriate MediaSource depending on the chosen option 12452f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivistatus_t StagefrightRecorder::setupMediaSource( 12462f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi sp<MediaSource> *mediaSource) { 12472f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi if (mVideoSource == VIDEO_SOURCE_DEFAULT 12482f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi || mVideoSource == VIDEO_SOURCE_CAMERA) { 12492f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi sp<CameraSource> cameraSource; 1250516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber status_t err = setupCameraSource(&cameraSource); 1251516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber if (err != OK) { 12522f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi return err; 12532f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi } 1254516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber *mediaSource = cameraSource; 1255516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber } else if (mVideoSource == VIDEO_SOURCE_GRALLOC_BUFFER) { 1256516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber // If using GRAlloc buffers, setup surfacemediasource. 12572f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi // Later a handle to that will be passed 12582f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi // to the client side when queried 1259516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber status_t err = setupSurfaceMediaSource(); 1260516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber if (err != OK) { 1261516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber return err; 12622f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi } 12632f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi *mediaSource = mSurfaceMediaSource; 12642f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi } else { 1265516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber return INVALID_OPERATION; 1266516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber } 12672f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi return OK; 1268ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber} 1269ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber 1270ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber// setupSurfaceMediaSource creates a source with the given 1271ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber// width and height and framerate. 1272ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber// TODO: This could go in a static function inside SurfaceMediaSource 1273ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber// similar to that in CameraSource 1274ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huberstatus_t StagefrightRecorder::setupSurfaceMediaSource() { 1275ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber status_t err = OK; 1276ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber mSurfaceMediaSource = new SurfaceMediaSource(mVideoWidth, mVideoHeight); 127797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu if (mSurfaceMediaSource == NULL) { 127897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu return NO_INIT; 127997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu } 128097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu 128197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu if (mFrameRate == -1) { 128297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu int32_t frameRate = 0; 128397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu CHECK (mSurfaceMediaSource->getFormat()->findInt32( 128497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu kKeyFrameRate, &frameRate)); 128597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu ALOGI("Frame rate is not explicitly set. Use the current frame " 12865778822d86b0337407514b9372562b86edfa91cdAndreas Huber "rate (%d fps)", frameRate); 1287729de186450f78c099637e1fce743fe531862c52Andreas Huber mFrameRate = frameRate; 12884471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber } else { 12894471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber err = mSurfaceMediaSource->setFrameRate(mFrameRate); 12904471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber } 12914471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber CHECK(mFrameRate != -1); 12928b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen 12938b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen mIsMetaDataStoredInVideoBuffers = 12948b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen mSurfaceMediaSource->isMetaDataStoredInVideoBuffers(); 12959806555d3930be43e11106281dee354820ac1c88Andreas Huber return err; 12968b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen} 12978b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen 12988b71241ce7353731ab75322c46e090ee35014a33Marco Nelissenstatus_t StagefrightRecorder::setupCameraSource( 12998b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen sp<CameraSource> *cameraSource) { 13009806555d3930be43e11106281dee354820ac1c88Andreas Huber status_t err = OK; 13019806555d3930be43e11106281dee354820ac1c88Andreas Huber if ((err = checkVideoEncoderCapabilities()) != OK) { 13029806555d3930be43e11106281dee354820ac1c88Andreas Huber return err; 13039806555d3930be43e11106281dee354820ac1c88Andreas Huber } 13049806555d3930be43e11106281dee354820ac1c88Andreas Huber Size videoSize; 13059806555d3930be43e11106281dee354820ac1c88Andreas Huber videoSize.width = mVideoWidth; 1306f933441648ef6a71dee783d733aac17b9508b452Andreas Huber videoSize.height = mVideoHeight; 1307f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (mCaptureTimeLapse) { 13085778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (mTimeBetweenTimeLapseFrameCaptureUs < 0) { 1309f933441648ef6a71dee783d733aac17b9508b452Andreas Huber ALOGE("Invalid mTimeBetweenTimeLapseFrameCaptureUs value: %lld", 13105778822d86b0337407514b9372562b86edfa91cdAndreas Huber mTimeBetweenTimeLapseFrameCaptureUs); 1311f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return BAD_VALUE; 13125778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 13135778822d86b0337407514b9372562b86edfa91cdAndreas Huber 1314f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mCameraSourceTimeLapse = CameraSourceTimeLapse::CreateFromCamera( 1315f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mCamera, mCameraProxy, mCameraId, 1316f933441648ef6a71dee783d733aac17b9508b452Andreas Huber videoSize, mFrameRate, mPreviewSurface, 1317f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mTimeBetweenTimeLapseFrameCaptureUs); 1318f933441648ef6a71dee783d733aac17b9508b452Andreas Huber *cameraSource = mCameraSourceTimeLapse; 1319f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } else { 1320f933441648ef6a71dee783d733aac17b9508b452Andreas Huber *cameraSource = CameraSource::CreateFromCamera( 1321f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mCamera, mCameraProxy, mCameraId, videoSize, mFrameRate, 1322f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mPreviewSurface, true /*storeMetaDataInVideoBuffers*/); 1323f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 1324f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mCamera.clear(); 1325f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mCameraProxy.clear(); 1326f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (*cameraSource == NULL) { 1327f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return UNKNOWN_ERROR; 1328f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 1329f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1330f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if ((*cameraSource)->initCheck() != OK) { 1331f933441648ef6a71dee783d733aac17b9508b452Andreas Huber (*cameraSource).clear(); 1332f933441648ef6a71dee783d733aac17b9508b452Andreas Huber *cameraSource = NULL; 1333f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return NO_INIT; 1334f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 1335f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1336f933441648ef6a71dee783d733aac17b9508b452Andreas Huber // When frame rate is not set, the actual frame rate will be set to 1337f933441648ef6a71dee783d733aac17b9508b452Andreas Huber // the current frame rate being used. 1338f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (mFrameRate == -1) { 1339f933441648ef6a71dee783d733aac17b9508b452Andreas Huber int32_t frameRate = 0; 1340f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK ((*cameraSource)->getFormat()->findInt32( 1341f933441648ef6a71dee783d733aac17b9508b452Andreas Huber kKeyFrameRate, &frameRate)); 1342f933441648ef6a71dee783d733aac17b9508b452Andreas Huber ALOGI("Frame rate is not explicitly set. Use the current frame " 1343f933441648ef6a71dee783d733aac17b9508b452Andreas Huber "rate (%d fps)", frameRate); 1344f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mFrameRate = frameRate; 1345f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 1346f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1347f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK(mFrameRate != -1); 1348f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1349f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mIsMetaDataStoredInVideoBuffers = 1350f933441648ef6a71dee783d733aac17b9508b452Andreas Huber (*cameraSource)->isMetaDataStoredInVideoBuffers(); 1351f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1352f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return OK; 13535778822d86b0337407514b9372562b86edfa91cdAndreas Huber} 13545778822d86b0337407514b9372562b86edfa91cdAndreas Huber 13555778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t StagefrightRecorder::setupVideoEncoder( 13565778822d86b0337407514b9372562b86edfa91cdAndreas Huber sp<MediaSource> cameraSource, 13575778822d86b0337407514b9372562b86edfa91cdAndreas Huber int32_t videoBitRate, 13585778822d86b0337407514b9372562b86edfa91cdAndreas Huber sp<MediaSource> *source) { 13595778822d86b0337407514b9372562b86edfa91cdAndreas Huber source->clear(); 13605778822d86b0337407514b9372562b86edfa91cdAndreas Huber 13615778822d86b0337407514b9372562b86edfa91cdAndreas Huber sp<MetaData> enc_meta = new MetaData; 13625778822d86b0337407514b9372562b86edfa91cdAndreas Huber enc_meta->setInt32(kKeyBitRate, videoBitRate); 13635778822d86b0337407514b9372562b86edfa91cdAndreas Huber enc_meta->setInt32(kKeyFrameRate, mFrameRate); 13645778822d86b0337407514b9372562b86edfa91cdAndreas Huber 13655778822d86b0337407514b9372562b86edfa91cdAndreas Huber switch (mVideoEncoder) { 13665778822d86b0337407514b9372562b86edfa91cdAndreas Huber case VIDEO_ENCODER_H263: 13675778822d86b0337407514b9372562b86edfa91cdAndreas Huber enc_meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_H263); 13685778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 13695778822d86b0337407514b9372562b86edfa91cdAndreas Huber 13705778822d86b0337407514b9372562b86edfa91cdAndreas Huber case VIDEO_ENCODER_MPEG_4_SP: 13715778822d86b0337407514b9372562b86edfa91cdAndreas Huber enc_meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_MPEG4); 13725778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 13735778822d86b0337407514b9372562b86edfa91cdAndreas Huber 13745778822d86b0337407514b9372562b86edfa91cdAndreas Huber case VIDEO_ENCODER_H264: 13755778822d86b0337407514b9372562b86edfa91cdAndreas Huber enc_meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_AVC); 13765778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 13775778822d86b0337407514b9372562b86edfa91cdAndreas Huber 13785778822d86b0337407514b9372562b86edfa91cdAndreas Huber default: 13795778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(!"Should not be here, unsupported video encoding."); 1380aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke break; 1381aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke } 1382ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber 1383ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber sp<MetaData> meta = cameraSource->getFormat(); 1384ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber 1385ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber int32_t width, height, stride, sliceHeight, colorFormat; 13865778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(meta->findInt32(kKeyWidth, &width)); 13875778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(meta->findInt32(kKeyHeight, &height)); 13885778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(meta->findInt32(kKeyStride, &stride)); 13895778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(meta->findInt32(kKeySliceHeight, &sliceHeight)); 13905778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(meta->findInt32(kKeyColorFormat, &colorFormat)); 13915778822d86b0337407514b9372562b86edfa91cdAndreas Huber 13925778822d86b0337407514b9372562b86edfa91cdAndreas Huber enc_meta->setInt32(kKeyWidth, width); 13935778822d86b0337407514b9372562b86edfa91cdAndreas Huber enc_meta->setInt32(kKeyHeight, height); 13945778822d86b0337407514b9372562b86edfa91cdAndreas Huber enc_meta->setInt32(kKeyIFramesInterval, mIFramesIntervalSec); 13955778822d86b0337407514b9372562b86edfa91cdAndreas Huber enc_meta->setInt32(kKeyStride, stride); 13965778822d86b0337407514b9372562b86edfa91cdAndreas Huber enc_meta->setInt32(kKeySliceHeight, sliceHeight); 13975778822d86b0337407514b9372562b86edfa91cdAndreas Huber enc_meta->setInt32(kKeyColorFormat, colorFormat); 13985778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (mVideoTimeScale > 0) { 13995778822d86b0337407514b9372562b86edfa91cdAndreas Huber enc_meta->setInt32(kKeyTimeScale, mVideoTimeScale); 14005778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 14015778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (mVideoEncoderProfile != -1) { 14025778822d86b0337407514b9372562b86edfa91cdAndreas Huber enc_meta->setInt32(kKeyVideoProfile, mVideoEncoderProfile); 14035778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 14045778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (mVideoEncoderLevel != -1) { 14055778822d86b0337407514b9372562b86edfa91cdAndreas Huber enc_meta->setInt32(kKeyVideoLevel, mVideoEncoderLevel); 14065778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 14075778822d86b0337407514b9372562b86edfa91cdAndreas Huber 14085778822d86b0337407514b9372562b86edfa91cdAndreas Huber OMXClient client; 14095778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK_EQ(client.connect(), (status_t)OK); 14105778822d86b0337407514b9372562b86edfa91cdAndreas Huber 14115778822d86b0337407514b9372562b86edfa91cdAndreas Huber uint32_t encoder_flags = 0; 14125778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (mIsMetaDataStoredInVideoBuffers) { 14135778822d86b0337407514b9372562b86edfa91cdAndreas Huber encoder_flags |= OMXCodec::kStoreMetaDataInVideoBuffers; 14145778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 14155778822d86b0337407514b9372562b86edfa91cdAndreas Huber 14165778822d86b0337407514b9372562b86edfa91cdAndreas Huber // Do not wait for all the input buffers to become available. 14175778822d86b0337407514b9372562b86edfa91cdAndreas Huber // This give timelapse video recording faster response in 14185778822d86b0337407514b9372562b86edfa91cdAndreas Huber // receiving output from video encoder component. 14195778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (mCaptureTimeLapse) { 14205778822d86b0337407514b9372562b86edfa91cdAndreas Huber encoder_flags |= OMXCodec::kOnlySubmitOneInputBufferAtOneTime; 14215778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 14225778822d86b0337407514b9372562b86edfa91cdAndreas Huber 14235778822d86b0337407514b9372562b86edfa91cdAndreas Huber sp<MediaSource> encoder = OMXCodec::Create( 14245778822d86b0337407514b9372562b86edfa91cdAndreas Huber client.interface(), enc_meta, 14255778822d86b0337407514b9372562b86edfa91cdAndreas Huber true /* createEncoder */, cameraSource, 14265778822d86b0337407514b9372562b86edfa91cdAndreas Huber NULL, encoder_flags); 14275778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (encoder == NULL) { 14285778822d86b0337407514b9372562b86edfa91cdAndreas Huber ALOGW("Failed to create the encoder"); 14295778822d86b0337407514b9372562b86edfa91cdAndreas Huber // When the encoder fails to be created, we need 14305778822d86b0337407514b9372562b86edfa91cdAndreas Huber // release the camera source due to the camera's lock 14315778822d86b0337407514b9372562b86edfa91cdAndreas Huber // and unlock mechanism. 14325778822d86b0337407514b9372562b86edfa91cdAndreas Huber cameraSource->stop(); 14335778822d86b0337407514b9372562b86edfa91cdAndreas Huber return UNKNOWN_ERROR; 14345778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 14355778822d86b0337407514b9372562b86edfa91cdAndreas Huber 14365778822d86b0337407514b9372562b86edfa91cdAndreas Huber *source = encoder; 14375778822d86b0337407514b9372562b86edfa91cdAndreas Huber 14385778822d86b0337407514b9372562b86edfa91cdAndreas Huber return OK; 14395778822d86b0337407514b9372562b86edfa91cdAndreas Huber} 14405778822d86b0337407514b9372562b86edfa91cdAndreas Huber 14415778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t StagefrightRecorder::setupAudioEncoder(const sp<MediaWriter>& writer) { 14425778822d86b0337407514b9372562b86edfa91cdAndreas Huber status_t status = BAD_VALUE; 14435778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (OK != (status = checkAudioEncoderCapabilities())) { 14445778822d86b0337407514b9372562b86edfa91cdAndreas Huber return status; 14455778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 1446aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke 14475778822d86b0337407514b9372562b86edfa91cdAndreas Huber switch(mAudioEncoder) { 14485778822d86b0337407514b9372562b86edfa91cdAndreas Huber case AUDIO_ENCODER_AMR_NB: 14495778822d86b0337407514b9372562b86edfa91cdAndreas Huber case AUDIO_ENCODER_AMR_WB: 14505778822d86b0337407514b9372562b86edfa91cdAndreas Huber case AUDIO_ENCODER_AAC: 14515778822d86b0337407514b9372562b86edfa91cdAndreas Huber case AUDIO_ENCODER_HE_AAC: 14525778822d86b0337407514b9372562b86edfa91cdAndreas Huber case AUDIO_ENCODER_AAC_ELD: 14535778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 14545778822d86b0337407514b9372562b86edfa91cdAndreas Huber 14555778822d86b0337407514b9372562b86edfa91cdAndreas Huber default: 14565778822d86b0337407514b9372562b86edfa91cdAndreas Huber ALOGE("Unsupported audio encoder: %d", mAudioEncoder); 14575778822d86b0337407514b9372562b86edfa91cdAndreas Huber return UNKNOWN_ERROR; 14585778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 1459f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1460f933441648ef6a71dee783d733aac17b9508b452Andreas Huber sp<MediaSource> audioEncoder = createAudioSource(); 1461f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (audioEncoder == NULL) { 1462f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return UNKNOWN_ERROR; 14635778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 1464f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1465f933441648ef6a71dee783d733aac17b9508b452Andreas Huber writer->addSource(audioEncoder); 1466f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return OK; 1467f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 1468f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1469f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t StagefrightRecorder::setupMPEG4Recording( 1470f933441648ef6a71dee783d733aac17b9508b452Andreas Huber int outputFd, 1471f933441648ef6a71dee783d733aac17b9508b452Andreas Huber int32_t videoWidth, int32_t videoHeight, 1472ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber int32_t videoBitRate, 1473ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber int32_t *totalBitRate, 1474ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber sp<MediaWriter> *mediaWriter) { 1475ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber mediaWriter->clear(); 1476ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber *totalBitRate = 0; 1477f933441648ef6a71dee783d733aac17b9508b452Andreas Huber status_t err = OK; 14785778822d86b0337407514b9372562b86edfa91cdAndreas Huber sp<MediaWriter> writer = new MPEG4Writer(outputFd); 1479f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 14805778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (mVideoSource < VIDEO_SOURCE_LIST_END) { 1481f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 148297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu sp<MediaSource> mediaSource; 148397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu err = setupMediaSource(&mediaSource); 148497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu if (err != OK) { 148597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu return err; 148697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu } 148797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu 148897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu sp<MediaSource> encoder; 148997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu err = setupVideoEncoder(mediaSource, videoBitRate, &encoder); 149097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu if (err != OK) { 149197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu return err; 149297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu } 149397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu 149497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu writer->addSource(encoder); 149597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu *totalBitRate += videoBitRate; 149697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu } 149797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu 149897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu // Audio source is added at the end if it exists. 149997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu // This help make sure that the "recoding" sound is suppressed for 150097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu // camcorder applications in the recorded files. 150197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu if (!mCaptureTimeLapse && (mAudioSource != AUDIO_SOURCE_CNT)) { 150297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu err = setupAudioEncoder(writer); 150397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu if (err != OK) return err; 150497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu *totalBitRate += mAudioBitRate; 150597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu } 150697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu 150797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu if (mInterleaveDurationUs > 0) { 150897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu reinterpret_cast<MPEG4Writer *>(writer.get())-> 150997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu setInterleaveDuration(mInterleaveDurationUs); 151097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu } 151197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu if (mLongitudex10000 > -3600000 && mLatitudex10000 > -3600000) { 151297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu reinterpret_cast<MPEG4Writer *>(writer.get())-> 151397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu setGeoData(mLatitudex10000, mLongitudex10000); 151497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu } 151597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu if (mMaxFileDurationUs != 0) { 151697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu writer->setMaxFileDuration(mMaxFileDurationUs); 151797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu } 151897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu if (mMaxFileSizeBytes != 0) { 151997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu writer->setMaxFileSize(mMaxFileSizeBytes); 15205778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 15215778822d86b0337407514b9372562b86edfa91cdAndreas Huber 15225778822d86b0337407514b9372562b86edfa91cdAndreas Huber mStartTimeOffsetMs = mEncoderProfiles->getStartTimeOffsetMs(mCameraId); 15235778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (mStartTimeOffsetMs > 0) { 15245778822d86b0337407514b9372562b86edfa91cdAndreas Huber reinterpret_cast<MPEG4Writer *>(writer.get())-> 15255778822d86b0337407514b9372562b86edfa91cdAndreas Huber setStartTimeOffsetMs(mStartTimeOffsetMs); 15265778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 15275778822d86b0337407514b9372562b86edfa91cdAndreas Huber 15285778822d86b0337407514b9372562b86edfa91cdAndreas Huber writer->setListener(mListener); 15295778822d86b0337407514b9372562b86edfa91cdAndreas Huber *mediaWriter = writer; 15305778822d86b0337407514b9372562b86edfa91cdAndreas Huber return OK; 15315778822d86b0337407514b9372562b86edfa91cdAndreas Huber} 15325778822d86b0337407514b9372562b86edfa91cdAndreas Huber 15335778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid StagefrightRecorder::setupMPEG4MetaData(int64_t startTimeUs, int32_t totalBitRate, 15345778822d86b0337407514b9372562b86edfa91cdAndreas Huber sp<MetaData> *meta) { 15355778822d86b0337407514b9372562b86edfa91cdAndreas Huber (*meta)->setInt64(kKeyTime, startTimeUs); 15365778822d86b0337407514b9372562b86edfa91cdAndreas Huber (*meta)->setInt32(kKeyFileType, mOutputFormat); 15375778822d86b0337407514b9372562b86edfa91cdAndreas Huber (*meta)->setInt32(kKeyBitRate, totalBitRate); 15385778822d86b0337407514b9372562b86edfa91cdAndreas Huber (*meta)->setInt32(kKey64BitFileOffset, mUse64BitFileOffset); 15395778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (mMovieTimeScale > 0) { 15405778822d86b0337407514b9372562b86edfa91cdAndreas Huber (*meta)->setInt32(kKeyTimeScale, mMovieTimeScale); 15415778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 15425778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (mTrackEveryTimeDurationUs > 0) { 15435778822d86b0337407514b9372562b86edfa91cdAndreas Huber (*meta)->setInt64(kKeyTrackTimeStatus, mTrackEveryTimeDurationUs); 15445778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 15455778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (mRotationDegrees != 0) { 15465778822d86b0337407514b9372562b86edfa91cdAndreas Huber (*meta)->setInt32(kKeyRotation, mRotationDegrees); 15475778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 15485778822d86b0337407514b9372562b86edfa91cdAndreas Huber} 15495778822d86b0337407514b9372562b86edfa91cdAndreas Huber 15505778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t StagefrightRecorder::startMPEG4Recording() { 15515778822d86b0337407514b9372562b86edfa91cdAndreas Huber int32_t totalBitRate; 15525778822d86b0337407514b9372562b86edfa91cdAndreas Huber status_t err = setupMPEG4Recording( 15535778822d86b0337407514b9372562b86edfa91cdAndreas Huber mOutputFd, mVideoWidth, mVideoHeight, 15545778822d86b0337407514b9372562b86edfa91cdAndreas Huber mVideoBitRate, &totalBitRate, &mWriter); 15555778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (err != OK) { 15565778822d86b0337407514b9372562b86edfa91cdAndreas Huber return err; 15575778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 15585778822d86b0337407514b9372562b86edfa91cdAndreas Huber 15595778822d86b0337407514b9372562b86edfa91cdAndreas Huber int64_t startTimeUs = systemTime() / 1000; 15605778822d86b0337407514b9372562b86edfa91cdAndreas Huber sp<MetaData> meta = new MetaData; 15615778822d86b0337407514b9372562b86edfa91cdAndreas Huber setupMPEG4MetaData(startTimeUs, totalBitRate, &meta); 15625778822d86b0337407514b9372562b86edfa91cdAndreas Huber 1563f933441648ef6a71dee783d733aac17b9508b452Andreas Huber err = mWriter->start(meta.get()); 1564f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (err != OK) { 15655778822d86b0337407514b9372562b86edfa91cdAndreas Huber return err; 1566729de186450f78c099637e1fce743fe531862c52Andreas Huber } 1567729de186450f78c099637e1fce743fe531862c52Andreas Huber 15685778822d86b0337407514b9372562b86edfa91cdAndreas Huber return OK; 1569729de186450f78c099637e1fce743fe531862c52Andreas Huber} 1570729de186450f78c099637e1fce743fe531862c52Andreas Huber 1571729de186450f78c099637e1fce743fe531862c52Andreas Huberstatus_t StagefrightRecorder::pause() { 1572729de186450f78c099637e1fce743fe531862c52Andreas Huber ALOGV("pause"); 1573729de186450f78c099637e1fce743fe531862c52Andreas Huber if (mWriter == NULL) { 1574729de186450f78c099637e1fce743fe531862c52Andreas Huber return UNKNOWN_ERROR; 1575729de186450f78c099637e1fce743fe531862c52Andreas Huber } 1576729de186450f78c099637e1fce743fe531862c52Andreas Huber mWriter->pause(); 1577729de186450f78c099637e1fce743fe531862c52Andreas Huber 15785778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (mStarted) { 15795778822d86b0337407514b9372562b86edfa91cdAndreas Huber mStarted = false; 15805778822d86b0337407514b9372562b86edfa91cdAndreas Huber 15815778822d86b0337407514b9372562b86edfa91cdAndreas Huber uint32_t params = 0; 1582729de186450f78c099637e1fce743fe531862c52Andreas Huber if (mAudioSource != AUDIO_SOURCE_CNT) { 15835778822d86b0337407514b9372562b86edfa91cdAndreas Huber params |= IMediaPlayerService::kBatteryDataTrackAudio; 15845778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 15855778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (mVideoSource != VIDEO_SOURCE_LIST_END) { 1586729de186450f78c099637e1fce743fe531862c52Andreas Huber params |= IMediaPlayerService::kBatteryDataTrackVideo; 15875778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 15885778822d86b0337407514b9372562b86edfa91cdAndreas Huber 15895778822d86b0337407514b9372562b86edfa91cdAndreas Huber addBatteryData(params); 15905778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 1591729de186450f78c099637e1fce743fe531862c52Andreas Huber 1592729de186450f78c099637e1fce743fe531862c52Andreas Huber 15935778822d86b0337407514b9372562b86edfa91cdAndreas Huber return OK; 15945778822d86b0337407514b9372562b86edfa91cdAndreas Huber} 15955778822d86b0337407514b9372562b86edfa91cdAndreas Huber 1596729de186450f78c099637e1fce743fe531862c52Andreas Huberstatus_t StagefrightRecorder::stop() { 1597729de186450f78c099637e1fce743fe531862c52Andreas Huber ALOGV("stop"); 1598729de186450f78c099637e1fce743fe531862c52Andreas Huber status_t err = OK; 1599729de186450f78c099637e1fce743fe531862c52Andreas Huber 16002f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi if (mCaptureTimeLapse && mCameraSourceTimeLapse != NULL) { 16012f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi mCameraSourceTimeLapse->startQuickReadReturns(); 16022f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi mCameraSourceTimeLapse = NULL; 16032f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi } 16042f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi 16052f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi if (mWriter != NULL) { 16062f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi err = mWriter->stop(); 16072f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi mWriter.clear(); 16082f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi } 16092f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi 16102f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi if (mOutputFd >= 0) { 16112f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi ::close(mOutputFd); 16122f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi mOutputFd = -1; 16132f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi } 16142f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi 16152f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi if (mStarted) { 16162f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi mStarted = false; 16172f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi 16182f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi uint32_t params = 0; 16192f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi if (mAudioSource != AUDIO_SOURCE_CNT) { 16202f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi params |= IMediaPlayerService::kBatteryDataTrackAudio; 16212f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi } 16222f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi if (mVideoSource != VIDEO_SOURCE_LIST_END) { 16232f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi params |= IMediaPlayerService::kBatteryDataTrackVideo; 16242f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi } 16252f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi 16262f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi addBatteryData(params); 16272f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi } 1628729de186450f78c099637e1fce743fe531862c52Andreas Huber 1629729de186450f78c099637e1fce743fe531862c52Andreas Huber 1630729de186450f78c099637e1fce743fe531862c52Andreas Huber return err; 1631729de186450f78c099637e1fce743fe531862c52Andreas Huber} 1632729de186450f78c099637e1fce743fe531862c52Andreas Huber 1633729de186450f78c099637e1fce743fe531862c52Andreas Huberstatus_t StagefrightRecorder::close() { 1634729de186450f78c099637e1fce743fe531862c52Andreas Huber ALOGV("close"); 1635729de186450f78c099637e1fce743fe531862c52Andreas Huber stop(); 1636729de186450f78c099637e1fce743fe531862c52Andreas Huber 1637729de186450f78c099637e1fce743fe531862c52Andreas Huber return OK; 1638729de186450f78c099637e1fce743fe531862c52Andreas Huber} 1639729de186450f78c099637e1fce743fe531862c52Andreas Huber 1640729de186450f78c099637e1fce743fe531862c52Andreas Huberstatus_t StagefrightRecorder::reset() { 1641729de186450f78c099637e1fce743fe531862c52Andreas Huber ALOGV("reset"); 1642729de186450f78c099637e1fce743fe531862c52Andreas Huber stop(); 1643729de186450f78c099637e1fce743fe531862c52Andreas Huber 1644729de186450f78c099637e1fce743fe531862c52Andreas Huber // No audio or video source by default 1645729de186450f78c099637e1fce743fe531862c52Andreas Huber mAudioSource = AUDIO_SOURCE_CNT; 1646729de186450f78c099637e1fce743fe531862c52Andreas Huber mVideoSource = VIDEO_SOURCE_LIST_END; 1647729de186450f78c099637e1fce743fe531862c52Andreas Huber 1648729de186450f78c099637e1fce743fe531862c52Andreas Huber // Default parameters 1649729de186450f78c099637e1fce743fe531862c52Andreas Huber mOutputFormat = OUTPUT_FORMAT_THREE_GPP; 1650729de186450f78c099637e1fce743fe531862c52Andreas Huber mAudioEncoder = AUDIO_ENCODER_AMR_NB; 1651729de186450f78c099637e1fce743fe531862c52Andreas Huber mVideoEncoder = VIDEO_ENCODER_H263; 1652729de186450f78c099637e1fce743fe531862c52Andreas Huber mVideoWidth = 176; 1653729de186450f78c099637e1fce743fe531862c52Andreas Huber mVideoHeight = 144; 1654729de186450f78c099637e1fce743fe531862c52Andreas Huber mFrameRate = -1; 1655729de186450f78c099637e1fce743fe531862c52Andreas Huber mVideoBitRate = 192000; 1656729de186450f78c099637e1fce743fe531862c52Andreas Huber mSampleRate = 8000; 1657729de186450f78c099637e1fce743fe531862c52Andreas Huber mAudioChannels = 1; 1658729de186450f78c099637e1fce743fe531862c52Andreas Huber mAudioBitRate = 12200; 1659729de186450f78c099637e1fce743fe531862c52Andreas Huber mInterleaveDurationUs = 0; 1660729de186450f78c099637e1fce743fe531862c52Andreas Huber mIFramesIntervalSec = 1; 1661729de186450f78c099637e1fce743fe531862c52Andreas Huber mAudioSourceNode = 0; 1662729de186450f78c099637e1fce743fe531862c52Andreas Huber mUse64BitFileOffset = false; 1663729de186450f78c099637e1fce743fe531862c52Andreas Huber mMovieTimeScale = -1; 1664729de186450f78c099637e1fce743fe531862c52Andreas Huber mAudioTimeScale = -1; 1665729de186450f78c099637e1fce743fe531862c52Andreas Huber mVideoTimeScale = -1; 1666729de186450f78c099637e1fce743fe531862c52Andreas Huber mCameraId = 0; 1667729de186450f78c099637e1fce743fe531862c52Andreas Huber mStartTimeOffsetMs = -1; 1668c1d8115e8a0bdaeb2b723d395b9a85a02c90c933Andreas Huber mVideoEncoderProfile = -1; 1669c1d8115e8a0bdaeb2b723d395b9a85a02c90c933Andreas Huber mVideoEncoderLevel = -1; 1670729de186450f78c099637e1fce743fe531862c52Andreas Huber mMaxFileDurationUs = 0; 1671729de186450f78c099637e1fce743fe531862c52Andreas Huber mMaxFileSizeBytes = 0; 1672729de186450f78c099637e1fce743fe531862c52Andreas Huber mTrackEveryTimeDurationUs = 0; 1673729de186450f78c099637e1fce743fe531862c52Andreas Huber mCaptureTimeLapse = false; 1674729de186450f78c099637e1fce743fe531862c52Andreas Huber mTimeBetweenTimeLapseFrameCaptureUs = -1; 1675729de186450f78c099637e1fce743fe531862c52Andreas Huber mCameraSourceTimeLapse = NULL; 1676f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mIsMetaDataStoredInVideoBuffers = false; 1677f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mEncoderProfiles = MediaProfiles::getInstance(); 1678f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mRotationDegrees = 0; 1679f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mLatitudex10000 = -3600000; 1680f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mLongitudex10000 = -3600000; 1681f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1682f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mOutputFd = -1; 1683f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1684f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return OK; 1685f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 1686f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1687f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t StagefrightRecorder::getMaxAmplitude(int *max) { 1688f933441648ef6a71dee783d733aac17b9508b452Andreas Huber ALOGV("getMaxAmplitude"); 1689f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1690f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (max == NULL) { 1691f933441648ef6a71dee783d733aac17b9508b452Andreas Huber ALOGE("Null pointer argument"); 1692f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return BAD_VALUE; 1693f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 1694f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1695f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (mAudioSourceNode != 0) { 1696f933441648ef6a71dee783d733aac17b9508b452Andreas Huber *max = mAudioSourceNode->getMaxAmplitude(); 1697f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } else { 1698f933441648ef6a71dee783d733aac17b9508b452Andreas Huber *max = 0; 1699f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 1700f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1701f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return OK; 1702f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 1703f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1704f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t StagefrightRecorder::dump( 1705f933441648ef6a71dee783d733aac17b9508b452Andreas Huber int fd, const Vector<String16>& args) const { 1706f933441648ef6a71dee783d733aac17b9508b452Andreas Huber ALOGV("dump"); 1707f933441648ef6a71dee783d733aac17b9508b452Andreas Huber const size_t SIZE = 256; 1708f933441648ef6a71dee783d733aac17b9508b452Andreas Huber char buffer[SIZE]; 1709f933441648ef6a71dee783d733aac17b9508b452Andreas Huber String8 result; 1710f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (mWriter != 0) { 1711f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mWriter->dump(fd, args); 1712f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } else { 1713f933441648ef6a71dee783d733aac17b9508b452Andreas Huber snprintf(buffer, SIZE, " No file writer\n"); 1714f933441648ef6a71dee783d733aac17b9508b452Andreas Huber result.append(buffer); 1715f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 1716f933441648ef6a71dee783d733aac17b9508b452Andreas Huber snprintf(buffer, SIZE, " Recorder: %p\n", this); 1717f933441648ef6a71dee783d733aac17b9508b452Andreas Huber snprintf(buffer, SIZE, " Output file (fd %d):\n", mOutputFd); 1718f933441648ef6a71dee783d733aac17b9508b452Andreas Huber result.append(buffer); 1719f933441648ef6a71dee783d733aac17b9508b452Andreas Huber snprintf(buffer, SIZE, " File format: %d\n", mOutputFormat); 1720f933441648ef6a71dee783d733aac17b9508b452Andreas Huber result.append(buffer); 1721f933441648ef6a71dee783d733aac17b9508b452Andreas Huber snprintf(buffer, SIZE, " Max file size (bytes): %lld\n", mMaxFileSizeBytes); 1722f933441648ef6a71dee783d733aac17b9508b452Andreas Huber result.append(buffer); 1723f933441648ef6a71dee783d733aac17b9508b452Andreas Huber snprintf(buffer, SIZE, " Max file duration (us): %lld\n", mMaxFileDurationUs); 1724f933441648ef6a71dee783d733aac17b9508b452Andreas Huber result.append(buffer); 1725f933441648ef6a71dee783d733aac17b9508b452Andreas Huber snprintf(buffer, SIZE, " File offset length (bits): %d\n", mUse64BitFileOffset? 64: 32); 1726f933441648ef6a71dee783d733aac17b9508b452Andreas Huber result.append(buffer); 1727f933441648ef6a71dee783d733aac17b9508b452Andreas Huber snprintf(buffer, SIZE, " Interleave duration (us): %d\n", mInterleaveDurationUs); 1728f933441648ef6a71dee783d733aac17b9508b452Andreas Huber result.append(buffer); 1729f933441648ef6a71dee783d733aac17b9508b452Andreas Huber snprintf(buffer, SIZE, " Progress notification: %lld us\n", mTrackEveryTimeDurationUs); 1730f933441648ef6a71dee783d733aac17b9508b452Andreas Huber result.append(buffer); 1731f933441648ef6a71dee783d733aac17b9508b452Andreas Huber snprintf(buffer, SIZE, " Audio\n"); 1732f933441648ef6a71dee783d733aac17b9508b452Andreas Huber result.append(buffer); 1733f933441648ef6a71dee783d733aac17b9508b452Andreas Huber snprintf(buffer, SIZE, " Source: %d\n", mAudioSource); 1734f933441648ef6a71dee783d733aac17b9508b452Andreas Huber result.append(buffer); 1735f933441648ef6a71dee783d733aac17b9508b452Andreas Huber snprintf(buffer, SIZE, " Encoder: %d\n", mAudioEncoder); 1736f933441648ef6a71dee783d733aac17b9508b452Andreas Huber result.append(buffer); 1737f933441648ef6a71dee783d733aac17b9508b452Andreas Huber snprintf(buffer, SIZE, " Bit rate (bps): %d\n", mAudioBitRate); 1738f933441648ef6a71dee783d733aac17b9508b452Andreas Huber result.append(buffer); 1739f933441648ef6a71dee783d733aac17b9508b452Andreas Huber snprintf(buffer, SIZE, " Sampling rate (hz): %d\n", mSampleRate); 1740f933441648ef6a71dee783d733aac17b9508b452Andreas Huber result.append(buffer); 1741f933441648ef6a71dee783d733aac17b9508b452Andreas Huber snprintf(buffer, SIZE, " Number of channels: %d\n", mAudioChannels); 1742f933441648ef6a71dee783d733aac17b9508b452Andreas Huber result.append(buffer); 1743f933441648ef6a71dee783d733aac17b9508b452Andreas Huber snprintf(buffer, SIZE, " Max amplitude: %d\n", mAudioSourceNode == 0? 0: mAudioSourceNode->getMaxAmplitude()); 1744f933441648ef6a71dee783d733aac17b9508b452Andreas Huber result.append(buffer); 1745f933441648ef6a71dee783d733aac17b9508b452Andreas Huber snprintf(buffer, SIZE, " Video\n"); 1746f933441648ef6a71dee783d733aac17b9508b452Andreas Huber result.append(buffer); 1747f933441648ef6a71dee783d733aac17b9508b452Andreas Huber snprintf(buffer, SIZE, " Source: %d\n", mVideoSource); 1748f933441648ef6a71dee783d733aac17b9508b452Andreas Huber result.append(buffer); 1749f933441648ef6a71dee783d733aac17b9508b452Andreas Huber snprintf(buffer, SIZE, " Camera Id: %d\n", mCameraId); 1750f933441648ef6a71dee783d733aac17b9508b452Andreas Huber result.append(buffer); 1751f933441648ef6a71dee783d733aac17b9508b452Andreas Huber snprintf(buffer, SIZE, " Start time offset (ms): %d\n", mStartTimeOffsetMs); 1752e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber result.append(buffer); 1753e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber snprintf(buffer, SIZE, " Encoder: %d\n", mVideoEncoder); 1754e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber result.append(buffer); 1755e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber snprintf(buffer, SIZE, " Encoder profile: %d\n", mVideoEncoderProfile); 1756e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber result.append(buffer); 1757e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber snprintf(buffer, SIZE, " Encoder level: %d\n", mVideoEncoderLevel); 1758e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber result.append(buffer); 1759e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber snprintf(buffer, SIZE, " I frames interval (s): %d\n", mIFramesIntervalSec); 176094705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang result.append(buffer); 176194705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang snprintf(buffer, SIZE, " Frame size (pixels): %dx%d\n", mVideoWidth, mVideoHeight); 1762e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber result.append(buffer); 1763e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber snprintf(buffer, SIZE, " Frame rate (fps): %d\n", mFrameRate); 17645778822d86b0337407514b9372562b86edfa91cdAndreas Huber result.append(buffer); 17655778822d86b0337407514b9372562b86edfa91cdAndreas Huber snprintf(buffer, SIZE, " Bit rate (bps): %d\n", mVideoBitRate); 1766e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber result.append(buffer); 1767e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber ::write(fd, result.string(), result.size()); 1768e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber return OK; 1769e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber} 1770e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber} // namespace android 1771e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber