本文介绍了AV codec_de $ C $的FFmpeg的回报c_audio3 -1的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我用Android上FFmpeg的脱code MP3。我将所有德codeR使能正确地配置和使.so文件。下面是这为配置文件添加参数.SH:

  NDK =〜/ Android的NDK-R5B
平台= $ NDK /平台/ Android的-8 /弓臂/
preBUILT = $ NDK /工具链/ ARM-Linux的androideabi-4.4.3 / prebuilt / Linux的x86的
功能build_one
{
的./configure --target-OS = Linux的\\
     - preFIX = $preFIX \\
    --enable-交叉编译\\
    --extra-库= - lgcc\\
    --arch =手臂\\
    --CC = $preBUILT /斌/ ARM-Linux的androideabi-GCC \\
    --cross- preFIX = $preBUILT /斌/ ARM-Linux的androideabi- \\
    --nm = $preBUILT /斌/ ARM-Linux的androideabi纳米\\
    --sysroot = $ PLATFORM \\
    --extra-CFLAGS =-O3 -fpic -DANDROID -DHAVE_SYS_UIO_H = 1 -Dipv6mr_interface = ipv6mr_ifindex -fasm -Wno-psabi了-fno-short-枚举-fno严格走样-finline极限= $ 300 OPTIMIZE_CFLAGS\\
    --disable共享\\
    --enable-静\\
    --extra-LDFLAGS = - WL,-rpath链接= $平台/ usr / lib目录-L $平台/ usr / lib目录-nostdlib -lc -lm -ldl -llog\\
    --enable-分路器= MOV \\
    --enable-分路器= H264 \\
    --disable-ffplay \\
    --enable-协议=文件\\
    --enable-avformat \\
    --enable-AV codeC \\
    --enable-DE codeR = rawvideo \\
    --enable-DE codeR = MJPEG \\
    --enable-DE codeR = H263 \\
    --enable-DE codeR = MPEG4 \\
    --enable-DE codeR = H264 \\
    --enable-DE codeR = MP3 \\
    --enable-DE codeR = mp3adu \\
    --enable-DE codeR = mp3adufloat \\
    --enable-DE codeR = mp3float \\
    --enable-DE codeR = mp3on4 \\
    --enable-DE codeR = mp3on4float \\
    --enable-解析器= H264 \\
    --disable网\\
    --enable-zlib的\\
    --disable-avfilter \\
    --disable-avdevice \\
    $ ADDITIONAL_CONFIGURE_FLAG
使清洁
使-J4安装$preBUILT /斌/ ARM-Linux的androideabi-ARðlibav codeC / libav codec.a inverse.o$preBUILT /斌/ ARM-Linux的androideabi-LD -rpath链接= $平台/ usr / lib目录-L $平台/ usr / lib目录-soname libffmpeg.so -shared -nostdlib -z,noexecstack -Bsymbolic - -whole归档--no-未定义-o $preFIX / libffmpeg.so libav codeC / libav codec.a了libavformat / libavformat.a libavutil / libavutil.a libswscale / libswscale.a -lc -lm -lz -ldl -llog --warn一次--dynamic链接器= /系统/斌/连接器$preBUILT / lib中/ GCC / ARM-Linux的androideabi / 4.4.3 / libgcc.a中
}#arm v7vfpv3
CPU =的ARMv7-A
OPTIMIZE_CFLAGS = - mfloat-ABI = softfp -mfpu =的VFPv3-D16 -marm -march = $ CPU
preFIX = /安卓/ $ CPU
ADDITIONAL_CONFIGURE_FLAG =
build_one

我可以读文件,并获取信息(德code型\\格式类型),然后我按照FFmpeg的样品叫AV codec_de code_audio3脱code的音频文件,它的回报-1,解码失败。一些身体能告诉我是什么事,谢谢!

 的#include<&stdlib.h中GT;
