StagefrightRecorder.cpp revision b45c62c8e9b05c2703bdae18cc298ae55550db8a
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 <media/stagefright/AudioSource.h> 24#include <media/stagefright/AMRWriter.h> 25#include <media/stagefright/CameraSource.h> 26#include <media/stagefright/MPEG4Writer.h> 27#include <media/stagefright/MediaDebug.h> 28#include <media/stagefright/MediaDefs.h> 29#include <media/stagefright/MetaData.h> 30#include <media/stagefright/OMXClient.h> 31#include <media/stagefright/OMXCodec.h> 32#include <ui/ICamera.h> 33#include <ui/ISurface.h> 34#include <utils/Errors.h> 35 36namespace android { 37 38StagefrightRecorder::StagefrightRecorder() { 39 reset(); 40} 41 42StagefrightRecorder::~StagefrightRecorder() { 43 stop(); 44 45 if (mOutputFd >= 0) { 46 ::close(mOutputFd); 47 mOutputFd = -1; 48 } 49} 50 51status_t StagefrightRecorder::init() { 52 return OK; 53} 54 55status_t StagefrightRecorder::setAudioSource(audio_source as) { 56 mAudioSource = as; 57 58 return OK; 59} 60 61status_t StagefrightRecorder::setVideoSource(video_source vs) { 62 mVideoSource = vs; 63 64 return OK; 65} 66 67status_t StagefrightRecorder::setOutputFormat(output_format of) { 68 mOutputFormat = of; 69 70 return OK; 71} 72 73status_t StagefrightRecorder::setAudioEncoder(audio_encoder ae) { 74 mAudioEncoder = ae; 75 76 return OK; 77} 78 79status_t StagefrightRecorder::setVideoEncoder(video_encoder ve) { 80 mVideoEncoder = ve; 81 82 return OK; 83} 84 85status_t StagefrightRecorder::setVideoSize(int width, int height) { 86 mVideoWidth = width; 87 mVideoHeight = height; 88 89 return OK; 90} 91 92status_t StagefrightRecorder::setVideoFrameRate(int frames_per_second) { 93 mFrameRate = frames_per_second; 94 95 return OK; 96} 97 98status_t StagefrightRecorder::setCamera(const sp<ICamera> &camera) { 99 mCamera = camera; 100 101 return OK; 102} 103 104status_t StagefrightRecorder::setPreviewSurface(const sp<ISurface> &surface) { 105 mPreviewSurface = surface; 106 107 return OK; 108} 109 110status_t StagefrightRecorder::setOutputFile(const char *path) { 111 // We don't actually support this at all, as the media_server process 112 // no longer has permissions to create files. 113 114 return UNKNOWN_ERROR; 115} 116 117status_t StagefrightRecorder::setOutputFile(int fd, int64_t offset, int64_t length) { 118 // These don't make any sense, do they? 119 CHECK_EQ(offset, 0); 120 CHECK_EQ(length, 0); 121 122 if (mOutputFd >= 0) { 123 ::close(mOutputFd); 124 } 125 mOutputFd = dup(fd); 126 127 return OK; 128} 129 130status_t StagefrightRecorder::setParameters(const String8 ¶ms) { 131 mParams = params; 132 133 return OK; 134} 135 136status_t StagefrightRecorder::setListener(const sp<IMediaPlayerClient> &listener) { 137 mListener = listener; 138 139 return OK; 140} 141 142status_t StagefrightRecorder::prepare() { 143 return OK; 144} 145 146status_t StagefrightRecorder::start() { 147 if (mWriter != NULL) { 148 return UNKNOWN_ERROR; 149 } 150 151 switch (mOutputFormat) { 152 case OUTPUT_FORMAT_DEFAULT: 153 case OUTPUT_FORMAT_THREE_GPP: 154 case OUTPUT_FORMAT_MPEG_4: 155 return startMPEG4Recording(); 156 157 case OUTPUT_FORMAT_AMR_NB: 158 case OUTPUT_FORMAT_AMR_WB: 159 return startAMRRecording(); 160 161 default: 162 return UNKNOWN_ERROR; 163 } 164} 165 166sp<MediaSource> StagefrightRecorder::createAMRAudioSource() { 167 uint32_t sampleRate = 168 mAudioEncoder == AUDIO_ENCODER_AMR_NB ? 8000 : 16000; 169 170 sp<AudioSource> audioSource = 171 new AudioSource( 172 mAudioSource, 173 sampleRate, 174 AudioSystem::CHANNEL_IN_MONO); 175 176 status_t err = audioSource->initCheck(); 177 178 if (err != OK) { 179 return NULL; 180 } 181 182 sp<MetaData> encMeta = new MetaData; 183 encMeta->setCString( 184 kKeyMIMEType, 185 mAudioEncoder == AUDIO_ENCODER_AMR_NB 186 ? MEDIA_MIMETYPE_AUDIO_AMR_NB : MEDIA_MIMETYPE_AUDIO_AMR_WB); 187 188 int32_t maxInputSize; 189 CHECK(audioSource->getFormat()->findInt32( 190 kKeyMaxInputSize, &maxInputSize)); 191 192 encMeta->setInt32(kKeyMaxInputSize, maxInputSize); 193 encMeta->setInt32(kKeyChannelCount, 1); 194 encMeta->setInt32(kKeySampleRate, sampleRate); 195 196 OMXClient client; 197 CHECK_EQ(client.connect(), OK); 198 199 sp<MediaSource> audioEncoder = 200 OMXCodec::Create(client.interface(), encMeta, 201 true /* createEncoder */, audioSource); 202 203 return audioEncoder; 204} 205 206status_t StagefrightRecorder::startAMRRecording() { 207 if (mAudioSource == AUDIO_SOURCE_LIST_END 208 || mVideoSource != VIDEO_SOURCE_LIST_END) { 209 return UNKNOWN_ERROR; 210 } 211 212 if (mOutputFormat == OUTPUT_FORMAT_AMR_NB 213 && mAudioEncoder != AUDIO_ENCODER_DEFAULT 214 && mAudioEncoder != AUDIO_ENCODER_AMR_NB) { 215 return UNKNOWN_ERROR; 216 } else if (mOutputFormat == OUTPUT_FORMAT_AMR_WB 217 && mAudioEncoder != AUDIO_ENCODER_AMR_WB) { 218 return UNKNOWN_ERROR; 219 } 220 221 sp<MediaSource> audioEncoder = createAMRAudioSource(); 222 223 if (audioEncoder == NULL) { 224 return UNKNOWN_ERROR; 225 } 226 227 CHECK(mOutputFd >= 0); 228 mWriter = new AMRWriter(dup(mOutputFd)); 229 mWriter->addSource(audioEncoder); 230 mWriter->start(); 231 232 return OK; 233} 234 235status_t StagefrightRecorder::startMPEG4Recording() { 236 mWriter = new MPEG4Writer(dup(mOutputFd)); 237 238 if (mVideoSource == VIDEO_SOURCE_DEFAULT 239 || mVideoSource == VIDEO_SOURCE_CAMERA) { 240 CHECK(mCamera != NULL); 241 242 sp<CameraSource> cameraSource = 243 CameraSource::CreateFromICamera(mCamera); 244 245 CHECK(cameraSource != NULL); 246 247 cameraSource->setPreviewSurface(mPreviewSurface); 248 249 sp<MetaData> enc_meta = new MetaData; 250 switch (mVideoEncoder) { 251 case VIDEO_ENCODER_H263: 252 enc_meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_H263); 253 break; 254 255 case VIDEO_ENCODER_MPEG_4_SP: 256 enc_meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_MPEG4); 257 break; 258 259 case VIDEO_ENCODER_H264: 260 enc_meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_AVC); 261 break; 262 263 default: 264 CHECK(!"Should not be here, unsupported video encoding."); 265 break; 266 } 267 268 sp<MetaData> meta = cameraSource->getFormat(); 269 270 int32_t width, height; 271 CHECK(meta->findInt32(kKeyWidth, &width)); 272 CHECK(meta->findInt32(kKeyHeight, &height)); 273 274 enc_meta->setInt32(kKeyWidth, width); 275 enc_meta->setInt32(kKeyHeight, height); 276 277 OMXClient client; 278 CHECK_EQ(client.connect(), OK); 279 280 sp<MediaSource> encoder = 281 OMXCodec::Create( 282 client.interface(), enc_meta, 283 true /* createEncoder */, cameraSource); 284 285 CHECK(mOutputFd >= 0); 286 mWriter->addSource(encoder); 287 } 288 289 if (mAudioSource != AUDIO_SOURCE_LIST_END) { 290 sp<MediaSource> audioEncoder = createAMRAudioSource(); 291 292 if (audioEncoder == NULL) { 293 return UNKNOWN_ERROR; 294 } 295 296 mWriter->addSource(audioEncoder); 297 } 298 299 mWriter->start(); 300 return OK; 301} 302 303status_t StagefrightRecorder::stop() { 304 if (mWriter == NULL) { 305 return UNKNOWN_ERROR; 306 } 307 308 mWriter->stop(); 309 mWriter = NULL; 310 311 return OK; 312} 313 314status_t StagefrightRecorder::close() { 315 stop(); 316 317 return OK; 318} 319 320status_t StagefrightRecorder::reset() { 321 stop(); 322 323 mAudioSource = AUDIO_SOURCE_LIST_END; 324 mVideoSource = VIDEO_SOURCE_LIST_END; 325 mOutputFormat = OUTPUT_FORMAT_LIST_END; 326 mAudioEncoder = AUDIO_ENCODER_LIST_END; 327 mVideoEncoder = VIDEO_ENCODER_LIST_END; 328 mVideoWidth = -1; 329 mVideoHeight = -1; 330 mFrameRate = -1; 331 mOutputFd = -1; 332 333 return OK; 334} 335 336status_t StagefrightRecorder::getMaxAmplitude(int *max) { 337 *max = 0; 338 339 return OK; 340} 341 342} // namespace android 343