StagefrightRecorder.cpp revision c32cd79d9ad4aba7d959b5b3be7361b4715e6f18
1/* 2 * Copyright (C) 2009 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17//#define LOG_NDEBUG 0 18#define LOG_TAG "StagefrightRecorder" 19#include <utils/Log.h> 20 21#include "StagefrightRecorder.h" 22 23#include <binder/IPCThreadState.h> 24#include <media/stagefright/AudioSource.h> 25#include <media/stagefright/AMRWriter.h> 26#include <media/stagefright/CameraSource.h> 27#include <media/stagefright/MPEG4Writer.h> 28#include <media/stagefright/MediaDebug.h> 29#include <media/stagefright/MediaDefs.h> 30#include <media/stagefright/MetaData.h> 31#include <media/stagefright/OMXClient.h> 32#include <media/stagefright/OMXCodec.h> 33#include <camera/ICamera.h> 34#include <camera/Camera.h> 35#include <surfaceflinger/ISurface.h> 36#include <utils/Errors.h> 37#include <sys/types.h> 38#include <unistd.h> 39 40namespace android { 41 42StagefrightRecorder::StagefrightRecorder() { 43 reset(); 44} 45 46StagefrightRecorder::~StagefrightRecorder() { 47 stop(); 48 49 if (mOutputFd >= 0) { 50 ::close(mOutputFd); 51 mOutputFd = -1; 52 } 53} 54 55status_t StagefrightRecorder::init() { 56 return OK; 57} 58 59status_t StagefrightRecorder::setAudioSource(audio_source as) { 60 mAudioSource = as; 61 62 return OK; 63} 64 65status_t StagefrightRecorder::setVideoSource(video_source vs) { 66 mVideoSource = vs; 67 68 return OK; 69} 70 71status_t StagefrightRecorder::setOutputFormat(output_format of) { 72 mOutputFormat = of; 73 74 return OK; 75} 76 77status_t StagefrightRecorder::setAudioEncoder(audio_encoder ae) { 78 mAudioEncoder = ae; 79 80 return OK; 81} 82 83status_t StagefrightRecorder::setVideoEncoder(video_encoder ve) { 84 mVideoEncoder = ve; 85 86 return OK; 87} 88 89status_t StagefrightRecorder::setVideoSize(int width, int height) { 90 mVideoWidth = width; 91 mVideoHeight = height; 92 93 return OK; 94} 95 96status_t StagefrightRecorder::setVideoFrameRate(int frames_per_second) { 97 mFrameRate = frames_per_second; 98 99 return OK; 100} 101 102status_t StagefrightRecorder::setCamera(const sp<ICamera> &camera) { 103 LOGV("setCamera: pid %d pid %d", IPCThreadState::self()->getCallingPid(), getpid()); 104 if (camera == 0) { 105 LOGE("camera is NULL"); 106 return UNKNOWN_ERROR; 107 } 108 109 mFlags &= ~ FLAGS_SET_CAMERA | FLAGS_HOT_CAMERA; 110 mCamera = Camera::create(camera); 111 if (mCamera == 0) { 112 LOGE("Unable to connect to camera"); 113 return UNKNOWN_ERROR; 114 } 115 116 LOGV("Connected to camera"); 117 mFlags |= FLAGS_SET_CAMERA; 118 if (mCamera->previewEnabled()) { 119 LOGV("camera is hot"); 120 mFlags |= FLAGS_HOT_CAMERA; 121 } 122 123 return OK; 124} 125 126status_t StagefrightRecorder::setPreviewSurface(const sp<ISurface> &surface) { 127 mPreviewSurface = surface; 128 129 return OK; 130} 131 132status_t StagefrightRecorder::setOutputFile(const char *path) { 133 // We don't actually support this at all, as the media_server process 134 // no longer has permissions to create files. 135 136 return UNKNOWN_ERROR; 137} 138 139status_t StagefrightRecorder::setOutputFile(int fd, int64_t offset, int64_t length) { 140 // These don't make any sense, do they? 141 CHECK_EQ(offset, 0); 142 CHECK_EQ(length, 0); 143 144 if (mOutputFd >= 0) { 145 ::close(mOutputFd); 146 } 147 mOutputFd = dup(fd); 148 149 return OK; 150} 151 152status_t StagefrightRecorder::setParameters(const String8 ¶ms) { 153 mParams = params; 154 155 return OK; 156} 157 158status_t StagefrightRecorder::setListener(const sp<IMediaPlayerClient> &listener) { 159 mListener = listener; 160 161 return OK; 162} 163 164status_t StagefrightRecorder::prepare() { 165 return OK; 166} 167 168status_t StagefrightRecorder::start() { 169 if (mWriter != NULL) { 170 return UNKNOWN_ERROR; 171 } 172 173 switch (mOutputFormat) { 174 case OUTPUT_FORMAT_DEFAULT: 175 case OUTPUT_FORMAT_THREE_GPP: 176 case OUTPUT_FORMAT_MPEG_4: 177 return startMPEG4Recording(); 178 179 case OUTPUT_FORMAT_AMR_NB: 180 case OUTPUT_FORMAT_AMR_WB: 181 return startAMRRecording(); 182 183 default: 184 return UNKNOWN_ERROR; 185 } 186} 187 188sp<MediaSource> StagefrightRecorder::createAMRAudioSource() { 189 uint32_t sampleRate = 190 mAudioEncoder == AUDIO_ENCODER_AMR_NB ? 8000 : 16000; 191 192 sp<AudioSource> audioSource = 193 new AudioSource( 194 mAudioSource, 195 sampleRate, 196 AudioSystem::CHANNEL_IN_MONO); 197 198 status_t err = audioSource->initCheck(); 199 200 if (err != OK) { 201 return NULL; 202 } 203 204 sp<MetaData> encMeta = new MetaData; 205 encMeta->setCString( 206 kKeyMIMEType, 207 mAudioEncoder == AUDIO_ENCODER_AMR_NB 208 ? MEDIA_MIMETYPE_AUDIO_AMR_NB : MEDIA_MIMETYPE_AUDIO_AMR_WB); 209 210 int32_t maxInputSize; 211 CHECK(audioSource->getFormat()->findInt32( 212 kKeyMaxInputSize, &maxInputSize)); 213 214 encMeta->setInt32(kKeyMaxInputSize, maxInputSize); 215 encMeta->setInt32(kKeyChannelCount, 1); 216 encMeta->setInt32(kKeySampleRate, sampleRate); 217 218 OMXClient client; 219 CHECK_EQ(client.connect(), OK); 220 221 sp<MediaSource> audioEncoder = 222 OMXCodec::Create(client.interface(), encMeta, 223 true /* createEncoder */, audioSource); 224 225 return audioEncoder; 226} 227 228status_t StagefrightRecorder::startAMRRecording() { 229 if (mAudioSource == AUDIO_SOURCE_LIST_END 230 || mVideoSource != VIDEO_SOURCE_LIST_END) { 231 return UNKNOWN_ERROR; 232 } 233 234 if (mOutputFormat == OUTPUT_FORMAT_AMR_NB 235 && mAudioEncoder != AUDIO_ENCODER_DEFAULT 236 && mAudioEncoder != AUDIO_ENCODER_AMR_NB) { 237 return UNKNOWN_ERROR; 238 } else if (mOutputFormat == OUTPUT_FORMAT_AMR_WB 239 && mAudioEncoder != AUDIO_ENCODER_AMR_WB) { 240 return UNKNOWN_ERROR; 241 } 242 243 sp<MediaSource> audioEncoder = createAMRAudioSource(); 244 245 if (audioEncoder == NULL) { 246 return UNKNOWN_ERROR; 247 } 248 249 CHECK(mOutputFd >= 0); 250 mWriter = new AMRWriter(dup(mOutputFd)); 251 mWriter->addSource(audioEncoder); 252 mWriter->start(); 253 254 return OK; 255} 256 257status_t StagefrightRecorder::startMPEG4Recording() { 258 mWriter = new MPEG4Writer(dup(mOutputFd)); 259 260 if (mVideoSource == VIDEO_SOURCE_DEFAULT 261 || mVideoSource == VIDEO_SOURCE_CAMERA) { 262 CHECK(mCamera != NULL); 263 264 sp<CameraSource> cameraSource = 265 CameraSource::CreateFromCamera(mCamera); 266 267 CHECK(cameraSource != NULL); 268 269 cameraSource->setPreviewSurface(mPreviewSurface); 270 271 sp<MetaData> enc_meta = new MetaData; 272 switch (mVideoEncoder) { 273 case VIDEO_ENCODER_H263: 274 enc_meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_H263); 275 break; 276 277 case VIDEO_ENCODER_MPEG_4_SP: 278 enc_meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_MPEG4); 279 break; 280 281 case VIDEO_ENCODER_H264: 282 enc_meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_AVC); 283 break; 284 285 default: 286 CHECK(!"Should not be here, unsupported video encoding."); 287 break; 288 } 289 290 sp<MetaData> meta = cameraSource->getFormat(); 291 292 int32_t width, height; 293 CHECK(meta->findInt32(kKeyWidth, &width)); 294 CHECK(meta->findInt32(kKeyHeight, &height)); 295 296 enc_meta->setInt32(kKeyWidth, width); 297 enc_meta->setInt32(kKeyHeight, height); 298 299 OMXClient client; 300 CHECK_EQ(client.connect(), OK); 301 302 sp<MediaSource> encoder = 303 OMXCodec::Create( 304 client.interface(), enc_meta, 305 true /* createEncoder */, cameraSource); 306 307 CHECK(mOutputFd >= 0); 308 mWriter->addSource(encoder); 309 } 310 311 if (mAudioSource != AUDIO_SOURCE_LIST_END) { 312 sp<MediaSource> audioEncoder = createAMRAudioSource(); 313 314 if (audioEncoder == NULL) { 315 return UNKNOWN_ERROR; 316 } 317 318 mWriter->addSource(audioEncoder); 319 } 320 321 mWriter->start(); 322 return OK; 323} 324 325status_t StagefrightRecorder::stop() { 326 if (mWriter == NULL) { 327 return UNKNOWN_ERROR; 328 } 329 330 mWriter->stop(); 331 mWriter = NULL; 332 333 return OK; 334} 335 336status_t StagefrightRecorder::close() { 337 stop(); 338 339 if (mCamera != 0) { 340 if ((mFlags & FLAGS_HOT_CAMERA) == 0) { 341 LOGV("Camera was cold when we started, stopping preview"); 342 mCamera->stopPreview(); 343 } 344 if (mFlags & FLAGS_SET_CAMERA) { 345 LOGV("Unlocking camera"); 346 mCamera->unlock(); 347 } 348 mFlags = 0; 349 } 350 return OK; 351} 352 353status_t StagefrightRecorder::reset() { 354 stop(); 355 356 mAudioSource = AUDIO_SOURCE_LIST_END; 357 mVideoSource = VIDEO_SOURCE_LIST_END; 358 mOutputFormat = OUTPUT_FORMAT_LIST_END; 359 mAudioEncoder = AUDIO_ENCODER_LIST_END; 360 mVideoEncoder = VIDEO_ENCODER_LIST_END; 361 mVideoWidth = -1; 362 mVideoHeight = -1; 363 mFrameRate = -1; 364 mOutputFd = -1; 365 mFlags = 0; 366 367 return OK; 368} 369 370status_t StagefrightRecorder::getMaxAmplitude(int *max) { 371 *max = 0; 372 373 return OK; 374} 375 376} // namespace android 377