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