Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 2ffcb6c4 authored by Jean-Baptiste Queru's avatar Jean-Baptiste Queru
Browse files

eclair snapshot

parent 3ccdc3ef
Loading
Loading
Loading
Loading
+46 −0
Original line number Diff line number Diff line
ifeq ($(BUILD_WITH_FULL_STAGEFRIGHT),true)

LOCAL_PATH:= $(call my-dir)

include $(CLEAR_VARS)

LOCAL_SRC_FILES:=       \
	stagefright.cpp

LOCAL_SHARED_LIBRARIES := \
	libstagefright

LOCAL_C_INCLUDES:= \
	$(JNI_H_INCLUDE) \
	frameworks/base/media/libstagefright \
	$(TOP)/external/opencore/extern_libs_v2/khronos/openmax/include

LOCAL_CFLAGS += -Wno-multichar

LOCAL_MODULE:= stagefright

include $(BUILD_EXECUTABLE)

################################################################################

include $(CLEAR_VARS)

LOCAL_SRC_FILES:=         \
        SineSource.cpp    \
        record.cpp

LOCAL_SHARED_LIBRARIES := \
	libstagefright

LOCAL_C_INCLUDES:= \
	$(JNI_H_INCLUDE) \
	frameworks/base/media/libstagefright \
	$(TOP)/external/opencore/extern_libs_v2/khronos/openmax/include

LOCAL_CFLAGS += -Wno-multichar

LOCAL_MODULE:= record

include $(BUILD_EXECUTABLE)

endif
+101 −0
Original line number Diff line number Diff line
#include "SineSource.h"

#include <math.h>

#include <media/stagefright/MediaBufferGroup.h>
#include <media/stagefright/MediaDebug.h>
#include <media/stagefright/MediaDefs.h>
#include <media/stagefright/MetaData.h>

namespace android {

SineSource::SineSource(int32_t sampleRate, int32_t numChannels)
    : mStarted(false),
      mSampleRate(sampleRate),
      mNumChannels(numChannels),
      mPhase(0),
      mGroup(NULL) {
    CHECK(numChannels == 1 || numChannels == 2);
}

SineSource::~SineSource() {
    if (mStarted) {
        stop();
    }
}

status_t SineSource::start(MetaData *params) {
    CHECK(!mStarted);

    mGroup = new MediaBufferGroup;
    mGroup->add_buffer(new MediaBuffer(kBufferSize));

    mPhase = 0;
    mStarted = true;

    return OK;
}

status_t SineSource::stop() {
    CHECK(mStarted);

    delete mGroup;
    mGroup = NULL;

    mStarted = false;

    return OK;
}

sp<MetaData> SineSource::getFormat() {
    sp<MetaData> meta = new MetaData;
    meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_RAW);
    meta->setInt32(kKeyChannelCount, mNumChannels);
    meta->setInt32(kKeySampleRate, mSampleRate);

    return meta;
}

status_t SineSource::read(
        MediaBuffer **out, const ReadOptions *options) {
    *out = NULL;

    MediaBuffer *buffer;
    status_t err = mGroup->acquire_buffer(&buffer);

    if (err != OK) {
        return err;
    }

    size_t frameSize = mNumChannels * sizeof(int16_t);
    size_t numFramesPerBuffer = buffer->size() / frameSize;

    int16_t *ptr = (int16_t *)buffer->data();

    const double k = kFrequency / mSampleRate * (2.0 * M_PI);

    double x = mPhase * k;
    for (size_t i = 0; i < numFramesPerBuffer; ++i) {
        int16_t amplitude = (int16_t)(32767.0 * sin(x));
        
        *ptr++ = amplitude;
        if (mNumChannels == 2) {
            *ptr++ = amplitude;
        }

        x += k;
    }

    buffer->meta_data()->setInt32(kKeyTimeUnits, mPhase);
    buffer->meta_data()->setInt32(kKeyTimeScale, mSampleRate);

    mPhase += numFramesPerBuffer;

    buffer->set_range(0, numFramesPerBuffer * frameSize);

    *out = buffer;

    return OK;
}

}  // namespace android
+39 −0
Original line number Diff line number Diff line
#ifndef SINE_SOURCE_H_

#define SINE_SOURCE_H_

#include <media/stagefright/MediaSource.h>

namespace android {

struct MediaBufferGroup;

struct SineSource : public MediaSource {
    SineSource(int32_t sampleRate, int32_t numChannels);

