StagefrightRecorder.cpp revision 050b28a593350047845a45a14cc5026221ac1620
146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown/* 246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown * Copyright (C) 2009 The Android Open Source Project 346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown * 446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown * Licensed under the Apache License, Version 2.0 (the "License"); 546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown * you may not use this file except in compliance with the License. 646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown * You may obtain a copy of the License at 746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown * 846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown * http://www.apache.org/licenses/LICENSE-2.0 946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown * 1046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown * Unless required by applicable law or agreed to in writing, software 1146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown * distributed under the License is distributed on an "AS IS" BASIS, 1246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown * See the License for the specific language governing permissions and 1446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown * limitations under the License. 1546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown */ 1646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown 1746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown//#define LOG_NDEBUG 0 1846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown#define LOG_TAG "StagefrightRecorder" 1946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown#include <utils/Log.h> 2046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown 211f2451007c660091b7b090c1ea332f9044515d2dJeff Brown#include "StagefrightRecorder.h" 221f2451007c660091b7b090c1ea332f9044515d2dJeff Brown 2346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown#include <binder/IPCThreadState.h> 2446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown#include <media/stagefright/AudioSource.h> 2546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown#include <media/stagefright/AMRWriter.h> 2646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown#include <media/stagefright/CameraSource.h> 2746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown#include <media/stagefright/MPEG4Writer.h> 281f2451007c660091b7b090c1ea332f9044515d2dJeff Brown#include <media/stagefright/MediaDebug.h> 291f2451007c660091b7b090c1ea332f9044515d2dJeff Brown#include <media/stagefright/MediaDefs.h> 3046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown#include <media/stagefright/MetaData.h> 3146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown#include <media/stagefright/OMXClient.h> 321f2451007c660091b7b090c1ea332f9044515d2dJeff Brown#include <media/stagefright/OMXCodec.h> 331f2451007c660091b7b090c1ea332f9044515d2dJeff Brown#include <camera/ICamera.h> 341f2451007c660091b7b090c1ea332f9044515d2dJeff Brown#include <camera/Camera.h> 3546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown#include <surfaceflinger/ISurface.h> 3646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown#include <utils/Errors.h> 371f2451007c660091b7b090c1ea332f9044515d2dJeff Brown#include <sys/types.h> 381f2451007c660091b7b090c1ea332f9044515d2dJeff Brown#include <unistd.h> 391f2451007c660091b7b090c1ea332f9044515d2dJeff Brown#include <ctype.h> 401f2451007c660091b7b090c1ea332f9044515d2dJeff Brown 411f2451007c660091b7b090c1ea332f9044515d2dJeff Brownnamespace android { 421f2451007c660091b7b090c1ea332f9044515d2dJeff Brown 4346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff BrownStagefrightRecorder::StagefrightRecorder() { 4446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown reset(); 4546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown} 46 47StagefrightRecorder::~StagefrightRecorder() { 48 stop(); 49 50 if (mOutputFd >= 0) { 51 ::close(mOutputFd); 52 mOutputFd = -1; 53 } 54} 55 56status_t StagefrightRecorder::init() { 57 return OK; 58} 59 60status_t StagefrightRecorder::setAudioSource(audio_source as) { 61 mAudioSource = as; 62 63 return OK; 64} 65 66status_t StagefrightRecorder::setVideoSource(video_source vs) { 67 mVideoSource = vs; 68 69 return OK; 70} 71 72status_t StagefrightRecorder::setOutputFormat(output_format of) { 73 mOutputFormat = of; 74 75 return OK; 76} 77 78status_t StagefrightRecorder::setAudioEncoder(audio_encoder ae) { 79 mAudioEncoder = ae; 80 81 return OK; 82} 83 84status_t StagefrightRecorder::setVideoEncoder(video_encoder ve) { 85 mVideoEncoder = ve; 86 87 return OK; 88} 89 90status_t StagefrightRecorder::setVideoSize(int width, int height) { 91 mVideoWidth = width; 92 mVideoHeight = height; 93 94 return OK; 95} 96 97status_t StagefrightRecorder::setVideoFrameRate(int frames_per_second) { 98 mFrameRate = frames_per_second; 99 100 return OK; 101} 102 103status_t StagefrightRecorder::setCamera(const sp<ICamera> &camera) { 104 LOGV("setCamera: pid %d pid %d", IPCThreadState::self()->getCallingPid(), getpid()); 105 if (camera == 0) { 106 LOGE("camera is NULL"); 107 return UNKNOWN_ERROR; 108 } 109 110 mFlags &= ~ FLAGS_SET_CAMERA | FLAGS_HOT_CAMERA; 111 mCamera = Camera::create(camera); 112 if (mCamera == 0) { 113 LOGE("Unable to connect to camera"); 114 return UNKNOWN_ERROR; 115 } 116 117 LOGV("Connected to camera"); 118 mFlags |= FLAGS_SET_CAMERA; 119 if (mCamera->previewEnabled()) { 120 LOGV("camera is hot"); 121 mFlags |= FLAGS_HOT_CAMERA; 122 } 123 124 return OK; 125} 126 127status_t StagefrightRecorder::setPreviewSurface(const sp<ISurface> &surface) { 128 mPreviewSurface = surface; 129 130 return OK; 131} 132 133status_t StagefrightRecorder::setOutputFile(const char *path) { 134 // We don't actually support this at all, as the media_server process 135 // no longer has permissions to create files. 136 137 return UNKNOWN_ERROR; 138} 139 140status_t StagefrightRecorder::setOutputFile(int fd, int64_t offset, int64_t length) { 141 // These don't make any sense, do they? 142 CHECK_EQ(offset, 0); 143 CHECK_EQ(length, 0); 144 145 if (mOutputFd >= 0) { 146 ::close(mOutputFd); 147 } 148 mOutputFd = dup(fd); 149 150 return OK; 151} 152 153// Attempt to parse an int64 literal optionally surrounded by whitespace, 154// returns true on success, false otherwise. 155static bool safe_strtoi64(const char *s, int32_t *val) { 156 char *end; 157 *val = static_cast<int32_t>(strtoll(s, &end, 10)); 158 159 if (end == s || errno == ERANGE) { 160 return false; 161 } 162 163 // Skip trailing whitespace 164 while (isspace(*end)) { 165 ++end; 166 } 167 168 // For a successful return, the string must contain nothing but a valid 169 // int64 literal optionally surrounded by whitespace. 170 171 return *end == '\0'; 172} 173 174// Trim both leading and trailing whitespace from the given string. 175static void TrimString(String8 *s) { 176 size_t num_bytes = s->bytes(); 177 const char *data = s->string(); 178 179 size_t leading_space = 0; 180 while (leading_space < num_bytes && isspace(data[leading_space])) { 181 ++leading_space; 182 } 183 184 size_t i = num_bytes; 185 while (i > leading_space && isspace(data[i - 1])) { 186 --i; 187 } 188 189 s->setTo(String8(&data[leading_space], i - leading_space)); 190} 191 192status_t StagefrightRecorder::setParamAudioSamplingRate(int32_t sampleRate) { 193 LOGV("setParamAudioSamplingRate: %d", sampleRate); 194 mSampleRate = sampleRate; 195 return OK; 196} 197 198status_t StagefrightRecorder::setParamAudioNumberOfChannels(int32_t channels) { 199 LOGV("setParamAudioNumberOfChannels: %d", channels); 200 mAudioChannels = channels; 201 return OK; 202} 203 204status_t StagefrightRecorder::setParamAudioEncodingBitRate(int32_t bitRate) { 205 LOGV("setParamAudioEncodingBitRate: %d", bitRate); 206 mAudioBitRate = bitRate; 207 return OK; 208} 209 210status_t StagefrightRecorder::setParamVideoEncodingBitRate(int32_t bitRate) { 211 LOGV("setParamVideoEncodingBitRate: %d", bitRate); 212 mVideoBitRate = bitRate; 213 return OK; 214} 215 216status_t StagefrightRecorder::setMaxDurationOrFileSize(int32_t limit, bool limit_is_duration) { 217 LOGV("setMaxDurationOrFileSize: limit (%d) for %s", 218 limit, limit_is_duration?"duration":"size"); 219 return OK; 220} 221 222status_t StagefrightRecorder::setParameter( 223 const String8 &key, const String8 &value) { 224 LOGV("setParameter: key (%s) => value (%s)", key.string(), value.string()); 225 if (key == "max-duration") { 226 int32_t max_duration_ms; 227 if (safe_strtoi64(value.string(), &max_duration_ms)) { 228 return setMaxDurationOrFileSize( 229 max_duration_ms, true /* limit_is_duration */); 230 } 231 } else if (key == "max-filesize") { 232 int32_t max_filesize_bytes; 233 if (safe_strtoi64(value.string(), &max_filesize_bytes)) { 234 return setMaxDurationOrFileSize( 235 max_filesize_bytes, false /* limit is filesize */); 236 } 237 } else if (key == "audio-param-sampling-rate") { 238 int32_t sampling_rate; 239 if (safe_strtoi64(value.string(), &sampling_rate)) { 240 return setParamAudioSamplingRate(sampling_rate); 241 } 242 } else if (key == "audio-param-number-of-channels") { 243 int32_t number_of_channels; 244 if (safe_strtoi64(value.string(), &number_of_channels)) { 245 return setParamAudioNumberOfChannels(number_of_channels); 246 } 247 } else if (key == "audio-param-encoding-bitrate") { 248 int32_t audio_bitrate; 249 if (safe_strtoi64(value.string(), &audio_bitrate)) { 250 return setParamAudioEncodingBitRate(audio_bitrate); 251 } 252 } else if (key == "video-param-encoding-bitrate") { 253 int32_t video_bitrate; 254 if (safe_strtoi64(value.string(), &video_bitrate)) { 255 return setParamVideoEncodingBitRate(video_bitrate); 256 } 257 } else { 258 LOGE("setParameter: failed to find key %s", key.string()); 259 return BAD_VALUE; 260 } 261 return OK; 262} 263 264status_t StagefrightRecorder::setParameters(const String8 ¶ms) { 265 LOGV("setParameters: %s", params.string()); 266 const char *cparams = params.string(); 267 const char *key_start = cparams; 268 for (;;) { 269 const char *equal_pos = strchr(key_start, '='); 270 if (equal_pos == NULL) { 271 LOGE("Parameters %s miss a value", cparams); 272 return BAD_VALUE; 273 } 274 String8 key(key_start, equal_pos - key_start); 275 TrimString(&key); 276 if (key.length() == 0) { 277 LOGE("Parameters %s contains an empty key", cparams); 278 return BAD_VALUE; 279 } 280 const char *value_start = equal_pos + 1; 281 const char *semicolon_pos = strchr(value_start, ';'); 282 String8 value; 283 if (semicolon_pos == NULL) { 284 value.setTo(value_start); 285 } else { 286 value.setTo(value_start, semicolon_pos - value_start); 287 } 288 if (setParameter(key, value) != OK) { 289 return BAD_VALUE; 290 } 291 if (semicolon_pos == NULL) { 292 break; // Reaches the end 293 } 294 key_start = semicolon_pos + 1; 295 } 296 return OK; 297} 298 299status_t StagefrightRecorder::setListener(const sp<IMediaPlayerClient> &listener) { 300 mListener = listener; 301 302 return OK; 303} 304 305status_t StagefrightRecorder::prepare() { 306 return OK; 307} 308 309status_t StagefrightRecorder::start() { 310 if (mWriter != NULL) { 311 return UNKNOWN_ERROR; 312 } 313 314 switch (mOutputFormat) { 315 case OUTPUT_FORMAT_DEFAULT: 316 case OUTPUT_FORMAT_THREE_GPP: 317 case OUTPUT_FORMAT_MPEG_4: 318 return startMPEG4Recording(); 319 320 case OUTPUT_FORMAT_AMR_NB: 321 case OUTPUT_FORMAT_AMR_WB: 322 return startAMRRecording(); 323 324 default: 325 return UNKNOWN_ERROR; 326 } 327} 328 329sp<MediaSource> StagefrightRecorder::createAudioSource() { 330 sp<AudioSource> audioSource = 331 new AudioSource( 332 mAudioSource, 333 mSampleRate, 334 AudioSystem::CHANNEL_IN_MONO); 335 336 status_t err = audioSource->initCheck(); 337 338 if (err != OK) { 339 LOGE("audio source is not initialized"); 340 return NULL; 341 } 342 343 sp<MetaData> encMeta = new MetaData; 344 const char *mime; 345 switch (mAudioEncoder) { 346 case AUDIO_ENCODER_AMR_NB: 347 case AUDIO_ENCODER_DEFAULT: 348 mime = MEDIA_MIMETYPE_AUDIO_AMR_NB; 349 break; 350 case AUDIO_ENCODER_AMR_WB: 351 mime = MEDIA_MIMETYPE_AUDIO_AMR_WB; 352 break; 353 case AUDIO_ENCODER_AAC: 354 mime = MEDIA_MIMETYPE_AUDIO_AAC; 355 break; 356 default: 357 LOGE("Unknown audio encoder: %d", mAudioEncoder); 358 return NULL; 359 } 360 encMeta->setCString(kKeyMIMEType, mime); 361 362 int32_t maxInputSize; 363 CHECK(audioSource->getFormat()->findInt32( 364 kKeyMaxInputSize, &maxInputSize)); 365 366 encMeta->setInt32(kKeyMaxInputSize, maxInputSize); 367 encMeta->setInt32(kKeyChannelCount, mAudioChannels); 368 encMeta->setInt32(kKeySampleRate, mSampleRate); 369 370 OMXClient client; 371 CHECK_EQ(client.connect(), OK); 372 373 sp<MediaSource> audioEncoder = 374 OMXCodec::Create(client.interface(), encMeta, 375 true /* createEncoder */, audioSource); 376 377 return audioEncoder; 378} 379 380status_t StagefrightRecorder::startAMRRecording() { 381 if (mAudioSource == AUDIO_SOURCE_LIST_END 382 || mVideoSource != VIDEO_SOURCE_LIST_END) { 383 return UNKNOWN_ERROR; 384 } 385 386 if (mOutputFormat == OUTPUT_FORMAT_AMR_NB 387 && mAudioEncoder != AUDIO_ENCODER_DEFAULT 388 && mAudioEncoder != AUDIO_ENCODER_AMR_NB) { 389 return UNKNOWN_ERROR; 390 } else if (mOutputFormat == OUTPUT_FORMAT_AMR_WB 391 && mAudioEncoder != AUDIO_ENCODER_AMR_WB) { 392 return UNKNOWN_ERROR; 393 } 394 395 sp<MediaSource> audioEncoder = createAudioSource(); 396 397 if (audioEncoder == NULL) { 398 return UNKNOWN_ERROR; 399 } 400 401 CHECK(mOutputFd >= 0); 402 mWriter = new AMRWriter(dup(mOutputFd)); 403 mWriter->addSource(audioEncoder); 404 mWriter->start(); 405 406 return OK; 407} 408 409status_t StagefrightRecorder::startMPEG4Recording() { 410 mWriter = new MPEG4Writer(dup(mOutputFd)); 411 412 // Add audio source first if it exists 413 if (mAudioSource != AUDIO_SOURCE_LIST_END) { 414 sp<MediaSource> audioEncoder; 415 switch(mAudioEncoder) { 416 case AUDIO_ENCODER_AMR_NB: 417 case AUDIO_ENCODER_AMR_WB: 418 case AUDIO_ENCODER_AAC: 419 audioEncoder = createAudioSource(); 420 break; 421 default: 422 LOGE("Unsupported audio encoder: %d", mAudioEncoder); 423 return UNKNOWN_ERROR; 424 } 425 426 if (audioEncoder == NULL) { 427 return UNKNOWN_ERROR; 428 } 429 430 mWriter->addSource(audioEncoder); 431 } 432 if (mVideoSource == VIDEO_SOURCE_DEFAULT 433 || mVideoSource == VIDEO_SOURCE_CAMERA) { 434 CHECK(mCamera != NULL); 435 436 sp<CameraSource> cameraSource = 437 CameraSource::CreateFromCamera(mCamera); 438 439 CHECK(cameraSource != NULL); 440 441 cameraSource->setPreviewSurface(mPreviewSurface); 442 443 sp<MetaData> enc_meta = new MetaData; 444 switch (mVideoEncoder) { 445 case VIDEO_ENCODER_H263: 446 enc_meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_H263); 447 break; 448 449 case VIDEO_ENCODER_MPEG_4_SP: 450 enc_meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_MPEG4); 451 break; 452 453 case VIDEO_ENCODER_H264: 454 enc_meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_AVC); 455 break; 456 457 default: 458 CHECK(!"Should not be here, unsupported video encoding."); 459 break; 460 } 461 462 sp<MetaData> meta = cameraSource->getFormat(); 463 464 int32_t width, height; 465 CHECK(meta->findInt32(kKeyWidth, &width)); 466 CHECK(meta->findInt32(kKeyHeight, &height)); 467 468 enc_meta->setInt32(kKeyWidth, width); 469 enc_meta->setInt32(kKeyHeight, height); 470 471 OMXClient client; 472 CHECK_EQ(client.connect(), OK); 473 474 sp<MediaSource> encoder = 475 OMXCodec::Create( 476 client.interface(), enc_meta, 477 true /* createEncoder */, cameraSource); 478 479 CHECK(mOutputFd >= 0); 480 mWriter->addSource(encoder); 481 } 482 483 mWriter->start(); 484 return OK; 485} 486 487status_t StagefrightRecorder::stop() { 488 if (mWriter == NULL) { 489 return UNKNOWN_ERROR; 490 } 491 492 mWriter->stop(); 493 mWriter = NULL; 494 495 return OK; 496} 497 498status_t StagefrightRecorder::close() { 499 stop(); 500 501 if (mCamera != 0) { 502 if ((mFlags & FLAGS_HOT_CAMERA) == 0) { 503 LOGV("Camera was cold when we started, stopping preview"); 504 mCamera->stopPreview(); 505 } 506 if (mFlags & FLAGS_SET_CAMERA) { 507 LOGV("Unlocking camera"); 508 mCamera->unlock(); 509 } 510 mFlags = 0; 511 } 512 return OK; 513} 514 515status_t StagefrightRecorder::reset() { 516 stop(); 517 518 // No audio or video source by default 519 mAudioSource = AUDIO_SOURCE_LIST_END; 520 mVideoSource = VIDEO_SOURCE_LIST_END; 521 522 // Default parameters 523 mOutputFormat = OUTPUT_FORMAT_THREE_GPP; 524 mAudioEncoder = AUDIO_ENCODER_AMR_NB; 525 mVideoEncoder = VIDEO_ENCODER_H263; 526 mVideoWidth = 176; 527 mVideoHeight = 144; 528 mFrameRate = 20; 529 mVideoBitRate = 192000; 530 mSampleRate = 8000; 531 mAudioChannels = 1; 532 mAudioBitRate = 12200; 533 534 mOutputFd = -1; 535 mFlags = 0; 536 537 return OK; 538} 539 540status_t StagefrightRecorder::getMaxAmplitude(int *max) { 541 *max = 0; 542 543 return OK; 544} 545 546} // namespace android 547