record.cpp revision 693d271e62a3726689ff68f4505ba49228eb94b2
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#include <media/stagefright/OMXDecoder.h>
30
31using namespace android;
32
33class DummySource : public MediaSource {
34public:
35    DummySource(int width, int height)
36        : mWidth(width),
37          mHeight(height),
38          mSize((width * height * 3) / 2) {
39        mGroup.add_buffer(new MediaBuffer(mSize));
40    }
41
42    virtual sp<MetaData> getFormat() {
43        sp<MetaData> meta = new MetaData;
44        meta->setInt32(kKeyWidth, mWidth);
45        meta->setInt32(kKeyHeight, mHeight);
46        meta->setCString(kKeyMIMEType, "video/raw");
47
48        return meta;
49    }
50
51    virtual status_t getMaxSampleSize(size_t *max_size) {
52        *max_size = mSize;
53        return OK;
54    }
55
56    virtual status_t start(MetaData *params) {
57        return OK;
58    }
59
60    virtual status_t stop() {
61        return OK;
62    }
63
64    virtual status_t read(
65            MediaBuffer **buffer, const MediaSource::ReadOptions *options) {
66        status_t err = mGroup.acquire_buffer(buffer);
67        if (err != OK) {
68            return err;
69        }
70
71        char x = (char)((double)rand() / RAND_MAX * 255);
72        memset((*buffer)->data(), x, mSize);
73        (*buffer)->set_range(0, mSize);
74
75        return OK;
76    }
77
78protected:
79    virtual ~DummySource() {}
80
81private:
82    MediaBufferGroup mGroup;
83    int mWidth, mHeight;
84    size_t mSize;
85
86    DummySource(const DummySource &);
87    DummySource &operator=(const DummySource &);
88};
89
90#define USE_OMX_CODEC   1
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        assert(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    assert(client.connect() == android::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#if USE_OMX_CODEC
144    sp<OMXCodec> decoder = OMXCodec::Create(
145            client.interface(), meta, false /* createEncoder */, source);
146#else
147    sp<OMXDecoder> decoder = OMXDecoder::Create(
148            &client, meta, false /* createEncoder */, source);
149#endif
150
151    int width, height;
152    bool success = meta->findInt32(kKeyWidth, &width);
153    success = success && meta->findInt32(kKeyHeight, &height);
154    assert(success);
155#else
156    int width = 320;
157    int height = 240;
158    sp<MediaSource> decoder = new DummySource(width, height);
159#endif
160
161    sp<MetaData> enc_meta = new MetaData;
162    // enc_meta->setCString(kKeyMIMEType, "video/3gpp");
163    enc_meta->setCString(kKeyMIMEType, "video/mp4v-es");
164    enc_meta->setInt32(kKeyWidth, width);
165    enc_meta->setInt32(kKeyHeight, height);
166
167#if USE_OMX_CODEC
168    sp<OMXCodec> encoder =
169        OMXCodec::Create(
170                client.interface(), enc_meta, true /* createEncoder */, decoder);
171#else
172    sp<OMXDecoder> encoder = OMXDecoder::Create(
173            &client, enc_meta, true /* createEncoder */, decoder);
174#endif
175
176#if 1
177    sp<MPEG4Writer> writer = new MPEG4Writer("/sdcard/output.mp4");
178    writer->addSource(enc_meta, encoder);
179    writer->start();
180    sleep(20);
181    printf("stopping now.\n");
182    writer->stop();
183#else
184    encoder->start();
185
186    MediaBuffer *buffer;
187    while (encoder->read(&buffer) == ::OK) {
188        printf("got an output frame of size %d\n", buffer->range_length());
189
190        buffer->release();
191        buffer = NULL;
192    }
193
194    encoder->stop();
195#endif
196
197    client.disconnect();
198#endif
199
200#if 0
201    CameraSource *source = CameraSource::Create();
202    printf("source = %p\n", source);
203
204    for (int i = 0; i < 100; ++i) {
205        MediaBuffer *buffer;
206        status_t err = source->read(&buffer);
207        assert(err == OK);
208
209        printf("got a frame, data=%p, size=%d\n",
210               buffer->data(), buffer->range_length());
211
212        buffer->release();
213        buffer = NULL;
214    }
215
216    delete source;
217    source = NULL;
218#endif
219
220    return 0;
221}
222
223