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 &params) {
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