#包括LT&;&stdio.h中GT;
#包括LT&;&jni.h GT;
#包括LT&;机器人/ log.h>
#包括libav codeC / AV codec.h
的#include了libavformat / avformat.h#定义AUDIO_INBUF_SIZE 20480
#定义AUDIO_REFILL_THRESH 4096
#定义LOG_TAGFFmpegTest
LOG_LEVEL的#define 10
#定义LOGI(一级,...)如果(水平< = LOG_LEVEL){__android_log_print(ANDROID_LOG_INFO,LOG_TAG,__VA_ARGS__);}
#定义LOGE(一级,...)如果(水平< = LOG_LEVEL){__android_log_print(ANDROID_LOG_ERROR,LOG_TAG,__VA_ARGS__);}字符* sourceFileName;
字符* resultFileName;
AVFormatContext * gFormatCtx;
INT audioStreamIndex;
AV codeC * G codeC;
AV codecContext * G codecCtx;
FILE *的资源文件,* resultFile;
INT out_size,LEN;
uint8_t有* outbuf中;
uint8_t有INBUF [AUDIO_INBUF_SIZE + FF_INPUT_BUFFER_PADDING_SIZE];
AVPacket avpkt;JNIEXPORT无效JNICALL Java_roman10_ffmpegTest_VideoBrowser_naDe code(JNIEnv的* pEnv,jobject pObj,的jstring source_file_name,的jstring result_file_name)
{
    LOGI(10,开始去code);
    / *获取源文件的名称* /
    sourceFileName =(字符*)(* pEnv) - GT; GetStringUTFChars(pEnv,source_file_name,NULL);
    如果(sourceFileName == NULL){
        LOGE(1,不能得到的源文件名!);
        出口(1);
    }
    LOGI(10,源文件名是%S,sourceFileName);    AV codec_init();    av_register_all();    / *获取源文件的格式财产以后AVFormatContext * /
    INT lError;
    如果((lError = av_open_input_file(安培;!gFormatCtx,sourceFileName,NULL,0,NULL))= 0){
        LOGE(1,错误的开源文件:%D,lError);
        出口(1);
    }
    如果((lError = av_find_stream_info(gFormatCtx))小于0){
        LOGE(1,发现错误流信息数:%d,lError);
        出口(1);
    }
    LOGI(10,音频格式:%S,gFormatCtx-> iformat->名);
    LOGI(10,音频比特率:%D,gFormatCtx-> BIT_RATE);    / * ???获取源文件的音频流的ID和codeC? * /
    audioStreamIndex = av_find_best_stream(gFormatCtx,AVMEDIA_TYPE_AUDIO,-1,-1,&安培; G codeC,0);
    LOGI(10,audioStreamIndex%D,audioStreamIndex);
    如果(audioStreamIndex == AVERROR_STREAM_NOT_FOUND){
        LOGE(1,找不到一个音频流);
        出口(1);
    }否则如果(audioStreamIndex == AVERROR_DE codeR_NOT_FOUND){
        LOGE(1,音频流中,但没有去codeR被发现!);
        出口(1);
    }
    LOGI(10,音频$ C $抄送:%S,G codeC->名);    / *获取音频流codeC财产以后AV codecContext * /
    G codecCtx = gFormatCtx->流[audioStreamIndex] - > codeC;
    如果(AV codec_open(G codecCtx,G codeC)小于0){
    LOGE(1,无法打开音频codeC!);
        出口(1);
    }    / * ??? G codeC = AV codec_find_de codeR(G codecCtx-> codec_id);
    如果(!G codeC){
    LOGE(1,codeC没有找到);
        返回;
    }    G codecCtx = AV codec_alloc_context();    如果(AV codec_open(G codecCtx,G codeC)小于0){
    LOGE(1,无法打开codeC);
        出口(1);
    } ... * /    outbuf中的malloc =(AV codeC_MAX_AUDIO_FRAME_SIZE);    的SourceFile = FOPEN(sourceFileName,RB);
    如果(!的资源文件){
    LOGE(1,无法打开%s,sourceFileName);
        出口(1);
    }
    / *获取结果文件名* /
    resultFileName =(字符*)(* pEnv) - GT; GetStringUTFChars(pEnv,result_file_name,NULL);
    LOGI(10,结果文件名称为%s,resultFileName);
    resultFile = FOPEN(resultFileName,WB);
    如果(!resultFile){
    LOGE(1,无法创建结果文件);
        av_free(G codecCtx);
        出口(1);
    }    av_init_packet(安培; avpkt);    avpkt.data = INBUF;
    avpkt.size = FREAD(INBUF,1,AUDIO_INBUF_SIZE,的资源文件);
    LOGI(10,avpkt.size数:%d,avpkt.size);
    / *德code文件* /
    而(avpkt.size大于0){
        out_size = AV codeC_MAX_AUDIO_FRAME_SIZE;
        LEN = AV codec_de code_audio3(G codecCtx,(短*)outbuf中和放大器; out_size,&安培; avpkt);
        如果(LEN℃,){
            LOGE(1,错误而解码数:%d,LEN);
            出口(1);
        }
        如果(out_size大于0){
            FWRITE(outbuf中1,out_size,resultFile);
        }
        avpkt.size - = LEN;
        avpkt.data + = LEN;
        如果(avpkt.size< AUDIO_REFILL_THRESH){
            memmove与(INBUF,avpkt.data,avpkt.size);
            avpkt.data = INBUF;
            LEN = FREAD(avpkt.data + avpkt.size,1,
                        AUDIO_INBUF_SIZE - avpkt.size,的资源文件);
            如果(LEN大于0)
                avpkt.size + = LEN;
        }
    }    FCLOSE(resultFile);
    FCLOSE(的资源文件);
    免费(outbuf中);    AV codec_close(G codecCtx);
    av_free(G codecCtx);    LOGI(10,最终德code);
}


