一次ffmpeg -c copy 在avformat_write_header函数处报错:Could not find tag for codec rawvideo in stream #0的原因分析
一、背景
在一次处理视频转换的时候使用了copy模式,然后在avformat_write_header函数处报错:Could not find tag for codec rawvideo in stream #0
二、分析
1.首先avformat_write_header调用如下
ret = avformat_write_header(of->ctx, &of->opts);
if (ret < 0) {
av_log(NULL, AV_LOG_ERROR,
"Could not write header for output file #%d "
"(incorrect codec parameters ?): %s\n",
file_index, av_err2str(ret));
return ret;
}
2.从错误的字面意思上看,应该是tag与codec类型不一致导致了这个报错,调试发现tag是mpeg4,codec是rawvideo(其实这里已经可以分析出原因了,但是当时没意识到)
3.做了一个测试,修改了tag
of->ctx->streams[0]->codecpar->codec_tag = 0x31637661;
of->ctx->streams[0]->codecpar->codec_id = AV_CODEC_ID_H264;of->ctx->streams[1]->codecpar->codec_tag = 0x6134706d;
of->ctx->streams[1]->codecpar->codec_id = AV_CODEC_ID_AAC;
果然,avformat_write_header执行通过,但是输出的文件不能播放,所以编解码设置还是有问题
4.为了解决这个问题,首先下载了ffmpeg对应分支的源码,找到avformat_write_header的实现,试图分析出报错的根本原因
5.ffmpeg的源码中的文件很多,好在报这个错误的地方只有一个,在movenc.c文件的mov_init函数中,函数命名上来看应该是初始化输出文件的mov头信息的函数,应该就是这里。源码是这样写的
track->tag = mov_find_codec_tag(s, track);
if (!track->tag) {
av_log(s, AV_LOG_ERROR, "Could not find tag for codec %s in stream #%d, "
"codec not currently supported in container\n",
avcodec_get_name(st->codecpar->codec_id), i);
return AVERROR(EINVAL);
}
6.还是不能进一步找到原因,于是找到了mov_find_codec_tag的源码,还是在moven.c中
static int mov_find_codec_tag(AVFormatContext *s, MOVTrack *track)
{
int tag;if (is_cover_image(track->st))
return ff_codec_get_tag(codec_cover_image_tags, track->par->codec_id);if (track->mode == MODE_MP4 || track->mode == MODE_PSP)
tag = track->par->codec_tag;
else if (track->mode == MODE_ISM)
tag = track->par->codec_tag;
else if (track->mode == MODE_IPOD) {
if (!av_match_ext(s->url, "m4a") &&
!av_match_ext(s->url, "m4v") &&
!av_match_ext(s->url, "m4b"))
av_log(s, AV_LOG_WARNING, "Warning, extension is not .m4a nor .m4v "
"Quicktime/Ipod might not play the file\n");
tag = track->par->codec_tag;
} else if (track->mode & MODE_3GP)
tag = track->par->codec_tag;
else if (track->mode == MODE_F4V)
tag = track->par->codec_tag;
else
tag = mov_get_codec_tag(s, track);return tag;
}
首先,mode确认是MP4,所以是track->par->codec_tag为0导致了报错,为什么这个tag为0呢,在执行到avformat_write_header前一步的时候,tag还是有值的,所以应该是在avformat_write_header执行过程中有地方修改到了这个tag。
7.继续追溯,找到下面两个类
input_streams,记录输入流的信息,在open_input_file时初始化里面的部分数据
output_streams,记录输出流的信息,当ffmpeg选项为-c copy时,会在init_output_stream_streamcopy函数中将输入流的编解码信息拷贝给输出流
8.再往上分析,发现是Openfile的时候编解码器的参数就没初始化成功
9.分析openfile的入参,发现不是正常的文件,而是数据流
三、总结
-c copy不能用于数据流情况
一次ffmpeg -c copy 在avformat_write_header函数处报错:Could not find tag for codec rawvideo in stream #0的原因分析相关推荐
- php 正则报错,PHP正则替换函数preg_replace()报错:Notice Use of undefined constant的解决方法分析...
本文实例讲述了PHP正则替换函数preg_replace()报错:Notice Use of undefined constant的解决方法.分享给大家供大家参考,具体如下: 环境错误级别:error ...
- verilog “function”函数一直报错解决办法
verilog "function"函数一直报错 ,经qq群中的大佬指点,发现是在 function 函数内部的逻辑部分缺少 begin--end导致.在此记录一下. functi ...
- ffmpeg打开视频解码器失败:Could not find codec parameters for stream 0 (Video: h264): unspecified size...
在使用ffmpeg进行拉流分离音视频数据再解码播放操作的时候: 有时候经常会报错: Could not find codec parameters for stream 0 (Video: h264) ...
- 函数yield报错ValueError: too many values to unpack (expected 2)
ValueError: too many values to unpack (expected 2)报错原因:用于接收返回值的变量多于函数本应该返回的值.在含有yield的函数中有这样的报错,可能是因 ...
- python 函数嵌套 报错_《Python》 函数嵌套、闭包和迭代器
一.函数的嵌套: 1.函数的嵌套调用 defmax2(x,y): m= x if x>y elseyreturnmdefmax4(a,b,c,d): res1=max2(a,b) res2=ma ...
- len函数python返回值类型_python的len函数为什么报错
len函数返回序列类型对象(字符或字符串.元组.列表和字典等)的项目个数(长度). 语法len(object) 函数返回一个大于0的int型整数,表示对象的项目个数. 参数说明 举例 1. 当参数是序 ...
- module ‘tensorflow‘ has no attribute xxx tensorflow版本问题类导致API函数的报错
目录 1. module 'tensorflow' has no attribute 'Session' 2. The Session graph is empty. Add operations t ...
- C++ 第三章 纯虚函数Virtual报错
Virtual 后的函数=0则为纯虚函数 #include <iostream>using namespace std;class FA {public:void Func1() {pri ...
- EXCEL自定义函数无法运行的原因:可以在VBA里运行的函数,在EXCEL用自定义函数为什么报错?
目录 1目标问题: 为什么VBA里,function可以运行的代码,在EXCEL用自定义函数,会返回错误值? 2 先说结论 2.1 最容易发生的原因 2.2 其他原因梳理 3 自定义函数返回值的情况 ...
最新文章
- 游戏开发随想之2D游戏架构
- Visual C++ 菜单
- 对数据类型而言运算符无效。运算符为 add,类型为 text。
- cad转dxf格式文件太大_如何玩转CAD看图?1分钟,一款完全免费的高效软件,解决所有看图...
- [转载] python中字典中追加_python 中字典中的删除,pop 方法与 popitem 方法
- HDU 3065 病毒侵袭持续中(AC自动机)题解
- Java面试题大全带答案
- 语音识别算法原理文档整理(一)
- 如何用计算机管理员权限,如何以管理员身份运行电脑?急
- python入门自学软件手机版_python编程入门
- 您的组织策略阻止我们为您完成此操作,有关详细信息,请联系技术支持
- react native使用echarts图表
- 如何将手机中Word文档转换成PDF
- 牛散NO.2:MACD西施说风情,柳下惠高位勿迷情
- IE8跳转谷歌浏览器亲测有效
- Orange's:一个操作系统的实现 Descriptor 3宏详解
- 加性高斯白噪声信道:MATLAB小例题
- 计算机网络基础选择题
- 【索引分类】位图索引
- echo 多行_【庭审现场】利用注销公司诈骗 多行不义必自毙_政务_澎湃新闻
热门文章
- e代理创始人兼CEO何文迪:中国财富管理行业正式进入“开放平台”阶段
- Cherry键盘-windows键-没反应
- 苹果新款笔记本_谷歌发布售价99美元的新款Wi-Fi路由器(全文)_苹果 新款MacBook Pro 13英寸_笔记本新闻...
- DB2 sequence 获取下一个值
- php怎么设置段落之间的距离,css如何设置段落间距?margin 属性设置段落间距(代码实例)...
- Python 用 OpenCV 实现 PS 高光/阴影选区
- Python 爬取微博、百度实时热点
- 小博老师浅谈Context(一)
- windows ce 专题
- 什么叫做信息安全?包含哪些内容?与网络安全有什么区别?