从ffmpeg filter里出来的数据直接送给avcodec_encode_audio2编码,写文件有错。

http://hi.baidu.com/mingyuejingque/item/78e71aff57ae9ec5a835a2e4

感谢mingyuejingque

st = avformat_new_stream( m_oc, NULL);

if (!st) {

fprintf(stderr, "Could not allocate
stream\n");

exit(1);

}

st->id = m_oc->nb_streams-1;

AVCodecContext *c = st->codec;

c->codec_type = in_stream->codec->codec_type;

/* Some formats want stream headers to be separate. */

if (m_oc->oformat->flags & AVFMT_GLOBALHEADER)

c->flags |= CODEC_FLAG_GLOBAL_HEADER;

switch ((codec)->type) {

case AVMEDIA_TYPE_AUDIO:

c->sample_fmt = FORCE_smaple_fmt;

//       c->bit_rate = FORCE_BIT_RATE;

c->sample_rate = FORCE_sample_rate;

c->codec_id = FORCE_CODEC_AUDIO;

c->channels =
in_stream->codec->channels;

c->channel_layout   = in_stream->codec->channel_layout;

c->time_base = in_stream->codec->time_base;

// c->profile = FORCE_profile;

m_AudioStream = st;

/* open it */

ret = avcodec_open2(c, codec, NULL);

if (ret < 0) {

printf("Could not open audio codec");

exit(1);

}

m_Codec = codec;

m_CodecContext = c; //这是音频编码的,视频没做编码。

break;

}

/* Some formats want stream headers to be separate. */

if (m_oc->oformat->flags & AVFMT_GLOBALHEADER)

c->flags |= CODEC_FLAG_GLOBAL_HEADER;

叼,这样写的代码有个潜规则,那就是:

if (av_buffersrc_add_frame_flags(m_filter_in_param.buffersrc_ctx, in_frame,
0) < 0) {

av_log(NULL, AV_LOG_ERROR, "Error while feeding the audio
filtergraph\n");

goto quit;

}

while (1) {

ret = av_buffersink_get_frame(m_filter_in_param.buffersink_ctx,
filt_frame);

if(ret == AVERROR(EAGAIN) || ret == AVERROR_EOF)

{

ret = -1;

goto quit;

}

if(ret < 0)

goto quit;

ret = avcodec_encode_audio2(m_CodecContext, new_packet, filt_frame,
&got_frame);

av_frame_free( &filt_frame );

if ( got_frame )

goto quit;

}

从这里编码出来的packet,让ffmpeg写到文件里去的时候会报错:

[mp4 @ 0119ad00] Malformed AAC bitstream detected: use audio bitstream
filter

‘aac_adtstoasc‘ to fix it (‘-bsf:a aac_adtstoasc‘ option with ffmpeg)

小孩子要什么filter来修正啊,叼,试了大半天也不知道哪个合适,并且也不想随便就加filter下去,万一它消耗太多cpu怎么办。

又是看ffmpeg的源码,avcodec_open2  看到返回0是正常的,内部调用了c->codec_init()
我也看到aacenc.c里去了,用反证法:它里面要是说参数又问题,肯定会返回负值,既然返回0就说明它是正常执行的。

AVCodec *codec = avcodec_find_encoder( codecid );
//这个没什么好说,下面又没对codec做什么改变。

下面的AVCodecContext *c = st->codec;你就诡异了,

/* open it */

ret = avcodec_open2(c, codec, NULL);

if (ret < 0) {

printf("Could not open audio codec");

exit(1);

}

严重怀疑c,c就是stream->codec,这个stream是在AVFormatContext *m_oc里的流。
跟到ffmpeg源码里去,发现是:

c->flags |= CODEC_FLAG_GLOBAL_HEADER;  
这个标志位没设置,叼,一般这个都是写在函数末尾,这里先提前了,放到avcodec_open2前面去,这肯定是我粗心大意?

/* Some formats want stream headers to be separate. */

if (m_oc->oformat->flags & AVFMT_GLOBALHEADER)

c->flags |= CODEC_FLAG_GLOBAL_HEADER;

avcodec_open2( c, codec, NULL ); 哟西,没事了。假装没事发生。。。。。。。。

从ffmpeg filter里出来的数据直接送给avcodec_encode_audio2编码,写文件有错。,码迷,mamicode.com

时间: 2024-10-09 14:11:14

从ffmpeg filter里出来的数据直接送给avcodec_encode_audio2编码,写文件有错。的相关文章

【大数据系列】hadoop上传文件报错_COPYING_ could only be replicated to 0 nodes

使用hadoop上传文件 hdfs dfs -put  XXX 17/12/08 17:00:39 WARN hdfs.DFSClient: DataStreamer Exception org.apache.hadoop.ipc.RemoteException(java.io.IOException): File /user/sanglp/hadoop-2.7.4.tar.gz._COPYING_ could only be replicated to 0 nodes instead of m

ffmpeg filter过滤器 基础实例及全面解析

目录 目录 什么是ffmpeg filter 如何使用ffmpeg filter 1 将输入的1920x1080缩小到960x540输出 2 为视频添加logo 3 去掉视频的logo 自己写一个过滤器 filter的结构体 filter_frame调用流程 1 decode_video ffmpegc 2 av_buffersrc_add_frame_flagsbuffersrcc 3 av_buffersrc_add_frame_internal buffersrcc 4 request_f

ffmpeg 从内存中读取数据

http://blog.csdn.net/leixiaohua1020/article/details/12980423 ffmpeg一般情况下支持打开一个本地文件,例如"C:\test.avi" 或者是一个流媒体协议的URL,例如"rtmp://222.31.64.208/vod/test.flv" 其打开文件的函数是avformat_open_input(),直接将文件路径或者流媒体URL的字符串传递给该函数就可以了. 但其是否支持从内存中读取数据呢?这个问题困

(转) 从ffmpeg中提取出YUV数据

有时需要从ffmpeg中提取出YUV数据用作预览,另存什么的. ffmpeg是先解码成YUV, 再以这个YUV作为输入进行编码,所以YUV数据有两种:  解码后的YUV数据, 以及  编码重建的YUV数据.下面分别讲两个YUV数据从哪儿?以及如何取? 1. 解码后的YUV数据在ffmpeg/libavcodec/utils_codec.c的avcodec_decode_video2() 函数中: avcodec_decode_video2(...){  ...   ret = avctx->co

从记事本里导入工资数据到数据库的写法

从记事本里导入工资数据到数据库的写法, 这种需要用的opendialog 要先添加这个组件: 1 procedure TForm3.N6Click(Sender: TObject); 2 var 3 KeFuAry: TArray<string>; 4 YueFen: string; 5 MyList: TStringList; 6 MyAdoq: TADOQuery; 7 I: Integer; 8 begin 9 MyList := TStringList.Create; 10 MyAdo

因为权限原因要在filter里使用spring- service所产生的问题

参考: 加载顺序 http://blog.csdn.net/wayfoon322/article/details/2418011 filter 使用注入bean  http://zy116494718.iteye.com/blog/1918131 1. 项目spring使用的是注解方式:在filter里debug看源码,类型里 allBeanNamesByType ConcurrentHashMap<K,V>  (id=169) ,是有想要的roleService的,但是在如下代码里就是取不到

利用bloom filter算法处理大规模数据过滤

Bloom Filter是由Bloom在1970年提出的一种快速查找算法,通过多个hash算法来共同判断某个元素是否在某个集合内.可以用于网络爬虫的url重复过滤.垃圾邮件的过滤等等. 它相比hash容器的一个优势就是,不需要存储元素的实际数据到容器中去来一个个的比较是否存在. 只需要对应的位段来标记是否存在就行了,所以想当节省内存,特别适合海量的数据处理.并且由于省去了存储元素和比较操作,所以性能也比基于hash容器的高了很多. 但是由于bloom filter没有去比较元素,只通过多个has

将excel里的有效数据提取出来

1.将excel里的有效数据提取出来 import xlrd import os path="text" #创建文件“text” def readexcel(): dable=xlrd.open_workbook('考生号码.xls') #打开excel table=dable.sheets()[0] #鼠标光标位置 nrows=table.nrows #光标以后的所有内容,获取表的行数 for i in range(nrows): #for循环出excel表里所有数据 num=tab

linux 里 /etc/passwd 、/etc/shadow和/etc/group 文件内容解释

•/etc/passwd文件用于存放用户账户信息,每行代表一个账户,每个账户的各项信息用冒号分割,例如: root:x:0:0:root:/root:/bin/bash username:password:uid:gid:allname:homedir:shell 1.用户名. 2.密码,“x”代表密码存储在/etc/shadow中:当该值为其他任意非“x”值时,可以通过root用户切换(不需要密码),但是都无法通过非root用户切换到相应用户,因为无法获得起密码了. 3.uid,用户id,0-