关闭

ffmpeg-钱柜娱乐开户的编译以及使用

标签: ffmpeg钱柜娱乐开户视音频
5690人阅读 评论(0) 收藏 举报
分类:

ffmpeg能做什么不再赘述,几乎所有和音视频有关的东西都能做,只有你想不到的……


编译环境:

Ubuntu 16.04 64位

ffmpeg-3.0.5

fdkaac-0.1.5

libx264-20161204 

钱柜娱乐开户-ndk-r10d

eclipse  MARS


ffmpeg下载地址:http://www.ffmpeg.org/download.html

fdkaac下载地址:https://sourceforge.net/projects/opencore-amr/files/fdk-aac/

libx264下载地址:http://www.videolan.org/developers/x264.html


库的编译(Ubuntu下进行)

1.到上面网址分别下载ffmpeg、fdkaac和libx264源码;

(1)下载完解压后放在同一个文件夹下,我的文件夹名字叫做ffmpeg_x264_fdkaac,这样方便后面你看编译脚本;
(2)在ffmpeg_x264_fdkaac下再新建一个文件夹out,存放编译后的库。

2.下载ndk,放到你喜欢的目录下;


3.先编译fdkaac或libx264,再编译ffmpeg,这里贴上我用的脚本;

脚本存放的位置,原则上你想放哪里就放哪里。但是你如果想对我的脚本做最少的改动,就在ffmpeg_x264_fdkaac下新建一个文件夹,把三个脚本都放在这个文件夹下。因为configure前寻找目录时脚本里面是这样写的“cd..”。

4.你需要对脚本做的改动:

(1)每个脚本中的ndk路径。例如我的是export NDK=/home/sandy/钱柜娱乐开户-ndk-r10d,你改成你的;
(2)编译fdkaac和libx264的脚本,你如果和我的文件夹结构一样,除了NDK路径以外其它不用改,编译完后在out文件夹下就能看到编译好的库;
(3)编译ffmpeg的脚本,configure你需要根据自己的实际情况配置一下。这里的配置也很好理解,比如--enable-encoder=libx264就是打开h264编码器,其它的建议你在ffmpeg目录下,用./configure --help来仔细看应该用什么配置;
(4)每个脚本中都会export PREFIX=/home/sandy/ffmpeg_x264_fdkaac/out/...,然后configure下面都会有--prefix=$PREFIX,这是声明编译后的库存放的路径,如果不声明,编译后的库会存放在系统根目录下,所以声明了方便后面寻找。

build_faac.sh
export NDK=/home/sandy/钱柜娱乐开户-ndk-r10d
export 钱柜娱乐开户_ROOT=$NDK/platforms/钱柜娱乐开户-14/arch-arm
export 钱柜娱乐开户_BIN=$NDK/toolchains/arm-linux-钱柜娱乐开户eabi-4.8/prebuilt/linux-x86_64/bin
export PREFIX=/home/sandy/ffmpeg_x264_fdkaac/out/fdkaac

export CFLAGS="-D钱柜娱乐开户 -fPIC -ffunction-sections -funwind-tables -fstack-protector -march=armv7-a -mfloat-abi=softfp -mfpu=vfpv3-d16 -fomit-frame-pointer -fstrict-aliasing -funswitch-loops -finline-limit=300"

export LDFLAGS="-Wl,--fix-cortex-a8"
export CC="arm-linux-钱柜娱乐开户eabi-gcc --sysroot=$钱柜娱乐开户_ROOT"
export CXX="arm-linux-钱柜娱乐开户eabi-g++ --sysroot=$钱柜娱乐开户_ROOT"

export PATH=$钱柜娱乐开户_BIN:$PATH

cd ../fdk-aac-0.1.5
./configure --host=arm-linux-钱柜娱乐开户eabi  --with-sysroot="$钱柜娱乐开户_ROOT" --enable-static --disable-shared --prefix=$PREFIX
make clean
make -j4
make install

