120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber/*
220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * Copyright (C) 2009 The Android Open Source Project
320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *
420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * Licensed under the Apache License, Version 2.0 (the "License");
520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * you may not use this file except in compliance with the License.
620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * You may obtain a copy of the License at
720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *
820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *      http://www.apache.org/licenses/LICENSE-2.0
920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *
1020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * Unless required by applicable law or agreed to in writing, software
1120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * distributed under the License is distributed on an "AS IS" BASIS,
1220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * See the License for the specific language governing permissions and
1420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * limitations under the License.
1520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber */
1620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
17e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber#include "SineSource.h"
18e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber
1920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <binder/ProcessState.h>
20d91dc5a0602f54fc0d4d2187f37b5b8169bb62c3Dongwon Kang#include <media/MediaExtractor.h>
21f1d5aa162c02a16b7195a43a9bcea4d592600ac4James Dong#include <media/stagefright/foundation/ADebug.h>
225fb00a6d1f32523aa254fea95a7bee646f4ae9aeLajos Molnar#include <media/stagefright/foundation/ALooper.h>
235fb00a6d1f32523aa254fea95a7bee646f4ae9aeLajos Molnar#include <media/stagefright/foundation/AMessage.h>
24e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber#include <media/stagefright/AudioPlayer.h>
2520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <media/stagefright/CameraSource.h>
26bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber#include <media/stagefright/FileSource.h>
2720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <media/stagefright/MediaBufferGroup.h>
2818291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber#include <media/stagefright/MediaDefs.h>
295fb00a6d1f32523aa254fea95a7bee646f4ae9aeLajos Molnar#include <media/stagefright/MediaCodecSource.h>
3020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <media/stagefright/MetaData.h>
31d91dc5a0602f54fc0d4d2187f37b5b8169bb62c3Dongwon Kang#include <media/stagefright/MediaExtractorFactory.h>
3220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <media/stagefright/MPEG4Writer.h>
335fb00a6d1f32523aa254fea95a7bee646f4ae9aeLajos Molnar#include <media/stagefright/SimpleDecodingSource.h>
34e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber#include <media/MediaPlayerInterface.h>
3520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
3620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberusing namespace android;
3720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
3831de88566257d5546cf4eee9064d96926a4b0c24Lajos Molnarstatic const int32_t kAudioBitRate = 12200;
3931de88566257d5546cf4eee9064d96926a4b0c24Lajos Molnar#if 0
40f74c8f9ee26c91b129fe9a1acc254471a9f30cb1James Dongstatic const int32_t kFramerate = 24;  // fps
41f74c8f9ee26c91b129fe9a1acc254471a9f30cb1James Dongstatic const int32_t kIFramesIntervalSec = 1;
42f74c8f9ee26c91b129fe9a1acc254471a9f30cb1James Dongstatic const int32_t kVideoBitRate = 512 * 1024;
43f74c8f9ee26c91b129fe9a1acc254471a9f30cb1James Dongstatic const int64_t kDurationUs = 10000000LL;  // 10 seconds
44f74c8f9ee26c91b129fe9a1acc254471a9f30cb1James Dong
4520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberclass DummySource : public MediaSource {
46888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber
4720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberpublic:
48a73367993a9d53a4daceeb40ede183e60dd571e5James Dong    DummySource(int width, int height, int colorFormat)
49693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        : mWidth(width),
50693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber          mHeight(height),
51a73367993a9d53a4daceeb40ede183e60dd571e5James Dong          mColorFormat(colorFormat),
52693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber          mSize((width * height * 3) / 2) {
5320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        mGroup.add_buffer(new MediaBuffer(mSize));
54a73367993a9d53a4daceeb40ede183e60dd571e5James Dong
55a73367993a9d53a4daceeb40ede183e60dd571e5James Dong        // Check the color format to make sure
56a73367993a9d53a4daceeb40ede183e60dd571e5James Dong        // that the buffer size mSize it set correctly above.
57a73367993a9d53a4daceeb40ede183e60dd571e5James Dong        CHECK(colorFormat == OMX_COLOR_FormatYUV420SemiPlanar ||
58a73367993a9d53a4daceeb40ede183e60dd571e5James Dong              colorFormat == OMX_COLOR_FormatYUV420Planar);
5920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
6020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
61693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    virtual sp<MetaData> getFormat() {
62693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        sp<MetaData> meta = new MetaData;
63693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        meta->setInt32(kKeyWidth, mWidth);
64693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        meta->setInt32(kKeyHeight, mHeight);
65a73367993a9d53a4daceeb40ede183e60dd571e5James Dong        meta->setInt32(kKeyColorFormat, mColorFormat);
6618291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber        meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_RAW);
67693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
68693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        return meta;
69693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
70693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
71693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    virtual status_t start(MetaData *params) {
72888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber        mNumFramesOutput = 0;
73693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        return OK;
74693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
75693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
76693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    virtual status_t stop() {
77693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        return OK;
7820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
7920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
80693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    virtual status_t read(
81693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber            MediaBuffer **buffer, const MediaSource::ReadOptions *options) {
82888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber        if (mNumFramesOutput == kFramerate * 10) {
83888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber            // Stop returning data after 10 secs.
84888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber            return ERROR_END_OF_STREAM;
85888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber        }
86888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber
87888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber        // printf("DummySource::read\n");
88693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        status_t err = mGroup.acquire_buffer(buffer);
89693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        if (err != OK) {
9020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            return err;
9120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        }
9220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
9320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        char x = (char)((double)rand() / RAND_MAX * 255);
9420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        memset((*buffer)->data(), x, mSize);
9520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        (*buffer)->set_range(0, mSize);
96888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber        (*buffer)->meta_data()->clear();
97888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber        (*buffer)->meta_data()->setInt64(
98888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber                kKeyTime, (mNumFramesOutput * 1000000) / kFramerate);
99888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber        ++mNumFramesOutput;
10020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
101888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber        // printf("DummySource::read - returning buffer\n");
102df64d15042bbd5e0e4933ac49bf3c177dd94752cSteve Block        // ALOGI("DummySource::read - returning buffer");
103693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        return OK;
10420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
10520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
106693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huberprotected:
107693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    virtual ~DummySource() {}
108693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
10920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberprivate:
11020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    MediaBufferGroup mGroup;
111693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    int mWidth, mHeight;
112a73367993a9d53a4daceeb40ede183e60dd571e5James Dong    int mColorFormat;
11320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    size_t mSize;
114888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber    int64_t mNumFramesOutput;;
11520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
11620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    DummySource(const DummySource &);
11720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    DummySource &operator=(const DummySource &);
11820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber};
11920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
120693d271e62a3726689ff68f4505ba49228eb94b2Andreas Hubersp<MediaSource> createSource(const char *filename) {
121693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    sp<MediaSource> source;
12220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
12366326a5ee0869f1ee4d136a477e6effba428b3cbAndreas Huber    sp<MediaExtractor> extractor =
124d91dc5a0602f54fc0d4d2187f37b5b8169bb62c3Dongwon Kang        MediaExtractorFactory::Create(new FileSource(filename));
125b93ad64a423975748c7f5e1a5ea94ab8681bc899James Dong    if (extractor == NULL) {
126b93ad64a423975748c7f5e1a5ea94ab8681bc899James Dong        return NULL;
127b93ad64a423975748c7f5e1a5ea94ab8681bc899James Dong    }
128693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
129693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    size_t num_tracks = extractor->countTracks();
13020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
13120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    sp<MetaData> meta;
132693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    for (size_t i = 0; i < num_tracks; ++i) {
133693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        meta = extractor->getTrackMetaData(i);
1346d43768514650d65f4f3695da4f7c3e2eefd483cAndreas Huber        CHECK(meta.get() != NULL);
13520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
13620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        const char *mime;
13720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        if (!meta->findCString(kKeyMIMEType, &mime)) {
13820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            continue;
13920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        }
14020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
14120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        if (strncasecmp(mime, "video/", 6)) {
14220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            continue;
14320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        }
14420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
145693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        source = extractor->getTrack(i);
14620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        break;
14720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
14820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
149693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    return source;
150693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber}
151693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
152a73367993a9d53a4daceeb40ede183e60dd571e5James Dongenum {
153a73367993a9d53a4daceeb40ede183e60dd571e5James Dong    kYUV420SP = 0,
154a73367993a9d53a4daceeb40ede183e60dd571e5James Dong    kYUV420P  = 1,
155a73367993a9d53a4daceeb40ede183e60dd571e5James Dong};
156a73367993a9d53a4daceeb40ede183e60dd571e5James Dong
157a73367993a9d53a4daceeb40ede183e60dd571e5James Dong// returns -1 if mapping of the given color is unsuccessful
158a73367993a9d53a4daceeb40ede183e60dd571e5James Dong// returns an omx color enum value otherwise
159a73367993a9d53a4daceeb40ede183e60dd571e5James Dongstatic int translateColorToOmxEnumValue(int color) {
160a73367993a9d53a4daceeb40ede183e60dd571e5James Dong    switch (color) {
161a73367993a9d53a4daceeb40ede183e60dd571e5James Dong        case kYUV420SP:
162a73367993a9d53a4daceeb40ede183e60dd571e5James Dong            return OMX_COLOR_FormatYUV420SemiPlanar;
163a73367993a9d53a4daceeb40ede183e60dd571e5James Dong        case kYUV420P:
164a73367993a9d53a4daceeb40ede183e60dd571e5James Dong            return OMX_COLOR_FormatYUV420Planar;
165a73367993a9d53a4daceeb40ede183e60dd571e5James Dong        default:
166a73367993a9d53a4daceeb40ede183e60dd571e5James Dong            fprintf(stderr, "Unsupported color: %d\n", color);
167a73367993a9d53a4daceeb40ede183e60dd571e5James Dong            return -1;
168a73367993a9d53a4daceeb40ede183e60dd571e5James Dong    }
169a73367993a9d53a4daceeb40ede183e60dd571e5James Dong}
170a73367993a9d53a4daceeb40ede183e60dd571e5James Dong
171693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huberint main(int argc, char **argv) {
172693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    android::ProcessState::self()->startThreadPool();
173693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
174693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber#if 1
175a73367993a9d53a4daceeb40ede183e60dd571e5James Dong    if (argc != 3) {
176a73367993a9d53a4daceeb40ede183e60dd571e5James Dong        fprintf(stderr, "usage: %s <filename> <input_color_format>\n", argv[0]);
177a73367993a9d53a4daceeb40ede183e60dd571e5James Dong        fprintf(stderr, "       <input_color_format>:  0 (YUV420SP) or 1 (YUV420P)\n");
17820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        return 1;
17920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
18020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
181a73367993a9d53a4daceeb40ede183e60dd571e5James Dong    int colorFormat = translateColorToOmxEnumValue(atoi(argv[2]));
182a73367993a9d53a4daceeb40ede183e60dd571e5James Dong    if (colorFormat == -1) {
183a73367993a9d53a4daceeb40ede183e60dd571e5James Dong        fprintf(stderr, "input color format must be 0 (YUV420SP) or 1 (YUV420P)\n");
184a73367993a9d53a4daceeb40ede183e60dd571e5James Dong        return 1;
185a73367993a9d53a4daceeb40ede183e60dd571e5James Dong    }
186a73367993a9d53a4daceeb40ede183e60dd571e5James Dong    status_t err = OK;
187a73367993a9d53a4daceeb40ede183e60dd571e5James Dong
18803b268eac37ca2589bfff0bf58daf79d29cc14f4Andreas Huber#if 0
189693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    sp<MediaSource> source = createSource(argv[1]);
190693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
191693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    if (source == NULL) {
192693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        fprintf(stderr, "Unable to find a suitable video track.\n");
193693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber        return 1;
194693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    }
195693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
196693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    sp<MetaData> meta = source->getFormat();
197693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber
1985fb00a6d1f32523aa254fea95a7bee646f4ae9aeLajos Molnar    sp<MediaSource> decoder = SimpleDecodingSource::Create(source);
19920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
20020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    int width, height;
20120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    bool success = meta->findInt32(kKeyWidth, &width);
20220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    success = success && meta->findInt32(kKeyHeight, &height);
2036d43768514650d65f4f3695da4f7c3e2eefd483cAndreas Huber    CHECK(success);
204693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber#else
20503b268eac37ca2589bfff0bf58daf79d29cc14f4Andreas Huber    int width = 720;
206888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber    int height = 480;
207a73367993a9d53a4daceeb40ede183e60dd571e5James Dong    sp<MediaSource> decoder = new DummySource(width, height, colorFormat);
208693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber#endif
20920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
2105fb00a6d1f32523aa254fea95a7bee646f4ae9aeLajos Molnar    sp<AMessage> enc_meta = new AMessage;
2115fb00a6d1f32523aa254fea95a7bee646f4ae9aeLajos Molnar    // enc_meta->setString("mime", MEDIA_MIMETYPE_VIDEO_H263);
2125fb00a6d1f32523aa254fea95a7bee646f4ae9aeLajos Molnar    // enc_meta->setString("mime", MEDIA_MIMETYPE_VIDEO_MPEG4);
2135fb00a6d1f32523aa254fea95a7bee646f4ae9aeLajos Molnar    enc_meta->setString("mime", MEDIA_MIMETYPE_VIDEO_AVC);
2145fb00a6d1f32523aa254fea95a7bee646f4ae9aeLajos Molnar    enc_meta->setInt32("width", width);
2155fb00a6d1f32523aa254fea95a7bee646f4ae9aeLajos Molnar    enc_meta->setInt32("height", height);
2165fb00a6d1f32523aa254fea95a7bee646f4ae9aeLajos Molnar    enc_meta->setInt32("sample-rate", kFramerate);
21746f80165c595d81dda68f8f3fea27f4fb04937ddLajos Molnar    enc_meta->setInt32("bitrate", kVideoBitRate);
2185fb00a6d1f32523aa254fea95a7bee646f4ae9aeLajos Molnar    // enc_meta->setInt32("stride", width);
2195fb00a6d1f32523aa254fea95a7bee646f4ae9aeLajos Molnar    // enc_meta->setInt32("slice-height", height);
2205fb00a6d1f32523aa254fea95a7bee646f4ae9aeLajos Molnar    enc_meta->setInt32("i-frame-interval", kIFramesIntervalSec);
2215fb00a6d1f32523aa254fea95a7bee646f4ae9aeLajos Molnar    enc_meta->setInt32("color-format", colorFormat);
22220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
223bf697e37550d9e8376089b0b5e498613bede798cAndreas Huber    sp<MediaSource> encoder =
2245fb00a6d1f32523aa254fea95a7bee646f4ae9aeLajos Molnar        MediaCodecSource::Create(looper, format, decoder);
22520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
226888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber#if 1
227693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber    sp<MPEG4Writer> writer = new MPEG4Writer("/sdcard/output.mp4");
228888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber    writer->addSource(encoder);
229f74c8f9ee26c91b129fe9a1acc254471a9f30cb1James Dong    writer->setMaxFileDuration(kDurationUs);
230f1d5aa162c02a16b7195a43a9bcea4d592600ac4James Dong    CHECK_EQ((status_t)OK, writer->start());
231888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber    while (!writer->reachedEOS()) {
232f74c8f9ee26c91b129fe9a1acc254471a9f30cb1James Dong        fprintf(stderr, ".");
233888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber        usleep(100000);
234888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber    }
235a73367993a9d53a4daceeb40ede183e60dd571e5James Dong    err = writer->stop();
23620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#else
237f1d5aa162c02a16b7195a43a9bcea4d592600ac4James Dong    CHECK_EQ((status_t)OK, encoder->start());
23820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
23920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    MediaBuffer *buffer;
2406d43768514650d65f4f3695da4f7c3e2eefd483cAndreas Huber    while (encoder->read(&buffer) == OK) {
241f74c8f9ee26c91b129fe9a1acc254471a9f30cb1James Dong        printf(".");
242f74c8f9ee26c91b129fe9a1acc254471a9f30cb1James Dong        fflush(stdout);
243888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber        int32_t isSync;
244888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber        if (!buffer->meta_data()->findInt32(kKeyIsSyncFrame, &isSync)) {
245888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber            isSync = false;
246888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber        }
247888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber
248888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber        printf("got an output frame of size %d%s\n", buffer->range_length(),
249888f72a4628eed3c136ff2e346a15d129da0d520Andreas Huber               isSync ? " (SYNC)" : "");
25020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
25120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        buffer->release();
25220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        buffer = NULL;
25320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
25420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
255a73367993a9d53a4daceeb40ede183e60dd571e5James Dong    err = encoder->stop();
25620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#endif
25720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
258f74c8f9ee26c91b129fe9a1acc254471a9f30cb1James Dong    printf("$\n");
25920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#endif
26020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
26120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#if 0
262ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala    CameraSource *source = CameraSource::Create(
263ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala            String16(argv[0], strlen(argv[0])));
26403b268eac37ca2589bfff0bf58daf79d29cc14f4Andreas Huber    source->start();
26503b268eac37ca2589bfff0bf58daf79d29cc14f4Andreas Huber
26620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    printf("source = %p\n", source);
26720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
26820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    for (int i = 0; i < 100; ++i) {
26920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        MediaBuffer *buffer;
27020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        status_t err = source->read(&buffer);
271f1d5aa162c02a16b7195a43a9bcea4d592600ac4James Dong        CHECK_EQ(err, (status_t)OK);
27220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
27320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        printf("got a frame, data=%p, size=%d\n",
27420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber               buffer->data(), buffer->range_length());
27520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
27620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        buffer->release();
27720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        buffer = NULL;
27820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
27920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
280a73367993a9d53a4daceeb40ede183e60dd571e5James Dong    err = source->stop();
28103b268eac37ca2589bfff0bf58daf79d29cc14f4Andreas Huber
28220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    delete source;
28320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    source = NULL;
28420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#endif
28520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
286a73367993a9d53a4daceeb40ede183e60dd571e5James Dong    if (err != OK && err != ERROR_END_OF_STREAM) {
287a73367993a9d53a4daceeb40ede183e60dd571e5James Dong        fprintf(stderr, "record failed: %d\n", err);
288a73367993a9d53a4daceeb40ede183e60dd571e5James Dong        return 1;
289a73367993a9d53a4daceeb40ede183e60dd571e5James Dong    }
29020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    return 0;
29120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
2927a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber#else
293e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber
294ccb067b1d8424ba610cbd3de83368bd55b532b5bAndreas Huberint main(int /* argc */, char ** /* argv */) {
295e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber    android::ProcessState::self()->startThreadPool();
296e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber
297e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber    const int32_t kSampleRate = 22050;
298e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber    const int32_t kNumChannels = 2;
299e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber    sp<MediaSource> audioSource = new SineSource(kSampleRate, kNumChannels);
300e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber
301e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber#if 0
302e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber    sp<MediaPlayerBase::AudioSink> audioSink;
303e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber    AudioPlayer *player = new AudioPlayer(audioSink);
304e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber    player->setSource(audioSource);
305e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber    player->start();
306e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber
307e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber    sleep(10);
308e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber
309e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber    player->stop();
310e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber#endif
311e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber
3125fb00a6d1f32523aa254fea95a7bee646f4ae9aeLajos Molnar    sp<AMessage> encMeta = new AMessage;
3135fb00a6d1f32523aa254fea95a7bee646f4ae9aeLajos Molnar    encMeta->setString("mime",
3142b1892db4a2ab47bfc09e59a4c11751aea99e4eaAndreas Huber            0 ? MEDIA_MIMETYPE_AUDIO_AMR_WB : MEDIA_MIMETYPE_AUDIO_AAC);
3155fb00a6d1f32523aa254fea95a7bee646f4ae9aeLajos Molnar    encMeta->setInt32("sample-rate", kSampleRate);
3165fb00a6d1f32523aa254fea95a7bee646f4ae9aeLajos Molnar    encMeta->setInt32("channel-count", kNumChannels);
3175fb00a6d1f32523aa254fea95a7bee646f4ae9aeLajos Molnar    encMeta->setInt32("max-input-size", 8192);
3185fb00a6d1f32523aa254fea95a7bee646f4ae9aeLajos Molnar    encMeta->setInt32("bitrate", kAudioBitRate);
3195fb00a6d1f32523aa254fea95a7bee646f4ae9aeLajos Molnar
3205fb00a6d1f32523aa254fea95a7bee646f4ae9aeLajos Molnar    sp<ALooper> looper = new ALooper;
3215fb00a6d1f32523aa254fea95a7bee646f4ae9aeLajos Molnar    looper->setName("record");
3225fb00a6d1f32523aa254fea95a7bee646f4ae9aeLajos Molnar    looper->start();
323e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber
324ba8128f9db82da66f28c6e6740d4721d80da954eDongwon Kang    sp<MediaSource> encoder =
3255fb00a6d1f32523aa254fea95a7bee646f4ae9aeLajos Molnar        MediaCodecSource::Create(looper, encMeta, audioSource);
326e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber
327e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber    encoder->start();
328e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber
329e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber    int32_t n = 0;
330e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber    status_t err;
3311889c3edad32995c0cf26ae2248fe7c957b7ec84Dongwon Kang    MediaBufferBase *buffer;
332e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber    while ((err = encoder->read(&buffer)) == OK) {
333e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber        printf(".");
334e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber        fflush(stdout);
335e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber
336e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber        buffer->release();
337e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber        buffer = NULL;
338e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber
339456db75516efc889e1ee4e5e16021e77c03b0941Andreas Huber        if (++n == 100) {
340e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber            break;
341e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber        }
342e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber    }
343e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber    printf("$\n");
344e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber
345e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber    encoder->stop();
346e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber
347e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber    return 0;
348e5adbeee3401915ff8e1a983396ce3554436b11cAndreas Huber}
3497a6b9e2eca7d20457ace3538c689640e5bfda4f3Andreas Huber#endif
350