record.cpp revision f808c4cf1c3e2c6b18a2e9268bfa3cfc9ca793f8
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/MediaBufferGroup.h> 23#include <media/stagefright/MediaDebug.h> 24#include <media/stagefright/MediaDefs.h> 25#include <media/stagefright/MetaData.h> 26#include <media/stagefright/MediaExtractor.h> 27#include <media/stagefright/MPEG4Writer.h> 28#include <media/stagefright/MmapSource.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 MmapSource(filename)); 109 110 size_t num_tracks = extractor->countTracks(); 111 112 sp<MetaData> meta; 113 for (size_t i = 0; i < num_tracks; ++i) { 114 meta = extractor->getTrackMetaData(i); 115 CHECK(meta.get() != NULL); 116 117 const char *mime; 118 if (!meta->findCString(kKeyMIMEType, &mime)) { 119 continue; 120 } 121 122 if (strncasecmp(mime, "video/", 6)) { 123 continue; 124 } 125 126 source = extractor->getTrack(i); 127 break; 128 } 129 130 return source; 131} 132 133int main(int argc, char **argv) { 134 android::ProcessState::self()->startThreadPool(); 135 136 DataSource::RegisterDefaultSniffers(); 137 138#if 1 139 if (argc != 2) { 140 fprintf(stderr, "usage: %s filename\n", argv[0]); 141 return 1; 142 } 143 144 OMXClient client; 145 CHECK_EQ(client.connect(), OK); 146 147#if 1 148 sp<MediaSource> source = createSource(argv[1]); 149 150 if (source == NULL) { 151 fprintf(stderr, "Unable to find a suitable video track.\n"); 152 return 1; 153 } 154 155 sp<MetaData> meta = source->getFormat(); 156 157 sp<OMXCodec> decoder = OMXCodec::Create( 158 client.interface(), meta, false /* createEncoder */, source); 159 160 int width, height; 161 bool success = meta->findInt32(kKeyWidth, &width); 162 success = success && meta->findInt32(kKeyHeight, &height); 163 CHECK(success); 164#else 165 int width = 800; 166 int height = 480; 167 sp<MediaSource> decoder = new DummySource(width, height); 168#endif 169 170 sp<MetaData> enc_meta = new MetaData; 171 // enc_meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_H263); 172 enc_meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_MPEG4); 173 enc_meta->setInt32(kKeyWidth, width); 174 enc_meta->setInt32(kKeyHeight, height); 175 176 sp<OMXCodec> encoder = 177 OMXCodec::Create( 178 client.interface(), enc_meta, true /* createEncoder */, decoder); 179 180#if 1 181 sp<MPEG4Writer> writer = new MPEG4Writer("/sdcard/output.mp4"); 182 writer->addSource(encoder); 183 writer->start(); 184 while (!writer->reachedEOS()) { 185 usleep(100000); 186 } 187 writer->stop(); 188#else 189 encoder->start(); 190 191 MediaBuffer *buffer; 192 while (encoder->read(&buffer) == OK) { 193 int32_t isSync; 194 if (!buffer->meta_data()->findInt32(kKeyIsSyncFrame, &isSync)) { 195 isSync = false; 196 } 197 198 printf("got an output frame of size %d%s\n", buffer->range_length(), 199 isSync ? " (SYNC)" : ""); 200 201 buffer->release(); 202 buffer = NULL; 203 } 204 205 encoder->stop(); 206#endif 207 208 client.disconnect(); 209#endif 210 211#if 0 212 CameraSource *source = CameraSource::Create(); 213 printf("source = %p\n", source); 214 215 for (int i = 0; i < 100; ++i) { 216 MediaBuffer *buffer; 217 status_t err = source->read(&buffer); 218 CHECK_EQ(err, OK); 219 220 printf("got a frame, data=%p, size=%d\n", 221 buffer->data(), buffer->range_length()); 222 223 buffer->release(); 224 buffer = NULL; 225 } 226 227 delete source; 228 source = NULL; 229#endif 230 231 return 0; 232} 233#else 234 235int main(int argc, char **argv) { 236 android::ProcessState::self()->startThreadPool(); 237 238 OMXClient client; 239 CHECK_EQ(client.connect(), OK); 240 241 const int32_t kSampleRate = 22050; 242 const int32_t kNumChannels = 2; 243 sp<MediaSource> audioSource = new SineSource(kSampleRate, kNumChannels); 244 245#if 0 246 sp<MediaPlayerBase::AudioSink> audioSink; 247 AudioPlayer *player = new AudioPlayer(audioSink); 248 player->setSource(audioSource); 249 player->start(); 250 251 sleep(10); 252 253 player->stop(); 254#endif 255 256 sp<MetaData> encMeta = new MetaData; 257 encMeta->setCString(kKeyMIMEType, 258 1 ? MEDIA_MIMETYPE_AUDIO_AMR_WB : MEDIA_MIMETYPE_AUDIO_AAC); 259 encMeta->setInt32(kKeySampleRate, kSampleRate); 260 encMeta->setInt32(kKeyChannelCount, kNumChannels); 261 encMeta->setInt32(kKeyMaxInputSize, 8192); 262 263 sp<MediaSource> encoder = 264 OMXCodec::Create(client.interface(), encMeta, true, audioSource); 265 266 encoder->start(); 267 268 int32_t n = 0; 269 status_t err; 270 MediaBuffer *buffer; 271 while ((err = encoder->read(&buffer)) == OK) { 272 printf("."); 273 fflush(stdout); 274 275 buffer->release(); 276 buffer = NULL; 277 278 if (++n == 100) { 279 break; 280 } 281 } 282 printf("$\n"); 283 284 encoder->stop(); 285 286 client.disconnect(); 287 288 return 0; 289} 290#endif 291