record.cpp revision e5adbeee3401915ff8e1a983396ce3554436b11c
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#include "SineSource.h"
18
19#include <binder/ProcessState.h>
20#include <media/stagefright/AudioPlayer.h>
21#include <media/stagefright/CameraSource.h>
22#include <media/stagefright/MediaBufferGroup.h>
23#include <media/stagefright/MediaDebug.h>
24#include <media/stagefright/MetaData.h>
25#include <media/stagefright/MPEG4Extractor.h>
26#include <media/stagefright/MPEG4Writer.h>
27#include <media/stagefright/MmapSource.h>
28#include <media/stagefright/OMXClient.h>
29#include <media/stagefright/OMXCodec.h>
30#include <media/MediaPlayerInterface.h>
31
32using namespace android;
33
34#if 0
35class DummySource : public MediaSource {
36public:
37    DummySource(int width, int height)
38        : mWidth(width),
39          mHeight(height),
40          mSize((width * height * 3) / 2) {
41        mGroup.add_buffer(new MediaBuffer(mSize));
42    }
43
44    virtual sp<MetaData> getFormat() {
45        sp<MetaData> meta = new MetaData;
46        meta->setInt32(kKeyWidth, mWidth);
47        meta->setInt32(kKeyHeight, mHeight);
48        meta->setCString(kKeyMIMEType, "video/raw");
49
50        return meta;
51    }
52
53    virtual status_t getMaxSampleSize(size_t *max_size) {
54        *max_size = mSize;
55        return OK;
56    }
57
58    virtual status_t start(MetaData *params) {
59        return OK;
60    }
61
62    virtual status_t stop() {
63        return OK;
64    }
65
66    virtual status_t read(
67            MediaBuffer **buffer, const MediaSource::ReadOptions *options) {
68        status_t err = mGroup.acquire_buffer(buffer);
69        if (err != OK) {
70            return err;
71        }
72
73        char x = (char)((double)rand() / RAND_MAX * 255);
74        memset((*buffer)->data(), x, mSize);
75        (*buffer)->set_range(0, mSize);
76
77        return OK;
78    }
79
80protected:
81    virtual ~DummySource() {}
82
83private:
84    MediaBufferGroup mGroup;
85    int mWidth, mHeight;
86    size_t mSize;
87
88    DummySource(const DummySource &);
89    DummySource &operator=(const DummySource &);
90};
91
92sp<MediaSource> createSource(const char *filename) {
93    sp<MediaSource> source;
94
95    sp<MPEG4Extractor> extractor =
96        new MPEG4Extractor(new MmapSource(filename));
97
98    size_t num_tracks = extractor->countTracks();
99
100    sp<MetaData> meta;
101    for (size_t i = 0; i < num_tracks; ++i) {
102        meta = extractor->getTrackMetaData(i);
103        CHECK(meta.get() != NULL);
104
105        const char *mime;
106        if (!meta->findCString(kKeyMIMEType, &mime)) {
107            continue;
108        }
109
110        if (strncasecmp(mime, "video/", 6)) {
111            continue;
112        }
113
114        source = extractor->getTrack(i);
115        break;
116    }
117
118    return source;
119}
120
121int main(int argc, char **argv) {
122    android::ProcessState::self()->startThreadPool();
123
124#if 1
125    if (argc != 2) {
126        fprintf(stderr, "usage: %s filename\n", argv[0]);
127        return 1;
128    }
129
130    OMXClient client;
131    CHECK_EQ(client.connect(), OK);
132
133#if 0
134    sp<MediaSource> source = createSource(argv[1]);
135
136    if (source == NULL) {
137        fprintf(stderr, "Unable to find a suitable video track.\n");
138        return 1;
139    }
140
141    sp<MetaData> meta = source->getFormat();
142
143    sp<OMXCodec> decoder = OMXCodec::Create(
144            client.interface(), meta, false /* createEncoder */, source);
145
146    int width, height;
147    bool success = meta->findInt32(kKeyWidth, &width);
148    success = success && meta->findInt32(kKeyHeight, &height);
149    CHECK(success);
150#else
151    int width = 320;
152    int height = 240;
153    sp<MediaSource> decoder = new DummySource(width, height);
154#endif
155
156    sp<MetaData> enc_meta = new MetaData;
157    // enc_meta->setCString(kKeyMIMEType, "video/3gpp");
158    enc_meta->setCString(kKeyMIMEType, "video/mp4v-es");
159    enc_meta->setInt32(kKeyWidth, width);
160    enc_meta->setInt32(kKeyHeight, height);
161
162    sp<OMXCodec> encoder =
163        OMXCodec::Create(
164                client.interface(), enc_meta, true /* createEncoder */, decoder);
165
166#if 0
167    sp<MPEG4Writer> writer = new MPEG4Writer("/sdcard/output.mp4");
168    writer->addSource(enc_meta, encoder);
169    writer->start();
170    sleep(20);
171    printf("stopping now.\n");
172    writer->stop();
173#else
174    encoder->start();
175
176    MediaBuffer *buffer;
177    while (encoder->read(&buffer) == OK) {
178        printf("got an output frame of size %d\n", buffer->range_length());
179
180        buffer->release();
181        buffer = NULL;
182    }
183
184    encoder->stop();
185#endif
186
187    client.disconnect();
188#endif
189
190#if 0
191    CameraSource *source = CameraSource::Create();
192    printf("source = %p\n", source);
193
194    for (int i = 0; i < 100; ++i) {
195        MediaBuffer *buffer;
196        status_t err = source->read(&buffer);
197        CHECK_EQ(err, OK);
198
199        printf("got a frame, data=%p, size=%d\n",
200               buffer->data(), buffer->range_length());
201
202        buffer->release();
203        buffer = NULL;
204    }
205
206    delete source;
207    source = NULL;
208#endif
209
210    return 0;
211}
212#endif
213
214int main(int argc, char **argv) {
215    android::ProcessState::self()->startThreadPool();
216
217    OMXClient client;
218    CHECK_EQ(client.connect(), OK);
219
220    const int32_t kSampleRate = 22050;
221    const int32_t kNumChannels = 2;
222    sp<MediaSource> audioSource = new SineSource(kSampleRate, kNumChannels);
223
224#if 0
225    sp<MediaPlayerBase::AudioSink> audioSink;
226    AudioPlayer *player = new AudioPlayer(audioSink);
227    player->setSource(audioSource);
228    player->start();
229
230    sleep(10);
231
232    player->stop();
233#endif
234
235    sp<MetaData> encMeta = new MetaData;
236    encMeta->setCString(kKeyMIMEType, 1 ? "audio/3gpp" : "audio/mp4a-latm");
237    encMeta->setInt32(kKeySampleRate, kSampleRate);
238    encMeta->setInt32(kKeyChannelCount, kNumChannels);
239    encMeta->setInt32(kKeyMaxInputSize, 8192);
240
241    sp<MediaSource> encoder =
242        OMXCodec::Create(client.interface(), encMeta, true, audioSource);
243
244    encoder->start();
245
246    int32_t n = 0;
247    status_t err;
248    MediaBuffer *buffer;
249    while ((err = encoder->read(&buffer)) == OK) {
250        printf(".");
251        fflush(stdout);
252
253        buffer->release();
254        buffer = NULL;
255
256        if (++n == 10000) {
257            break;
258        }
259    }
260    printf("$\n");
261
262    encoder->stop();
263
264    client.disconnect();
265
266    return 0;
267}
268
269