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