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

Commit 5614c2c6 authored by James Dong's avatar James Dong Committed by Android Git Automerger
Browse files

am 02f5b544: Initial checkins of the mpeg4 and h263 software decoders based on PV

Merge commit '02f5b544' into eclair-mr2-plus-aosp

* commit '02f5b544':
  Initial checkins of the mpeg4 and h263 software decoders based on PV
parents bc1c8847 02f5b544
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -59,6 +59,7 @@ LOCAL_STATIC_LIBRARIES := \
        libstagefright_amrnbenc \
        libstagefright_amrwbdec \
        libstagefright_avcdec \
        libstagefright_m4vh263dec \
        libstagefright_mp3dec

LOCAL_SHARED_LIBRARIES += \
+5 −0
Original line number Diff line number Diff line
@@ -24,6 +24,7 @@
#include "include/AMRNBEncoder.h"
#include "include/AMRWBDecoder.h"
#include "include/AVCDecoder.h"
#include "include/M4vH263Decoder.h"
#include "include/MP3Decoder.h"
#endif

@@ -70,6 +71,7 @@ FACTORY_CREATE(AMRNBDecoder)
FACTORY_CREATE(AMRWBDecoder)
FACTORY_CREATE(AACDecoder)
FACTORY_CREATE(AVCDecoder)
FACTORY_CREATE(M4vH263Decoder)
FACTORY_CREATE(AMRNBEncoder)

static sp<MediaSource> InstantiateSoftwareCodec(
@@ -85,6 +87,7 @@ static sp<MediaSource> InstantiateSoftwareCodec(
        FACTORY_REF(AMRWBDecoder)
        FACTORY_REF(AACDecoder)
        FACTORY_REF(AVCDecoder)
        FACTORY_REF(M4vH263Decoder)
        FACTORY_REF(AMRNBEncoder)
    };
    for (size_t i = 0;
@@ -120,9 +123,11 @@ static const CodecInfo kDecoderInfo[] = {
    { MEDIA_MIMETYPE_AUDIO_AAC, "OMX.PV.aacdec" },
    { MEDIA_MIMETYPE_VIDEO_MPEG4, "OMX.qcom.video.decoder.mpeg4" },
    { MEDIA_MIMETYPE_VIDEO_MPEG4, "OMX.TI.Video.Decoder" },
    OPTIONAL(MEDIA_MIMETYPE_VIDEO_MPEG4, "M4vH264Decoder")
    { MEDIA_MIMETYPE_VIDEO_MPEG4, "OMX.PV.mpeg4dec" },
    { MEDIA_MIMETYPE_VIDEO_H263, "OMX.qcom.video.decoder.h263" },
    { MEDIA_MIMETYPE_VIDEO_H263, "OMX.TI.Video.Decoder" },
    OPTIONAL(MEDIA_MIMETYPE_VIDEO_H263, "M4vH264Decoder")
    { MEDIA_MIMETYPE_VIDEO_H263, "OMX.PV.h263dec" },
    { MEDIA_MIMETYPE_VIDEO_AVC, "OMX.qcom.video.decoder.avc" },
    { MEDIA_MIMETYPE_VIDEO_AVC, "OMX.TI.Video.Decoder" },
+4 −0
Original line number Diff line number Diff line
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)

include $(call all-makefiles-under,$(LOCAL_PATH))
+50 −0
Original line number Diff line number Diff line
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)

LOCAL_SRC_FILES := \
 	M4vH263Decoder.cpp \
 	src/adaptive_smooth_no_mmx.cpp \
 	src/bitstream.cpp \
 	src/block_idct.cpp \
 	src/cal_dc_scaler.cpp \
 	src/chvr_filter.cpp \
 	src/chv_filter.cpp \
 	src/combined_decode.cpp \
 	src/conceal.cpp \
 	src/datapart_decode.cpp \
 	src/dcac_prediction.cpp \
 	src/dec_pred_intra_dc.cpp \
 	src/deringing_chroma.cpp \
 	src/deringing_luma.cpp \
 	src/find_min_max.cpp \
 	src/get_pred_adv_b_add.cpp \
 	src/get_pred_outside.cpp \
 	src/idct.cpp \
 	src/idct_vca.cpp \
 	src/mb_motion_comp.cpp \
 	src/mb_utils.cpp \
 	src/packet_util.cpp \
 	src/post_filter.cpp \
 	src/post_proc_semaphore.cpp \
 	src/pp_semaphore_chroma_inter.cpp \
 	src/pp_semaphore_luma.cpp \
 	src/pvdec_api.cpp \
 	src/scaling_tab.cpp \
 	src/vlc_decode.cpp \
 	src/vlc_dequant.cpp \
 	src/vlc_tab.cpp \
 	src/vop.cpp \
 	src/zigzag_tab.cpp


LOCAL_MODULE := libstagefright_m4vh263dec

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

LOCAL_CFLAGS := -DOSCL_EXPORT_REF= -DOSCL_IMPORT_REF=

include $(BUILD_STATIC_LIBRARY)
+198 −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.
 */
#define LOG_NDEBUG 0
#define LOG_TAG "M4vH263Decoder"

#include "ESDS.h"
#include "M4vH263Decoder.h"

#include "mp4dec_api.h"

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

namespace android {

M4vH263Decoder::M4vH263Decoder(const sp<MediaSource> &source)
    : mSource(source),
      mStarted(false),
      mHandle(new tagvideoDecControls),
      mInputBuffer(NULL),
      mNumSamplesOutput(0) {
    memset(mHandle, 0, sizeof(tagvideoDecControls));

    mFormat = new MetaData;
    mFormat->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_RAW);
    CHECK(mSource->getFormat()->findInt32(kKeyWidth, &mWidth));
    CHECK(mSource->getFormat()->findInt32(kKeyHeight, &mHeight));
    mFormat->setInt32(kKeyWidth, mWidth);
    mFormat->setInt32(kKeyHeight, mHeight);
    mFormat->setInt32(kKeyColorFormat, OMX_COLOR_FormatYUV420Planar);
    mFormat->setCString(kKeyDecoderComponent, "M4vH263Decoder");

}

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

    delete mHandle;
    mHandle = NULL;
}

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

    const char *mime = NULL;
    CHECK(mSource->getFormat()->findCString(kKeyMIMEType, &mime));

    MP4DecodingMode mode;
    if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_MPEG4, mime)) {
        mode = MPEG4_MODE;
    } else {
        CHECK(!strcasecmp(MEDIA_MIMETYPE_VIDEO_H263, mime));
        mode = H263_MODE;
    }

    uint32_t type;
    const void *data = NULL;
    size_t size = 0;
    uint8_t *vol_data = NULL;
    int32_t vol_size = 0;
    if (mSource->getFormat()->findData(kKeyESDS, &type, &data, &size)) {
        ESDS esds((const uint8_t *)data, size);
        CHECK_EQ(esds.InitCheck(), OK);

        const void *codec_specific_data;
        size_t codec_specific_data_size;
        esds.getCodecSpecificInfo(&codec_specific_data, &codec_specific_data_size);

        vol_data = (uint8_t *) codec_specific_data;
        vol_size = codec_specific_data_size;
    } else {
        vol_data = NULL;
        vol_size = 0;
    }
    CHECK_EQ(PV_TRUE, PVInitVideoDecoder(
            mHandle, &vol_data, &vol_size, 1, mWidth, mHeight, mode));
    MP4DecodingMode actualMode = PVGetDecBitstreamMode(mHandle);
    CHECK_EQ(mode, actualMode);

    PVSetPostProcType((VideoDecControls *) mHandle, 0);
    size_t frameSize = (((mWidth + 15) & - 16) * ((mHeight + 15) & - 16) * 3) / 2;
    for (uint32_t i = 0; i < 2; ++i) {
        mFrames[i] = new MediaBuffer(frameSize);
        mFrames[i]->setObserver(this);
    }
    PVSetReferenceYUV(mHandle, (uint8_t *)mFrames[1]->data());

    mSource->start();

    mNumSamplesOutput = 0;
    mStarted = true;

    return OK;
}

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

    if (mInputBuffer) {
        mInputBuffer->release();
        mInputBuffer = NULL;
    }

    mSource->stop();

    releaseFrames();

    mStarted = false;
    return (PVCleanUpVideoDecoder(mHandle) == PV_TRUE)? OK: UNKNOWN_ERROR;
}

