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