1ea6a38c63b9e9aeb45aa22587c069bd3c5d83df8Andreas Huber/* 2ea6a38c63b9e9aeb45aa22587c069bd3c5d83df8Andreas Huber * Copyright (C) 2009 The Android Open Source Project 3ea6a38c63b9e9aeb45aa22587c069bd3c5d83df8Andreas Huber * 4ea6a38c63b9e9aeb45aa22587c069bd3c5d83df8Andreas Huber * Licensed under the Apache License, Version 2.0 (the "License"); 5ea6a38c63b9e9aeb45aa22587c069bd3c5d83df8Andreas Huber * you may not use this file except in compliance with the License. 6ea6a38c63b9e9aeb45aa22587c069bd3c5d83df8Andreas Huber * You may obtain a copy of the License at 7ea6a38c63b9e9aeb45aa22587c069bd3c5d83df8Andreas Huber * 8ea6a38c63b9e9aeb45aa22587c069bd3c5d83df8Andreas Huber * http://www.apache.org/licenses/LICENSE-2.0 9ea6a38c63b9e9aeb45aa22587c069bd3c5d83df8Andreas Huber * 10ea6a38c63b9e9aeb45aa22587c069bd3c5d83df8Andreas Huber * Unless required by applicable law or agreed to in writing, software 11ea6a38c63b9e9aeb45aa22587c069bd3c5d83df8Andreas Huber * distributed under the License is distributed on an "AS IS" BASIS, 12ea6a38c63b9e9aeb45aa22587c069bd3c5d83df8Andreas Huber * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13ea6a38c63b9e9aeb45aa22587c069bd3c5d83df8Andreas Huber * See the License for the specific language governing permissions and 14ea6a38c63b9e9aeb45aa22587c069bd3c5d83df8Andreas Huber * limitations under the License. 15ea6a38c63b9e9aeb45aa22587c069bd3c5d83df8Andreas Huber */ 16ea6a38c63b9e9aeb45aa22587c069bd3c5d83df8Andreas Huber 17ea6a38c63b9e9aeb45aa22587c069bd3c5d83df8Andreas Huber//#define LOG_NDEBUG 0 18ea6a38c63b9e9aeb45aa22587c069bd3c5d83df8Andreas Huber#define LOG_TAG "StagefrightRecorder" 19ea6a38c63b9e9aeb45aa22587c069bd3c5d83df8Andreas Huber#include <utils/Log.h> 20ea6a38c63b9e9aeb45aa22587c069bd3c5d83df8Andreas Huber 21ea6a38c63b9e9aeb45aa22587c069bd3c5d83df8Andreas Huber#include "StagefrightRecorder.h" 22ea6a38c63b9e9aeb45aa22587c069bd3c5d83df8Andreas Huber 23996dddff64f90d8469e24107c44bfd618cf0c2ddAndreas Huber#include <media/stagefright/AudioSource.h> 24996dddff64f90d8469e24107c44bfd618cf0c2ddAndreas Huber#include <media/stagefright/AMRWriter.h> 25ea6a38c63b9e9aeb45aa22587c069bd3c5d83df8Andreas Huber#include <media/stagefright/CameraSource.h> 26ea6a38c63b9e9aeb45aa22587c069bd3c5d83df8Andreas Huber#include <media/stagefright/MPEG4Writer.h> 27ea6a38c63b9e9aeb45aa22587c069bd3c5d83df8Andreas Huber#include <media/stagefright/MediaDebug.h> 28ea6a38c63b9e9aeb45aa22587c069bd3c5d83df8Andreas Huber#include <media/stagefright/MediaDefs.h> 29ea6a38c63b9e9aeb45aa22587c069bd3c5d83df8Andreas Huber#include <media/stagefright/MetaData.h> 30ea6a38c63b9e9aeb45aa22587c069bd3c5d83df8Andreas Huber#include <media/stagefright/OMXClient.h> 31ea6a38c63b9e9aeb45aa22587c069bd3c5d83df8Andreas Huber#include <media/stagefright/OMXCodec.h> 32000479f9e325b4e426a67033abd92d47da412725Mathias Agopian#include <camera/ICamera.h> 33000479f9e325b4e426a67033abd92d47da412725Mathias Agopian#include <surfaceflinger/ISurface.h> 34ea6a38c63b9e9aeb45aa22587c069bd3c5d83df8Andreas Huber#include <utils/Errors.h> 35ea6a38c63b9e9aeb45aa22587c069bd3c5d83df8Andreas Huber 36ea6a38c63b9e9aeb45aa22587c069bd3c5d83df8Andreas Hubernamespace android { 37ea6a38c63b9e9aeb45aa22587c069bd3c5d83df8Andreas Huber 38ea6a38c63b9e9aeb45aa22587c069bd3c5d83df8Andreas HuberStagefrightRecorder::StagefrightRecorder() { 39ea6a38c63b9e9aeb45aa22587c069bd3c5d83df8Andreas Huber reset(); 40ea6a38c63b9e9aeb45aa22587c069bd3c5d83df8Andreas Huber} 41ea6a38c63b9e9aeb45aa22587c069bd3c5d83df8Andreas Huber 42ea6a38c63b9e9aeb45aa22587c069bd3c5d83df8Andreas HuberStagefrightRecorder::~StagefrightRecorder() { 43ea6a38c63b9e9aeb45aa22587c069bd3c5d83df8Andreas Huber stop(); 44ea6a38c63b9e9aeb45aa22587c069bd3c5d83df8Andreas Huber 45ea6a38c63b9e9aeb45aa22587c069bd3c5d83df8Andreas Huber if (mOutputFd >= 0) { 46ea6a38c63b9e9aeb45aa22587c069bd3c5d83df8Andreas Huber ::close(mOutputFd); 47ea6a38c63b9e9aeb45aa22587c069bd3c5d83df8Andreas Huber mOutputFd = -1; 48ea6a38c63b9e9aeb45aa22587c069bd3c5d83df8Andreas Huber } 49ea6a38c63b9e9aeb45aa22587c069bd3c5d83df8Andreas Huber} 50ea6a38c63b9e9aeb45aa22587c069bd3c5d83df8Andreas Huber 51ea6a38c63b9e9aeb45aa22587c069bd3c5d83df8Andreas Huberstatus_t StagefrightRecorder::init() { 52ea6a38c63b9e9aeb45aa22587c069bd3c5d83df8Andreas Huber return OK; 53ea6a38c63b9e9aeb45aa22587c069bd3c5d83df8Andreas Huber} 54ea6a38c63b9e9aeb45aa22587c069bd3c5d83df8Andreas Huber 55ea6a38c63b9e9aeb45aa22587c069bd3c5d83df8Andreas Huberstatus_t StagefrightRecorder::setAudioSource(audio_source as) { 56ea6a38c63b9e9aeb45aa22587c069bd3c5d83df8Andreas Huber mAudioSource = as; 57ea6a38c63b9e9aeb45aa22587c069bd3c5d83df8Andreas Huber 58ea6a38c63b9e9aeb45aa22587c069bd3c5d83df8Andreas Huber return OK; 59ea6a38c63b9e9aeb45aa22587c069bd3c5d83df8Andreas Huber} 60ea6a38c63b9e9aeb45aa22587c069bd3c5d83df8Andreas Huber 61ea6a38c63b9e9aeb45aa22587c069bd3c5d83df8Andreas Huberstatus_t StagefrightRecorder::setVideoSource(video_source vs) { 62ea6a38c63b9e9aeb45aa22587c069bd3c5d83df8Andreas Huber mVideoSource = vs; 63ea6a38c63b9e9aeb45aa22587c069bd3c5d83df8Andreas Huber 64ea6a38c63b9e9aeb45aa22587c069bd3c5d83df8Andreas Huber return OK; 65ea6a38c63b9e9aeb45aa22587c069bd3c5d83df8Andreas Huber} 66ea6a38c63b9e9aeb45aa22587c069bd3c5d83df8Andreas Huber 67ea6a38c63b9e9aeb45aa22587c069bd3c5d83df8Andreas Huberstatus_t StagefrightRecorder::setOutputFormat(output_format of) { 68ea6a38c63b9e9aeb45aa22587c069bd3c5d83df8Andreas Huber mOutputFormat = of; 69ea6a38c63b9e9aeb45aa22587c069bd3c5d83df8Andreas Huber 70ea6a38c63b9e9aeb45aa22587c069bd3c5d83df8Andreas Huber return OK; 71ea6a38c63b9e9aeb45aa22587c069bd3c5d83df8Andreas Huber} 72ea6a38c63b9e9aeb45aa22587c069bd3c5d83df8Andreas Huber 73ea6a38c63b9e9aeb45aa22587c069bd3c5d83df8Andreas Huberstatus_t StagefrightRecorder::setAudioEncoder(audio_encoder ae) { 74ea6a38c63b9e9aeb45aa22587c069bd3c5d83df8Andreas Huber mAudioEncoder = ae; 75ea6a38c63b9e9aeb45aa22587c069bd3c5d83df8Andreas Huber 76ea6a38c63b9e9aeb45aa22587c069bd3c5d83df8Andreas Huber return OK; 77ea6a38c63b9e9aeb45aa22587c069bd3c5d83df8Andreas Huber} 78ea6a38c63b9e9aeb45aa22587c069bd3c5d83df8Andreas Huber 79ea6a38c63b9e9aeb45aa22587c069bd3c5d83df8Andreas Huberstatus_t StagefrightRecorder::setVideoEncoder(video_encoder ve) { 80ea6a38c63b9e9aeb45aa22587c069bd3c5d83df8Andreas Huber mVideoEncoder = ve; 81ea6a38c63b9e9aeb45aa22587c069bd3c5d83df8Andreas Huber 82ea6a38c63b9e9aeb45aa22587c069bd3c5d83df8Andreas Huber return OK; 83ea6a38c63b9e9aeb45aa22587c069bd3c5d83df8Andreas Huber} 84ea6a38c63b9e9aeb45aa22587c069bd3c5d83df8Andreas Huber 85ea6a38c63b9e9aeb45aa22587c069bd3c5d83df8Andreas Huberstatus_t StagefrightRecorder::setVideoSize(int width, int height) { 86ea6a38c63b9e9aeb45aa22587c069bd3c5d83df8Andreas Huber mVideoWidth = width; 87ea6a38c63b9e9aeb45aa22587c069bd3c5d83df8Andreas Huber mVideoHeight = height; 88ea6a38c63b9e9aeb45aa22587c069bd3c5d83df8Andreas Huber 89ea6a38c63b9e9aeb45aa22587c069bd3c5d83df8Andreas Huber return OK; 90ea6a38c63b9e9aeb45aa22587c069bd3c5d83df8Andreas Huber} 91ea6a38c63b9e9aeb45aa22587c069bd3c5d83df8Andreas Huber 92ea6a38c63b9e9aeb45aa22587c069bd3c5d83df8Andreas Huberstatus_t StagefrightRecorder::setVideoFrameRate(int frames_per_second) { 93ea6a38c63b9e9aeb45aa22587c069bd3c5d83df8Andreas Huber mFrameRate = frames_per_second; 94ea6a38c63b9e9aeb45aa22587c069bd3c5d83df8Andreas Huber 95ea6a38c63b9e9aeb45aa22587c069bd3c5d83df8Andreas Huber return OK; 96ea6a38c63b9e9aeb45aa22587c069bd3c5d83df8Andreas Huber} 97ea6a38c63b9e9aeb45aa22587c069bd3c5d83df8Andreas Huber 98ea6a38c63b9e9aeb45aa22587c069bd3c5d83df8Andreas Huberstatus_t StagefrightRecorder::setCamera(const sp<ICamera> &camera) { 99ea6a38c63b9e9aeb45aa22587c069bd3c5d83df8Andreas Huber mCamera = camera; 100ea6a38c63b9e9aeb45aa22587c069bd3c5d83df8Andreas Huber 101ea6a38c63b9e9aeb45aa22587c069bd3c5d83df8Andreas Huber return OK; 102ea6a38c63b9e9aeb45aa22587c069bd3c5d83df8Andreas Huber} 103ea6a38c63b9e9aeb45aa22587c069bd3c5d83df8Andreas Huber 104ea6a38c63b9e9aeb45aa22587c069bd3c5d83df8Andreas Huberstatus_t StagefrightRecorder::setPreviewSurface(const sp<ISurface> &surface) { 105ea6a38c63b9e9aeb45aa22587c069bd3c5d83df8Andreas Huber mPreviewSurface = surface; 106ea6a38c63b9e9aeb45aa22587c069bd3c5d83df8Andreas Huber 107ea6a38c63b9e9aeb45aa22587c069bd3c5d83df8Andreas Huber return OK; 108ea6a38c63b9e9aeb45aa22587c069bd3c5d83df8Andreas Huber} 109ea6a38c63b9e9aeb45aa22587c069bd3c5d83df8Andreas Huber 110ea6a38c63b9e9aeb45aa22587c069bd3c5d83df8Andreas Huberstatus_t StagefrightRecorder::setOutputFile(const char *path) { 111ea6a38c63b9e9aeb45aa22587c069bd3c5d83df8Andreas Huber // We don't actually support this at all, as the media_server process 112ea6a38c63b9e9aeb45aa22587c069bd3c5d83df8Andreas Huber // no longer has permissions to create files. 113ea6a38c63b9e9aeb45aa22587c069bd3c5d83df8Andreas Huber 114ea6a38c63b9e9aeb45aa22587c069bd3c5d83df8Andreas Huber return UNKNOWN_ERROR; 115ea6a38c63b9e9aeb45aa22587c069bd3c5d83df8Andreas Huber} 116ea6a38c63b9e9aeb45aa22587c069bd3c5d83df8Andreas Huber 117ea6a38c63b9e9aeb45aa22587c069bd3c5d83df8Andreas Huberstatus_t StagefrightRecorder::setOutputFile(int fd, int64_t offset, int64_t length) { 118ea6a38c63b9e9aeb45aa22587c069bd3c5d83df8Andreas Huber // These don't make any sense, do they? 119ea6a38c63b9e9aeb45aa22587c069bd3c5d83df8Andreas Huber CHECK_EQ(offset, 0); 120ea6a38c63b9e9aeb45aa22587c069bd3c5d83df8Andreas Huber CHECK_EQ(length, 0); 121ea6a38c63b9e9aeb45aa22587c069bd3c5d83df8Andreas Huber 122ea6a38c63b9e9aeb45aa22587c069bd3c5d83df8Andreas Huber if (mOutputFd >= 0) { 123ea6a38c63b9e9aeb45aa22587c069bd3c5d83df8Andreas Huber ::close(mOutputFd); 124ea6a38c63b9e9aeb45aa22587c069bd3c5d83df8Andreas Huber } 125ea6a38c63b9e9aeb45aa22587c069bd3c5d83df8Andreas Huber mOutputFd = dup(fd); 126ea6a38c63b9e9aeb45aa22587c069bd3c5d83df8Andreas Huber 127ea6a38c63b9e9aeb45aa22587c069bd3c5d83df8Andreas Huber return OK; 128ea6a38c63b9e9aeb45aa22587c069bd3c5d83df8Andreas Huber} 129ea6a38c63b9e9aeb45aa22587c069bd3c5d83df8Andreas Huber 130ea6a38c63b9e9aeb45aa22587c069bd3c5d83df8Andreas Huberstatus_t StagefrightRecorder::setParameters(const String8 ¶ms) { 131ea6a38c63b9e9aeb45aa22587c069bd3c5d83df8Andreas Huber mParams = params; 132ea6a38c63b9e9aeb45aa22587c069bd3c5d83df8Andreas Huber 133ea6a38c63b9e9aeb45aa22587c069bd3c5d83df8Andreas Huber return OK; 134ea6a38c63b9e9aeb45aa22587c069bd3c5d83df8Andreas Huber} 135ea6a38c63b9e9aeb45aa22587c069bd3c5d83df8Andreas Huber 136ea6a38c63b9e9aeb45aa22587c069bd3c5d83df8Andreas Huberstatus_t StagefrightRecorder::setListener(const sp<IMediaPlayerClient> &listener) { 137ea6a38c63b9e9aeb45aa22587c069bd3c5d83df8Andreas Huber mListener = listener; 138ea6a38c63b9e9aeb45aa22587c069bd3c5d83df8Andreas Huber 139ea6a38c63b9e9aeb45aa22587c069bd3c5d83df8Andreas Huber return OK; 140ea6a38c63b9e9aeb45aa22587c069bd3c5d83df8Andreas Huber} 141ea6a38c63b9e9aeb45aa22587c069bd3c5d83df8Andreas Huber 142ea6a38c63b9e9aeb45aa22587c069bd3c5d83df8Andreas Huberstatus_t StagefrightRecorder::prepare() { 143ea6a38c63b9e9aeb45aa22587c069bd3c5d83df8Andreas Huber return OK; 144ea6a38c63b9e9aeb45aa22587c069bd3c5d83df8Andreas Huber} 145ea6a38c63b9e9aeb45aa22587c069bd3c5d83df8Andreas Huber 146ea6a38c63b9e9aeb45aa22587c069bd3c5d83df8Andreas Huberstatus_t StagefrightRecorder::start() { 147ea6a38c63b9e9aeb45aa22587c069bd3c5d83df8Andreas Huber if (mWriter != NULL) { 148ea6a38c63b9e9aeb45aa22587c069bd3c5d83df8Andreas Huber return UNKNOWN_ERROR; 149ea6a38c63b9e9aeb45aa22587c069bd3c5d83df8Andreas Huber } 150ea6a38c63b9e9aeb45aa22587c069bd3c5d83df8Andreas Huber 151996dddff64f90d8469e24107c44bfd618cf0c2ddAndreas Huber switch (mOutputFormat) { 152996dddff64f90d8469e24107c44bfd618cf0c2ddAndreas Huber case OUTPUT_FORMAT_DEFAULT: 153996dddff64f90d8469e24107c44bfd618cf0c2ddAndreas Huber case OUTPUT_FORMAT_THREE_GPP: 154996dddff64f90d8469e24107c44bfd618cf0c2ddAndreas Huber case OUTPUT_FORMAT_MPEG_4: 155996dddff64f90d8469e24107c44bfd618cf0c2ddAndreas Huber return startMPEG4Recording(); 156996dddff64f90d8469e24107c44bfd618cf0c2ddAndreas Huber 157996dddff64f90d8469e24107c44bfd618cf0c2ddAndreas Huber case OUTPUT_FORMAT_AMR_NB: 158996dddff64f90d8469e24107c44bfd618cf0c2ddAndreas Huber case OUTPUT_FORMAT_AMR_WB: 159996dddff64f90d8469e24107c44bfd618cf0c2ddAndreas Huber return startAMRRecording(); 160996dddff64f90d8469e24107c44bfd618cf0c2ddAndreas Huber 161996dddff64f90d8469e24107c44bfd618cf0c2ddAndreas Huber default: 162996dddff64f90d8469e24107c44bfd618cf0c2ddAndreas Huber return UNKNOWN_ERROR; 163996dddff64f90d8469e24107c44bfd618cf0c2ddAndreas Huber } 164996dddff64f90d8469e24107c44bfd618cf0c2ddAndreas Huber} 165996dddff64f90d8469e24107c44bfd618cf0c2ddAndreas Huber 166996dddff64f90d8469e24107c44bfd618cf0c2ddAndreas Hubersp<MediaSource> StagefrightRecorder::createAMRAudioSource() { 167996dddff64f90d8469e24107c44bfd618cf0c2ddAndreas Huber uint32_t sampleRate = 168996dddff64f90d8469e24107c44bfd618cf0c2ddAndreas Huber mAudioEncoder == AUDIO_ENCODER_AMR_NB ? 8000 : 16000; 169996dddff64f90d8469e24107c44bfd618cf0c2ddAndreas Huber 170996dddff64f90d8469e24107c44bfd618cf0c2ddAndreas Huber sp<AudioSource> audioSource = 171996dddff64f90d8469e24107c44bfd618cf0c2ddAndreas Huber new AudioSource( 172996dddff64f90d8469e24107c44bfd618cf0c2ddAndreas Huber mAudioSource, 173996dddff64f90d8469e24107c44bfd618cf0c2ddAndreas Huber sampleRate, 174996dddff64f90d8469e24107c44bfd618cf0c2ddAndreas Huber AudioSystem::CHANNEL_IN_MONO); 175996dddff64f90d8469e24107c44bfd618cf0c2ddAndreas Huber 176996dddff64f90d8469e24107c44bfd618cf0c2ddAndreas Huber status_t err = audioSource->initCheck(); 177996dddff64f90d8469e24107c44bfd618cf0c2ddAndreas Huber 178996dddff64f90d8469e24107c44bfd618cf0c2ddAndreas Huber if (err != OK) { 179996dddff64f90d8469e24107c44bfd618cf0c2ddAndreas Huber return NULL; 180996dddff64f90d8469e24107c44bfd618cf0c2ddAndreas Huber } 181996dddff64f90d8469e24107c44bfd618cf0c2ddAndreas Huber 182996dddff64f90d8469e24107c44bfd618cf0c2ddAndreas Huber sp<MetaData> encMeta = new MetaData; 183996dddff64f90d8469e24107c44bfd618cf0c2ddAndreas Huber encMeta->setCString( 184996dddff64f90d8469e24107c44bfd618cf0c2ddAndreas Huber kKeyMIMEType, 185996dddff64f90d8469e24107c44bfd618cf0c2ddAndreas Huber mAudioEncoder == AUDIO_ENCODER_AMR_NB 186996dddff64f90d8469e24107c44bfd618cf0c2ddAndreas Huber ? MEDIA_MIMETYPE_AUDIO_AMR_NB : MEDIA_MIMETYPE_AUDIO_AMR_WB); 187996dddff64f90d8469e24107c44bfd618cf0c2ddAndreas Huber 188259b7c1c1bc40a4a47214944b8a0587c36e8c144Andreas Huber int32_t maxInputSize; 189259b7c1c1bc40a4a47214944b8a0587c36e8c144Andreas Huber CHECK(audioSource->getFormat()->findInt32( 190259b7c1c1bc40a4a47214944b8a0587c36e8c144Andreas Huber kKeyMaxInputSize, &maxInputSize)); 191259b7c1c1bc40a4a47214944b8a0587c36e8c144Andreas Huber 192259b7c1c1bc40a4a47214944b8a0587c36e8c144Andreas Huber encMeta->setInt32(kKeyMaxInputSize, maxInputSize); 193996dddff64f90d8469e24107c44bfd618cf0c2ddAndreas Huber encMeta->setInt32(kKeyChannelCount, 1); 194996dddff64f90d8469e24107c44bfd618cf0c2ddAndreas Huber encMeta->setInt32(kKeySampleRate, sampleRate); 195996dddff64f90d8469e24107c44bfd618cf0c2ddAndreas Huber 196996dddff64f90d8469e24107c44bfd618cf0c2ddAndreas Huber OMXClient client; 197996dddff64f90d8469e24107c44bfd618cf0c2ddAndreas Huber CHECK_EQ(client.connect(), OK); 198996dddff64f90d8469e24107c44bfd618cf0c2ddAndreas Huber 199996dddff64f90d8469e24107c44bfd618cf0c2ddAndreas Huber sp<MediaSource> audioEncoder = 200996dddff64f90d8469e24107c44bfd618cf0c2ddAndreas Huber OMXCodec::Create(client.interface(), encMeta, 201996dddff64f90d8469e24107c44bfd618cf0c2ddAndreas Huber true /* createEncoder */, audioSource); 202996dddff64f90d8469e24107c44bfd618cf0c2ddAndreas Huber 203996dddff64f90d8469e24107c44bfd618cf0c2ddAndreas Huber return audioEncoder; 204996dddff64f90d8469e24107c44bfd618cf0c2ddAndreas Huber} 205996dddff64f90d8469e24107c44bfd618cf0c2ddAndreas Huber 206996dddff64f90d8469e24107c44bfd618cf0c2ddAndreas Huberstatus_t StagefrightRecorder::startAMRRecording() { 207996dddff64f90d8469e24107c44bfd618cf0c2ddAndreas Huber if (mAudioSource == AUDIO_SOURCE_LIST_END 208996dddff64f90d8469e24107c44bfd618cf0c2ddAndreas Huber || mVideoSource != VIDEO_SOURCE_LIST_END) { 209996dddff64f90d8469e24107c44bfd618cf0c2ddAndreas Huber return UNKNOWN_ERROR; 210996dddff64f90d8469e24107c44bfd618cf0c2ddAndreas Huber } 211996dddff64f90d8469e24107c44bfd618cf0c2ddAndreas Huber 212996dddff64f90d8469e24107c44bfd618cf0c2ddAndreas Huber if (mOutputFormat == OUTPUT_FORMAT_AMR_NB 213996dddff64f90d8469e24107c44bfd618cf0c2ddAndreas Huber && mAudioEncoder != AUDIO_ENCODER_DEFAULT 214996dddff64f90d8469e24107c44bfd618cf0c2ddAndreas Huber && mAudioEncoder != AUDIO_ENCODER_AMR_NB) { 215996dddff64f90d8469e24107c44bfd618cf0c2ddAndreas Huber return UNKNOWN_ERROR; 216996dddff64f90d8469e24107c44bfd618cf0c2ddAndreas Huber } else if (mOutputFormat == OUTPUT_FORMAT_AMR_WB 217996dddff64f90d8469e24107c44bfd618cf0c2ddAndreas Huber && mAudioEncoder != AUDIO_ENCODER_AMR_WB) { 218996dddff64f90d8469e24107c44bfd618cf0c2ddAndreas Huber return UNKNOWN_ERROR; 219996dddff64f90d8469e24107c44bfd618cf0c2ddAndreas Huber } 220996dddff64f90d8469e24107c44bfd618cf0c2ddAndreas Huber 221996dddff64f90d8469e24107c44bfd618cf0c2ddAndreas Huber sp<MediaSource> audioEncoder = createAMRAudioSource(); 222996dddff64f90d8469e24107c44bfd618cf0c2ddAndreas Huber 223996dddff64f90d8469e24107c44bfd618cf0c2ddAndreas Huber if (audioEncoder == NULL) { 224996dddff64f90d8469e24107c44bfd618cf0c2ddAndreas Huber return UNKNOWN_ERROR; 225996dddff64f90d8469e24107c44bfd618cf0c2ddAndreas Huber } 226996dddff64f90d8469e24107c44bfd618cf0c2ddAndreas Huber 227996dddff64f90d8469e24107c44bfd618cf0c2ddAndreas Huber CHECK(mOutputFd >= 0); 228996dddff64f90d8469e24107c44bfd618cf0c2ddAndreas Huber mWriter = new AMRWriter(dup(mOutputFd)); 229996dddff64f90d8469e24107c44bfd618cf0c2ddAndreas Huber mWriter->addSource(audioEncoder); 230996dddff64f90d8469e24107c44bfd618cf0c2ddAndreas Huber mWriter->start(); 231996dddff64f90d8469e24107c44bfd618cf0c2ddAndreas Huber 232996dddff64f90d8469e24107c44bfd618cf0c2ddAndreas Huber return OK; 233996dddff64f90d8469e24107c44bfd618cf0c2ddAndreas Huber} 234996dddff64f90d8469e24107c44bfd618cf0c2ddAndreas Huber 235996dddff64f90d8469e24107c44bfd618cf0c2ddAndreas Huberstatus_t StagefrightRecorder::startMPEG4Recording() { 236996dddff64f90d8469e24107c44bfd618cf0c2ddAndreas Huber mWriter = new MPEG4Writer(dup(mOutputFd)); 237996dddff64f90d8469e24107c44bfd618cf0c2ddAndreas Huber 238996dddff64f90d8469e24107c44bfd618cf0c2ddAndreas Huber if (mVideoSource == VIDEO_SOURCE_DEFAULT 239996dddff64f90d8469e24107c44bfd618cf0c2ddAndreas Huber || mVideoSource == VIDEO_SOURCE_CAMERA) { 240ea6a38c63b9e9aeb45aa22587c069bd3c5d83df8Andreas Huber CHECK(mCamera != NULL); 241ea6a38c63b9e9aeb45aa22587c069bd3c5d83df8Andreas Huber 242ea6a38c63b9e9aeb45aa22587c069bd3c5d83df8Andreas Huber sp<CameraSource> cameraSource = 243ea6a38c63b9e9aeb45aa22587c069bd3c5d83df8Andreas Huber CameraSource::CreateFromICamera(mCamera); 244ea6a38c63b9e9aeb45aa22587c069bd3c5d83df8Andreas Huber 245ea6a38c63b9e9aeb45aa22587c069bd3c5d83df8Andreas Huber CHECK(cameraSource != NULL); 246ea6a38c63b9e9aeb45aa22587c069bd3c5d83df8Andreas Huber 247ea6a38c63b9e9aeb45aa22587c069bd3c5d83df8Andreas Huber cameraSource->setPreviewSurface(mPreviewSurface); 248ea6a38c63b9e9aeb45aa22587c069bd3c5d83df8Andreas Huber 249ea6a38c63b9e9aeb45aa22587c069bd3c5d83df8Andreas Huber sp<MetaData> enc_meta = new MetaData; 250ea6a38c63b9e9aeb45aa22587c069bd3c5d83df8Andreas Huber switch (mVideoEncoder) { 251ea6a38c63b9e9aeb45aa22587c069bd3c5d83df8Andreas Huber case VIDEO_ENCODER_H263: 252ea6a38c63b9e9aeb45aa22587c069bd3c5d83df8Andreas Huber enc_meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_H263); 253ea6a38c63b9e9aeb45aa22587c069bd3c5d83df8Andreas Huber break; 254ea6a38c63b9e9aeb45aa22587c069bd3c5d83df8Andreas Huber 255ea6a38c63b9e9aeb45aa22587c069bd3c5d83df8Andreas Huber case VIDEO_ENCODER_MPEG_4_SP: 256ea6a38c63b9e9aeb45aa22587c069bd3c5d83df8Andreas Huber enc_meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_MPEG4); 257ea6a38c63b9e9aeb45aa22587c069bd3c5d83df8Andreas Huber break; 258ea6a38c63b9e9aeb45aa22587c069bd3c5d83df8Andreas Huber 259ea6a38c63b9e9aeb45aa22587c069bd3c5d83df8Andreas Huber case VIDEO_ENCODER_H264: 260ea6a38c63b9e9aeb45aa22587c069bd3c5d83df8Andreas Huber enc_meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_AVC); 261ea6a38c63b9e9aeb45aa22587c069bd3c5d83df8Andreas Huber break; 262ea6a38c63b9e9aeb45aa22587c069bd3c5d83df8Andreas Huber 263ea6a38c63b9e9aeb45aa22587c069bd3c5d83df8Andreas Huber default: 264ea6a38c63b9e9aeb45aa22587c069bd3c5d83df8Andreas Huber CHECK(!"Should not be here, unsupported video encoding."); 265ea6a38c63b9e9aeb45aa22587c069bd3c5d83df8Andreas Huber break; 266ea6a38c63b9e9aeb45aa22587c069bd3c5d83df8Andreas Huber } 267ea6a38c63b9e9aeb45aa22587c069bd3c5d83df8Andreas Huber 268ea6a38c63b9e9aeb45aa22587c069bd3c5d83df8Andreas Huber sp<MetaData> meta = cameraSource->getFormat(); 269ea6a38c63b9e9aeb45aa22587c069bd3c5d83df8Andreas Huber 270ea6a38c63b9e9aeb45aa22587c069bd3c5d83df8Andreas Huber int32_t width, height; 271ea6a38c63b9e9aeb45aa22587c069bd3c5d83df8Andreas Huber CHECK(meta->findInt32(kKeyWidth, &width)); 272ea6a38c63b9e9aeb45aa22587c069bd3c5d83df8Andreas Huber CHECK(meta->findInt32(kKeyHeight, &height)); 273ea6a38c63b9e9aeb45aa22587c069bd3c5d83df8Andreas Huber 274ea6a38c63b9e9aeb45aa22587c069bd3c5d83df8Andreas Huber enc_meta->setInt32(kKeyWidth, width); 275ea6a38c63b9e9aeb45aa22587c069bd3c5d83df8Andreas Huber enc_meta->setInt32(kKeyHeight, height); 276ea6a38c63b9e9aeb45aa22587c069bd3c5d83df8Andreas Huber 277ea6a38c63b9e9aeb45aa22587c069bd3c5d83df8Andreas Huber OMXClient client; 278ea6a38c63b9e9aeb45aa22587c069bd3c5d83df8Andreas Huber CHECK_EQ(client.connect(), OK); 279ea6a38c63b9e9aeb45aa22587c069bd3c5d83df8Andreas Huber 280ea6a38c63b9e9aeb45aa22587c069bd3c5d83df8Andreas Huber sp<MediaSource> encoder = 281ea6a38c63b9e9aeb45aa22587c069bd3c5d83df8Andreas Huber OMXCodec::Create( 282ea6a38c63b9e9aeb45aa22587c069bd3c5d83df8Andreas Huber client.interface(), enc_meta, 283ea6a38c63b9e9aeb45aa22587c069bd3c5d83df8Andreas Huber true /* createEncoder */, cameraSource); 284ea6a38c63b9e9aeb45aa22587c069bd3c5d83df8Andreas Huber 285ea6a38c63b9e9aeb45aa22587c069bd3c5d83df8Andreas Huber CHECK(mOutputFd >= 0); 286ea6a38c63b9e9aeb45aa22587c069bd3c5d83df8Andreas Huber mWriter->addSource(encoder); 287ea6a38c63b9e9aeb45aa22587c069bd3c5d83df8Andreas Huber } 288ea6a38c63b9e9aeb45aa22587c069bd3c5d83df8Andreas Huber 289996dddff64f90d8469e24107c44bfd618cf0c2ddAndreas Huber if (mAudioSource != AUDIO_SOURCE_LIST_END) { 290996dddff64f90d8469e24107c44bfd618cf0c2ddAndreas Huber sp<MediaSource> audioEncoder = createAMRAudioSource(); 291996dddff64f90d8469e24107c44bfd618cf0c2ddAndreas Huber 292996dddff64f90d8469e24107c44bfd618cf0c2ddAndreas Huber if (audioEncoder == NULL) { 293996dddff64f90d8469e24107c44bfd618cf0c2ddAndreas Huber return UNKNOWN_ERROR; 294996dddff64f90d8469e24107c44bfd618cf0c2ddAndreas Huber } 295996dddff64f90d8469e24107c44bfd618cf0c2ddAndreas Huber 296996dddff64f90d8469e24107c44bfd618cf0c2ddAndreas Huber mWriter->addSource(audioEncoder); 297996dddff64f90d8469e24107c44bfd618cf0c2ddAndreas Huber } 298996dddff64f90d8469e24107c44bfd618cf0c2ddAndreas Huber 299996dddff64f90d8469e24107c44bfd618cf0c2ddAndreas Huber mWriter->start(); 300ea6a38c63b9e9aeb45aa22587c069bd3c5d83df8Andreas Huber return OK; 301ea6a38c63b9e9aeb45aa22587c069bd3c5d83df8Andreas Huber} 302ea6a38c63b9e9aeb45aa22587c069bd3c5d83df8Andreas Huber 303ea6a38c63b9e9aeb45aa22587c069bd3c5d83df8Andreas Huberstatus_t StagefrightRecorder::stop() { 304ea6a38c63b9e9aeb45aa22587c069bd3c5d83df8Andreas Huber if (mWriter == NULL) { 305ea6a38c63b9e9aeb45aa22587c069bd3c5d83df8Andreas Huber return UNKNOWN_ERROR; 306ea6a38c63b9e9aeb45aa22587c069bd3c5d83df8Andreas Huber } 307ea6a38c63b9e9aeb45aa22587c069bd3c5d83df8Andreas Huber 308ea6a38c63b9e9aeb45aa22587c069bd3c5d83df8Andreas Huber mWriter->stop(); 309ea6a38c63b9e9aeb45aa22587c069bd3c5d83df8Andreas Huber mWriter = NULL; 310ea6a38c63b9e9aeb45aa22587c069bd3c5d83df8Andreas Huber 311ea6a38c63b9e9aeb45aa22587c069bd3c5d83df8Andreas Huber return OK; 312ea6a38c63b9e9aeb45aa22587c069bd3c5d83df8Andreas Huber} 313ea6a38c63b9e9aeb45aa22587c069bd3c5d83df8Andreas Huber 314ea6a38c63b9e9aeb45aa22587c069bd3c5d83df8Andreas Huberstatus_t StagefrightRecorder::close() { 315ea6a38c63b9e9aeb45aa22587c069bd3c5d83df8Andreas Huber stop(); 316ea6a38c63b9e9aeb45aa22587c069bd3c5d83df8Andreas Huber 317ea6a38c63b9e9aeb45aa22587c069bd3c5d83df8Andreas Huber return OK; 318ea6a38c63b9e9aeb45aa22587c069bd3c5d83df8Andreas Huber} 319ea6a38c63b9e9aeb45aa22587c069bd3c5d83df8Andreas Huber 320ea6a38c63b9e9aeb45aa22587c069bd3c5d83df8Andreas Huberstatus_t StagefrightRecorder::reset() { 321ea6a38c63b9e9aeb45aa22587c069bd3c5d83df8Andreas Huber stop(); 322ea6a38c63b9e9aeb45aa22587c069bd3c5d83df8Andreas Huber 323ea6a38c63b9e9aeb45aa22587c069bd3c5d83df8Andreas Huber mAudioSource = AUDIO_SOURCE_LIST_END; 324ea6a38c63b9e9aeb45aa22587c069bd3c5d83df8Andreas Huber mVideoSource = VIDEO_SOURCE_LIST_END; 325ea6a38c63b9e9aeb45aa22587c069bd3c5d83df8Andreas Huber mOutputFormat = OUTPUT_FORMAT_LIST_END; 326ea6a38c63b9e9aeb45aa22587c069bd3c5d83df8Andreas Huber mAudioEncoder = AUDIO_ENCODER_LIST_END; 327ea6a38c63b9e9aeb45aa22587c069bd3c5d83df8Andreas Huber mVideoEncoder = VIDEO_ENCODER_LIST_END; 328ea6a38c63b9e9aeb45aa22587c069bd3c5d83df8Andreas Huber mVideoWidth = -1; 329ea6a38c63b9e9aeb45aa22587c069bd3c5d83df8Andreas Huber mVideoHeight = -1; 330ea6a38c63b9e9aeb45aa22587c069bd3c5d83df8Andreas Huber mFrameRate = -1; 331ea6a38c63b9e9aeb45aa22587c069bd3c5d83df8Andreas Huber mOutputFd = -1; 332ea6a38c63b9e9aeb45aa22587c069bd3c5d83df8Andreas Huber 333ea6a38c63b9e9aeb45aa22587c069bd3c5d83df8Andreas Huber return OK; 334ea6a38c63b9e9aeb45aa22587c069bd3c5d83df8Andreas Huber} 335ea6a38c63b9e9aeb45aa22587c069bd3c5d83df8Andreas Huber 336ea6a38c63b9e9aeb45aa22587c069bd3c5d83df8Andreas Huberstatus_t StagefrightRecorder::getMaxAmplitude(int *max) { 337996dddff64f90d8469e24107c44bfd618cf0c2ddAndreas Huber *max = 0; 338996dddff64f90d8469e24107c44bfd618cf0c2ddAndreas Huber 339996dddff64f90d8469e24107c44bfd618cf0c2ddAndreas Huber return OK; 340ea6a38c63b9e9aeb45aa22587c069bd3c5d83df8Andreas Huber} 341ea6a38c63b9e9aeb45aa22587c069bd3c5d83df8Andreas Huber 342ea6a38c63b9e9aeb45aa22587c069bd3c5d83df8Andreas Huber} // namespace android 343