解决方案

首先,AV codeC打印很多有用的信息到标准输出/标准错误,所以做以下的(至少在一些错误):

 静态无效CB(无效*,INT,为const char * FMT,va_list的VL){
  __android_log_print(ANDROID_LOG_DEBUG,avlib,格式化,VL);
}
av_log_set_callback(CB);

我想,你有缺少的头的错误。无论如何,在这里你几乎可以找到工作的使用示例:
使用ffmpeg的API

I use FFmpeg on android to decode mp3. I set all decoder enable on configure and make the .so file correctly. Here's the .sh which add parameter for configure file:

NDK=~/android-ndk-r5b
PLATFORM=$NDK/platforms/android-8/arch-arm/
PREBUILT=$NDK/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86


function build_one
{
./configure --target-os=linux \
    --prefix=$PREFIX \
    --enable-cross-compile \
    --extra-libs="-lgcc" \
    --arch=arm \
    --cc=$PREBUILT/bin/arm-linux-androideabi-gcc \
    --cross-prefix=$PREBUILT/bin/arm-linux-androideabi- \
    --nm=$PREBUILT/bin/arm-linux-androideabi-nm \
    --sysroot=$PLATFORM \
    --extra-cflags=" -O3 -fpic -DANDROID -DHAVE_SYS_UIO_H=1 -Dipv6mr_interface=ipv6mr_ifindex -fasm -Wno-psabi -fno-short-enums  -fno-strict-aliasing -finline-limit=300 $OPTIMIZE_CFLAGS " \
    --disable-shared \
    --enable-static \
    --extra-ldflags="-Wl,-rpath-link=$PLATFORM/usr/lib -L$PLATFORM/usr/lib  -nostdlib -lc -lm -ldl -llog" \
    --enable-demuxer=mov \
    --enable-demuxer=h264 \
    --disable-ffplay \
    --enable-protocol=file \
    --enable-avformat \
    --enable-avcodec \
    --enable-decoder=rawvideo \
    --enable-decoder=mjpeg \
    --enable-decoder=h263 \
    --enable-decoder=mpeg4 \
    --enable-decoder=h264 \
    --enable-decoder=mp3 \
    --enable-decoder=mp3adu \
    --enable-decoder=mp3adufloat \
    --enable-decoder=mp3float \
    --enable-decoder=mp3on4 \
    --enable-decoder=mp3on4float \
    --enable-parser=h264 \
    --disable-network \
    --enable-zlib \
    --disable-avfilter \
    --disable-avdevice \
    $ADDITIONAL_CONFIGURE_FLAG


make clean
make  -j4 install

$PREBUILT/bin/arm-linux-androideabi-ar d libavcodec/libavcodec.a inverse.o

$PREBUILT/bin/arm-linux-androideabi-ld -rpath-link=$PLATFORM/usr/lib -L$PLATFORM/usr/lib  -soname libffmpeg.so -shared -nostdlib  -z,noexecstack -Bsymbolic --whole-archive --no-undefined -o $PREFIX/libffmpeg.so libavcodec/libavcodec.a libavformat/libavformat.a libavutil/libavutil.a libswscale/libswscale.a -lc -lm -lz -ldl -llog  --warn-once  --dynamic-linker=/system/bin/linker $PREBUILT/lib/gcc/arm-linux-androideabi/4.4.3/libgcc.a
}

