如何在FFmpeg C++代码中保留H.265视频的hvc1编码标签?
解决FFmpeg C++重封装时保留HEVC的hvc1编码标签问题
问题背景
我尝试复制带有HEVC视频的MP4文件,源文件的编码标签为hvc1:
Stream #0:0(und): Video: hevc (Main) (hvc1 / 0x31637668)
但复制后编码标签变为hev1:
Stream #0:0(und): Video: hevc (Main) (hev1 / 0x31766568)
已知FFmpeg命令行可通过-tag:v hvc1实现保留hvc1标签,但我在C++代码中尝试设置标签却无效,附上相关代码求解决方法。
问题分析
看你代码里的逻辑,你用av_codec_get_tag2去获取输出格式对应的编码器标签,但MP4容器对HEVC的默认标签是hev1,所以这个函数返回的就是hev1的数值,自然覆盖了你想要的hvc1。另外你后面多余的编码器上下文分配代码也没必要——重封装不需要编解码,只需要复制流参数就行,那部分代码反而可能干扰参数设置。
解决代码修改方案
直接针对HEVC视频流手动指定hvc1标签,替换你原来设置codec_tag的逻辑:
for (i = 0; i < (int)ifmt_ctx->nb_streams; i++) { AVStream *out_stream; AVStream *in_stream = ifmt_ctx->streams[i]; AVCodecParameters *in_codecpar = in_stream->codecpar; if (in_codecpar->codec_type != AVMEDIA_TYPE_AUDIO && in_codecpar->codec_type != AVMEDIA_TYPE_VIDEO && in_codecpar->codec_type != AVMEDIA_TYPE_SUBTITLE) { stream_mapping[i] = -1; continue; } stream_mapping[i] = stream_index++; out_stream = avformat_new_stream(ofmt_ctx, NULL); if (!out_stream) { fprintf(stderr, "Failed allocating output stream\n"); ret = AVERROR_UNKNOWN; goto end; } // 复制输入流的编码参数到输出流 ret = avcodec_parameters_copy(out_stream->codecpar, in_codecpar); if (ret < 0) { fprintf(stderr, "Failed to copy codec parameters\n"); goto end; } // 单独处理HEVC视频流,强制设置hvc1标签 if (in_codecpar->codec_id == AV_CODEC_ID_HEVC && in_codecpar->codec_type == AVMEDIA_TYPE_VIDEO) { // MKTAG是FFmpeg宏,把字符转成对应32位标签值,hvc1对应0x31637668 out_stream->codecpar->codec_tag = MKTAG('h','v','c','1'); } else { // 其他流按原有逻辑获取默认标签 unsigned int tag = 0; if (av_codec_get_tag2(ofmt_ctx->oformat->codec_tag, in_codecpar->codec_id, &tag) == 0) { av_log(NULL, AV_LOG_WARNING, "Could not find codec tag for codec id %d, using default 0.\n", in_codecpar->codec_id); } out_stream->codecpar->codec_tag = tag; } // 重封装不需要编码器上下文,删掉下面两行冗余代码 // out_stream->codec = avcodec_alloc_context3(encoder); // avcodec_parameters_to_context(out_stream->codec, parameters); }
补充说明
在MP4容器里,HEVC的两个标签区别在于:
hev1:只包含基础编码信息,不附带SPS/PPS等序列参数hvc1:包含完整的SPS/PPS数据,兼容性更强(很多设备只认hvc1)
FFmpeg的MP4复用器默认用hev1,所以必须手动指定hvc1才能和源文件保持一致。
内容的提问来源于stack exchange,提问作者ppcat
相关产品推荐
相关产品推荐

