记录FFmpeg遇见的坑
来源:互联网 发布:js获取数字前两位 编辑:程序博客网 时间:2024/05/18 02:13
利用av_frame_clone可以将一个frame clone后,其实也只是v_frame_alloc()+av_frame_ref()。但是有时候在音频帧的clone后不知道为什么会导致了返回了NULL。这个时候就懵逼了。这个debug进去后发现了一个问题,就是channel_layout没有设置导致的。这个因为是我手动设置解码器,所以忘记弄了,这个一般直接读取的话没有那个错误。
假如你用ffmpeg解码后再进行编码,不知为什么如果源过快时候会发现画面卡顿,音频声音差,只要你将输入源sleep,情况明显改善。这时,其实是内存污染作怪。在ffmpeg里面,解码后的avframe内存还是归ffmpeg管理,当你每次读包解码时候,过快这样就会导致那种情况了。你要做的是用av_frame_clone,那样的话那个就可以了。
假如你将一个音频文件转码成aac文件结尾的文件,这个时候你会发现有个问题是,不知道为什么文件的播放时间总是会比我们实际的时间会长,而且这种长度会随着本来的音频时间长度成线性关系增加。这时,你可能会怀疑自己的编码是不是哪里出了问题。但事实上不是,那是因为aac文件播放本来就有adts,而在ffmpeg里面计算aac文件播放的duration时间,跟踪源码发现ffmpeg里面计算文件是长度是对比视频跟音频的长度,取其最大的。代码如下
static void estimate_timings_from_bit_rate(AVFormatContext *ic){ int64_t filesize, duration; int i, show_warning = 0; AVStream *st; /* if bit_rate is already set, we believe it */ if (ic->bit_rate <= 0) { int64_t bit_rate = 0; for (i = 0; i < ic->nb_streams; i++) { st = ic->streams[i]; if (st->codecpar->bit_rate <= 0 && st->internal->avctx->bit_rate > 0) st->codecpar->bit_rate = st->internal->avctx->bit_rate; if (st->codecpar->bit_rate > 0) { if (INT64_MAX - st->codecpar->bit_rate < bit_rate) { bit_rate = 0; break; } bit_rate += st->codecpar->bit_rate; } else if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && st->codec_info_nb_frames > 1) { // If we have a videostream with packets but without a bitrate // then consider the sum not known bit_rate = 0; break; } } ic->bit_rate = bit_rate; } /* if duration is already set, we believe it */ if (ic->duration == AV_NOPTS_VALUE && ic->bit_rate != 0) { filesize = ic->pb ? avio_size(ic->pb) : 0; if (filesize > ic->internal->data_offset) { filesize -= ic->internal->data_offset; for (i = 0; i < ic->nb_streams; i++) { st = ic->streams[i]; if ( st->time_base.num <= INT64_MAX / ic->bit_rate && st->duration == AV_NOPTS_VALUE) { duration = av_rescale(8 * filesize, st->time_base.den, ic->bit_rate * (int64_t) st->time_base.num); st->duration = duration; show_warning = 1; } } } } if (show_warning) av_log(ic, AV_LOG_WARNING, "Estimating duration from bitrate, this may be inaccurate\n");}
在这里你看到duration是将filesize来依据,而aac文件这里就出了个问题了,它会将一些别的信息添加进去,这个具体是什么信息,还没有深入研究,估计是一些设置信息,然后就会出现上述的bug。
在ffmpeg里面,假如你试过用avformat_open_input去读取rtmp流,而rtmp流不正确,这时不得不等待2分钟,通过网上的搜索,我们看到很多设置timeout,但我不知道是不是只有我这里会这样,我设置timeout后,连正确的流也拉取不了,最后一直查找资料跟debug发现我设置的参数是错误的,应该是rw_timeout,设置后,终于能正常时间内连接。
Queue input is backward in time,在ffmpeg里面,假如你用音频编码aac的时候,可能遇到这个警告。源代码如下:
if(afq->frame_count && new[-1].pts >= new->pts) av_log(afq->avctx, AV_LOG_WARNING, "Queue input is backward in time\n");
1.编码的nbsample不对
2.pts不对
linux编译Android,利用sdk编译./ndk-build NDK_PROJECT_PATH=/home/zoring/sour/libyuv APP_BUILD_SCRIPT=/home/zoring/sour/libyuv/Android.mk
上面NDK_PROJECT_PATH是指文件的文件
APP_BUILD_SCRIPT是Android.mk的位置。
基本用这个可以编译好MP3lame的
另外附上x264编译的
#!/bin/bashNDK=$HOME/sour/android-ndk-r10dSYSROOT=$NDK/platforms/android-9/arch-arm/TOOLCHAIN=$NDK/toolchains/arm-linux-androideabi-4.8/prebuilt/linux-x86_64export PLATFORM=$NDK/platforms/android-8/arch-armfunction build_one{./configure --prefix=$PREFIX \--enable-static \--enable-shared \--enable-pic \--disable-asm \--disable-cli \--host=arm-linux \--cross-prefix=$TOOLCHAIN/bin/arm-linux-androideabi- \--sysroot=$PLATFORM make cleanmake -j8make installsudo ldconfig}CPU=armPREFIX=$HOME/sour/FFmpeg-release-3.2/android/$CPUADDI_CFLAGS="-marm"build_one
最后是ffmpeg的编译shell
#!/bin/bashNDK=$HOME/sour/android-ndk-r10dSYSROOT=$NDK/platforms/android-9/arch-arm/TOOLCHAIN=$NDK/toolchains/arm-linux-androideabi-4.8/prebuilt/linux-x86_64function build_one{./configure \ --prefix=$PREFIX \ --enable-shared \ --disable-static \ --disable-doc \ --disable-ffmpeg \ --disable-ffplay \ --disable-ffprobe \ --disable-ffserver \ --disable-avdevice \ --disable-doc \ --enable-gpl \ --enable-nonfree \ --enable-pthreads \ --enable-libx264 \ --enable-libmp3lame \ --disable-symver \--enable-yasm --enable-asm --enable-neon --enable-mmx --enable-mmxext --enable-sse --enable-sse2 --enable-sse3 --enable-ssse3 --enable-sse4 --enable-sse42 --enable-avx --enable-avx2 --enable-inline-asm --enable-fma3 --enable-fma4 --enable-jni --enable-mediacodec \--cc=$TOOLCHAIN/bin/arm-linux-androideabi-gcc \ --cross-prefix=$TOOLCHAIN/bin/arm-linux-androideabi- \ --target-os=linux \ --arch=arm \ --enable-cross-compile \ --sysroot=$SYSROOT \ --extra-cflags="-Os -fpic $ADDI_CFLAGS" \ --extra-ldflags="$ADDI_LDFLAGS" \ --extra-cflags="-I $HOME/sour/FFmpeg-release-3.2/android/$CPU/include/" \ --extra-ldflags="-L $HOME/sour/FFmpeg-release-3.2/android/$CPU/lib/" \--enable-neon $ADDITIONAL_CONFIGURE_FLAGmake cleanmakemake install}CPU=armPREFIX=$(pwd)/android/$CPUADDI_CFLAGS="-marm"build_one
后面是ios的shell
#!/bin/sh# directoriesSOURCE="ffmpeg-3.3"FAT="FFmpeg-iOS"SCRATCH="scratch"# must be an absolute pathTHIN=`pwd`/"thin"X264=/Users/administrator/Desktop/FFmpeg-iOS-build-script/x264LAME=/Users/administrator/Desktop/FFmpeg-iOS-build-script/lame#X264=`pwd`/"x264"#FDK_AAC=`pwd`/"fdk-aac"#LAME=`pwd`/"lame"echo "hello x264 $X264"echo "hello lame $LAME"CONFIGURE_FLAGS="--enable-cross-compile --disable-debug --disable-programs --enable-yasm --enable-asm --eanble-neon --enable-mmx --enable-mmxext --enable-sse --enable-sse2 --enable-sse3 --enable-ssse3 --enable-sse4 --enable-sse42 --enable-avx --enable-avx2 --enable-inline-asm \ --disable-doc --enable-pic --enable-videotoolbox --disable-ffmpeg --disable-ffplay --disable-ffserver --enable-pthreads --disable-debug --enable-fma3 --enable-fma4"#---新加MP3---if [ "$LAME" ]echo "走lame1"thenecho "走lame2"CONFIGURE_FLAGS="$CONFIGURE_FLAGS --enable-gpl --enable-libmp3lame"echo "走lame3"fi#---新加MP3---if [ "$X264" ]thenCONFIGURE_FLAGS="$CONFIGURE_FLAGS --enable-gpl --enable-libx264"fiif [ "$FDK_AAC" ]thenCONFIGURE_FLAGS="$CONFIGURE_FLAGS --enable-gpl --enable-nonfree --enable-libfdk-aac"fi# avresample#CONFIGURE_FLAGS="$CONFIGURE_FLAGS --enable-avresample"ARCHS="arm64 armv7 x86_64 i386"COMPILE="y"LIPO="y"DEPLOYMENT_TARGET="6.0"if [ "$*" ]thenif [ "$*" = "lipo" ]then# skip compileCOMPILE=elseARCHS="$*"if [ $# -eq 1 ]then# skip lipoLIPO=fififiif [ "$COMPILE" ]thenif [ ! `which yasm` ]thenecho 'Yasm not found'if [ ! `which brew` ]thenecho 'Homebrew not found. Trying to install...' ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)" \|| exit 1fiecho 'Trying to install Yasm...'brew install yasm || exit 1fiif [ ! `which gas-preprocessor.pl` ]thenecho 'gas-preprocessor.pl not found. Trying to install...'(curl -L https://github.com/libav/gas-preprocessor/raw/master/gas-preprocessor.pl \-o /usr/local/bin/gas-preprocessor.pl \&& chmod +x /usr/local/bin/gas-preprocessor.pl) \|| exit 1fiif [ ! -r $SOURCE ]thenecho 'FFmpeg source not found. Trying to download...'curl http://www.ffmpeg.org/releases/$SOURCE.tar.bz2 | tar xj \|| exit 1fiCWD=`pwd`for ARCH in $ARCHSdoecho "building $ARCH..."mkdir -p "$SCRATCH/$ARCH"cd "$SCRATCH/$ARCH"CFLAGS="-arch $ARCH"if [ "$ARCH" = "i386" -o "$ARCH" = "x86_64" ]then PLATFORM="iPhoneSimulator" CFLAGS="$CFLAGS -mios-simulator-version-min=$DEPLOYMENT_TARGET"else PLATFORM="iPhoneOS" CFLAGS="$CFLAGS -mios-version-min=$DEPLOYMENT_TARGET -fembed-bitcode" if [ "$ARCH" = "arm64" ] then EXPORT="GASPP_FIX_XCODE5=1" fifiXCRUN_SDK=`echo $PLATFORM | tr '[:upper:]' '[:lower:]'`CC="xcrun -sdk $XCRUN_SDK clang"# force "configure" to use "gas-preprocessor.pl" (FFmpeg 3.3)if [ "$ARCH" = "arm64" ]then AS="gas-preprocessor.pl -arch aarch64 -- $CC"else AS="$CC"fiCXXFLAGS="$CFLAGS"LDFLAGS="$CFLAGS"#---新加MP3---if [ "$LAME" ]thenCFLAGS="$CFLAGS -I$LAME/include"LDFLAGS="$LDFLAGS -L$LAME/lib"fi#---新加MP3---if [ "$X264" ]thenCFLAGS="$CFLAGS -I$X264/include"LDFLAGS="$LDFLAGS -L$X264/lib"fiif [ "$FDK_AAC" ]thenCFLAGS="$CFLAGS -I$FDK_AAC/include"LDFLAGS="$LDFLAGS -L$FDK_AAC/lib"fiecho "hello root CFLAGS:$CFLAGS"echo "hello root CONFIGURE_FLAGS:$CONFIGURE_FLAGS"echo "hello root LDFLAGS:$LDFLAGS"TMPDIR=${TMPDIR/%\/} $CWD/$SOURCE/configure \ --target-os=darwin \ --arch=$ARCH \ --cc="$CC" \ --as="$AS" \ $CONFIGURE_FLAGS \ --extra-cflags="$CFLAGS" \ --extra-ldflags="$LDFLAGS" \ --prefix="$THIN/$ARCH" \|| exit 1make -j3 install $EXPORT || exit 1cd $CWDdonefiif [ "$LIPO" ]thenecho "building fat binaries..."mkdir -p $FAT/libset - $ARCHSCWD=`pwd`cd $THIN/$1/libfor LIB in *.adocd $CWDecho lipo -create `find $THIN -name $LIB` -output $FAT/lib/$LIB 1>&2lipo -create `find $THIN -name $LIB` -output $FAT/lib/$LIB || exit 1donecd $CWDcp -rf $THIN/$1/include $FATfiecho Done
linux编译Android,利用sdk编译./ndk-build NDK_PROJECT_PATH=/home/zoring/sour/libyuv APP_BUILD_SCRIPT=/home/zoring/sour/libyuv/Android.mk
上面NDK_PROJECT_PATH是指文件的文件
APP_BUILD_SCRIPT是Android.mk的位置。
基本用这个可以编译好MP3lame的
另外附上x264编译的
在一个项目重构里面,发现声音急促,以及声音断续,一开始以为pts不对,但发现不对。pts是正确的,那么剩下的代码都是根据之前的项目的用的,那么出现逻辑上的错误也很少可能,只能是内存污染。但我是用new的,应该不存在的。最后发现用av_frame_clone解决了问题,这个问题我猜测是ffmpeg内部有个内存管理的,类似于c++的自动内存管理,所以才会导致内存的污染问题出现。
网上的一些cbr说法里面,你会发现不管用,在官网那里提供那里的命令时候输出为ts时也是不管用,很多误人子弟的说这样。
ffmpeg -i /home/zoring/45.ts -b 4000k -minrate 4000k -maxrate 4000k -bufsize 1835k -vcodec libx264 -f mpegts -muxrate 4000K -y trailer.ts
亲测可用。
有时你会看到那个null(libx264)而不是那个详细信息,这个是因为av_dump_format在avformat_write_header之后。
- 记录FFmpeg遇见的坑
- ffmpeg工作遇见坑
- 学习android过程遇见的错误记录
- Hadoop -MapReduce遇见的小问题记录
- MATLAB使用过程遇见的问题记录
- 记录Spring +shiro 单元测试遇见的问题
- 自学h5+ app遇见的问题记录
- 记录一个遇到的坑 请求数据时遇见 provisional headers are shown!
- oracle遇见问题记录
- Android遇见的一些坑
- 初玩树莓派所遇见的坑
- 合成视频遇见的坑
- 使用StaggeredGridLayoutManager遇见的坑
- android新手遇见的坑
- FFMPEG的安装过程记录
- j2me开发中遇见的一点错误记录
- mysql安装并实验成功,记录遇见的问题
- 调试中遇见的错误记录--逐步增加
- hiho一下 第158周 非法二进制数 (dp)
- javax.net.ssl.SSLHandshakeException:PKIX path building failed解决方法的代码
- 关于数组的splice,split,join的用法。
- http://blog.csdn.net/luoshengyang/article/details/6559955/
- X11 相关的配置
- 记录FFmpeg遇见的坑
- vue中v-on绑定自定事件
- 命令代换
- oracle——监听(三、监听配置)
- 【linux】读文件
- 从数据恢复角度出发 python解释NTFS runlist的代码
- $(function(){})和$(document).ready(function(){})
- 深入理解C代码中的注释
- 生存危机——我的工作会不会被机器取代