使用 CMakeLists.txt 编译 SO 提供给第三方调用(1)

创建 c++ 项目,

将 mainactive 调用 c++ 部分的 java 代码全部去掉,这个只要用来 编译 so 文件

将  native-lib.cpp 删掉

新增一个 使用 mediacodec 进行解码 h264 的类的头文件

#ifndef TESTADD_DECODEOP_H
#define TESTADD_DECODEOP_H
class AMediaCodec;
class DecodeOp
{
private:
    int mWidth;
    int mHeight;
    int mOriFrameSize;
    int mFrameSize;
    AMediaCodec *mMediaCodec;

public:
    int init(int width, int height);
    int fini();
    int decode(char *bufData, int bufSize, char *outBuf);

};
#endif //TESTADD_DECODEOP_H

新增一个 cpp文件 DecodeOp.cpp

不明白代码 mOriFrameSize = width * height * 3 / 2;   这个应该是 Y 分量 应该是 /3 才对啊 

#include "DecodeOp.h"
#include <media/NdkMediaCodec.h>
//#include "CommonOp.h"
#include <stdlib.h>
#include <stdio.h>
#include <string.h>

#define MIN(_a,_b) ((_a) > (_b) ? (_b) : (_a))

int DecodeOp::init(int width, int height)
{
    const char *mine = "video/avc";
    mMediaCodec = AMediaCodec_createDecoderByType(mine);
    //注意这里,如果系统不存在对应的mine,mMediaCodec也会返回对象,
    //不过之后涉及到mMediaCodec的任何函数都会直接导致程序崩掉。
    if (NULL == mMediaCodec)
    {
        return 0;
    }

    AMediaFormat *videoFormat = AMediaFormat_new();
    AMediaFormat_setString(videoFormat, "mime", "video/avc");
    AMediaFormat_setInt32(videoFormat, AMEDIAFORMAT_KEY_WIDTH, width);
    AMediaFormat_setInt32(videoFormat, AMEDIAFORMAT_KEY_HEIGHT, height);
    media_status_t status = AMediaCodec_configure(mMediaCodec, videoFormat, NULL, NULL, 0);
    if (status != AMEDIA_OK)
    {
        AMediaCodec_delete(mMediaCodec);
        mMediaCodec = NULL;
        return 0;
    }

    mWidth = width;
    mHeight = height;
    mOriFrameSize = width * height * 3 / 2; 
    mFrameSize = mOriFrameSize;

    status = AMediaCodec_start(mMediaCodec);
    if (status != AMEDIA_OK)
    {
        AMediaCodec_delete(mMediaCodec);
        mMediaCodec = NULL;
        return 0;
    }

    return 1;
}

int DecodeOp::fini()
{
    AMediaCodec_stop(mMediaCodec);
    AMediaCodec_delete(mMediaCodec);
    mMediaCodec = NULL;
    return 1;
}

