record.cpp revision 20111aa043c5f404472bc63b90bc5aad906b1101
120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber/* 220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * Copyright (C) 2009 The Android Open Source Project 320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * 420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * Licensed under the Apache License, Version 2.0 (the "License"); 520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * you may not use this file except in compliance with the License. 620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * You may obtain a copy of the License at 720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * 820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * http://www.apache.org/licenses/LICENSE-2.0 920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * 1020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * Unless required by applicable law or agreed to in writing, software 1120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * distributed under the License is distributed on an "AS IS" BASIS, 1220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * See the License for the specific language governing permissions and 1420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * limitations under the License. 1520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber */ 1620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#undef NDEBUG 1820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <assert.h> 1920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 2020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <binder/ProcessState.h> 2120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <media/stagefright/CameraSource.h> 2220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <media/stagefright/MediaBufferGroup.h> 2320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <media/stagefright/MetaData.h> 2420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <media/stagefright/MPEG4Extractor.h> 2520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <media/stagefright/MPEG4Writer.h> 2620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <media/stagefright/MmapSource.h> 2720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <media/stagefright/OMXClient.h> 2820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <media/stagefright/OMXDecoder.h> 2920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 3020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberusing namespace android; 3120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 3220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberclass DummySource : public MediaSource { 3320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberpublic: 3420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber DummySource(int width, int height) 3520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber : mSize((width * height * 3) / 2) { 3620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mGroup.add_buffer(new MediaBuffer(mSize)); 3720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 3820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 3920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber virtual ::status_t getMaxSampleSize(size_t *max_size) { 4020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *max_size = mSize; 4120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ::OK; 4220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 4320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 4420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber virtual ::status_t read(MediaBuffer **buffer) { 4520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber ::status_t err = mGroup.acquire_buffer(buffer); 4620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (err != ::OK) { 4720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return err; 4820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 4920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 5020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber char x = (char)((double)rand() / RAND_MAX * 255); 5120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber memset((*buffer)->data(), x, mSize); 5220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber (*buffer)->set_range(0, mSize); 5320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 5420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ::OK; 5520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 5620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 5720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberprivate: 5820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber MediaBufferGroup mGroup; 5920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber size_t mSize; 6020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 6120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber DummySource(const DummySource &); 6220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber DummySource &operator=(const DummySource &); 6320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}; 6420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 6520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberint main(int argc, char **argv) { 6620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber android::ProcessState::self()->startThreadPool(); 6720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 6820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#if 1 6920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (argc != 2) { 7020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber fprintf(stderr, "usage: %s filename\n", argv[0]); 7120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return 1; 7220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 7320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 7420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber MPEG4Extractor extractor(new MmapSource(argv[1])); 7520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber int num_tracks; 7620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber assert(extractor.countTracks(&num_tracks) == ::OK); 7720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 7820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber MediaSource *source = NULL; 7920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber sp<MetaData> meta; 8020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber for (int i = 0; i < num_tracks; ++i) { 8120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber meta = extractor.getTrackMetaData(i); 8220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber assert(meta.get() != NULL); 8320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 8420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber const char *mime; 8520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (!meta->findCString(kKeyMIMEType, &mime)) { 8620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber continue; 8720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 8820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 8920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (strncasecmp(mime, "video/", 6)) { 9020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber continue; 9120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 9220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 9320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (extractor.getTrack(i, &source) != ::OK) { 9420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber source = NULL; 9520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber continue; 9620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 9720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 9820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 9920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 10020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (source == NULL) { 10120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber fprintf(stderr, "Unable to find a suitable video track.\n"); 10220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return 1; 10320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 10420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 10520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber OMXClient client; 10620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber assert(client.connect() == android::OK); 10720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 10820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber OMXDecoder *decoder = OMXDecoder::Create(&client, meta); 10920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber decoder->setSource(source); 11020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 11120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber int width, height; 11220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber bool success = meta->findInt32(kKeyWidth, &width); 11320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber success = success && meta->findInt32(kKeyHeight, &height); 11420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber assert(success); 11520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 11620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber sp<MetaData> enc_meta = new MetaData; 11720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber // enc_meta->setCString(kKeyMIMEType, "video/3gpp"); 11820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber enc_meta->setCString(kKeyMIMEType, "video/mp4v-es"); 11920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber enc_meta->setInt32(kKeyWidth, width); 12020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber enc_meta->setInt32(kKeyHeight, height); 12120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 12220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber OMXDecoder *encoder = OMXDecoder::CreateEncoder(&client, enc_meta); 12320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 12420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber encoder->setSource(decoder); 12520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber // encoder->setSource(meta, new DummySource(width, height)); 12620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 12720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#if 1 12820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber MPEG4Writer writer("/sdcard/output.mp4"); 12920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber writer.addSource(enc_meta, encoder); 13020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber writer.start(); 13120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber sleep(120); 13220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber writer.stop(); 13320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#else 13420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber encoder->start(); 13520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 13620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber MediaBuffer *buffer; 13720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber while (encoder->read(&buffer) == ::OK) { 13820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber printf("got an output frame of size %d\n", buffer->range_length()); 13920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 14020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber buffer->release(); 14120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber buffer = NULL; 14220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 14320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 14420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber encoder->stop(); 14520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#endif 14620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 14720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber delete encoder; 14820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber encoder = NULL; 14920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 15020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber delete decoder; 15120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber decoder = NULL; 15220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 15320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber client.disconnect(); 15420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 15520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber delete source; 15620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber source = NULL; 15720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#endif 15820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 15920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#if 0 16020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber CameraSource *source = CameraSource::Create(); 16120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber printf("source = %p\n", source); 16220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 16320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber for (int i = 0; i < 100; ++i) { 16420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber MediaBuffer *buffer; 16520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err = source->read(&buffer); 16620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber assert(err == OK); 16720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 16820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber printf("got a frame, data=%p, size=%d\n", 16920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber buffer->data(), buffer->range_length()); 17020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 17120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber buffer->release(); 17220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber buffer = NULL; 17320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 17420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 17520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber delete source; 17620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber source = NULL; 17720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#endif 17820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 17920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return 0; 18020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 18120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 182