StagefrightRecorder.cpp revision 2dce41ad26cb3e9e15c9e456a84bcf5309548ca0
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 encMeta->setInt32(kKeyChannelCount, 1); 189 encMeta->setInt32(kKeySampleRate, sampleRate); 190 191 OMXClient client; 192 CHECK_EQ(client.connect(), OK); 193 194 sp<MediaSource> audioEncoder = 195 OMXCodec::Create(client.interface(), encMeta, 196 true /* createEncoder */, audioSource); 197 198 return audioEncoder; 199} 200 201status_t StagefrightRecorder::startAMRRecording() { 202 if (mAudioSource == AUDIO_SOURCE_LIST_END 203 || mVideoSource != VIDEO_SOURCE_LIST_END) { 204 return UNKNOWN_ERROR; 205 } 206 207 if (mOutputFormat == OUTPUT_FORMAT_AMR_NB 208 && mAudioEncoder != AUDIO_ENCODER_DEFAULT 209 && mAudioEncoder != AUDIO_ENCODER_AMR_NB) { 210 return UNKNOWN_ERROR; 211 } else if (mOutputFormat == OUTPUT_FORMAT_AMR_WB 212 && mAudioEncoder != AUDIO_ENCODER_AMR_WB) { 213 return UNKNOWN_ERROR; 214 } 215 216 sp<MediaSource> audioEncoder = createAMRAudioSource(); 217 218 if (audioEncoder == NULL) { 219 return UNKNOWN_ERROR; 220 } 221 222 CHECK(mOutputFd >= 0); 223 mWriter = new AMRWriter(dup(mOutputFd)); 224 mWriter->addSource(audioEncoder); 225 mWriter->start(); 226 227 return OK; 228} 229 230status_t StagefrightRecorder::startMPEG4Recording() { 231 mWriter = new MPEG4Writer(dup(mOutputFd)); 232 233 if (mVideoSource == VIDEO_SOURCE_DEFAULT 234 || mVideoSource == VIDEO_SOURCE_CAMERA) { 235 CHECK(mCamera != NULL); 236 237 sp<CameraSource> cameraSource = 238 CameraSource::CreateFromICamera(mCamera); 239 240 CHECK(cameraSource != NULL); 241 242 cameraSource->setPreviewSurface(mPreviewSurface); 243 244 sp<MetaData> enc_meta = new MetaData; 245 switch (mVideoEncoder) { 246 case VIDEO_ENCODER_H263: 247 enc_meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_H263); 248 break; 249 250 case VIDEO_ENCODER_MPEG_4_SP: 251 enc_meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_MPEG4); 252 break; 253 254 case VIDEO_ENCODER_H264: 255 enc_meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_AVC); 256 break; 257 258 default: 259 CHECK(!"Should not be here, unsupported video encoding."); 260 break; 261 } 262 263 sp<MetaData> meta = cameraSource->getFormat(); 264 265 int32_t width, height; 266 CHECK(meta->findInt32(kKeyWidth, &width)); 267 CHECK(meta->findInt32(kKeyHeight, &height)); 268 269 enc_meta->setInt32(kKeyWidth, width); 270 enc_meta->setInt32(kKeyHeight, height); 271 272 OMXClient client; 273 CHECK_EQ(client.connect(), OK); 274 275 sp<MediaSource> encoder = 276 OMXCodec::Create( 277 client.interface(), enc_meta, 278 true /* createEncoder */, cameraSource); 279 280 CHECK(mOutputFd >= 0); 281 mWriter->addSource(encoder); 282 } 283 284 if (mAudioSource != AUDIO_SOURCE_LIST_END) { 285 sp<MediaSource> audioEncoder = createAMRAudioSource(); 286 287 if (audioEncoder == NULL) { 288 return UNKNOWN_ERROR; 289 } 290 291 mWriter->addSource(audioEncoder); 292 } 293 294 mWriter->start(); 295 return OK; 296} 297 298status_t StagefrightRecorder::stop() { 299 if (mWriter == NULL) { 300 return UNKNOWN_ERROR; 301 } 302 303 mWriter->stop(); 304 mWriter = NULL; 305 306 return OK; 307} 308 309status_t StagefrightRecorder::close() { 310 stop(); 311 312 return OK; 313} 314 315status_t StagefrightRecorder::reset() { 316 stop(); 317 318 mAudioSource = AUDIO_SOURCE_LIST_END; 319 mVideoSource = VIDEO_SOURCE_LIST_END; 320 mOutputFormat = OUTPUT_FORMAT_LIST_END; 321 mAudioEncoder = AUDIO_ENCODER_LIST_END; 322 mVideoEncoder = VIDEO_ENCODER_LIST_END; 323 mVideoWidth = -1; 324 mVideoHeight = -1; 325 mFrameRate = -1; 326 mOutputFd = -1; 327 328 return OK; 329} 330 331status_t StagefrightRecorder::getMaxAmplitude(int *max) { 332 *max = 0; 333 334 return OK; 335} 336 337} // namespace android 338