sp<MetaData> M4vH263Decoder::getFormat() {
    return mFormat;
}

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

    int64_t seekTimeUs;
    if (options && options->getSeekTo(&seekTimeUs)) {
        CHECK_EQ(PVResetVideoDecoder(mHandle), PV_TRUE);
    }

    MediaBuffer *inputBuffer = NULL;
    status_t err = mSource->read(&inputBuffer, options);
    if (err != OK) {
        return err;
    }

    uint8_t *bitstream = (uint8_t *) inputBuffer->data() + inputBuffer->range_offset();
    uint32_t timestamp = 0xFFFFFFFF;
    int32_t bufferSize = inputBuffer->range_length();
    uint32_t useExtTimestamp = 0;
    CHECK_EQ(PV_TRUE, PVDecodeVideoFrame(mHandle, &bitstream, &timestamp, &bufferSize,
            &useExtTimestamp,  (uint8_t *)mFrames[mNumSamplesOutput & 0x01]->data()));

    // Check whether video dimension is changed.
    // If so, notify the client about the change.
    int32_t width, height;
    PVGetVideoDimensions(mHandle, &width, &height);
    if (mWidth != width || mHeight != height) {
        mFormat->setInt32(kKeyWidth, width);
        mFormat->setInt32(kKeyHeight, height);
        return INFO_FORMAT_CHANGED;
    }

    PVSetReferenceYUV(mHandle, (uint8_t *)mFrames[mNumSamplesOutput & 0x01]->data());
    *out = mFrames[mNumSamplesOutput & 0x01];
    (*out)->add_ref();

    int64_t timeUs;
    CHECK(inputBuffer->meta_data()->findInt64(kKeyTime, &timeUs));
    (*out)->meta_data()->setInt64(kKeyTime, timeUs);

    ++mNumSamplesOutput;
    inputBuffer->release();

    return OK;
}

void M4vH263Decoder::releaseFrames() {
    for (size_t i = 0; i < sizeof(mFrames) / sizeof(mFrames[0]); ++i) {
        MediaBuffer *buffer = mFrames[i];

        buffer->setObserver(NULL);
        buffer->release();

        mFrames[i] = NULL;
    }
}

void M4vH263Decoder::signalBufferReturned(MediaBuffer *buffer) {
    LOGV("signalBufferReturned");
}


}  // namespace android
Loading