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