record.cpp revision b93ad64a423975748c7f5e1a5ea94ab8681bc899
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#include "SineSource.h" 18 19#include <binder/ProcessState.h> 20#include <media/stagefright/AudioPlayer.h> 21#include <media/stagefright/CameraSource.h> 22#include <media/stagefright/FileSource.h> 23#include <media/stagefright/MediaBufferGroup.h> 24#include <media/stagefright/MediaDebug.h> 25#include <media/stagefright/MediaDefs.h> 26#include <media/stagefright/MetaData.h> 27#include <media/stagefright/MediaExtractor.h> 28#include <media/stagefright/MPEG4Writer.h> 29#include <media/stagefright/OMXClient.h> 30#include <media/stagefright/OMXCodec.h> 31#include <media/MediaPlayerInterface.h> 32 33using namespace android; 34 35#if 1 36class DummySource : public MediaSource { 37 static const int32_t kFramerate = 24; // fps 38 39public: 40 DummySource(int width, int height) 41 : mWidth(width), 42 mHeight(height), 43 mSize((width * height * 3) / 2) { 44 mGroup.add_buffer(new MediaBuffer(mSize)); 45 } 46 47 virtual sp<MetaData> getFormat() { 48 sp<MetaData> meta = new MetaData; 49 meta->setInt32(kKeyWidth, mWidth); 50 meta->setInt32(kKeyHeight, mHeight); 51 meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_RAW); 52 53 return meta; 54 } 55 56 virtual status_t start(MetaData *params) { 57 mNumFramesOutput = 0; 58 return OK; 59 } 60 61 virtual status_t stop() { 62 return OK; 63 } 64 65 virtual status_t read( 66 MediaBuffer **buffer, const MediaSource::ReadOptions *options) { 67 if (mNumFramesOutput == kFramerate * 10) { 68 // Stop returning data after 10 secs. 69 return ERROR_END_OF_STREAM; 70 } 71 72 // printf("DummySource::read\n"); 73 status_t err = mGroup.acquire_buffer(buffer); 74 if (err != OK) { 75 return err; 76 } 77 78 char x = (char)((double)rand() / RAND_MAX * 255); 79 memset((*buffer)->data(), x, mSize); 80 (*buffer)->set_range(0, mSize); 81 (*buffer)->meta_data()->clear(); 82 (*buffer)->meta_data()->setInt64( 83 kKeyTime, (mNumFramesOutput * 1000000) / kFramerate); 84 ++mNumFramesOutput; 85 86 // printf("DummySource::read - returning buffer\n"); 87 // LOGI("DummySource::read - returning buffer"); 88 return OK; 89 } 90 91protected: 92 virtual ~DummySource() {} 93 94private: 95 MediaBufferGroup mGroup; 96 int mWidth, mHeight; 97 size_t mSize; 98 int64_t mNumFramesOutput;; 99 100 DummySource(const DummySource &); 101 DummySource &operator=(const DummySource &); 102}; 103 104sp<MediaSource> createSource(const char *filename) { 105 sp<MediaSource> source; 106 107 sp<MediaExtractor> extractor = 108 MediaExtractor::Create(new FileSource(filename)); 109 if (extractor == NULL) { 110 return NULL; 111 } 112 113 size_t num_tracks = extractor->countTracks(); 114 115 sp<MetaData> meta; 116 for (size_t i = 0; i < num_tracks; ++i) { 117 meta = extractor->getTrackMetaData(i); 118 CHECK(meta.get() != NULL); 119 120 const char *mime; 121 if (!meta->findCString(kKeyMIMEType, &mime)) { 122 continue; 123 } 124 125 if (strncasecmp(mime, "video/", 6)) { 126 continue; 127 } 128 129 source = extractor->getTrack(i); 130 break; 131 } 132 133 return source; 134} 135 136int main(int argc, char **argv) { 137 android::ProcessState::self()->startThreadPool(); 138 139 DataSource::RegisterDefaultSniffers(); 140 141#if 1 142 if (argc != 2) { 143 fprintf(stderr, "usage: %s filename\n", argv[0]); 144 return 1; 145 } 146 147 OMXClient client; 148 CHECK_EQ(client.connect(), OK); 149 150#if 1 151 sp<MediaSource> source = createSource(argv[1]); 152 153 if (source == NULL) { 154 fprintf(stderr, "Unable to find a suitable video track.\n"); 155 return 1; 156 } 157 158 sp<MetaData> meta = source->getFormat(); 159 160 sp<MediaSource> decoder = OMXCodec::Create( 161 client.interface(), meta, false /* createEncoder */, source); 162 163 int width, height; 164 bool success = meta->findInt32(kKeyWidth, &width); 165 success = success && meta->findInt32(kKeyHeight, &height); 166 CHECK(success); 167#else 168 int width = 800; 169 int height = 480; 170 sp<MediaSource> decoder = new DummySource(width, height); 171#endif 172 173 sp<MetaData> enc_meta = new MetaData; 174 // enc_meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_H263); 175 enc_meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_MPEG4); 176 enc_meta->setInt32(kKeyWidth, width); 177 enc_meta->setInt32(kKeyHeight, height); 178 179 sp<MediaSource> encoder = 180 OMXCodec::Create( 181 client.interface(), enc_meta, true /* createEncoder */, decoder); 182 183#if 1 184 sp<MPEG4Writer> writer = new MPEG4Writer("/sdcard/output.mp4"); 185 writer->addSource(encoder); 186 writer->start(); 187 while (!writer->reachedEOS()) { 188 usleep(100000); 189 } 190 writer->stop(); 191#else 192 encoder->start(); 193 194 MediaBuffer *buffer; 195 while (encoder->read(&buffer) == OK) { 196 int32_t isSync; 197 if (!buffer->meta_data()->findInt32(kKeyIsSyncFrame, &isSync)) { 198 isSync = false; 199 } 200 201 printf("got an output frame of size %d%s\n", buffer->range_length(), 202 isSync ? " (SYNC)" : ""); 203 204 buffer->release(); 205 buffer = NULL; 206 } 207 208 encoder->stop(); 209#endif 210 211 client.disconnect(); 212#endif 213 214#if 0 215 CameraSource *source = CameraSource::Create(); 216 printf("source = %p\n", source); 217 218 for (int i = 0; i < 100; ++i) { 219 MediaBuffer *buffer; 220 status_t err = source->read(&buffer); 221 CHECK_EQ(err, OK); 222 223 printf("got a frame, data=%p, size=%d\n", 224 buffer->data(), buffer->range_length()); 225 226 buffer->release(); 227 buffer = NULL; 228 } 229 230 delete source; 231 source = NULL; 232#endif 233 234 return 0; 235} 236#else 237 238int main(int argc, char **argv) { 239 android::ProcessState::self()->startThreadPool(); 240 241 OMXClient client; 242 CHECK_EQ(client.connect(), OK); 243 244 const int32_t kSampleRate = 22050; 245 const int32_t kNumChannels = 2; 246 sp<MediaSource> audioSource = new SineSource(kSampleRate, kNumChannels); 247 248#if 0 249 sp<MediaPlayerBase::AudioSink> audioSink; 250 AudioPlayer *player = new AudioPlayer(audioSink); 251 player->setSource(audioSource); 252 player->start(); 253 254 sleep(10); 255 256 player->stop(); 257#endif 258 259 sp<MetaData> encMeta = new MetaData; 260 encMeta->setCString(kKeyMIMEType, 261 1 ? MEDIA_MIMETYPE_AUDIO_AMR_WB : MEDIA_MIMETYPE_AUDIO_AAC); 262 encMeta->setInt32(kKeySampleRate, kSampleRate); 263 encMeta->setInt32(kKeyChannelCount, kNumChannels); 264 encMeta->setInt32(kKeyMaxInputSize, 8192); 265 266 sp<MediaSource> encoder = 267 OMXCodec::Create(client.interface(), encMeta, true, audioSource); 268 269 encoder->start(); 270 271 int32_t n = 0; 272 status_t err; 273 MediaBuffer *buffer; 274 while ((err = encoder->read(&buffer)) == OK) { 275 printf("."); 276 fflush(stdout); 277 278 buffer->release(); 279 buffer = NULL; 280 281 if (++n == 100) { 282 break; 283 } 284 } 285 printf("$\n"); 286 287 encoder->stop(); 288 289 client.disconnect(); 290 291 return 0; 292} 293#endif 294