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