record.cpp revision 03b268eac37ca2589bfff0bf58daf79d29cc14f4
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 0 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 = 720; 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->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_AVC); 177 enc_meta->setInt32(kKeyWidth, width); 178 enc_meta->setInt32(kKeyHeight, height); 179 180 sp<MediaSource> encoder = 181 OMXCodec::Create( 182 client.interface(), enc_meta, true /* createEncoder */, decoder); 183 184#if 1 185 sp<MPEG4Writer> writer = new MPEG4Writer("/sdcard/output.mp4"); 186 writer->addSource(encoder); 187 writer->start(); 188 while (!writer->reachedEOS()) { 189 usleep(100000); 190 } 191 writer->stop(); 192#else 193 encoder->start(); 194 195 MediaBuffer *buffer; 196 while (encoder->read(&buffer) == OK) { 197 int32_t isSync; 198 if (!buffer->meta_data()->findInt32(kKeyIsSyncFrame, &isSync)) { 199 isSync = false; 200 } 201 202 printf("got an output frame of size %d%s\n", buffer->range_length(), 203 isSync ? " (SYNC)" : ""); 204 205 buffer->release(); 206 buffer = NULL; 207 } 208 209 encoder->stop(); 210#endif 211 212 client.disconnect(); 213#endif 214 215#if 0 216 CameraSource *source = CameraSource::Create(); 217 source->start(); 218 219 printf("source = %p\n", source); 220 221 for (int i = 0; i < 100; ++i) { 222 MediaBuffer *buffer; 223 status_t err = source->read(&buffer); 224 CHECK_EQ(err, OK); 225 226 printf("got a frame, data=%p, size=%d\n", 227 buffer->data(), buffer->range_length()); 228 229 buffer->release(); 230 buffer = NULL; 231 } 232 233 source->stop(); 234 235 delete source; 236 source = NULL; 237#endif 238 239 return 0; 240} 241#else 242 243int main(int argc, char **argv) { 244 android::ProcessState::self()->startThreadPool(); 245 246 OMXClient client; 247 CHECK_EQ(client.connect(), OK); 248 249 const int32_t kSampleRate = 22050; 250 const int32_t kNumChannels = 2; 251 sp<MediaSource> audioSource = new SineSource(kSampleRate, kNumChannels); 252 253#if 0 254 sp<MediaPlayerBase::AudioSink> audioSink; 255 AudioPlayer *player = new AudioPlayer(audioSink); 256 player->setSource(audioSource); 257 player->start(); 258 259 sleep(10); 260 261 player->stop(); 262#endif 263 264 sp<MetaData> encMeta = new MetaData; 265 encMeta->setCString(kKeyMIMEType, 266 1 ? MEDIA_MIMETYPE_AUDIO_AMR_WB : MEDIA_MIMETYPE_AUDIO_AAC); 267 encMeta->setInt32(kKeySampleRate, kSampleRate); 268 encMeta->setInt32(kKeyChannelCount, kNumChannels); 269 encMeta->setInt32(kKeyMaxInputSize, 8192); 270 271 sp<MediaSource> encoder = 272 OMXCodec::Create(client.interface(), encMeta, true, audioSource); 273 274 encoder->start(); 275 276 int32_t n = 0; 277 status_t err; 278 MediaBuffer *buffer; 279 while ((err = encoder->read(&buffer)) == OK) { 280 printf("."); 281 fflush(stdout); 282 283 buffer->release(); 284 buffer = NULL; 285 286 if (++n == 100) { 287 break; 288 } 289 } 290 printf("$\n"); 291 292 encoder->stop(); 293 294 client.disconnect(); 295 296 return 0; 297} 298#endif 299