ffmpegandroid库
❶ 如何在Android上集成ffmpeg
环境要求Vitamio3.0是使用AndroidNDKr8b版本带闹编译生成的,所以建议也使用此版本的NDK编译您改写过的FFmpeg,根据开发者的反馈,使用其它版本的NDK可能导致很多问题甚至塌镇崩溃。编译生成FFmpeg首先,从我们的GitHub网址:/yixia/FFmpeg-Android下载一份FFmpeg-Android库的拷贝,根据自己的需求对FFmpeg-Android.sh进行适当修改。最常见的场景是编译FFmpeg中你的程序需要的某几个特定模块,其它大部分不需要动。这种情况下,只需要在shell脚本下修改FFMPEG_FLAGS,所有可用参数都在FFmpeg的配置脚本里有详细说明,可通过configure--help查阅。个别情况下,如果需要为FFmpeg打补丁,那可能会麻烦些。我假定你自己已经知道了要怎么做。简言之,你只要懂FFmpeg-Android.sh或者编写自己的编译/生成脚本即可。最后,在bash中运行FFmpeg-Android.sh脚本,既然是bash脚本,也许可能在zsh中运行。打包libarm.so在VitamioBundle中找到res/raw/libarm.so这个文件:=>fileres/raw/libarm.sores/raw/libarm.so:7-ziparchivedata,version0.3如你所见,它是个7-zip压缩文件,因此可以直接将其解压到随便哪里后,用你自团行粗己在前一步生成的libffmpeg.so替换其中原来的每个libffmpeg.so。60armv661vfp70armv771neon最后,将替换后的数据照原样重新打包成libarm.so即可。
❷ Android FFmpeg so库编译 支持Https
编译armv7架构的openssl、ffmpeg的a、so库,目前openssl只编译了静态库,编译动态库,ffmpeg链接openssl编译的时候会出现链接的是带版本号的openssl动态库(如:libcrypto.so.1.1),这样在Android ndk开发下不能找到.so.1.1的库,而so.1.1格式对于Android开发不合法,所以只编译opessl静态库(不会生成.so.1.1的文件)进行解决了,如果有大神有解决方案,可以分享哈。
改后:
改后:
❸ android studio中怎么调用ffmpeg库
整体调用逻辑为:
1 编译完ffmpeg库
2 使用jni方式撰写c代码,其中需要包含相应的ffmpeg的头文件
3 撰写相应的Android.mk文件,里面指定需要编译的c代码以及需要链接的动态库
4 执行ndk-build生成相应的jni库
5 创建andorid java程序,代码中loadLibrary相应ffmpeg库以及刚才生成的jni库
6 静态方法声明native函数,这些函数在jni写的c语言中都已经实现过
❹ 如何用Android NDK编译FFmpeg
Android内置的编解码器实在太少,于是我们需要FFmpeg。Android提供了NDK,为我们使用FFmpeg这种C语言代码提供了方便。
不过为了用NDK编译FFmpeg,还真的花费了不少时间,也得到了很多人的帮助,最应该谢谢havlenapetr。我蠢巧神觉得我现在这些方法算带亏是比较简洁的了--
下面就尽量详细的说一下我是怎么在项目中使用FFmpeg的,但是基于我混乱的表达能力,有不明白的就问我。
你得了解JNI和Android NDK的基本用法,若觉得我的文章还不错,可以看之前写的JNI简单入门和Android NDK入门
首先创建一个标准的Android项目vPlayer
android create project -n vPlayer -t 8 -p vPlayer -k me.abitno.vplayer -a PlayerView
然后在vPlayer目录里
mkdir jni && cd jni
wget http //ffmpeg org/releases/ffmpeg-0.6.tar.bz2
tar xf ffmpeg-0.6.tar.bz2 && mv ffmpeg-0.6 ffmpeg && cd ffmpeg
在ffmpeg下新建一个config.sh,内容如下,注意把PREBUILT和PLATFORM设置正确。另外里面有些参数你也可以自行调整,我主要是为了配置一个播放器而这样设置的。
#!/bin/bash
PREBUILT=/home/abitno/Android/android-ndk-r4/build/prebuilt/linux-x86/arm-eabi-4.4.0
PLATFORM=/home/abitno/Android/android-ndk-r4/build/platforms/android-8/arch-arm
./configure --target-os=linux \
--arch=arm \
--enable-version3 \
--enable-gpl \
--enable-nonfree \
--disable-stripping \
--disable-ffmpeg \
--disable-ffplay \
--disable-ffserver \
--disable-ffprobe \
--disable-encoders \
--disable-muxers \
--disable-devices \宽举
--disable-protocols \
--enable-protocol=file \
--enable-avfilter \
--disable-network \
--disable-mpegaudio-hp \
--disable-avdevice \
--enable-cross-compile \
--cc=$PREBUILT/bin/arm-eabi-gcc \
--cross-prefix=$PREBUILT/bin/arm-eabi- \
--nm=$PREBUILT/bin/arm-eabi-nm \
--extra-cflags="-fPIC -DANDROID" \
--disable-asm \
--enable-neon \
--enable-armv5te \
--extra-ldflags="-Wl,-T,$PREBUILT/arm-eabi/lib/ldscripts/armelf.x -Wl,-rpath-link=$PLATFORM/usr/lib -L$PLATFORM/usr/lib -nostdlib $PREBUILT/lib/gcc/arm-eabi/4.4.0/crtbegin.o $PREBUILT/lib/gcc/arm-eabi/4.4.0/crtend.o -lc -lm -ldl"
运行config.sh开始configure
chmod +x config.sh
./config.sh
configure完成后,编辑刚刚生成的config.h,找到这句
#define restrict restrict
Android的GCC不支持restrict关键字,于是修改成下面这样
#define restrict
编辑libavutil/libm.h,把其中的static方法都删除。
分别修改libavcodec、libavfilter、libavformat、libavutil、libpostproc和libswscale下的Makefile,把下面两句删除
include $(SUBDIR)../subdir.mak
include $(SUBDIR)../config.mak
在ffmpeg下添加一个文件av.mk,内容如下
# LOCAL_PATH is one of libavutil, libavcodec, libavformat, or libswscale
#include $(LOCAL_PATH)/../config-$(TARGET_ARCH).mak
include $(LOCAL_PATH)/../config.mak
OBJS :=
OBJS-yes :=
MMX-OBJS-yes :=
include $(LOCAL_PATH)/Makefile
# collect objects
OBJS-$(HAVE_MMX) += $(MMX-OBJS-yes)
OBJS += $(OBJS-yes)
FFNAME := lib$(NAME)
FFLIBS := $(foreach,NAME,$(FFLIBS),lib$(NAME))
FFCFLAGS = -DHAVE_AV_CONFIG_H -Wno-sign-compare -Wno-switch -Wno-pointer-sign
FFCFLAGS += -DTARGET_CONFIG=\"config-$(TARGET_ARCH).h\"
ALL_S_FILES := $(wildcard $(LOCAL_PATH)/$(TARGET_ARCH)/*.S)
ALL_S_FILES := $(addprefix $(TARGET_ARCH)/, $(notdir $(ALL_S_FILES)))
ifneq ($(ALL_S_FILES),)
ALL_S_OBJS := $(patsubst %.S,%.o,$(ALL_S_FILES))
C_OBJS := $(filter-out $(ALL_S_OBJS),$(OBJS))
S_OBJS := $(filter $(ALL_S_OBJS),$(OBJS))
else
C_OBJS := $(OBJS)
S_OBJS :=
endif
C_FILES := $(patsubst %.o,%.c,$(C_OBJS))
S_FILES := $(patsubst %.o,%.S,$(S_OBJS))
FFFILES := $(sort $(S_FILES)) $(sort $(C_FILES))
接下来要添加一系列的Android.mk,在jni根目录下的内容如下
include $(all-subdir-makefiles)
在ffmpeg目录下,Android.mk
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_STATIC_LIBRARIES := libavformat libavcodec libavutil libpostproc libswscale
LOCAL_MODULE := ffmpeg
include $(BUILD_SHARED_LIBRARY)
include $(call all-makefiles-under,$(LOCAL_PATH))
libavformat/Android.mk
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
include $(LOCAL_PATH)/../av.mk
LOCAL_SRC_FILES := $(FFFILES)
LOCAL_C_INCLUDES := \
$(LOCAL_PATH) \
$(LOCAL_PATH)/..
LOCAL_CFLAGS += $(FFCFLAGS)
LOCAL_CFLAGS += -include "string.h" -Dipv6mr_interface=ipv6mr_ifindex
LOCAL_LDLIBS := -lz
LOCAL_STATIC_LIBRARIES := $(FFLIBS)
LOCAL_MODULE := $(FFNAME)
include $(BUILD_STATIC_LIBRARY)
libavcodec/Android.mk
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
include $(LOCAL_PATH)/../av.mk
LOCAL_SRC_FILES := $(FFFILES)
LOCAL_C_INCLUDES := \
$(LOCAL_PATH) \
$(LOCAL_PATH)/..
LOCAL_CFLAGS += $(FFCFLAGS)
LOCAL_LDLIBS := -lz
LOCAL_STATIC_LIBRARIES := $(FFLIBS)
LOCAL_MODULE := $(FFNAME)
include $(BUILD_STATIC_LIBRARY)
libavfilter、libavutil、libpostproc和libswscale下的Android.mk内容如下
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
include $(LOCAL_PATH)/../av.mk
LOCAL_SRC_FILES := $(FFFILES)
LOCAL_C_INCLUDES := \
$(LOCAL_PATH) \
$(LOCAL_PATH)/..
LOCAL_CFLAGS += $(FFCFLAGS)
LOCAL_STATIC_LIBRARIES := $(FFLIBS)
LOCAL_MODULE := $(FFNAME)
include $(BUILD_STATIC_LIBRARY)
最外层的jni/Android.mk和jni/ffmpeg/Android.mk我只是随便这样写的,你应该根据自己的需求改写。
最后运行ndk-build,经过漫长的等待就编译完成了。至于具体怎么应用可能以后会写,我变得太懒了。。。
转载,仅供参考
❺ Android平台FFmpeg实现rtmp推流-C++的实现
视频编码有几种方式:
1.硬编码,使用MediaCodec实现
2.软编码,使用FFmpeg或者libx264库来实现。
本文分享在Android平台视频编码-软编码的实现,也就是用FFmpeg来实现视频的编码,rtmp推流到服务器上,相机采集视频将在下一篇文章分享。
流媒体服务器使用 nginx-rtmp-mole 来进行搭建。
本文所使用FFmpeg的版本是4.1,关于FFmpeg编译成Android平台so库如果有需要,我将在下一篇文章分享说明。
视频编码比较耗cpu,上传视频数据的会耗网络io,所以需要开启新线程去处理,这里我用HandlerThread来处理视频的编码上传。
初始化编码相关操作
这里我们使用的是FFmpeg,所以在编码前我们会先做一些初始化以及参数设置工作。
FFmpeg初始化
av_register_all()
创建输出格式上下文
avformat_alloc_output_context2()
获取编码器
avcodec_find_encoder(AV_CODEC_ID_H264) 获取H264的编码器
设置编码器参数
使用给定的编码器和参数初始化编码上下文
avcodec_open2(pCodecCtx, pCodec, ¶m)
创建视频流
video_st = avformat_new_stream(ofmt_ctx, pCodec)
打开输出上下文
avio_open(&ofmt_ctx->pb, out_path, AVIO_FLAG_READ_WRITE)
写入输出头信息
avformat_write_header(ofmt_ctx, NULL)
像素格式转换
AV_PIX_FMT_YUV420P,它是纯平面存储。总共三个平面,分别存放,Y、U、V数据。
当图像宽是width,高是height时,Y分量的大小就是width×heitht,而U是width×heitht/4,V也是U是width×heitht/4。
H264编码
首先我们需要了解两个数据结构AVFrame、AVPacket
AVFrame存放的是原始数据、AVPacket存放的是编码后的数据。
创建AVPacket
av_new_packet(&enc_pkt, picture_size);
开始编码
ret = avcodec_encode_video2(pCodecCtx, pFrameYUV);
输出一帧编码后的视频数据
ret = av_write_frame(pCodecCtx, &enc_pkt);
释放资源
小伙伴们有疑问的可以在下方评论区评论。
❻ 如何用Android NDK编译FFmpeg
Android NDK编译FFmpeg可以采用cygwin方法来游旁羡实现。
具体步骤:
1、首先是config脚本,编译ffmpeg之前必须得先configure一下,configure是一个shell脚本神拍,1根据命令行参数不同来裁剪模块,生成特定的config.h文件。
2、confiure脚本文件在ffmpeg目录里可以找到。
3、重新建立以个启余shell脚本文件config.sh,这个文件只是为了编译方便。
4、例子:
注意:
编写config脚本时候,其中的路径需要使用windows形式的路径,不能使用/cygwindriver/d/android 这种格式的路径。
❼ 如何在Android上集成ffmpeg
下面春渗岁把喊陵具体编译步骤描述如下,假定扒睁NDK安装在~/android-ndk-r7: 1. 首先从FFmpeg官网下载最新的release版本源码ffmpeg-0.11.tar.gz解压缩到Android源码树的ffmpeg/下。 2 准备一个编译脚本build_android.sh并放在ffmpeg/下面,这个脚本也是Rockp...
❽ 如何在Android上集成ffmpeg
下面把具体编译步骤描述如下,假定NDK安装在~/android-ndk-r7:
1. 首先从FFmpeg官网下载最新的release版本源码ffmpeg-0.11.tar.gz解压缩到Android源码树的ffmpeg/下。
2 准备一个编译脚本build_android.sh并放在ffmpeg/下面,这个脚本也是Rockplayer提供的,需做一些修改,其内容附在后面。咱目前用的也会附在后面。
3 在ffmpeg目录下运行./build_android.sh开始编译FFmpeg,编译好的libffmpeg.so会放在文件夹android里面,一共有3个版本分别对应3种ARM体系结构,包括armv7-a、armv7-a-vfp、armv6_vfp,根据所运行的硬件平台选取其中一个版本。为了编译使用FFmpeg的程序时可以方便地找到libffmpeg.so,可将它复制到$OUT/system/lib/和$OUT/obj/lib/,当然这一步也可以加在build_android.sh中做。
4. 接下来就是编译可执行文件ffmpeg了,这个工具可以在命令行下完成FFmpeg提供的几乎所有功能包括编码、解码、转码等,也是用来调试和验证很有用的工具。其实上述编译完后在$ANDROID_BUILD_TOP/external/ffmpeg/下也会生成ffmpeg,但是在设备上无法运行。为了编出能在设备上运行的ffmpeg,可以写一个简单的Android.mk,
❾ 如何在Android用FFmpeg解码图像
CC libavcodec/log2_tab.o
CC libavutil/log2_tab.o
CC libswresample/log2_tab.o
AR libavcodec/滑陆局libavcodec.a
LD libavutil/libavutil.so.52
AR libavutil/libavutil.a
AR libswresample/libswresample.a
LD libavcodec/libavcodec.so.55
LD libswresample/libswresample.so.0
LD libswscale/libswscale.so.2
LD libavformat/libavformat.so.55
INSTALL libavformat/libavformat.a
INSTALL libavformat/libavformat.so
STRIP install-libavformat-shared
INSTALL libavcodec/libavcodec.a
INSTALL libavcodec/信让libavcodec.so
STRIP install-libavcodec-shared
INSTALL libswresample/libswresample.a
INSTALL libswresample/libswresample.so
STRIP install-libswresample-shared
INSTALL libswscale/libswscale.a
INSTALL libswscale/libswscale.so
STRIP install-libswscale-shared
INSTALL libavutil/libavutil.a
INSTALL libavutil/libavutil.so
STRIP install-libavutil-shared
INSTALL libavformat/avformat.h
INSTALL libavformat/avio.h
INSTALL libavformat/version.h
INSTALL libavformat/libavformat.pc
INSTALL libavcodec/avcodec.h
INSTALL libavcodec/avfft.h
INSTALL libavcodec/dxva2.h
INSTALL libavcodec/old_codec_ids.h
INSTALL libavcodec/vaapi.h
INSTALL libavcodec/vda.h
INSTALL libavcodec/vdpau.h
INSTALL libavcodec/version.h
INSTALL libavcodec/xvmc.h
INSTALL libavcodec/libavcodec.pc
INSTALL libswresample/swresample.h
INSTALL libswresample/version.h
INSTALL libswresample/libswresample.pc
INSTALL libswscale/swscale.h
INSTALL libswscale/version.h
INSTALL libswscale/悉汪libswscale.pc
INSTALL libavutil/adler32.h
INSTALL libavutil/aes.h
INSTALL libavutil/attributes.h
INSTALL libavutil/audio_fifo.h
INSTALL libavutil/audioconvert.h
INSTALL libavutil/avassert.h
INSTALL libavutil/avstring.h
INSTALL libavutil/avutil.h
INSTALL libavutil/base64.h
INSTALL libavutil/blowfish.h
INSTALL libavutil/bprint.h
INSTALL libavutil/bswap.h
INSTALL libavutil/buffer.h
INSTALL libavutil/channel_layout.h
INSTALL libavutil/common.h
INSTALL libavutil/cpu.h
INSTALL libavutil/crc.h
INSTALL libavutil/error.h
INSTALL libavutil/eval.h
INSTALL libavutil/fifo.h
INSTALL libavutil/file.h
INSTALL libavutil/frame.h
INSTALL libavutil/hmac.h
INSTALL libavutil/imgutils.h
INSTALL libavutil/intfloat.h
INSTALL libavutil/intfloat_readwrite.h
INSTALL libavutil/intreadwrite.h
INSTALL libavutil/lfg.h
INSTALL libavutil/log.h
INSTALL libavutil/mathematics.h
INSTALL libavutil/md5.h
INSTALL libavutil/mem.h
INSTALL libavutil/murmur3.h
INSTALL libavutil/dict.h
INSTALL libavutil/old_pix_fmts.h
INSTALL libavutil/opt.h
INSTALL libavutil/parseutils.h
INSTALL libavutil/pixdesc.h
INSTALL libavutil/pixfmt.h
INSTALL libavutil/random_seed.h
INSTALL libavutil/rational.h
INSTALL libavutil/ripemd.h
INSTALL libavutil/samplefmt.h
INSTALL libavutil/sha.h
INSTALL libavutil/sha512.h
INSTALL libavutil/time.h
INSTALL libavutil/timecode.h
INSTALL libavutil/timestamp.h
INSTALL libavutil/version.h
INSTALL libavutil/xtea.h
INSTALL libavutil/lzo.h
INSTALL libavutil/avconfig.h
INSTALL libavutil/libavutil.pc
link ffmpeg.
二、新建一个Android工程,在工程目录下新建一个jni文件夹,在文件夹下新建一个ffmpeg文件夹,用来放ffmpeg相关的头文件。在ffmpeg文件夹下新建Android.mk文件用来预先加载ffmpeg动态库。Android.mk文件内容如下:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := ffmpeg
LOCAL_SRC_FILES := /path/to/build/output/libffmpeg.so
include $(PREBUILT_SHARED_LIBRARY)
三、在jni下新建Android.mk文件和Application.mk两个文件用来指定编译的顺序和编译的平台以及对应的cpu指令集。
Application.mk
APP_ABI := armeabi
APP_PLATFORM := android-9
Android.mk
include $(call all-subdir-makefiles)
四、编写JNI文件,用来绑定java文件与.c文件的交互,文件内容如下:
/*
* ffmpeg_jni.c
*
* Created on: Sep 1, 2014
* Author: clarck
*/
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <jni.h>
#include "../include/ffmpeg_logger.h"
#include "../include/ffmpeg.h"
// 指定要注册的类,对应完整的java类名
#define JNIREG_CLASS "com/clarck/android/ffmpeg/MainActivity"
JNIEXPORT void JNICALL native_setDataSource(JNIEnv *env, jclass classzz, jstring path) {
char *filepath = ffmpeg_jstringTostr(env, path);
ffmpeg_setDataSource(filepath);
}
//Java和JNI函数的绑定
static JNINativeMethod method_table[] = {
{ "setDataSource", "(Ljava/lang/String;)V", native_setDataSource }
};
//注册native方法到java中
static int registerNativeMethods(JNIEnv *env, const char *className,
JNINativeMethod *gMethods, int numMethods) {
jclass clazz;
clazz = (*env)->FindClass(env, className);
if (clazz == NULL) {
return JNI_FALSE;
}
if ((*env)->RegisterNatives(env, clazz, gMethods, numMethods) < 0) {
return JNI_FALSE;
}
return JNI_TRUE;
}
//调用注册方法
int register_ndk_load(JNIEnv *env) {
return registerNativeMethods(env, JNIREG_CLASS, method_table,
(int) (sizeof(method_table) / sizeof(method_table[0])));
}
JNIEXPORT jint JNI_OnLoad(JavaVM *vm, void *reserved) {
JNIEnv *env = NULL;
jint result = -1;
if ((*vm)->GetEnv(vm, (void**)&env, JNI_VERSION_1_6) != JNI_OK) {
return result;
}
register_ndk_load(env);
//返回JNI的版本
return JNI_VERSION_1_6;
}
五、编写ffmpeg调用函数,内容如下:
/*
* ffmpeg.c
*
* Created on: Sep 1, 2014
* Author: clarck
*/
#include <jni.h>
#include <android/native_window_jni.h>
#include "../include/ffmpeg.h"
#include "../include/ffmpeg_logger.h"
#include "../ffmpeg/include/libavcodec/avcodec.h"
#include "../ffmpeg/include/libavformat/avformat.h"
#include "../ffmpeg/include/libavutil/pixfmt.h"
#include "../ffmpeg/include/libswscale/swscale.h"
char* ffmpeg_jstringTostr(JNIEnv* env, jstring jstr) {
char* pStr = NULL;
jclass jstrObj = (*env)->FindClass(env, "java/lang/String");
jstring encode = (*env)->NewStringUTF(env, "utf-8");
jmethodID methodId = (*env)->GetMethodID(env, jstrObj, "getBytes",
"(Ljava/lang/String;)[B");
jbyteArray byteArray = (jbyteArray) (*env)->CallObjectMethod(env, jstr,
methodId, encode);
jsize strLen = (*env)->GetArrayLength(env, byteArray);
jbyte *jBuf = (*env)->GetByteArrayElements(env, byteArray, JNI_FALSE);
if (jBuf > 0) {
pStr = (char*) malloc(strLen + 1);
if (!pStr) {
return NULL ;
}
memcpy(pStr, jBuf, strLen);
pStr[strLen] = 0;
}
(*env)->ReleaseByteArrayElements(env, byteArray, jBuf, 0);
return pStr;
}
void ffmpeg_setDataSource(char *file_path) {
LOGI("ffmpeg_setDataSource:%s", file_path);
AVFormatContext *pFormatCtx;
AVCodecContext *pCodecCtx;
AVCodec *pCodec;
AVFrame *pFrame, *pFrameYUV;
AVPacket *packet;
uint8_t *out_buffer;
static struct SwsContext *img_convert_ctx;
int videoStream, i, numBytes;
int ret, got_picture;
av_register_all();
pFormatCtx = avformat_alloc_context();
if (avformat_open_input(&pFormatCtx, file_path, NULL, NULL) != 0) {
LOGE("can‘t open the file. \n");
return;
}
if (avformat_find_stream_info(pFormatCtx, NULL) < 0) {
LOGE("Could‘t find stream infomation.\n");
return;
}
videoStream = 1;
for (i = 0; i < pFormatCtx->nb_streams; i++) {
if (pFormatCtx->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO) {
videoStream = i;
}
}
if (videoStream == -1) {
LOGE("Didn‘t find a video stream.\n");
return;
}
pCodecCtx = pFormatCtx->streams[videoStream]->codec;
pCodec = avcodec_find_decoder(pCodecCtx->codec_id);
if (pCodec == NULL) {
LOGE("Codec not found.\n");
return;
}
if (avcodec_open2(pCodecCtx, pCodec, NULL) < 0) {
LOGE("Could not open codec.\n");
return;
}
pFrame = av_frame_alloc();
pFrameYUV = av_frame_alloc();
numBytes = avpicture_get_size(AV_PIX_FMT_YUV420P, pCodecCtx->width,
pCodecCtx->height);
out_buffer = (uint8_t *) av_malloc(numBytes * sizeof(uint8_t));
avpicture_fill((AVPicture *) pFrameYUV, out_buffer, AV_PIX_FMT_YUV420P,
pCodecCtx->width, pCodecCtx->height);
int y_size = pCodecCtx->width * pCodecCtx->height;
packet = (AVPacket *) malloc(sizeof(AVPacket));
av_new_packet(packet, y_size);
av_mp_format(pFormatCtx, 0, file_path, 0);
while (av_read_frame(pFormatCtx, packet) >= 0) {
if (packet->stream_index == videoStream) {
ret = avcodec_decode_video2(pCodecCtx, pFrame, &got_picture,
packet);
LOGI("avcodec_decode_video2 ret:%d", ret);
if (ret < 0) {
LOGE("decode error.\n");
return;
}
if (got_picture) {
//TODO 此处可以将解码出来的图片保存起来。
}
}
av_free_packet(packet);
}
av_free(out_buffer);
av_free(pFrameYUV);
avcodec_close(pCodecCtx);
avformat_close_input(&pFormatCtx);
}
六、编写Android.mk用来编译相关的.c文件,内容如下:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
FFMPEG_PATH := ../ffmpeg
LOCAL_C_INCLUDES := $(LOCAL_PATH)/$(FFMPEG_PATH)/include
LOCAL_MODULE := ffmpeg_player
LOCAL_SRC_FILES += ffmpeg_jni.c
http://..com/question/1669365314957160107.html