build_x264.sh
export NDK=/home/sandy/钱柜娱乐开户-ndk-r10d
export PREBUILT=$NDK/toolchains/arm-linux-钱柜娱乐开户eabi-4.8/prebuilt
export PLATFORM=$NDK/platforms/钱柜娱乐开户-14/arch-arm
export PREFIX=/home/sandy/ffmpeg_x264_fdkaac/out/x264
cd ../x264
./configure --prefix=$PREFIX \
--enable-static \
--disable-shared \
--enable-pic \
--disable-asm \
--disable-cli \
--host=arm-linux \
--cross-prefix=$PREBUILT/linux-x86_64/bin/arm-linux-钱柜娱乐开户eabi- \
--sysroot=$PLATFORM
make
make install


build_ffmpeg.sh
#!/bin/bash
export NDK=/home/sandy/钱柜娱乐开户-ndk-r10d
SYSROOT=$NDK/platforms/钱柜娱乐开户-14/arch-arm/
TOOLCHAIN=$NDK/toolchains/arm-linux-钱柜娱乐开户eabi-4.8/prebuilt/linux-x86_64
CPU=arm 
PREFIX=/home/sandy/ffmpeg_x264_fdkaac/out/ffmpeg
ADDI_CFLAGS="-marm"
export outfaac=/home/sandy/ffmpeg_x264_fdkaac/out/fdkaac
export outx264=/home/sandy/ffmpeg_x264_fdkaac/out/x264


function build_one    
{    
cd ../ffmpeg-3.0.5
./configure \
--enable-nonfree \
--enable-version3 \
--prefix=$PREFIX \
--enable-static \
--enable-cross-compile \
--enable-gpl \
--disable-shared \
--disable-doc \
--disable-ffserver \
--disable-ffprobe \
--disable-devices \
--disable-avdevice \
--disable-encoders \
--disable-decoders \
--disable-protocols \
--disable-muxers \
--disable-demuxers \
--disable-bsfs \
--disable-network \
--enable-libx264 \
--enable-encoder=libx264 \
--enable-libfdk_aac \
--enable-decoder=pcm_alaw \
--enable-encoder=pcm_alaw \
--enable-decoder=pcm_mulaw \
--enable-decoder=pcm_mulaw \
--enable-decoder=h264 \
--enable-encoder=aac \
--enable-decoder=aac \
--enable-protocol=file \
--enable-protocol=rtsp \
--enable-muxer=mp4 \
--enable-muxer=mov \
--enable-demuxer=mp4 \
--enable-demuxer=mov \
--enable-demuxer=flv \
--enable-demuxer=avi \
--enable-bsf=h264_mp4toannexb \
--enable-bsf=aac_adtstoasc \
--cross-prefix=$TOOLCHAIN/bin/arm-linux-钱柜娱乐开户eabi- \
--target-os=linux \
--arch=arm \
--sysroot=$SYSROOT \
--extra-cflags="-I$outx264/include -I$outfaac/include -fPIC -D钱柜娱乐开户 -D__thumb__ -mthumb -Wfatal-errors -Wno-deprecated -mfloat-abi=softfp -mfpu=vfpv3-d16 -marm -march=armv7-a" \
--extra-ldflags="-L$outx264/lib -L$outfaac/lib"
$ADDITIONAL_CONFIGURE_FLAG
}
  
build_one
make clean
make -j4
make install


库的使用




这里以在新工程中的使用为例
1.新建好工程后,右键工程名选择钱柜娱乐开户 Tools->Add Native Support,填写so库的名字,确定,这时工程会多出jni文件夹,并且文件夹下有钱柜娱乐开户.mk文件和以so库名字命名的.cpp文件;

2.导入库。在jni文件夹下创建两个文件夹include和prebuilt,名字可以随便起,总之一个是放头文件的,一个是放静态库的,将刚才编译好的头文件和静态库放在这两个文件夹里;

3.编辑java文件。新建一个类,这里以h264编码为例,直接上代码;
public class FFmpeg {
	
	static {
		try {
			System.loadLibrary("ckffmpegutil");
		} catch (Exception e) {
			// TODO: handle exception
			Log.d("ckdebug", "can not load ckffmpegutil");
		}
	}
	
	public static native int InitH264Encoder(int width, int height, int framerate);
	public static native void ReleaseH264Encoder();

}


