一、背景

在一次处理视频转换的时候使用了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的原因分析相关推荐

  1. php 正则报错,PHP正则替换函数preg_replace()报错:Notice Use of undefined constant的解决方法分析...

    本文实例讲述了PHP正则替换函数preg_replace()报错:Notice Use of undefined constant的解决方法.分享给大家供大家参考,具体如下: 环境错误级别:error ...

  2. verilog “function”函数一直报错解决办法

    verilog "function"函数一直报错 ,经qq群中的大佬指点,发现是在 function 函数内部的逻辑部分缺少 begin--end导致.在此记录一下. functi ...

  3. ffmpeg打开视频解码器失败:Could not find codec parameters for stream 0 (Video: h264): unspecified size...

    在使用ffmpeg进行拉流分离音视频数据再解码播放操作的时候: 有时候经常会报错: Could not find codec parameters for stream 0 (Video: h264) ...

  4. 函数yield报错ValueError: too many values to unpack (expected 2)

    ValueError: too many values to unpack (expected 2)报错原因:用于接收返回值的变量多于函数本应该返回的值.在含有yield的函数中有这样的报错,可能是因 ...

  5. python 函数嵌套 报错_《Python》 函数嵌套、闭包和迭代器

    一.函数的嵌套: 1.函数的嵌套调用 defmax2(x,y): m= x if x>y elseyreturnmdefmax4(a,b,c,d): res1=max2(a,b) res2=ma ...

  6. len函数python返回值类型_python的len函数为什么报错

    len函数返回序列类型对象(字符或字符串.元组.列表和字典等)的项目个数(长度). 语法len(object) 函数返回一个大于0的int型整数,表示对象的项目个数. 参数说明 举例 1. 当参数是序 ...

  7. module ‘tensorflow‘ has no attribute xxx tensorflow版本问题类导致API函数的报错

    目录 1. module 'tensorflow' has no attribute 'Session' 2. The Session graph is empty. Add operations t ...

  8. C++ 第三章 纯虚函数Virtual报错

    Virtual 后的函数=0则为纯虚函数 #include <iostream>using namespace std;class FA {public:void Func1() {pri ...

  9. EXCEL自定义函数无法运行的原因:可以在VBA里运行的函数,在EXCEL用自定义函数为什么报错?

    目录 1目标问题: 为什么VBA里,function可以运行的代码,在EXCEL用自定义函数,会返回错误值? 2 先说结论 2.1 最容易发生的原因 2.2 其他原因梳理 3  自定义函数返回值的情况 ...

最新文章

  1. 游戏开发随想之2D游戏架构
  2. Visual C++ 菜单
  3. 对数据类型而言运算符无效。运算符为 add,类型为 text。
  4. cad转dxf格式文件太大_如何玩转CAD看图?1分钟,一款完全免费的高效软件,解决所有看图...
  5. [转载] python中字典中追加_python 中字典中的删除,pop 方法与 popitem 方法
  6. HDU 3065 病毒侵袭持续中(AC自动机)题解
  7. Java面试题大全带答案
  8. 语音识别算法原理文档整理(一)
  9. 如何用计算机管理员权限,如何以管理员身份运行电脑?急
  10. python入门自学软件手机版_python编程入门
  11. 您的组织策略阻止我们为您完成此操作,有关详细信息,请联系技术支持
  12. react native使用echarts图表
  13. 如何将手机中Word文档转换成PDF
  14. 牛散NO.2:MACD西施说风情,柳下惠高位勿迷情
  15. IE8跳转谷歌浏览器亲测有效
  16. Orange's:一个操作系统的实现 Descriptor 3宏详解
  17. 加性高斯白噪声信道:MATLAB小例题
  18. 计算机网络基础选择题
  19. 【索引分类】位图索引
  20. echo 多行_【庭审现场】利用注销公司诈骗 多行不义必自毙_政务_澎湃新闻

热门文章

  1. e代理创始人兼CEO何文迪:中国财富管理行业正式进入“开放平台”阶段
  2. Cherry键盘-windows键-没反应
  3. 苹果新款笔记本_谷歌发布售价99美元的新款Wi-Fi路由器(全文)_苹果 新款MacBook Pro 13英寸_笔记本新闻...
  4. DB2 sequence 获取下一个值
  5. php怎么设置段落之间的距离,css如何设置段落间距?margin 属性设置段落间距(代码实例)...
  6. Python 用 OpenCV 实现 PS 高光/阴影选区
  7. Python 爬取微博、百度实时热点
  8. 小博老师浅谈Context(一)
  9. windows ce 专题
  10. 什么叫做信息安全?包含哪些内容?与网络安全有什么区别?