record.cpp revision 20111aa043c5f404472bc63b90bc5aad906b1101
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 = OMXDecoder::CreateEncoder(&client, enc_meta);
123
124    encoder->setSource(decoder);
125    // encoder->setSource(meta, new DummySource(width, height));
126
127#if 1
128    MPEG4Writer writer("/sdcard/output.mp4");
129    writer.addSource(enc_meta, encoder);
130    writer.start();
131    sleep(120);
132    writer.stop();
133#else
134    encoder->start();
135
136    MediaBuffer *buffer;
137    while (encoder->read(&buffer) == ::OK) {
138        printf("got an output frame of size %d\n", buffer->range_length());
139
140        buffer->release();
141        buffer = NULL;
142    }
143
144    encoder->stop();
145#endif
146
147    delete encoder;
148    encoder = NULL;
149
150    delete decoder;
151    decoder = NULL;
152
153    client.disconnect();
154
155    delete source;
156    source = NULL;
157#endif
158
159#if 0
160    CameraSource *source = CameraSource::Create();
161    printf("source = %p\n", source);
162
163    for (int i = 0; i < 100; ++i) {
164        MediaBuffer *buffer;
165        status_t err = source->read(&buffer);
166        assert(err == OK);
167
168        printf("got a frame, data=%p, size=%d\n",
169               buffer->data(), buffer->range_length());
170
171        buffer->release();
172        buffer = NULL;
173    }
174
175    delete source;
176    source = NULL;
177#endif
178
179    return 0;
180}
181
182