4.运用javah命令生成头文件,具体步骤:cd到工程目录下->敲命令javah -classpath bin/classes -d jni com.example.ckffmpeg.ffmpeg(上面新建的Java文件的全类名),jni文件夹下会生成头文件com_example_ckffmpeg_FFmpeg.h,再新建对应的资源文件com_example_ckffmpeg_FFmpeg.c(删掉系统生成的.cpp文件),编辑资源文件,这里顺便贴上ffmpeg编码的关键部分代码;

#include <stdio.h>

#include "H264Encoder.h"
#include <com_钱柜娱乐开户_concox_FFmpeg.h>

#include <libavformat/avformat.h>
#include <libavcodec/avcodec.h>

AVCodecContext *h264_enc_ctx;
AVFrame *h264_enc_frame;
unsigned char I420Buffer[1280 * 720 * 3];
long long frameNumber;
int frame_rate;

void yv12_2_yuv420p(unsigned char *yv12_buf, unsigned char *I420_buf, int width, int height)
{
	unsigned int wh = width*height;

	// 拷贝y分量
	int i = 0, j = 0;
	for (i=0; i<height; ++i)
	{
		for (j=0; j<width; ++j)
		{
			I420_buf[i*width + j] = yv12_buf[i*width + j];
		}
	}

	// 拷贝U、V分量
	int half_height = height/4;
	for (i=0; i<half_height; i++)
	{
		for (j=0; j<width; j++)
		{
			I420_buf[wh + i*width + j] = yv12_buf[wh + half_height*width + i*width + j];//拷贝U分量
			I420_buf[wh + half_height*width + i*width + j] = yv12_buf[wh + i*width + j];//拷贝V分量
		}
	}
}

/* 检查支持的图像格式 */
void check_pixel_fmt(AVCodec *codec)
{
    const enum AVPixelFormat *p = codec->pix_fmts;
    // 打印出支持的图像格式
    while (*p != -1) {
        LOGD("支持的图像格式:%d\n", *p);
        p++;
    }
}

int initH264Encoder(int width, int height, long bitrate, int framerate)
{
	av_register_all();
	avcodec_register_all();

	AVCodec *pCodec = avcodec_find_encoder(AV_CODEC_ID_H264);
	if (pCodec == NULL) {
		LOGD("could not find H264 encoder!");
		return -1;
	}

	if (h264_enc_ctx) {
		avcodec_free_context(&h264_enc_ctx);
	}

	if (h264_enc_frame) {
		av_frame_free(&h264_enc_frame);
	}

	h264_enc_ctx = avcodec_alloc_context3(pCodec);
	if (h264_enc_ctx == NULL) {
		LOGD("could not init H264 encode context!");
		return -2;
	}

	h264_enc_ctx->bit_rate = bitrate;
	h264_enc_ctx->time_base = (AVRational){1, framerate};
	h264_enc_ctx->width = width;
	h264_enc_ctx->height = height;
	h264_enc_ctx->gop_size = framerate; // 1s一帧关键帧
	h264_enc_ctx->pix_fmt = AV_PIX_FMT_YUV420P;
	h264_enc_ctx->max_b_frames = 0;
	h264_enc_ctx->color_range = AVCOL_RANGE_MPEG;
	h264_enc_ctx->qmin = 10;
	h264_enc_ctx->qmax = 51;

	AVDictionary *options = {0};
	av_dict_set(&options, "preset", "fast", 0);// 编码速度设为slow,画面质量更好
	av_dict_set(&options, "tune", "zerolatency", 0);// 0延迟

	if (avcodec_open2(h264_enc_ctx, pCodec, &options) < 0) {
		LOGD	("could not open H264 encoder!\n");
		avcodec_free_context(&h264_enc_ctx);
		return -3;
	}
	av_dict_free(&options);

	h264_enc_frame = av_frame_alloc();
	if (h264_enc_frame == NULL) {
		LOGD("could not allocate video frame!\n");
		avcodec_free_context(&h264_enc_ctx);
		return -4;
	}

	int ret = av_image_fill_arrays(h264_enc_frame->data, h264_enc_frame->linesize, NULL, AV_PIX_FMT_YUV420P, width, height, 1);
	if (ret < 0) {
		LOGD("could not fill video frame array\n");
		releaseH264Encoder();
		return -5;
	}
	LOGD("required video frame src bytes: %d\n", ret);

	check_pixel_fmt(pCodec);
	frameNumber = 0;
	frame_rate = framerate;
	return 0;
}

