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

Commit 53a76bd0 authored by Andreas Huber's avatar Andreas Huber
Browse files

Split the ColorConverter off SoftwareRenderer, metadata support in stagefright.

parent 2d295a96
Loading
Loading
Loading
Loading
+65 −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 COLOR_CONVERTER_H_

#define COLOR_CONVERTER_H_

#include <sys/types.h>

#include <OMX_Video.h>

namespace android {

struct ColorConverter {
    ColorConverter(OMX_COLOR_FORMATTYPE from, OMX_COLOR_FORMATTYPE to);
    ~ColorConverter();

    bool isValid() const;

    void convert(
            size_t width, size_t height,
            const void *srcBits, size_t srcSkip,
            void *dstBits, size_t dstSkip);

private:
    OMX_COLOR_FORMATTYPE mSrcFormat, mDstFormat;
    uint8_t *mClip;

    uint8_t *initClip();

    void convertCbYCrY(
            size_t width, size_t height,
            const void *srcBits, size_t srcSkip,
            void *dstBits, size_t dstSkip);

    void convertYUV420Planar(
            size_t width, size_t height,
            const void *srcBits, size_t srcSkip,
            void *dstBits, size_t dstSkip);

    void convertQCOMYUV420SemiPlanar(
            size_t width, size_t height,
            const void *srcBits, size_t srcSkip,
            void *dstBits, size_t dstSkip);

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

}  // namespace android

#endif  // COLOR_CONVERTER_H_
+2 −9
Original line number Diff line number Diff line
@@ -18,7 +18,7 @@

#define SOFTWARE_RENDERER_H_

#include <OMX_Video.h>
#include <media/stagefright/ColorConverter.h>
#include <media/stagefright/VideoRenderer.h>
#include <utils/RefBase.h>

@@ -41,13 +41,8 @@ public:
            const void *data, size_t size, void *platformPrivate);

private:
    uint8_t *initClip();

    void renderCbYCrY(const void *data, size_t size);
    void renderYUV420Planar(const void *data, size_t size);
    void renderQCOMYUV420SemiPlanar(const void *data, size_t size);

    OMX_COLOR_FORMATTYPE mColorFormat;
    ColorConverter mConverter;
    sp<ISurface> mISurface;
    size_t mDisplayWidth, mDisplayHeight;
    size_t mDecodedWidth, mDecodedHeight;
@@ -55,8 +50,6 @@ private:
    sp<MemoryHeapBase> mMemoryHeap;
    int mIndex;

    uint8_t *mClip;

    SoftwareRenderer(const SoftwareRenderer &);
    SoftwareRenderer &operator=(const SoftwareRenderer &);
};
+3 −2
Original line number Diff line number Diff line
@@ -19,7 +19,8 @@ LOCAL_SRC_FILES:= \
ifeq ($(BUILD_WITH_FULL_STAGEFRIGHT),true)

LOCAL_SRC_FILES +=                      \
    StagefrightPlayer.cpp
    StagefrightPlayer.cpp               \
    StagefrightMetadataRetriever.cpp

LOCAL_CFLAGS += -DBUILD_WITH_FULL_STAGEFRIGHT=1

+8 −1
Original line number Diff line number Diff line
@@ -37,6 +37,7 @@
#include "VorbisMetadataRetriever.h"
#include "MidiMetadataRetriever.h"
#include "MetadataRetrieverClient.h"
#include "StagefrightMetadataRetriever.h"

namespace android {

@@ -105,9 +106,15 @@ static sp<MediaMetadataRetrieverBase> createRetriever(player_type playerType)
            LOGV("create midi metadata retriever");
            p = new MidiMetadataRetriever();
            break;
#if BUILD_WITH_FULL_STAGEFRIGHT
        case STAGEFRIGHT_PLAYER:
            LOGV("create StagefrightMetadataRetriever");
            p = new StagefrightMetadataRetriever;
            break;
#endif
        default:
            // TODO:
            // support for STAGEFRIGHT_PLAYER and TEST_PLAYER
            // support for TEST_PLAYER
            LOGE("player type %d is not supported",  playerType);
            break;
    }
+194 −0
Original line number Diff line number Diff line
/*
**
** Copyright 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.
*/

//#define LOG_NDEBUG 0
#define LOG_TAG "StagefrightMetadataRetriever"
#include <utils/Log.h>

#include "StagefrightMetadataRetriever.h"

#include <media/stagefright/CachingDataSource.h>
#include <media/stagefright/ColorConverter.h>
#include <media/stagefright/DataSource.h>
#include <media/stagefright/HTTPDataSource.h>
#include <media/stagefright/MediaDebug.h>
#include <media/stagefright/MediaExtractor.h>
#include <media/stagefright/MetaData.h>
#include <media/stagefright/MmapSource.h>
#include <media/stagefright/OMXCodec.h>