#arm v7vfpv3
CPU=armv7-a
OPTIMIZE_CFLAGS="-mfloat-abi=softfp -mfpu=vfpv3-d16 -marm -march=$CPU "
PREFIX=./android/$CPU 
ADDITIONAL_CONFIGURE_FLAG=
build_one

I can read file and get info (decode type\ format type), then I follow the FFmpeg's sample to call avcodec_decode_audio3 to decode audio file, it return -1, decoding failed. Is some body can tell me what is happened, thanks!

#include <stdlib.h>
#include <stdio.h>
#include <jni.h>
#include <android/log.h>
#include "libavcodec/avcodec.h"
#include "libavformat/avformat.h"

#define AUDIO_INBUF_SIZE 20480
#define AUDIO_REFILL_THRESH 4096
#define LOG_TAG "FFmpegTest"
#define LOG_LEVEL 10
#define LOGI(level, ...) if (level <= LOG_LEVEL) {__android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__);}
#define LOGE(level, ...) if (level <= LOG_LEVEL) {__android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__);}

char *sourceFileName;
char *resultFileName;
AVFormatContext *gFormatCtx;
int audioStreamIndex;
AVCodec *gCodec;
AVCodecContext *gCodecCtx;
FILE *sourceFile, *resultFile;
int out_size, len;
uint8_t *outbuf;
uint8_t inbuf[AUDIO_INBUF_SIZE + FF_INPUT_BUFFER_PADDING_SIZE];
AVPacket avpkt;