    virtual status_t start(MetaData *params);
    virtual status_t stop();

    virtual sp<MetaData> getFormat();

    virtual status_t read(
            MediaBuffer **out, const ReadOptions *options = NULL);

protected:
    virtual ~SineSource();

private:
    enum { kBufferSize = 8192 };
    static const double kFrequency = 500.0;

    bool mStarted;
    int32_t mSampleRate;
    int32_t mNumChannels;
    size_t mPhase;

    MediaBufferGroup *mGroup;
};

}  // namespace android

#endif // SINE_SOURCE_H_
+71 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2009 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef ANDROID_WAVEWRITER_H_

#define ANDROID_WAVEWRITER_H_

namespace android {

class WaveWriter {
public:
    WaveWriter(const char *filename,
               uint16_t num_channels, uint32_t sampling_rate)
        : mFile(fopen(filename, "wb")),
          mTotalBytes(0) {
        fwrite("RIFFxxxxWAVEfmt \x10\x00\x00\x00\x01\x00", 1, 22, mFile); 
        write_u16(num_channels);
        write_u32(sampling_rate);
        write_u32(sampling_rate * num_channels * 2);
        write_u16(num_channels * 2);
        write_u16(16);
        fwrite("dataxxxx", 1, 8, mFile);
    }

    ~WaveWriter() {
        fseek(mFile, 40, SEEK_SET);
        write_u32(mTotalBytes);

        fseek(mFile, 4, SEEK_SET);
        write_u32(36 + mTotalBytes);

        fclose(mFile);
        mFile = NULL;
    }

    void Append(const void *data, size_t size) {
        fwrite(data, 1, size, mFile);
        mTotalBytes += size;
    }

private:
    void write_u16(uint16_t x) {
        fputc(x & 0xff, mFile);
        fputc(x >> 8, mFile);
    }

    void write_u32(uint32_t x) {
        write_u16(x & 0xffff);
        write_u16(x >> 16);
    }

    FILE *mFile;
    size_t mTotalBytes;
};

}  // namespace android

#endif  // ANDROID_WAVEWRITER_H_
+265 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2009 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "SineSource.h"

#include <binder/ProcessState.h>
#include <media/stagefright/AudioPlayer.h>
#include <media/stagefright/CameraSource.h>
#include <media/stagefright/MediaBufferGroup.h>
#include <media/stagefright/MediaDebug.h>
#include <media/stagefright/MediaDefs.h>
#include <media/stagefright/MetaData.h>
#include <media/stagefright/MPEG4Extractor.h>
#include <media/stagefright/MPEG4Writer.h>
#include <media/stagefright/MmapSource.h>
#include <media/stagefright/OMXClient.h>
#include <media/stagefright/OMXCodec.h>
#include <media/MediaPlayerInterface.h>

using namespace android;

#if 0
class DummySource : public MediaSource {
public:
    DummySource(int width, int height)
        : mWidth(width),
          mHeight(height),
          mSize((width * height * 3) / 2) {
        mGroup.add_buffer(new MediaBuffer(mSize));
    }

    virtual sp<MetaData> getFormat() {
        sp<MetaData> meta = new MetaData;
        meta->setInt32(kKeyWidth, mWidth);
        meta->setInt32(kKeyHeight, mHeight);
        meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_RAW);

        return meta;
    }

    virtual status_t start(MetaData *params) {
        return OK;
    }

    virtual status_t stop() {
        return OK;
    }

    virtual status_t read(
            MediaBuffer **buffer, const MediaSource::ReadOptions *options) {
        status_t err = mGroup.acquire_buffer(buffer);
        if (err != OK) {
            return err;
        }

        char x = (char)((double)rand() / RAND_MAX * 255);
        memset((*buffer)->data(), x, mSize);
        (*buffer)->set_range(0, mSize);

        return OK;
    }

protected:
    virtual ~DummySource() {}

private:
    MediaBufferGroup mGroup;
    int mWidth, mHeight;
    size_t mSize;

    DummySource(const DummySource &);
    DummySource &operator=(const DummySource &);
};

