记录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之后。

原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 监控手机软件离线状态怎么办 云课堂忘记密码怎么办 广州办培训机构怎么办 一师一优课账号忘了怎么办 云相册空间不足怎么办 三星云空间不足怎么办 三星储存空间不足怎么办 宁阳县教育局强制补课怎么办 沉迷网络该怎么办英语 29岁沉迷游戏怎么办 学乐云登录不上怎么办 魔方学院无法识别怎么办 路由器卫士忘记密码怎么办 邮箱号忘记密码怎么办 水卡没钱了怎么办 旅行青蛙换手机怎么办 软件尚未受信任怎么办 百度搜不到的怎么办 百度中搜不到怎么办 山寨云网络异常怎么办 手机太重了怎么办 百度云网页版打不开怎么办 微鲸电视打不开怎么办 手机一直没信号怎么办 孩子作业效率低怎么办 员工做事效率低怎么办 吉他和弦转换慢怎么办 耳机低音轰头怎么办? 全民k歌太占内存怎么办 qq音乐登录失效怎么办 电视猫自动升级怎么办 酷狗账号注销怎么办 电脑监控老是坏怎么办 qq音乐qq登不上怎么办? 繁星工会解约不同意怎么办? dnf封号120小时怎么办 h1z1账号忘了怎么办 股票账户忘了怎么办 手机帐号被锁定怎么办 id帐号被锁定怎么办 微博帐号锁定怎么办