int DecodeOp::decode(char *bufData, int bufSize, char *outBuf) {
    if (NULL == mMediaCodec)
        return 0;

    ssize_t bufidx = AMediaCodec_dequeueInputBuffer(mMediaCodec, 2000);
    if (bufidx >= 0) {
        // 获取buffer的索引
        size_t outsize;
        uint8_t *inputBuf = AMediaCodec_getInputBuffer(mMediaCodec, bufidx, &outsize);
        if (inputBuf != nullptr && bufSize <= outsize) {
            // 将待解码的数据copy到硬件中
            memcpy(inputBuf, bufData, bufSize);
            media_status_t status = AMediaCodec_queueInputBuffer(mMediaCodec, bufidx, 0, bufSize,
                                                                 2000 /* pts */, 0);
        }
    }

    AMediaCodecBufferInfo info;
    ssize_t outbufidx = AMediaCodec_dequeueOutputBuffer(mMediaCodec, &info, 2000);
    if (outbufidx >= 0) {
        size_t outsize;
        uint8_t *outputBuf = AMediaCodec_getOutputBuffer(mMediaCodec, outbufidx, &outsize);
        if (outputBuf != nullptr) {
            //pts = info.presentationTimeUs;
            //int32_t pts32 = (int32_t) pts;
            uint8_t *dst = (uint8_t *) outBuf;
            memcpy(dst, outputBuf, MIN(mOriFrameSize, mFrameSize));

            uint8_t *uvBuf = outputBuf + mFrameSize;

            uint32_t uvSize = MIN(mOriFrameSize >> 1, mFrameSize >> 1);
            uint8_t *uBuf = dst + mOriFrameSize;
            uint8_t *vBuf = uBuf + (mOriFrameSize >> 2);
            memcpy(uBuf, uvBuf, uvSize);
            AMediaCodec_releaseOutputBuffer(mMediaCodec, outbufidx, info.size != 0);
            return 1;
        }
    } else {
        switch (outbufidx) {
            case AMEDIACODEC_INFO_OUTPUT_FORMAT_CHANGED:
                // 解码输出的格式发生变化
            {
                auto format = AMediaCodec_getOutputFormat(mMediaCodec);
                AMediaFormat_getInt32(format, "width", &mWidth);
                AMediaFormat_getInt32(format, "height", &mHeight);
                int32_t localColorFMT;
                AMediaFormat_getInt32(format, AMEDIAFORMAT_KEY_COLOR_FORMAT, &localColorFMT);
                /*
                mColorFormat = getTTFormatFromMC(localColorFMT);
                int32_t stride = 0;
                AMediaFormat_getInt32(format, "stride", &stride);
                if(stride == 0) {
                    stride = mWidth;
                }
                mLineSize[0] = stride;
                mFrameSize    = stride * mHeight;
                mOriFrameSize = stride * mOriHeight;
                */
                return 0;
            }
            case AMEDIACODEC_INFO_OUTPUT_BUFFERS_CHANGED:
                break;
            default:
                break;
        }
    }
    return 1;
}

修改 CMakeList.txt 

修改了 源文件由 native-lib.cpp 改为  DecodeOp.cpp

修改了输出 库的名称 由 native-lib 改为 MediaH264

增加了 调用 库  mediandk 应该= gcc 里面 的 -lmediandk

# For more information about using CMake with Android Studio, read the
# documentation: https://d.android.com/studio/projects/add-native-code.html

# Sets the minimum version of CMake required to build the native library.

cmake_minimum_required(VERSION 3.4.1)

# Creates and names a library, sets it as either STATIC
# or SHARED, and provides the relative paths to its source code.
# You can define multiple libraries, and CMake builds them for you.
# Gradle automatically packages shared libraries with your APK.

add_library( # Sets the name of the library.
-       native-lib
+       MediaH264

        # Sets the library as a shared library.
        SHARED

        # Provides a relative path to your source file(s).
-       native-lib.cpp
+       DecodeOp.cpp)

# Searches for a specified prebuilt library and stores the path as a
# variable. Because CMake includes system libraries in the search path by
# default, you only need to specify the name of the public NDK library
# you want to add. CMake verifies that the library exists before
# completing its build.

find_library( # Sets the name of the path variable.
        log-lib
        # Specifies the name of the NDK library that
        # you want CMake to locate.
        log)

#find_library( # Sets the name of the path variable.
#        mediandk-lib
#
#        # Specifies the name of the NDK library that
#        # you want CMake to locate.
#        mediandk)

# Specifies libraries CMake should link to your target library. You
# can link multiple libraries, such as libraries you define in this
# build script, prebuilt third-party libraries, or system libraries.

target_link_libraries( # Specifies the target library.
        MediaH264
        # Links the target library to the log library
        # included in the NDK.
        ${log-lib} 
+       mediandk)

顺利编译通过,下次试试在 通过库 调用这个 库

参考说明:

https://blog.csdn.net/hukou6335490/article/details/83687419

http://euhat.com/wp/2018/09/26/android-jni%E5%9F%BA%E4%BA%8Endkmediacodec%E7%A1%AC%E8%A7%A3%E7%A0%81mjpeg/

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值