JNIEXPORT void JNICALL Java_roman10_ffmpegTest_VideoBrowser_naDecode(JNIEnv *pEnv, jobject pObj, jstring source_file_name, jstring result_file_name)
{
    LOGI(10, "start decode.");
    /* get source file's name */
    sourceFileName = (char *)(*pEnv)->GetStringUTFChars(pEnv, source_file_name, NULL);
    if (sourceFileName == NULL) {
        LOGE(1, "cannot get the source file name!");
        exit(1);
    }
    LOGI(10, "source file name is %s", sourceFileName);

    avcodec_init();

    av_register_all();

    /* get format somthing of source file to AVFormatContext */
    int lError;
    if ((lError = av_open_input_file(&gFormatCtx, sourceFileName, NULL, 0, NULL)) !=0 ) {
        LOGE(1, "Error open source file: %d", lError);
        exit(1);
    }
    if ((lError = av_find_stream_info(gFormatCtx)) < 0) {
        LOGE(1, "Error find stream information: %d", lError);
        exit(1);
    }
    LOGI(10, "audio format: %s", gFormatCtx->iformat->name);
    LOGI(10, "audio bitrate: %d", gFormatCtx->bit_rate);

    /* ???get audio stream's id and codec of source file??? */
    audioStreamIndex = av_find_best_stream(gFormatCtx, AVMEDIA_TYPE_AUDIO, -1, -1, &gCodec, 0);
    LOGI(10, "audioStreamIndex %d", audioStreamIndex);
    if (audioStreamIndex == AVERROR_STREAM_NOT_FOUND) {
        LOGE(1, "cannot find a audio stream");
        exit(1);
    } else if (audioStreamIndex == AVERROR_DECODER_NOT_FOUND) {
        LOGE(1, "audio stream found, but no decoder is found!");
        exit(1);
    }
    LOGI(10, "audio codec: %s", gCodec->name);

    /* get codec somthing of audio stream to AVCodecContext */
    gCodecCtx = gFormatCtx->streams[audioStreamIndex]->codec;
    if (avcodec_open(gCodecCtx, gCodec) < 0) {
    LOGE(1, "cannot open the audio codec!");
        exit(1);
    }

    /* ???gCodec = avcodec_find_decoder(gCodecCtx->codec_id);
    if (!gCodec) {
    LOGE(1, "codec not found");
        return;
    }

    gCodecCtx= avcodec_alloc_context();

    if (avcodec_open(gCodecCtx, gCodec) < 0) {
    LOGE(1, "could not open codec");
        exit(1);
    }??? */

    outbuf = malloc(AVCODEC_MAX_AUDIO_FRAME_SIZE);

    sourceFile = fopen(sourceFileName, "rb");
    if (!sourceFile) {
    LOGE(1, "could not open %s", sourceFileName);
        exit(1);
    }
    /* get result file's name */
    resultFileName = (char *)(*pEnv)->GetStringUTFChars(pEnv, result_file_name, NULL);
    LOGI(10, "result file name is %s", resultFileName);
    resultFile = fopen(resultFileName, "wb");
    if (!resultFile) {
    LOGE(1, "could not create result file");
        av_free(gCodecCtx);
        exit(1);
    }

    av_init_packet(&avpkt);

    avpkt.data = inbuf;
    avpkt.size = fread(inbuf, 1, AUDIO_INBUF_SIZE, sourceFile);
    LOGI(10, "avpkt.size: %d", avpkt.size);
    /* decode file */
    while (avpkt.size > 0) {
        out_size = AVCODEC_MAX_AUDIO_FRAME_SIZE;
        len = avcodec_decode_audio3(gCodecCtx, (short *)outbuf, &out_size, &avpkt);
        if (len < 0) {
            LOGE(1, "Error while decoding: %d", len);
            exit(1);
        }
        if (out_size > 0) {
            fwrite(outbuf, 1, out_size, resultFile);
        }
        avpkt.size -= len;
        avpkt.data += len;
        if (avpkt.size < AUDIO_REFILL_THRESH) {
            memmove(inbuf, avpkt.data, avpkt.size);
            avpkt.data = inbuf;
            len = fread(avpkt.data + avpkt.size, 1,
                        AUDIO_INBUF_SIZE - avpkt.size, sourceFile);
            if (len > 0)
                avpkt.size += len;
        }
    }

    fclose(resultFile);
    fclose(sourceFile);
    free(outbuf);

    avcodec_close(gCodecCtx);
    av_free(gCodecCtx);

    LOGI(10, "end decode.");
}
解决方案

First of all, avcodec prints many useful messages to stdout/stderr, so do following (at least while something wrong):

static void cb(void*, int, const char* fmt, va_list vl) {
  __android_log_print(ANDROID_LOG_DEBUG, "avlib", fmt, vl);
}
av_log_set_callback(cb);

I suppose that you have "missing header" error. Anyway, here you can find almost working usage example:(Answer) mp3 decoding using ffmpeg API (Header missing)

这篇关于AV codec_de $ C $的FFmpeg的回报c_audio3 -1的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-29 23:03