StagefrightRecorder.cpp revision d329e21495eda9dbc531fdd0c26c77f1593ac3f4
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 <binder/IPCThreadState.h>
24#include <media/stagefright/AudioSource.h>
25#include <media/stagefright/AMRWriter.h>
26#include <media/stagefright/CameraSource.h>
27#include <media/stagefright/MPEG4Writer.h>
28#include <media/stagefright/MediaDebug.h>
29#include <media/stagefright/MediaDefs.h>
30#include <media/stagefright/MetaData.h>
31#include <media/stagefright/OMXClient.h>
32#include <media/stagefright/OMXCodec.h>
33#include <media/MediaProfiles.h>
34#include <camera/ICamera.h>
35#include <camera/Camera.h>
36#include <camera/CameraParameters.h>
37#include <surfaceflinger/ISurface.h>
38#include <utils/Errors.h>
39#include <sys/types.h>
40#include <unistd.h>
41#include <ctype.h>
42
43namespace android {
44
45StagefrightRecorder::StagefrightRecorder()
46    : mWriter(NULL),
47      mOutputFd(-1) {
48
49    LOGV("Constructor");
50    reset();
51}
52
53StagefrightRecorder::~StagefrightRecorder() {
54    LOGV("Destructor");
55    stop();
56
57    if (mOutputFd >= 0) {
58        ::close(mOutputFd);
59        mOutputFd = -1;
60    }
61}
62
63status_t StagefrightRecorder::init() {
64    LOGV("init");
65    return OK;
66}
67
68status_t StagefrightRecorder::setAudioSource(audio_source as) {
69    LOGV("setAudioSource: %d", as);
70    if (as < AUDIO_SOURCE_DEFAULT ||
71        as >= AUDIO_SOURCE_LIST_END) {
72        return BAD_VALUE;
73    }
74
75    if (as == AUDIO_SOURCE_DEFAULT) {
76        mAudioSource = AUDIO_SOURCE_MIC;
77    } else {
78        mAudioSource = as;
79    }
80
81    return OK;
82}
83
84status_t StagefrightRecorder::setVideoSource(video_source vs) {
85    LOGV("setVideoSource: %d", vs);
86    if (vs < VIDEO_SOURCE_DEFAULT ||
87        vs >= VIDEO_SOURCE_LIST_END) {
88        return BAD_VALUE;
89    }
90
91    if (vs == VIDEO_SOURCE_DEFAULT) {
92        mVideoSource = VIDEO_SOURCE_CAMERA;
93    } else {
94        mVideoSource = vs;
95    }
96
97    return OK;
98}
99
100status_t StagefrightRecorder::setOutputFormat(output_format of) {
101    LOGV("setOutputFormat: %d", of);
102    if (of < OUTPUT_FORMAT_DEFAULT ||
103        of >= OUTPUT_FORMAT_LIST_END) {
104        return BAD_VALUE;
105    }
106
107    if (of == OUTPUT_FORMAT_DEFAULT) {
108        mOutputFormat = OUTPUT_FORMAT_THREE_GPP;
109    } else {
110        mOutputFormat = of;
111    }
112
113    return OK;
114}
115
116status_t StagefrightRecorder::setAudioEncoder(audio_encoder ae) {
117    LOGV("setAudioEncoder: %d", ae);
118    if (ae < AUDIO_ENCODER_DEFAULT ||
119        ae >= AUDIO_ENCODER_LIST_END) {
120        return BAD_VALUE;
121    }
122
123    if (ae == AUDIO_ENCODER_DEFAULT) {
124        mAudioEncoder = AUDIO_ENCODER_AMR_NB;
125    } else {
126        mAudioEncoder = ae;
127    }
128
129    return OK;
130}
131
132status_t StagefrightRecorder::setVideoEncoder(video_encoder ve) {
133    LOGV("setVideoEncoder: %d", ve);
134    if (ve < VIDEO_ENCODER_DEFAULT ||
135        ve >= VIDEO_ENCODER_LIST_END) {
136        return BAD_VALUE;
137    }
138
139    if (ve == VIDEO_ENCODER_DEFAULT) {
140        mVideoEncoder = VIDEO_ENCODER_H263;
141    } else {
142        mVideoEncoder = ve;
143    }
144
145    return OK;
146}
147
148status_t StagefrightRecorder::setVideoSize(int width, int height) {
149    LOGV("setVideoSize: %dx%d", width, height);
150    if (width <= 0 || height <= 0) {
151        LOGE("Invalid video size: %dx%d", width, height);
152        return BAD_VALUE;
153    }
154
155    // Additional check on the dimension will be performed later
156    mVideoWidth = width;
157    mVideoHeight = height;
158
159    return OK;
160}
161
162status_t StagefrightRecorder::setVideoFrameRate(int frames_per_second) {
163    LOGV("setVideoFrameRate: %d", frames_per_second);
164    if (frames_per_second <= 0 || frames_per_second > 30) {
165        LOGE("Invalid video frame rate: %d", frames_per_second);
166        return BAD_VALUE;
167    }
168
169    // Additional check on the frame rate will be performed later
170    mFrameRate = frames_per_second;
171
172    return OK;
173}
174
175status_t StagefrightRecorder::setCamera(const sp<ICamera> &camera) {
176    LOGV("setCamera");
177    if (camera == 0) {
178        LOGE("camera is NULL");
179        return UNKNOWN_ERROR;
180    }
181
182    int64_t token = IPCThreadState::self()->clearCallingIdentity();
183    mFlags &= ~FLAGS_HOT_CAMERA;
184    mCamera = Camera::create(camera);
185    if (mCamera == 0) {
186        LOGE("Unable to connect to camera");
187        IPCThreadState::self()->restoreCallingIdentity(token);
188        return UNKNOWN_ERROR;
189    }
190
191    LOGV("Connected to camera");
192    if (mCamera->previewEnabled()) {
193        LOGV("camera is hot");
194        mFlags |= FLAGS_HOT_CAMERA;
195    }
196    IPCThreadState::self()->restoreCallingIdentity(token);
197
198    return OK;
199}
200
201status_t StagefrightRecorder::setPreviewSurface(const sp<ISurface> &surface) {
202    LOGV("setPreviewSurface: %p", surface.get());
203    mPreviewSurface = surface;
204
205    return OK;
206}
207
208status_t StagefrightRecorder::setOutputFile(const char *path) {
209    LOGE("setOutputFile(const char*) should not be called");
210    // We don't actually support this at all, as the media_server process
211    // no longer has permissions to create files.
212
213    return UNKNOWN_ERROR;
214}
215
216status_t StagefrightRecorder::setOutputFile(int fd, int64_t offset, int64_t length) {
217    LOGV("setOutputFile: %d, %lld, %lld", fd, offset, length);
218    // These don't make any sense, do they?
219    CHECK_EQ(offset, 0);
220    CHECK_EQ(length, 0);
221
222    if (mOutputFd >= 0) {
223        ::close(mOutputFd);
224    }
225    mOutputFd = dup(fd);
226
227    return OK;
228}
229
230// Attempt to parse an int64 literal optionally surrounded by whitespace,
231// returns true on success, false otherwise.
232static bool safe_strtoi64(const char *s, int64_t *val) {
233    char *end;
234    *val = strtoll(s, &end, 10);
235
236    if (end == s || errno == ERANGE) {
237        return false;
238    }
239
240    // Skip trailing whitespace
241    while (isspace(*end)) {
242        ++end;
243    }
244
245    // For a successful return, the string must contain nothing but a valid
246    // int64 literal optionally surrounded by whitespace.
247
248    return *end == '\0';
249}
250
251// Return true if the value is in [0, 0x007FFFFFFF]
252static bool safe_strtoi32(const char *s, int32_t *val) {
253    int64_t temp;
254    if (safe_strtoi64(s, &temp)) {
255        if (temp >= 0 && temp <= 0x007FFFFFFF) {
256            *val = static_cast<int32_t>(temp);
257            return true;
258        }
259    }
260    return false;
261}
262
263// Trim both leading and trailing whitespace from the given string.
264static void TrimString(String8 *s) {
265    size_t num_bytes = s->bytes();
266    const char *data = s->string();
267
268    size_t leading_space = 0;
269    while (leading_space < num_bytes && isspace(data[leading_space])) {
270        ++leading_space;
271    }
272
273    size_t i = num_bytes;
274    while (i > leading_space && isspace(data[i - 1])) {
275        --i;
276    }
277
278    s->setTo(String8(&data[leading_space], i - leading_space));
279}
280
281status_t StagefrightRecorder::setParamAudioSamplingRate(int32_t sampleRate) {
282    LOGV("setParamAudioSamplingRate: %d", sampleRate);
283    if (sampleRate <= 0) {
284        LOGE("Invalid audio sampling rate: %d", sampleRate);
285        return BAD_VALUE;
286    }
287
288    // Additional check on the sample rate will be performed later.
289    mSampleRate = sampleRate;
290    return OK;
291}
292
293status_t StagefrightRecorder::setParamAudioNumberOfChannels(int32_t channels) {
294    LOGV("setParamAudioNumberOfChannels: %d", channels);
295    if (channels <= 0 || channels >= 3) {
296        LOGE("Invalid number of audio channels: %d", channels);
297    }
298
299    // Additional check on the number of channels will be performed later.
300    mAudioChannels = channels;
301    return OK;
302}
303
304status_t StagefrightRecorder::setParamAudioEncodingBitRate(int32_t bitRate) {
305    LOGV("setParamAudioEncodingBitRate: %d", bitRate);
306    if (bitRate <= 0) {
307        LOGE("Invalid audio encoding bit rate: %d", bitRate);
308        return BAD_VALUE;
309    }
310
311    // The target bit rate may not be exactly the same as the requested.
312    // It depends on many factors, such as rate control, and the bit rate
313    // range that a specific encoder supports. The mismatch between the
314    // the target and requested bit rate will NOT be treated as an error.
315    mAudioBitRate = bitRate;
316    return OK;
317}
318
319status_t StagefrightRecorder::setParamVideoEncodingBitRate(int32_t bitRate) {
320    LOGV("setParamVideoEncodingBitRate: %d", bitRate);
321    if (bitRate <= 0) {
322        LOGE("Invalid video encoding bit rate: %d", bitRate);
323        return BAD_VALUE;
324    }
325
326    // The target bit rate may not be exactly the same as the requested.
327    // It depends on many factors, such as rate control, and the bit rate
328    // range that a specific encoder supports. The mismatch between the
329    // the target and requested bit rate will NOT be treated as an error.
330    mVideoBitRate = bitRate;
331    return OK;
332}
333
334status_t StagefrightRecorder::setParamMaxDurationOrFileSize(int64_t limit,
335        bool limit_is_duration) {
336    LOGV("setParamMaxDurationOrFileSize: limit (%lld) for %s",
337            limit, limit_is_duration?"duration":"size");
338    if (limit_is_duration) {  // limit is in ms
339        if (limit <= 1000) {  // XXX: 1 second
340            LOGE("Max file duration is too short: %lld us", limit);
341        }
342        mMaxFileDurationUs = limit * 1000LL;
343    } else {
344        if (limit <= 1024) {  // XXX: 1 kB
345            LOGE("Max file size is too small: %lld bytes", limit);
346        }
347        mMaxFileSizeBytes = limit;
348    }
349    return OK;
350}
351
352status_t StagefrightRecorder::setParamInterleaveDuration(int32_t durationUs) {
353    LOGV("setParamInterleaveDuration: %d", durationUs);
354    if (durationUs <= 500000) {           //  500 ms
355        // If interleave duration is too small, it is very inefficient to do
356        // interleaving since the metadata overhead will count for a significant
357        // portion of the saved contents
358        LOGE("Audio/video interleave duration is too small: %d us", durationUs);
359        return BAD_VALUE;
360    } else if (durationUs >= 10000000) {  // 10 seconds
361        // If interleaving duration is too large, it can cause the recording
362        // session to use too much memory since we have to save the output
363        // data before we write them out
364        LOGE("Audio/video interleave duration is too large: %d us", durationUs);
365        return BAD_VALUE;
366    }
367    mInterleaveDurationUs = durationUs;
368    return OK;
369}
370
371// If interval <  0, only the first frame is I frame, and rest are all P frames
372// If interval == 0, all frames are encoded as I frames. No P frames
373// If interval >  0, it is the time spacing between 2 neighboring I frames
374status_t StagefrightRecorder::setParamVideoIFramesInterval(int32_t interval) {
375    LOGV("setParamVideoIFramesInterval: %d seconds", interval);
376    mIFramesInterval = interval;
377    return OK;
378}
379
380status_t StagefrightRecorder::setParam64BitFileOffset(bool use64Bit) {
381    LOGV("setParam64BitFileOffset: %s",
382        use64Bit? "use 64 bit file offset": "use 32 bit file offset");
383    mUse64BitFileOffset = use64Bit;
384    return OK;
385}
386
387status_t StagefrightRecorder::setParamVideoCameraId(int32_t cameraId) {
388    LOGV("setParamVideoCameraId: %d", cameraId);
389    if (cameraId < 0) {
390        return BAD_VALUE;
391    }
392    mCameraId = cameraId;
393    return OK;
394}
395
396status_t StagefrightRecorder::setParamTrackFrameStatus(int32_t nFrames) {
397    LOGV("setParamTrackFrameStatus: %d", nFrames);
398    if (nFrames <= 0) {
399        return BAD_VALUE;
400    }
401    mTrackEveryNumberOfFrames = nFrames;
402    return OK;
403}
404
405status_t StagefrightRecorder::setParamTrackTimeStatus(int64_t timeDurationUs) {
406    LOGV("setParamTrackTimeStatus: %lld", timeDurationUs);
407    if (timeDurationUs < 20000) {  // Infeasible if shorter than 20 ms?
408        return BAD_VALUE;
409    }
410    mTrackEveryTimeDurationUs = timeDurationUs;
411    return OK;
412}
413
414status_t StagefrightRecorder::setParameter(
415        const String8 &key, const String8 &value) {
416    LOGV("setParameter: key (%s) => value (%s)", key.string(), value.string());
417    if (key == "max-duration") {
418        int64_t max_duration_ms;
419        if (safe_strtoi64(value.string(), &max_duration_ms)) {
420            return setParamMaxDurationOrFileSize(
421                    max_duration_ms, true /* limit_is_duration */);
422        }
423    } else if (key == "max-filesize") {
424        int64_t max_filesize_bytes;
425        if (safe_strtoi64(value.string(), &max_filesize_bytes)) {
426            return setParamMaxDurationOrFileSize(
427                    max_filesize_bytes, false /* limit is filesize */);
428        }
429    } else if (key == "interleave-duration-us") {
430        int32_t durationUs;
431        if (safe_strtoi32(value.string(), &durationUs)) {
432            return setParamInterleaveDuration(durationUs);
433        }
434    } else if (key == "param-use-64bit-offset") {
435        int32_t use64BitOffset;
436        if (safe_strtoi32(value.string(), &use64BitOffset)) {
437            return setParam64BitFileOffset(use64BitOffset != 0);
438        }
439    } else if (key == "param-track-frame-status") {
440        int32_t nFrames;
441        if (safe_strtoi32(value.string(), &nFrames)) {
442            return setParamTrackFrameStatus(nFrames);
443        }
444    } else if (key == "param-track-time-status") {
445        int64_t timeDurationUs;
446        if (safe_strtoi64(value.string(), &timeDurationUs)) {
447            return setParamTrackTimeStatus(timeDurationUs);
448        }
449    } else if (key == "audio-param-sampling-rate") {
450        int32_t sampling_rate;
451        if (safe_strtoi32(value.string(), &sampling_rate)) {
452            return setParamAudioSamplingRate(sampling_rate);
453        }
454    } else if (key == "audio-param-number-of-channels") {
455        int32_t number_of_channels;
456        if (safe_strtoi32(value.string(), &number_of_channels)) {
457            return setParamAudioNumberOfChannels(number_of_channels);
458        }
459    } else if (key == "audio-param-encoding-bitrate") {
460        int32_t audio_bitrate;
461        if (safe_strtoi32(value.string(), &audio_bitrate)) {
462            return setParamAudioEncodingBitRate(audio_bitrate);
463        }
464    } else if (key == "video-param-encoding-bitrate") {
465        int32_t video_bitrate;
466        if (safe_strtoi32(value.string(), &video_bitrate)) {
467            return setParamVideoEncodingBitRate(video_bitrate);
468        }
469    } else if (key == "video-param-i-frames-interval") {
470        int32_t interval;
471        if (safe_strtoi32(value.string(), &interval)) {
472            return setParamVideoIFramesInterval(interval);
473        }
474    } else if (key == "video-param-camera-id") {
475        int32_t cameraId;
476        if (safe_strtoi32(value.string(), &cameraId)) {
477            return setParamVideoCameraId(cameraId);
478        }
479    } else {
480        LOGE("setParameter: failed to find key %s", key.string());
481    }
482    return BAD_VALUE;
483}
484
485status_t StagefrightRecorder::setParameters(const String8 &params) {
486    LOGV("setParameters: %s", params.string());
487    const char *cparams = params.string();
488    const char *key_start = cparams;
489    for (;;) {
490        const char *equal_pos = strchr(key_start, '=');
491        if (equal_pos == NULL) {
492            LOGE("Parameters %s miss a value", cparams);
493            return BAD_VALUE;
494        }
495        String8 key(key_start, equal_pos - key_start);
496        TrimString(&key);
497        if (key.length() == 0) {
498            LOGE("Parameters %s contains an empty key", cparams);
499            return BAD_VALUE;
500        }
501        const char *value_start = equal_pos + 1;
502        const char *semicolon_pos = strchr(value_start, ';');
503        String8 value;
504        if (semicolon_pos == NULL) {
505            value.setTo(value_start);
506        } else {
507            value.setTo(value_start, semicolon_pos - value_start);
508        }
509        if (setParameter(key, value) != OK) {
510            return BAD_VALUE;
511        }
512        if (semicolon_pos == NULL) {
513            break;  // Reaches the end
514        }
515        key_start = semicolon_pos + 1;
516    }
517    return OK;
518}
519
520status_t StagefrightRecorder::setListener(const sp<IMediaRecorderClient> &listener) {
521    mListener = listener;
522
523    return OK;
524}
525
526status_t StagefrightRecorder::prepare() {
527    return OK;
528}
529
530status_t StagefrightRecorder::start() {
531    if (mWriter != NULL) {
532        return UNKNOWN_ERROR;
533    }
534
535    switch (mOutputFormat) {
536        case OUTPUT_FORMAT_DEFAULT:
537        case OUTPUT_FORMAT_THREE_GPP:
538        case OUTPUT_FORMAT_MPEG_4:
539            return startMPEG4Recording();
540
541        case OUTPUT_FORMAT_AMR_NB:
542        case OUTPUT_FORMAT_AMR_WB:
543            return startAMRRecording();
544
545        case OUTPUT_FORMAT_AAC_ADIF:
546        case OUTPUT_FORMAT_AAC_ADTS:
547            return startAACRecording();
548
549        default:
550            return UNKNOWN_ERROR;
551    }
552}
553
554sp<MediaSource> StagefrightRecorder::createAudioSource() {
555    sp<AudioSource> audioSource =
556        new AudioSource(
557                mAudioSource,
558                mSampleRate,
559                mAudioChannels);
560
561    status_t err = audioSource->initCheck();
562
563    if (err != OK) {
564        LOGE("audio source is not initialized");
565        return NULL;
566    }
567
568    sp<MetaData> encMeta = new MetaData;
569    const char *mime;
570    switch (mAudioEncoder) {
571        case AUDIO_ENCODER_AMR_NB:
572        case AUDIO_ENCODER_DEFAULT:
573            mime = MEDIA_MIMETYPE_AUDIO_AMR_NB;
574            break;
575        case AUDIO_ENCODER_AMR_WB:
576            mime = MEDIA_MIMETYPE_AUDIO_AMR_WB;
577            break;
578        case AUDIO_ENCODER_AAC:
579            mime = MEDIA_MIMETYPE_AUDIO_AAC;
580            break;
581        default:
582            LOGE("Unknown audio encoder: %d", mAudioEncoder);
583            return NULL;
584    }
585    encMeta->setCString(kKeyMIMEType, mime);
586
587    int32_t maxInputSize;
588    CHECK(audioSource->getFormat()->findInt32(
589                kKeyMaxInputSize, &maxInputSize));
590
591    encMeta->setInt32(kKeyMaxInputSize, maxInputSize);
592    encMeta->setInt32(kKeyChannelCount, mAudioChannels);
593    encMeta->setInt32(kKeySampleRate, mSampleRate);
594    encMeta->setInt32(kKeyBitRate, mAudioBitRate);
595
596    OMXClient client;
597    CHECK_EQ(client.connect(), OK);
598
599    sp<MediaSource> audioEncoder =
600        OMXCodec::Create(client.interface(), encMeta,
601                         true /* createEncoder */, audioSource);
602    mAudioSourceNode = audioSource;
603
604    return audioEncoder;
605}
606
607status_t StagefrightRecorder::startAACRecording() {
608    CHECK(mOutputFormat == OUTPUT_FORMAT_AAC_ADIF ||
609          mOutputFormat == OUTPUT_FORMAT_AAC_ADTS);
610
611    CHECK(mAudioEncoder == AUDIO_ENCODER_AAC);
612    CHECK(mAudioSource != AUDIO_SOURCE_LIST_END);
613    CHECK(mOutputFd >= 0);
614
615    CHECK(0 == "AACWriter is not implemented yet");
616
617    return OK;
618}
619
620status_t StagefrightRecorder::startAMRRecording() {
621    CHECK(mOutputFormat == OUTPUT_FORMAT_AMR_NB ||
622          mOutputFormat == OUTPUT_FORMAT_AMR_WB);
623
624    if (mOutputFormat == OUTPUT_FORMAT_AMR_NB) {
625        if (mAudioEncoder != AUDIO_ENCODER_DEFAULT &&
626            mAudioEncoder != AUDIO_ENCODER_AMR_NB) {
627            LOGE("Invalid encoder %d used for AMRNB recording",
628                    mAudioEncoder);
629            return UNKNOWN_ERROR;
630        }
631        if (mSampleRate != 8000) {
632            LOGE("Invalid sampling rate %d used for AMRNB recording",
633                    mSampleRate);
634            return UNKNOWN_ERROR;
635        }
636    } else {  // mOutputFormat must be OUTPUT_FORMAT_AMR_WB
637        if (mAudioEncoder != AUDIO_ENCODER_AMR_WB) {
638            LOGE("Invlaid encoder %d used for AMRWB recording",
639                    mAudioEncoder);
640            return UNKNOWN_ERROR;
641        }
642        if (mSampleRate != 16000) {
643            LOGE("Invalid sample rate %d used for AMRWB recording",
644                    mSampleRate);
645            return UNKNOWN_ERROR;
646        }
647    }
648    if (mAudioChannels != 1) {
649        LOGE("Invalid number of audio channels %d used for amr recording",
650                mAudioChannels);
651        return UNKNOWN_ERROR;
652    }
653
654    if (mAudioSource >= AUDIO_SOURCE_LIST_END) {
655        LOGE("Invalid audio source: %d", mAudioSource);
656        return UNKNOWN_ERROR;
657    }
658
659    sp<MediaSource> audioEncoder = createAudioSource();
660
661    if (audioEncoder == NULL) {
662        return UNKNOWN_ERROR;
663    }
664
665    CHECK(mOutputFd >= 0);
666    mWriter = new AMRWriter(dup(mOutputFd));
667    mWriter->addSource(audioEncoder);
668
669    if (mMaxFileDurationUs != 0) {
670        mWriter->setMaxFileDuration(mMaxFileDurationUs);
671    }
672    if (mMaxFileSizeBytes != 0) {
673        mWriter->setMaxFileSize(mMaxFileSizeBytes);
674    }
675    mWriter->setListener(mListener);
676    mWriter->start();
677
678    return OK;
679}
680
681void StagefrightRecorder::clipVideoFrameRate() {
682    LOGV("clipVideoFrameRate: encoder %d", mVideoEncoder);
683    int minFrameRate = mEncoderProfiles->getVideoEncoderParamByName(
684                        "enc.vid.fps.min", mVideoEncoder);
685    int maxFrameRate = mEncoderProfiles->getVideoEncoderParamByName(
686                        "enc.vid.fps.max", mVideoEncoder);
687    if (mFrameRate < minFrameRate) {
688        LOGW("Intended video encoding frame rate (%d fps) is too small"
689             " and will be set to (%d fps)", mFrameRate, minFrameRate);
690        mFrameRate = minFrameRate;
691    } else if (mFrameRate > maxFrameRate) {
692        LOGW("Intended video encoding frame rate (%d fps) is too large"
693             " and will be set to (%d fps)", mFrameRate, maxFrameRate);
694        mFrameRate = maxFrameRate;
695    }
696}
697
698void StagefrightRecorder::clipVideoBitRate() {
699    LOGV("clipVideoBitRate: encoder %d", mVideoEncoder);
700    int minBitRate = mEncoderProfiles->getVideoEncoderParamByName(
701                        "enc.vid.bps.min", mVideoEncoder);
702    int maxBitRate = mEncoderProfiles->getVideoEncoderParamByName(
703                        "enc.vid.bps.max", mVideoEncoder);
704    if (mVideoBitRate < minBitRate) {
705        LOGW("Intended video encoding bit rate (%d bps) is too small"
706             " and will be set to (%d bps)", mVideoBitRate, minBitRate);
707        mVideoBitRate = minBitRate;
708    } else if (mVideoBitRate > maxBitRate) {
709        LOGW("Intended video encoding bit rate (%d bps) is too large"
710             " and will be set to (%d bps)", mVideoBitRate, maxBitRate);
711        mVideoBitRate = maxBitRate;
712    }
713}
714
715void StagefrightRecorder::clipVideoFrameWidth() {
716    LOGV("clipVideoFrameWidth: encoder %d", mVideoEncoder);
717    int minFrameWidth = mEncoderProfiles->getVideoEncoderParamByName(
718                        "enc.vid.width.min", mVideoEncoder);
719    int maxFrameWidth = mEncoderProfiles->getVideoEncoderParamByName(
720                        "enc.vid.width.max", mVideoEncoder);
721    if (mVideoWidth < minFrameWidth) {
722        LOGW("Intended video encoding frame width (%d) is too small"
723             " and will be set to (%d)", mVideoWidth, minFrameWidth);
724        mVideoWidth = minFrameWidth;
725    } else if (mVideoWidth > maxFrameWidth) {
726        LOGW("Intended video encoding frame width (%d) is too large"
727             " and will be set to (%d)", mVideoWidth, maxFrameWidth);
728        mVideoWidth = maxFrameWidth;
729    }
730}
731
732void StagefrightRecorder::clipVideoFrameHeight() {
733    LOGV("clipVideoFrameHeight: encoder %d", mVideoEncoder);
734    int minFrameHeight = mEncoderProfiles->getVideoEncoderParamByName(
735                        "enc.vid.height.min", mVideoEncoder);
736    int maxFrameHeight = mEncoderProfiles->getVideoEncoderParamByName(
737                        "enc.vid.height.max", mVideoEncoder);
738    if (mVideoHeight < minFrameHeight) {
739        LOGW("Intended video encoding frame height (%d) is too small"
740             " and will be set to (%d)", mVideoHeight, minFrameHeight);
741        mVideoHeight = minFrameHeight;
742    } else if (mVideoHeight > maxFrameHeight) {
743        LOGW("Intended video encoding frame height (%d) is too large"
744             " and will be set to (%d)", mVideoHeight, maxFrameHeight);
745        mVideoHeight = maxFrameHeight;
746    }
747}
748
749status_t StagefrightRecorder::startMPEG4Recording() {
750    mWriter = new MPEG4Writer(dup(mOutputFd));
751    int32_t totalBitRate = 0;
752
753    // Add audio source first if it exists
754    if (mAudioSource != AUDIO_SOURCE_LIST_END) {
755        sp<MediaSource> audioEncoder;
756        switch(mAudioEncoder) {
757            case AUDIO_ENCODER_AMR_NB:
758            case AUDIO_ENCODER_AMR_WB:
759            case AUDIO_ENCODER_AAC:
760                audioEncoder = createAudioSource();
761                break;
762            default:
763                LOGE("Unsupported audio encoder: %d", mAudioEncoder);
764                return UNKNOWN_ERROR;
765        }
766
767        if (audioEncoder == NULL) {
768            return UNKNOWN_ERROR;
769        }
770        totalBitRate += mAudioBitRate;
771        mWriter->addSource(audioEncoder);
772    }
773    if (mVideoSource == VIDEO_SOURCE_DEFAULT
774            || mVideoSource == VIDEO_SOURCE_CAMERA) {
775
776        clipVideoBitRate();
777        clipVideoFrameRate();
778        clipVideoFrameWidth();
779        clipVideoFrameHeight();
780
781        int64_t token = IPCThreadState::self()->clearCallingIdentity();
782        if (mCamera == 0) {
783            mCamera = Camera::connect(mCameraId);
784            if (mCamera == 0) {
785                LOGE("Camera connection could not be established.");
786                return -EBUSY;
787            }
788            mFlags &= ~FLAGS_HOT_CAMERA;
789            mCamera->lock();
790        }
791
792
793        // Set the actual video recording frame size
794        CameraParameters params(mCamera->getParameters());
795        params.setPreviewSize(mVideoWidth, mVideoHeight);
796        params.setPreviewFrameRate(mFrameRate);
797        String8 s = params.flatten();
798        CHECK_EQ(OK, mCamera->setParameters(s));
799        CameraParameters newCameraParams(mCamera->getParameters());
800
801        // Check on video frame size
802        int frameWidth = 0, frameHeight = 0;
803        newCameraParams.getPreviewSize(&frameWidth, &frameHeight);
804        if (frameWidth  < 0 || frameWidth  != mVideoWidth ||
805            frameHeight < 0 || frameHeight != mVideoHeight) {
806            LOGE("Failed to set the video frame size to %dx%d",
807                    mVideoWidth, mVideoHeight);
808            IPCThreadState::self()->restoreCallingIdentity(token);
809            return UNKNOWN_ERROR;
810        }
811
812        // Check on video frame rate
813        int frameRate = newCameraParams.getPreviewFrameRate();
814        if (frameRate < 0 || (frameRate - mFrameRate) != 0) {
815            LOGE("Failed to set frame rate to %d fps. The actual "
816                 "frame rate is %d", mFrameRate, frameRate);
817        }
818
819        CHECK_EQ(OK, mCamera->setPreviewDisplay(mPreviewSurface));
820        IPCThreadState::self()->restoreCallingIdentity(token);
821
822        sp<CameraSource> cameraSource =
823            CameraSource::CreateFromCamera(mCamera);
824
825        CHECK(cameraSource != NULL);
826
827        sp<MetaData> enc_meta = new MetaData;
828        enc_meta->setInt32(kKeyBitRate, mVideoBitRate);
829        enc_meta->setInt32(kKeySampleRate, mFrameRate);
830
831        switch (mVideoEncoder) {
832            case VIDEO_ENCODER_H263:
833                enc_meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_H263);
834                break;
835
836            case VIDEO_ENCODER_MPEG_4_SP:
837                enc_meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_MPEG4);
838                break;
839
840            case VIDEO_ENCODER_H264:
841                enc_meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_AVC);
842                break;
843
844            default:
845                CHECK(!"Should not be here, unsupported video encoding.");
846                break;
847        }
848
849        sp<MetaData> meta = cameraSource->getFormat();
850
851        int32_t width, height, stride, sliceHeight;
852        CHECK(meta->findInt32(kKeyWidth, &width));
853        CHECK(meta->findInt32(kKeyHeight, &height));
854        CHECK(meta->findInt32(kKeyStride, &stride));
855        CHECK(meta->findInt32(kKeySliceHeight, &sliceHeight));
856
857        enc_meta->setInt32(kKeyWidth, width);
858        enc_meta->setInt32(kKeyHeight, height);
859        enc_meta->setInt32(kKeyIFramesInterval, mIFramesInterval);
860        enc_meta->setInt32(kKeyStride, stride);
861        enc_meta->setInt32(kKeySliceHeight, sliceHeight);
862
863        OMXClient client;
864        CHECK_EQ(client.connect(), OK);
865
866        sp<MediaSource> encoder =
867            OMXCodec::Create(
868                    client.interface(), enc_meta,
869                    true /* createEncoder */, cameraSource);
870
871        CHECK(mOutputFd >= 0);
872        totalBitRate += mVideoBitRate;
873        mWriter->addSource(encoder);
874    }
875
876    {
877        // MPEGWriter specific handling
878        MPEG4Writer *writer = ((MPEG4Writer *) mWriter.get());
879        writer->setInterleaveDuration(mInterleaveDurationUs);
880    }
881
882    if (mMaxFileDurationUs != 0) {
883        mWriter->setMaxFileDuration(mMaxFileDurationUs);
884    }
885    if (mMaxFileSizeBytes != 0) {
886        mWriter->setMaxFileSize(mMaxFileSizeBytes);
887    }
888    mWriter->setListener(mListener);
889    sp<MetaData> meta = new MetaData;
890    meta->setInt64(kKeyTime, systemTime() / 1000);
891    meta->setInt32(kKeyFileType, mOutputFormat);
892    meta->setInt32(kKeyBitRate, totalBitRate);
893    meta->setInt32(kKey64BitFileOffset, mUse64BitFileOffset);
894    if (mTrackEveryNumberOfFrames > 0) {
895        meta->setInt32(kKeyTrackFrameStatus, mTrackEveryNumberOfFrames);
896    }
897    if (mTrackEveryTimeDurationUs > 0) {
898        meta->setInt64(kKeyTrackTimeStatus, mTrackEveryTimeDurationUs);
899    }
900    mWriter->start(meta.get());
901    return OK;
902}
903
904status_t StagefrightRecorder::pause() {
905    LOGV("pause");
906    if (mWriter == NULL) {
907        return UNKNOWN_ERROR;
908    }
909    mWriter->pause();
910    return OK;
911}
912
913status_t StagefrightRecorder::stop() {
914    LOGV("stop");
915    if (mWriter != NULL) {
916        mWriter->stop();
917        mWriter = NULL;
918    }
919
920    if (mCamera != 0) {
921        LOGV("Disconnect camera");
922        int64_t token = IPCThreadState::self()->clearCallingIdentity();
923        if ((mFlags & FLAGS_HOT_CAMERA) == 0) {
924            LOGV("Camera was cold when we started, stopping preview");
925            mCamera->stopPreview();
926        }
927        mCamera->unlock();
928        mCamera = NULL;
929        IPCThreadState::self()->restoreCallingIdentity(token);
930        mFlags = 0;
931    }
932
933    return OK;
934}
935
936status_t StagefrightRecorder::close() {
937    LOGV("close");
938    stop();
939
940    return OK;
941}
942
943status_t StagefrightRecorder::reset() {
944    LOGV("reset");
945    stop();
946
947    // No audio or video source by default
948    mAudioSource = AUDIO_SOURCE_LIST_END;
949    mVideoSource = VIDEO_SOURCE_LIST_END;
950
951    // Default parameters
952    mOutputFormat  = OUTPUT_FORMAT_THREE_GPP;
953    mAudioEncoder  = AUDIO_ENCODER_AMR_NB;
954    mVideoEncoder  = VIDEO_ENCODER_H263;
955    mVideoWidth    = 176;
956    mVideoHeight   = 144;
957    mFrameRate     = 20;
958    mVideoBitRate  = 192000;
959    mSampleRate    = 8000;
960    mAudioChannels = 1;
961    mAudioBitRate  = 12200;
962    mInterleaveDurationUs = 0;
963    mIFramesInterval = 1;
964    mAudioSourceNode = 0;
965    mUse64BitFileOffset = false;
966    mCameraId        = 0;
967    mTrackEveryNumberOfFrames = 0;
968    mTrackEveryTimeDurationUs = 0;
969    mEncoderProfiles = MediaProfiles::getInstance();
970
971    mOutputFd = -1;
972    mFlags = 0;
973
974    return OK;
975}
976
977status_t StagefrightRecorder::getMaxAmplitude(int *max) {
978    LOGV("getMaxAmplitude");
979
980    if (max == NULL) {
981        LOGE("Null pointer argument");
982        return BAD_VALUE;
983    }
984
985    if (mAudioSourceNode != 0) {
986        *max = mAudioSourceNode->getMaxAmplitude();
987    } else {
988        *max = 0;
989    }
990
991    return OK;
992}
993
994}  // namespace android
995