CMAKE-使用export.map限制导出函数

1 export.map

{
  global:
    aac_decoder_create;
    aac_decode_frame;
    aac_decode_close;
    
  local: *;
};

2 cmake

# set the minimum version for cmake
CMAKE_MINIMUM_REQUIRED (VERSION 2.8)
#
IF (APPLE) 
ELSE ()
    set(CMAKE_SHARED_LINKER_FLAGS "-Wl,-rpath=/usr/local/lib -Wl,-rpath-link=/usr/local/lib")
    set(CMAKE_SHARED_LINKER_FLAGS "-Wl,--version-script=${PROJECT_SOURCE_DIR}/libaac/export.map")
ENDIF ()  


# add all source files
AUX_SOURCE_DIRECTORY(. AACLIB_SRC)

# add search path for 3rd include 
INCLUDE_DIRECTORIES(${PROJECT_SOURCE_DIR}/3rd/includes/ffmpeg/)

# add search path for 3rd library
LINK_DIRECTORIES(${PROJECT_SOURCE_DIR}/3rd/libs/ffmpeg/)

# set output library
ADD_LIBRARY(aac SHARED ${AACLIB_SRC})

# avoid clean
SET_TARGET_PROPERTIES(aac PROPERTIES CLEAN_DIRECT_OUTPUT 1)

# add 3rd library dependencies 
IF (APPLE) 
    TARGET_LINK_LIBRARIES(aac avformat avcodec avutil avdevice avfilter swresample swscale)
ELSE ()    
    TARGET_LINK_LIBRARIES(aac libavformat.a libavcodec.a libavutil.a libavdevice.a libavfilter.a libswresample.a libswscale.a)
ENDIF ()  

3 ffaac.h

#if !defined(__FF_AAC_H__)
#define __FF_AAC_H__

void *aac_decoder_create(int sample_rate, int channels, int bit_rate);
int aac_decode_frame(void *pParam, unsigned char *pData, int nLen, unsigned char *pPCM, unsigned int *outLen);
void aac_decode_close(void *pParam);

#endif

4 ffaac.c

#include "ffaac.h"

extern "C" {
#include "libavformat/avformat.h"
#include "libswresample/swresample.h"
#include "libavcodec/avcodec.h"
}

typedef struct AACContext {
    AVCodecContext *pCodecCtx;
    AVFrame *pFrame;
    struct SwrContext *au_convert_ctx;
    int out_buffer_size;
} AACContext;

void *aac_decoder_create(int sample_rate, int channels, int bit_rate)
{
    av_register_all();
    AACContext *pComponent = (AACContext *)malloc(sizeof(AACContext));
    AVCodec *pCodec = avcodec_find_decoder(AV_CODEC_ID_AAC);
    if (pCodec == NULL)
    {
        printf("find aac decoder error\r\n");
        return 0;
    }
    // 创建显示contedxt
    pComponent->pCodecCtx = avcodec_alloc_context3(pCodec);
    pComponent->pCodecCtx->channels = channels;
    pComponent->pCodecCtx->sample_rate = sample_rate;
    pComponent->pCodecCtx->bit_rate = bit_rate;
    if(avcodec_open2(pComponent->pCodecCtx, pCodec, NULL) < 0)
    {
        printf("open codec error\r\n");
        return 0;
    }
    
    pComponent->pFrame = av_frame_alloc();
    

    uint64_t out_channel_layout = channels < 2 ? AV_CH_LAYOUT_MONO:AV_CH_LAYOUT_STEREO;
    int out_nb_samples = 1024;
    enum AVSampleFormat out_sample_fmt = AV_SAMPLE_FMT_S16;
    
    pComponent->au_convert_ctx = swr_alloc();
    pComponent->au_convert_ctx = swr_alloc_set_opts(pComponent->au_convert_ctx, out_channel_layout, out_sample_fmt, sample_rate,
                                      out_channel_layout, AV_SAMPLE_FMT_FLTP, sample_rate, 0, NULL);
    swr_init(pComponent->au_convert_ctx);
    int out_channels = av_get_channel_layout_nb_channels(out_channel_layout);
    pComponent->out_buffer_size = av_samples_get_buffer_size(NULL, out_channels, out_nb_samples, out_sample_fmt, 1);

    return (void *)pComponent;
}

int aac_decode_frame(void *pParam, unsigned char *pData, int nLen, unsigned char *pPCM, unsigned int *outLen)
{
    AACContext *pAACD = (AACContext *)pParam;
    AVPacket packet;
    av_init_packet(&packet);
    
    packet.size = nLen;
    packet.data = pData;
    
    int got_frame = 0;
    int nRet = 0;
    if (packet.size > 0)
    {
        nRet = avcodec_decode_audio4(pAACD->pCodecCtx, pAACD->pFrame, &got_frame, &packet);
        if (nRet < 0)
        {
   printf("avcodec_decode_audio4:%d\r\n",nRet);
            printf("avcodec_decode_audio4 %d  sameles = %d  outputSize = %d\r\n", nRet, pAACD->pFrame->nb_samples, pAACD->out_buffer_size);
            return nRet;
        }

        if(got_frame)
        {
            swr_convert(pAACD->au_convert_ctx, &pPCM, pAACD->out_buffer_size, (const uint8_t **)pAACD->pFrame->data, pAACD->pFrame->nb_samples);
            *outLen = pAACD->out_buffer_size;
        }
    }

    av_free_packet(&packet);
    if (nRet > 0)
    {
        return 0;
    }
    return -1;
}

void aac_decode_close(void *pParam)
{
    AACContext *pComponent = (AACContext *)pParam;
    if (pComponent == NULL)
    {
        return;
    }
    
    swr_free(&pComponent->au_convert_ctx);
    
    if (pComponent->pFrame != NULL)
    {
        av_frame_free(&pComponent->pFrame);
        pComponent->pFrame = NULL;
    }
    
    if (pComponent->pCodecCtx != NULL)
    {
        avcodec_close(pComponent->pCodecCtx);
        avcodec_free_context(&pComponent->pCodecCtx);
        pComponent->pCodecCtx = NULL;
    }
    
    free(pComponent);
}

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值