sp<MediaSource> createSource(const char *filename) {
    sp<MediaSource> source;

    sp<MPEG4Extractor> extractor =
        new MPEG4Extractor(new MmapSource(filename));

    size_t num_tracks = extractor->countTracks();

    sp<MetaData> meta;
    for (size_t i = 0; i < num_tracks; ++i) {
        meta = extractor->getTrackMetaData(i);
        CHECK(meta.get() != NULL);

        const char *mime;
        if (!meta->findCString(kKeyMIMEType, &mime)) {
            continue;
        }

        if (strncasecmp(mime, "video/", 6)) {
            continue;
        }

        source = extractor->getTrack(i);
        break;
    }

    return source;
}

int main(int argc, char **argv) {
    android::ProcessState::self()->startThreadPool();

#if 1
    if (argc != 2) {
        fprintf(stderr, "usage: %s filename\n", argv[0]);
        return 1;
    }

    OMXClient client;
    CHECK_EQ(client.connect(), OK);

#if 0
    sp<MediaSource> source = createSource(argv[1]);

    if (source == NULL) {
        fprintf(stderr, "Unable to find a suitable video track.\n");
        return 1;
    }

    sp<MetaData> meta = source->getFormat();

    sp<OMXCodec> decoder = OMXCodec::Create(
            client.interface(), meta, false /* createEncoder */, source);

    int width, height;
    bool success = meta->findInt32(kKeyWidth, &width);
    success = success && meta->findInt32(kKeyHeight, &height);
    CHECK(success);
#else
    int width = 320;
    int height = 240;
    sp<MediaSource> decoder = new DummySource(width, height);
#endif

    sp<MetaData> enc_meta = new MetaData;
    // enc_meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_H263);
    enc_meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_MPEG4);
    enc_meta->setInt32(kKeyWidth, width);
    enc_meta->setInt32(kKeyHeight, height);

    sp<OMXCodec> encoder =
        OMXCodec::Create(
                client.interface(), enc_meta, true /* createEncoder */, decoder);

#if 0
    sp<MPEG4Writer> writer = new MPEG4Writer("/sdcard/output.mp4");
    writer->addSource(enc_meta, encoder);
    writer->start();
    sleep(20);
    printf("stopping now.\n");
    writer->stop();
#else
    encoder->start();

    MediaBuffer *buffer;
    while (encoder->read(&buffer) == OK) {
        printf("got an output frame of size %d\n", buffer->range_length());

        buffer->release();
        buffer = NULL;
    }

    encoder->stop();
#endif

    client.disconnect();
#endif

#if 0
    CameraSource *source = CameraSource::Create();
    printf("source = %p\n", source);

    for (int i = 0; i < 100; ++i) {
        MediaBuffer *buffer;
        status_t err = source->read(&buffer);
        CHECK_EQ(err, OK);

        printf("got a frame, data=%p, size=%d\n",
               buffer->data(), buffer->range_length());

        buffer->release();
        buffer = NULL;
    }

    delete source;
    source = NULL;
#endif

    return 0;
}
#else

int main(int argc, char **argv) {
    android::ProcessState::self()->startThreadPool();

    OMXClient client;
    CHECK_EQ(client.connect(), OK);

    const int32_t kSampleRate = 22050;
    const int32_t kNumChannels = 2;
    sp<MediaSource> audioSource = new SineSource(kSampleRate, kNumChannels);

#if 0
    sp<MediaPlayerBase::AudioSink> audioSink;
    AudioPlayer *player = new AudioPlayer(audioSink);
    player->setSource(audioSource);
    player->start();

    sleep(10);

    player->stop();
#endif

    sp<MetaData> encMeta = new MetaData;
    encMeta->setCString(kKeyMIMEType,
            1 ? MEDIA_MIMETYPE_AUDIO_AMR_WB : MEDIA_MIMETYPE_AUDIO_AAC);
    encMeta->setInt32(kKeySampleRate, kSampleRate);
    encMeta->setInt32(kKeyChannelCount, kNumChannels);
    encMeta->setInt32(kKeyMaxInputSize, 8192);

    sp<MediaSource> encoder =
        OMXCodec::Create(client.interface(), encMeta, true, audioSource);

    encoder->start();

    int32_t n = 0;
    status_t err;
    MediaBuffer *buffer;
    while ((err = encoder->read(&buffer)) == OK) {
        printf(".");
        fflush(stdout);

        buffer->release();
        buffer = NULL;

        if (++n == 100) {
            break;
        }
    }
    printf("$\n");

    encoder->stop();

    client.disconnect();

    return 0;
}
#endif
Loading