用于FFMpeg 2.1的avcodec_find_decoder不适用于Android

时间:2013-12-23 20:05:28

标签: android android-ndk ffmpeg

我使用NDK将FFMpeg 2.1移植到Android,我编写了一个JNI函数来初始化视频。

以下是此C函数的代码:

JNIEXPORT int JNICALL Java_com_media_ffmpeg_FFMpeg_naInit(JNIEnv *pEnv, jobject pObj, jstring pfilename) {
    gVideoFileName = (char *) (*pEnv)->GetStringUTFChars(pEnv, pfilename, NULL);
    __android_log_print(ANDROID_LOG_INFO, TAG, "Init %s\n", gVideoFileName);

    avcodec_register_all();
    __android_log_print(ANDROID_LOG_INFO, TAG, "avcodec_register_all\n");

    av_register_all();
    __android_log_print(ANDROID_LOG_INFO, TAG, "av_register_all\n");

    VideoState *vs;
    __android_log_print(ANDROID_LOG_INFO, TAG, "VideoState var\n");

    vs = malloc(sizeof (VideoState));
    memset(vs, 0, sizeof(VideoState));
    __android_log_print(ANDROID_LOG_INFO, TAG, "malloc\n");

    gvs = vs;
    __android_log_print(ANDROID_LOG_INFO, TAG, "VideoState\n");

    //open the video file
    avformat_open_input(&vs->pFormatCtx, gVideoFileName, NULL, NULL);
    __android_log_print(ANDROID_LOG_INFO, TAG, "open_input\n");

    //retrieve stream info
    avformat_find_stream_info(vs->pFormatCtx, NULL);
    __android_log_print(ANDROID_LOG_INFO, TAG, "find_stream_info\n");

    //find the video stream
    AVCodecContext *pcodecctx;
    //find the first video stream
    vs->videoStreamIdx = -1;
    __android_log_print(ANDROID_LOG_INFO, TAG, "before loop\n");

    AVCodec *pcodec;

    vs->videoStreamIdx =  av_find_best_stream(vs->pFormatCtx, AVMEDIA_TYPE_VIDEO, -1, -1, &pcodec, 0);
    __android_log_print(ANDROID_LOG_INFO, TAG, "after loop. %d\n", vs->videoStreamIdx);

    //get the decoder from the video stream
    pcodecctx = vs->pFormatCtx->streams[vs->videoStreamIdx]->codec;
    __android_log_print(ANDROID_LOG_INFO, TAG, "stream selected %d, %d\n", pcodecctx != NULL ? 1 : 0, pcodecctx->codec_id);

    pcodec = avcodec_find_decoder(pcodecctx->codec_id);
    __android_log_print(ANDROID_LOG_INFO, TAG, "find_decoder\n");

    //open the codec
    avcodec_open2(pcodecctx, pcodec, NULL);
    __android_log_print(ANDROID_LOG_INFO, TAG, "open2\n");

    return 0;
}

当我从我的Java代码执行此函数时,永远不会显示日志find_decoder(在调用函数avcodec_find_decoder之后)。

一切正确:指针的值正确,pcodecctx->codec_id的值等于 28 。 但是当avcodec_find_decoder没有更多时,就像崩溃一样,我没有更多的日志。

使用和初始化FFMpeg时,我做错了什么?

PS:在此之前,而不是拨打malloc,然后memset我打电话给av_mallocz,但此时我也遇到了崩溃,并用{替换了此来电{1}}和malloc修复了崩溃。

修改

我使用此脚本构建了memset

FFMpeg

编辑2

以下是库构建配置的输出

#!/bin/bash
NDK=/Users/me/android-ndk
SYSROOT=$NDK/platforms/android-8/arch-arm/
TOOLCHAIN=$NDK/toolchains/arm-linux-androideabi-4.6/prebuilt/darwin-x86_64
function build_one
{
./configure \
 --prefix=$PREFIX \
 --disable-shared \
 --enable-static \
 --disable-doc \
 --disable-ffmpeg \
 --disable-ffplay \
 --disable-ffprobe \
 --disable-ffserver \
 --disable-avdevice \
 --disable-doc \
 --disable-symver \
 --cross-prefix=$TOOLCHAIN/bin/arm-linux-androideabi- \
 --target-os=linux \
 --arch=arm \
 --enable-cross-compile \
 --sysroot=$SYSROOT \
 --extra-cflags="-Os -fpic $ADDI_CFLAGS" \
 --extra-ldflags="$ADDI_LDFLAGS" \
 $ADDITIONAL_CONFIGURE_FLAG
make clean
make
make install
}
CPU=arm
PREFIX=$(pwd)/android/$CPU 
ADDI_CFLAGS="-marm"
build_one

0 个答案:

没有答案