问题描述
我用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的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!