FFmpeg在Android使用3
android 移植ffmpeg后so库的使用
- public class HelloJni extends Activity
- {
- /** Called when the activity is first created. */
- @Override
- public void onCreate(Bundle savedInstanceState)
- {
- super.onCreate(savedInstanceState);
- /* Create a TextView and set its content.
- * the text is retrieved by calling a native
- * function.
- */
- TextView tv = new TextView(this);
- String str = String.valueOf(stringFromJNI());
- str = str +"\n"+getVoice();
- tv.setText(str);
- setContentView(tv);
- }
- public native int getVoice();
- public native String stringFromJNI();
- public native String unimplementedStringFromJNI();
- static {
- System.loadLibrary("ffmpeg");
- System.loadLibrary("hello-jni");
- }
- }
这个是Android上层的使用。下面附上c层的代码
- /*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
- #include <string.h>
- #include <jni.h>
- #include <android/log.h>
- #include <ffmpeg/libavcodec/avcodec.h>
- #include <ffmpeg/libavformat/avformat.h>
- #include <ffmpeg/libswscale/swscale.h>
- #include <string.h>
- #define LOG_TAG "***************************lixingyun*****************" // 这个是自定义的LOG的标识
- #undef LOG // 取消默认的LOG
- #define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG,LOG_TAG,__VA_ARGS__) // 定义LOG类型
- #define LOGI(...) __android_log_print(ANDROID_LOG_INFO,LOG_TAG,__VA_ARGS__) // 定义LOG类型
- #define LOGW(...) __android_log_print(ANDROID_LOG_WARN,LOG_TAG,__VA_ARGS__) // 定义LOG类型
- #define LOGE(...) __android_log_print(ANDROID_LOG_ERROR,LOG_TAG,__VA_ARGS__) // 定义LOG类型
- #define LOGF(...) __android_log_print(ANDROID_LOG_FATAL,LOG_TAG,__VA_ARGS__) // 定义LOG类型
- /* This is a trivial JNI example where we use a native method
- * to return a new VM String. See the corresponding Java source
- * file located at:
- *
- * apps/samples/hello-jni/project/src/com/example/HelloJni/HelloJni.java
- */
- JNIEXPORT jstring Java_com_example_hellojni_HelloJni_stringFromJNI(JNIEnv* env,
- jobject thiz) {
- char str[25];
- sprintf(str, "%d", avcodec_version());
- return (*env)->NewStringUTF(env, str);
- // return (*env)->NewStringUTF(env, "Hello from JNI !");0
- }
- JNIEXPORT jint Java_com_example_hellojni_HelloJni_getVoice(JNIEnv* env,
- jobject thiz) {
- int flag = 0;
- AVPacket aacpkt;
- aacpkt.data = NULL;
- aacpkt.size = 0;
- const char *filename = "file:/sdcard/test.mp3";
- av_init_packet(&aacpkt);
- av_register_all(); //注册所有可解码类型
- AVFormatContext *pInFmtCtx = NULL; //文件格式
- AVCodecContext *pInCodecCtx = NULL; //编码格式
- pInFmtCtx = avformat_alloc_context();
- if (av_open_input_file(&pInFmtCtx, filename, NULL, 0, NULL) != 0) //获取文件格式
- LOGE("av_open_input_file error\n");
- if (av_find_stream_info(pInFmtCtx) < 0) //获取文件内音视频流的信息
- LOGE("av_find_stream_info error\n");
- unsigned int j;
- // Find the first audio stream
- int audioStream = -1;
- // Dump information about file onto standard error
- dump_format(pInFmtCtx, 0, filename, 0);
- //从FormatdContext的中找到对应流对应的编码类型,若是CODEC_TYPE_AUDIO则表示是音频
- for (j = 0; j < pInFmtCtx->nb_streams; j++) //找到音频对应的stream
- if (pInFmtCtx->streams[j]->codec->codec_type == CODEC_TYPE_AUDIO) {
- audioStream = j;
- break;
- }
- if (audioStream == -1) {
- printf("input file has no audio stream\n");
- return 0; // Didn't find a audio stream
- }
- LOGE("audio stream num: %d\n", audioStream);
- pInCodecCtx = pInFmtCtx->streams[audioStream]->codec; //音频的编码上下文
- AVCodec *pInCodec = NULL;
- /* FILE *file3 = fopen("codec_private_data_size.txt","w");
- for(int i = 0; i <200000; i++)
- {
- pInCodec = avcodec_find_decoder((CodecID)i);
- if (pInCodec!=NULL)
- {
- fprintf(file3,"%s %d\n",pInCodec->name,pInCodec->priv_data_size );
- }
- }
- fclose(file3);
- system("pause");
- */
- pInCodec = avcodec_find_decoder(pInCodecCtx->codec_id); //根据编码ID找到用于解码的结构体
- if (pInCodec == NULL) {
- printf("error no Codec found\n");
- return -1; // Codec not found
- }
- //使用test的代替pInCodecCtx也可以完成解码,可以看出只要获取以下几个重要信息就可以实现解码和重采样
- AVCodecContext *test = avcodec_alloc_context();
- test->bit_rate = pInCodecCtx->bit_rate; //重采样用
- test->sample_rate = pInCodecCtx->sample_rate; //重采样用
- test->channels = pInCodecCtx->channels; //重采样用
- test->extradata = pInCodecCtx->extradata; //若有则必有
- test->extradata_size = pInCodecCtx->extradata_size; //若有则必要
- test->codec_type = CODEC_TYPE_AUDIO; //不必要
- test->block_align = pInCodecCtx->block_align; //必要
- if (avcodec_open(test, pInCodec) < 0) //将两者结合以便在下面的解码函数中调用pInCodec中的对应解码函数
- {
- printf("error avcodec_open failed.\n");
- return -1; // Could not open codec
- }
- if (avcodec_open(pInCodecCtx, pInCodec) < 0) {
- printf("error avcodec_open failed.\n");
- return -1; // Could not open codec
- }
- static AVPacket packet;
- LOGI(" bit_rate = %d \r\n", pInCodecCtx->bit_rate);
- LOGI(" sample_rate = %d \r\n", pInCodecCtx->sample_rate);
- LOGI(" channels = %d \r\n", pInCodecCtx->channels);
- LOGI(" code_name = %s \r\n", pInCodecCtx->codec->name);
- //LOGI("extra data size: %d :data%x %x %x %x\n",pInCodecCtx->extradata_size,pInCodecCtx->extradata[0]
- // ,pInCodecCtx->extradata[1],pInCodecCtx->extradata[2],pInCodecCtx->extradata[3]);
- LOGI(" block_align = %d\n", pInCodecCtx->block_align);
- /********************************************************/
- unsigned char *outbuf = NULL;
- outbuf = (unsigned char *) malloc(AVCODEC_MAX_AUDIO_FRAME_SIZE * 2);
- int outsize;
- outsize = AVCODEC_MAX_AUDIO_FRAME_SIZE * 2;
- int len = 0;
- int size = 0;
- FILE *out_fp;
- out_fp = fopen("out.dat", "wb+");
- while (av_read_frame(pInFmtCtx, &aacpkt) >= 0) {
- LOGI("***************************");
- if (aacpkt.stream_index == audioStream) {
- int declen = 0;
- size = aacpkt.size;
- while (aacpkt.size > 0) {
- outsize = AVCODEC_MAX_AUDIO_FRAME_SIZE * 2;
- memset(outbuf, 0, outsize);
- len = avcodec_decode_audio3(pInCodecCtx, (int16_t *) outbuf,
- &outsize, &aacpkt);
- if (len < 0) {
- printf("avcodec_decode_audio3 failed!\n");
- break;
- }
- if (outsize > 0) {
- fwrite(outbuf, 1, outsize, out_fp);
- printf("write %d bytes\n", outsize);
- }
- declen += len;
- if (declen == size) {
- av_free_packet(&aacpkt);
- printf("packet decoded succeed!\n");
- break;
- } else if (declen < size) {
- aacpkt.size -= len;
- aacpkt.data += len;
- } else {
- printf("decode error!\n");
- break;
- }
- }
- }
- }
- fclose(out_fp);
- // Close the codec
- avcodec_close(pInCodecCtx);
- // Close the video file
- av_close_input_file(pInFmtCtx);
- return flag;
- }
其中的LOGE那几个就是Android下的哦。- LOCAL_PATH := $(call my-dir)
- include $(CLEAR_VARS)
- PATH_TO_FFMPEG_SOURCE:=$(LOCAL_PATH)/ffmpeg
- LOCAL_C_INCLUDES += $(PATH_TO_FFMPEG_SOURCE)
- LOCAL_LDLIBS := -lffmpeg -llog
- LOCAL_MODULE := hello-jni
- LOCAL_SRC_FILES := hello-jni.c
- include $(BUILD_SHARED_LIBRARY)
FFmpeg在Android使用3的更多相关文章
- How to Build FFmpeg for Android
http://www.roman10.net/how-to-build-ffmpeg-for-android/ ffmpeg is an open-source platform for record ...
- [原]ffmpeg编译android 硬解码支持库 libstagefright
最近花了一天时间将ffmpeg/tools/build_stagefright执行成功,主要是交叉编译所需要的各种动态库的支持没链接上,导致各种报错,基本上网络上问到的问题我都碰到了,特此记录下来. ...
- FFmpeg在Android上的移植之第一步
http://blog.sina.com.cn/s/blog_69a04cf40100x1fr.html 从事多媒体软件开发的人几乎没有不知道FFmpeg的,很多视频播放器都是基于FFmpeg开发的. ...
- FFmpeg的Android平台移植—编译篇
摘要:本文主要介绍将FFmpeg音视频编解码库移植到Android平台上的编译和基本测试过程. 环境准备: ubuntu-12.04.5 android-ndk64-r10-linux-x86_64. ...
- FFmpeg在Android上的移植优化步骤
http://blog.csdn.net/feixiang_john/article/details/7894188 从事多媒体软件开发的人几乎没有不知道FFmpeg的,很多视频播放器都是基于FFmp ...
- FFmpeg for Android compiled with x264, libass, fontconfig, freetype and fribidi
android下打算使用ffmpeg的 drawtext ,不过需要 --enable-libfreetype 但是freetype是个第三方库,所以需要先编译freetype,然后再编译ffmpe ...
- FFmpeg编译Android版本
FFmpeg是很好用的一个音视频库,功能强大,但是用起来并不是很方便.之前一直不想用FFmpeg,因为感觉编译太麻烦,但是到了不得不用的时候了,没办法,参考了网上大神的方法,在这里自己也记录一下方便以 ...
- FFmpeg 移植 Android
近期项目需要解析苹果的HLS流媒体协议,而FFmpeg从0.11.1“Happiness”版本开始,才增加了对HLS协议的支持.目前网上关于FFmpeg编译移植的文章有很多,但大多都是对旧版本的说明. ...
- Mac下通过FFMpeg实现Android手机推流和播放
一.Mac下搭建推流服务器(Nginx+RTMP+FFMpeg) 安装x264 git clone git://git.videolan.org/x264.git cd x264 ./configur ...
随机推荐
- 有n个人围成一圈,顺序排号。从第一个人开始报数(从1到3报数),凡报到3的人退出圈子,问最后留下的是原来第几号的那位。
先写我的思路,没有用指针的做法.如果你用的是VC,把第六行去掉. #include<stdio.h> #include<stdlib.h> int main() { setvb ...
- 轻轻修改配置文件完成 OpenStack 监控
当我们使用虚拟化云平台 OpenStack 时,必然要时时监控其虚拟机性能,随着近年企业级数据中心的不断发展,像混合虚拟化环境的业务需求也在持续增长中,因而也随之带来的监控需求更显重要,所以小编带来一 ...
- 转: 在.NET中操作数字证书
作者:玄魂出处:博客2010-06-23 12:05 http://winsystem.ctocio.com.cn/19/9492019.shtml .NET为我们提供了操作数字证书的两个主要的类,分 ...
- Hibernate中createCriteria即QBC查询的详细用法 .Hibernate中createCriteria即QBC查询的详细用法 .
现在假设有一个Student类,内有id,name,age属性String hql = "from Student s";按照以前的做法,我们通常是Query query = se ...
- Hibernate逍遥游记-第9章 Hibernate的映射类型
1. 2. <?xml version="1.0"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate ...
- 利用纯真ip地址库 查询 ip所属地
1. 首先下周数据源,选择是纯真数据库:http://www.cz88.net/ 2. 安装后,打开软件,将数据导出为txt格式. 3. 处理数据,参照网上的文章(http://www.jb51.ne ...
- Photoshop:热气球的制作方法
大致流程: 1.做等宽色块,加内发光 2.变形->膨化,弯曲20% 3.加高光和投影层,增加立体感 4.制作多列,合并后,滤镜->扭曲->球面化100%2次(注意放在在正方形画布中间 ...
- 基于Struts2框架实现登录案例 之 使用Struts2标签库简化表单+继承ActionSupport完成输入交验
一,使用Struts2标签库简化表单 在文章[基于Struts2框架实现登录案例]的基础上,通过使用Struts标签库可以简化登录页面login2.jsp <%@ page language=& ...
- 爬虫Larbin解析(一)——Larbin配置与使用
介绍 功能:网络爬虫 开发语言:c++ 开发者:Sébastien Ailleret(法国) 特点:只抓取网页,高效(一个简单的larbin的爬虫可以每天获取500万的网页) 安装 安装平台:Ubun ...
- win7右下角声音图标不见的解决方法
1.启动任务管理器 2.在进程选项卡里找到"explorer.exe",然后结束该进程 3.接着点击应用程序选项卡,点击新任务 4.输入explorer.exe,然后点击确定 5. ...