void releaseH264Encoder()
{
	if (h264_enc_ctx) {
		avcodec_free_context(&h264_enc_ctx);
	}

	if (h264_enc_frame) {
		av_frame_free(&h264_enc_frame);
	}
}

int H264Encode(unsigned char *inbuf, unsigned char *outbuf)
{
	if (!h264_enc_ctx || !h264_enc_frame) {
		LOGD("the H.264 encoder has not been inited!");
		return -1;
	}

	AVPacket pkt = {0};
	av_init_packet(&pkt);
	pkt.data = NULL;
	pkt.size = 0;

	h264_enc_frame->width = h264_enc_ctx->width;
	h264_enc_frame->height = h264_enc_ctx->height;
	h264_enc_frame->format = h264_enc_ctx->pix_fmt;
	h264_enc_frame->color_range = h264_enc_ctx->color_range;
	h264_enc_frame->pts = (frameNumber++ / frame_rate) / av_q2d(h264_enc_ctx->time_base);

	memset(I420Buffer, 0, 1280*720*3);
	yv12_2_yuv420p(inbuf, I420Buffer, h264_enc_ctx->width, h264_enc_ctx->height);

	h264_enc_frame->data[0] = I420Buffer;
	h264_enc_frame->data[1] = I420Buffer + h264_enc_ctx->width * h264_enc_ctx->height;
	h264_enc_frame->data[2] = I420Buffer + h264_enc_ctx->width * h264_enc_ctx->height * 5/4;

	int got_pic;
	int ret = avcodec_encode_video2(h264_enc_ctx, &pkt, h264_enc_frame, &got_pic);
	if (ret < 0) {
		LOGD("encode video failed!");
		av_packet_unref(&pkt);
		return -2;
	}

	if (got_pic) {
		memcpy(outbuf, pkt.data, pkt.size);
		ret = pkt.size;
		av_packet_unref(&pkt);
		return ret;
	}

	LOGD("encode success but has no picture");
	return 0;
}


5.编辑钱柜娱乐开户.mk文件

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)


LOCAL_C_INCLUDES +=	$(LOCAL_PATH)/include
LOCAL_MODULE    := libckffmpegutil
LOCAL_SRC_FILES := com_example_ckffmpeg_FFmpeg.c

LOCAL_LDLIBS := -llog -ljnigraphics -lz -l钱柜娱乐开户 -lm -pthread

LOCAL_LDLIBS +=$(LOCAL_PATH)/prebuilt/libfdk-aac.a
LOCAL_LDFLAGS+=$(LOCAL_PATH)/prebuilt/libavformat.a
LOCAL_LDFLAGS+=$(LOCAL_PATH)/prebuilt/libavfilter.a
LOCAL_LDFLAGS+=$(LOCAL_PATH)/prebuilt/libavcodec.a
LOCAL_LDFLAGS+=$(LOCAL_PATH)/prebuilt/libswscale.a
LOCAL_LDFLAGS+=$(LOCAL_PATH)/prebuilt/libavutil.a
LOCAL_LDFLAGS+=$(LOCAL_PATH)/prebuilt/libswresample.a
LOCAL_LDFLAGS+=$(LOCAL_PATH)/prebuilt/libpostproc.a
LOCAL_LDFLAGS+=$(LOCAL_PATH)/prebuilt/libx264.a

include $(BUILD_SHARED_LIBRARY)



PS:此文中贴的h264编码,我在实际使用过程中发现编码效率比较低,编640x480的图像,一帧需要将近200ms,项目中也不需要这个了,后面也没有再继续改进。视音频编解码这个东西水太深了,不是一两年能搞出名堂的……


这里主要也是记录一下ffmpeg的编译,能用到的朋友可以点个赞吐舌头