namespace android {

StagefrightMetadataRetriever::StagefrightMetadataRetriever() {
    LOGV("StagefrightMetadataRetriever()");

    DataSource::RegisterDefaultSniffers();
    CHECK_EQ(mClient.connect(), OK);
}

StagefrightMetadataRetriever::~StagefrightMetadataRetriever() {
    LOGV("~StagefrightMetadataRetriever()");
    mClient.disconnect();
}

status_t StagefrightMetadataRetriever::setDataSource(const char *uri) {
    LOGV("setDataSource(%s)", uri);

    sp<DataSource> source;
    if (!strncasecmp("file://", uri, 7)) {
        sp<MmapSource> mmapSource = new MmapSource(uri + 7);
        if (mmapSource->InitCheck() != OK) {
            return ERROR_IO;
        }
        source = mmapSource;
    } else if (!strncasecmp("http://", uri, 7)) {
        source = new HTTPDataSource(uri);
        source = new CachingDataSource(source, 64 * 1024, 10);
    } else {
        // Assume it's a filename.
        sp<MmapSource> mmapSource = new MmapSource(uri);
        if (mmapSource->InitCheck() != OK) {
            return ERROR_IO;
        }
        source = mmapSource;
    }

    mExtractor = MediaExtractor::Create(source);

    return mExtractor.get() != NULL ? OK : UNKNOWN_ERROR;
}

status_t StagefrightMetadataRetriever::setDataSource(
        int fd, int64_t offset, int64_t length) {
    LOGV("setDataSource(%d, %lld, %lld)", fd, offset, length);

    mExtractor = MediaExtractor::Create(
            new MmapSource(fd, offset, length));

    return OK;
}

VideoFrame *StagefrightMetadataRetriever::captureFrame() {
    LOGV("captureFrame");

    if (mExtractor.get() == NULL) {
        LOGE("no extractor.");
        return NULL;
    }

    size_t n = mExtractor->countTracks();
    size_t i;
    for (i = 0; i < n; ++i) {
        sp<MetaData> meta = mExtractor->getTrackMetaData(i);

        const char *mime;
        CHECK(meta->findCString(kKeyMIMEType, &mime));

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

    if (i == n) {
        LOGE("no video track found.");
        return NULL;
    }

    sp<MediaSource> source = mExtractor->getTrack(i);

    if (source.get() == NULL) {
        LOGE("unable to instantiate video track.");
        return NULL;
    }

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

    sp<MediaSource> decoder =
        OMXCodec::Create(
                mClient.interface(), meta, false, source);

    if (decoder.get() == NULL) {
        LOGE("unable to instantiate video decoder.");

        return NULL;
    }

    decoder->start();

    MediaBuffer *buffer;
    status_t err = decoder->read(&buffer);

    if (err != OK) {
        CHECK_EQ(buffer, NULL);

        LOGE("decoding frame failed.");
        decoder->stop();

        return NULL;
    }

    LOGI("successfully decoded video frame.");

    meta = decoder->getFormat();

    int32_t width, height;
    CHECK(meta->findInt32(kKeyWidth, &width));
    CHECK(meta->findInt32(kKeyHeight, &height));

    VideoFrame *frame = new VideoFrame;
    frame->mWidth = width;
    frame->mHeight = height;
    frame->mDisplayWidth = width;
    frame->mDisplayHeight = height;
    frame->mSize = width * height * 2;
    frame->mData = new uint8_t[frame->mSize];

    int32_t srcFormat;
    CHECK(meta->findInt32(kKeyColorFormat, &srcFormat));

    ColorConverter converter(
            (OMX_COLOR_FORMATTYPE)srcFormat, OMX_COLOR_Format16bitRGB565);
    CHECK(converter.isValid());

    converter.convert(
            width, height,
            (const uint8_t *)buffer->data() + buffer->range_offset(),
            0,
            frame->mData, width * 2);

    buffer->release();
    buffer = NULL;

    decoder->stop();

    return frame;
}

MediaAlbumArt *StagefrightMetadataRetriever::extractAlbumArt() {
    LOGV("extractAlbumArt (extractor: %s)", mExtractor.get() != NULL ? "YES" : "NO");

    return NULL;
}

const char *StagefrightMetadataRetriever::extractMetadata(int keyCode) {
    LOGV("extractMetadata %d (extractor: %s)",
         keyCode, mExtractor.get() != NULL ? "YES" : "NO");

    return NULL;
}

}  // namespace android
Loading