0
0
查看评论
发表评论
* 以上用户言论只代表其个人钱柜娱乐开户,不代表CSDN网站的钱柜娱乐开户或立场

钱柜娱乐开户 WiFi开发教程(一)——WiFi热点的创建与关闭

相对于BlueTooth,WiFi是当今使用最广的一种无线网络传输技术, 几乎所有智能手机、平板电脑和笔记本电脑都支持Wi-Fi上网。因此,掌握基本的WiFI开发技术是非常必要的。本教程将围绕一个小D...
  • a1533588867
  • a1533588867
  • 2016-09-07 14:28
  • 5603

钱柜娱乐开户热点相关功能开发

本文中所用到的方法,在MT6582平台、API19测试可行,其它平台不一定可以,要具体测。 附一个MT6582源码的链接https://github.com/CM-Huawei/Source_MT65...
  • ck_19900710
  • ck_19900710
  • 2017-06-30 14:47
  • 151

钱柜娱乐开户 AP热点(wifi热点)开发

功能:创建热点、获取热点名、检查是否开启wifi热点、关闭热点、开热点手机获取其他连入手机IP地址
  • guang_liang_
  • guang_liang_
  • 2017-02-15 22:30
  • 3485

钱柜娱乐开户 WiFi/WiFi热点开发总结

首先看一下WiFi的自我介绍:Wi-Fi是一种允许电子设备连接到一个无线局域网(WLAN)的技术,通常使用2.4G UHF或5G SHF ISM 射频频段。连接到无线局域网通常是有密码保护的;但也可是...
  • a_zhon
  • a_zhon
  • 2016-09-08 16:15
  • 3180

钱柜娱乐开户 -- Wifi热点的打开与关闭流程简介

钱柜娱乐开户 -- Wifi热点的打开与关闭流程简介 在钱柜娱乐开户手机中,热点也是一个较为常用的功能。对于framework开发者来说,要开发、维护SoftAp,了解framework...
  • u012805129
  • u012805129
  • 2017-05-10 13:49
  • 837

钱柜娱乐开户 WiFi开发 (二)Wifi热点

接着上一篇wifi的扫描连接等,这一篇主要说一下手机开启Wifi热点。 demo的下载地址会在最下面贴出来。 图片: 经测试开启wifi热点(无秘密,wpa安全类型,wpa2安全类型)都可以正常...
  • VNanyesheshou
  • VNanyesheshou
  • 2016-03-07 13:08
  • 14686

热点认证技术实现

热点认证技术实现代码可以在https://github.com/zhouyelihua/wifidog-yaha下载背景   当用户靠近路由器时候,打开App时候,会自动连接上菜鸟驿站提供的网络,当用...
  • zhouyelihua
  • zhouyelihua
  • 2016-11-02 20:24
  • 3684

钱柜娱乐开户应用程序创建热点以及自动链接Wifi,我遇到的问题以及我是怎么解决的

最近在做关于蓝牙传送数据 连接WiFi的应用,稍后会有代码个解析 一下是转载的  里面遇到的问题 我也遇到了,亲测 是可用的,网上百分之九十以上都是有问题的。想解决的 都自己好好读读吧。  htt...
  • u014510302
  • u014510302
  • 2015-11-12 16:49
  • 1720

钱柜娱乐开户 代码设置、打开wifi热点及热点的连接

用过快牙的朋友应该知道它们在两天设备之间传输文件的时候使用的是wifi热点,然后另一台便连接这个热点再进行传输。快牙传输速度惊人应该跟它的这种机制有关系吧。不知道它的搜索机制是怎样的,但我想应该可以通...
  • Happy_Develop_
  • Happy_Develop_
  • 2017-03-13 16:04
  • 2132

解决钱柜娱乐开户6.0不能开启热点

代码在钱柜娱乐开户4.4及左右版本能够正常运行1.添加开启热点所需要的权限 <
  • a_zhon
  • a_zhon
  • 2016-10-09 11:20
  • 3162
    个人资料
    • 访问:13710次
    • 积分:241
    • 等级:
    • 排名:千里之外
    • 原创:8篇
    • 转载:10篇
    • 译文:0篇
    • 评论:1条
    最新评论