ffmpeg hevc_ffmpeg视频解码

ffmpeg hevc_ffmpeg视频解码本次目标:1)将容器中的音频码流和视频码流分离出来。2)针对mp4文件中的码流情况进行修复。解封装的基本过程:#include<stdio.h>#include”libavcodec/avcodec.h”#include”libavformat/avformat.h”//MPEG-TS文件解封装得到的码流可播放,MP4解封装得到的码流不可播放;//这与容器的封装方式有关。voiddemuxer(constchar*url){//初始化格式上下文

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE稳定放心使用

本次目标:

1)将容器中的音频码流和视频码流分离出来。

2)针对mp4文件中的码流情况进行修复。

解封装的基本过程:

#include <stdio.h>
#include "libavcodec/avcodec.h"
#include "libavformat/avformat.h"

// MPEG-TS文件解封装得到的码流可直接播放
// MP4/FLV/MKV解封装得到的码流不可播放;
// 这与容器的封装方式有关。
void demuxer(const char *url) {
    // 初始化格式上下文
    AVFormatContext *fmt_ctx = avformat_alloc_context();
    if (fmt_ctx == NULL) {
        printf("failed to alloc format context\n");
        goto _Error;
    }

    // 打开输入流
    if (avformat_open_input(&fmt_ctx, url, NULL, NULL) < 0) {
        printf("failed to open input url\n");
        goto _Error;
    }

    // 读取媒体文件信息
    if (avformat_find_stream_info(fmt_ctx, NULL) < 0) {
        printf("failed to find stream\n");
        goto _Error;
    }
    av_dump_format(fmt_ctx, 0, url, 0);


    // 寻找音频流和视频流下标
    int video_index = -1, audio_index = -1;
    for (int i = 0; i < fmt_ctx->nb_streams; i++) {
        if (fmt_ctx->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
            video_index = i;
        } else if (fmt_ctx->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
            audio_index = i;
        }
    }
    if (video_index < 0 || audio_index < 0) {
        printf("failed to find stream index\n");
        goto _Error;
    }

    // 由打印的视频文件信息确定码流类型
    char audiofile[128], videofile[128];
    printf("type the name of output audiofile:");
    scanf("%s", audiofile);
    printf("\ntype the name of output videofile:");
    scanf("%s", videofile);
    FILE *faudio = fopen(audiofile, "w+");
    FILE *fvideo = fopen(videofile, "w+");
    AVPacket *packet = av_packet_alloc();

    while (av_read_frame(fmt_ctx, packet) == 0) {

        if (packet->stream_index == audio_index) {
            fwrite(packet->data, 1, packet->size, faudio);
        }
        else if (packet->stream_index == video_index) {
            fwrite(packet->data, 1, packet->size, fvideo);
        }
        av_packet_unref(packet);
    }

_Error:
    if (fmt_ctx) avformat_close_input(&fmt_ctx);
    if (faudio)  fclose(faudio);
    if (fvideo)  fclose(fvideo);
    if (packet)  av_packet_free(&packet);
}


int main(int argc, char const* argv[])
{
    demuxer(argv[1]);
    return 0;
}

编译测试:得到视频信息后,根据文件中的编码信息(mp3或aac,h264或mpeg4,mpeg4码流文件后辍为.m4v),命名解封装的码流文件。
image-20210514113830833

mp4文件解封装得到的h264码流和aac码流都不能解码播放!

1、mp4文件中的码流有什么不同

	Stream #0:0(und): Video: h264 (High) (avc1 / 0x31637661), yuv420p, 
	640x352, 748 kb/s, 23.98 fps, 23.98 tbr, 24k tbn, 47.95 tbc (default)
	
	Stream #0:1(und): Audio: aac (LC) (mp4a / 0x6134706D), 
	44100 Hz, stereo, fltp, 128 kb/s (default)

MP4封装格式是基于QuickTime容器格式定义,媒体描述与媒体数据分开。从MP4得到的H264和AAC码流是ES流,它们缺失解码时必要的起始码/SPS/PPSadts头

我们常规的H264帧数据保存格式是annexb,是具有起始码0x000001或0x00000001;mpeg-ts文件中保存的是视频码流是存在起始码的,而在mp4文件中没有起始码。

H.264视频编码格式主要分为两种形式,即带起始码的H.264码流不带起始码的H.264码流,其中,前者就是我们比较熟悉的H264、X264;后者就是指AVC1

More:MP4中的H264和AAC

2、怎么修复MP4中的码流?

AAC码流(mp4a):保存一帧码流数据前,补充相应的adts头;

H264码流(avc1):使用h264_mp4toannexb过滤器,对视频码流进行处理。

①每一帧前补充ADTS头

// 生成7字节的ADTS头
char *adts_header_gen(int len) {
    static char header[7];

    int profile = 2;    // AAC LC
    int freqidx = 4;    // 3 - 48k, 4 - 44.1k 
    int chncfg  = 2;    // 声道数量 

    header[0] = 0xFF;
    header[1] = 0xF1;
    header[2] = ((profile-1) << 6) | (freqidx << 2) | (chncfg >> 2);
    header[3] = ((chncfg & 3) << 6)| (len >> 11);
    header[4] = (len & 0x7FF) >> 3;
    header[5] = ((len & 0x7) << 5) | 0x1F;
    header[6] = 0xFC;
    return header;
}
if (packet->stream_index == audio_index) {
	// packet->size是adts中数据块的长度
	fwrite(adts_header_gen(packet->size+7), 1, 7, faudio);
	fwrite(packet->data, 1, packet->size, faudio);
}

More:AAC音频码流解析

②使用h264_mp4toannexb过滤器处理h264码流

// 初始化过滤器
const AVBitStreamFilter *bsf = av_bsf_get_by_name("h264_mp4toannexb");
if (bsf == NULL) {
	printf("failed to find stream filter\n");
	goto _Error;
}
AVBSFContext *bsf_ctx;
av_bsf_alloc(bsf, &bsf_ctx);
avcodec_parameters_copy(bsf_ctx->par_in, fmt_ctx->streams[video_index]->codecpar);
av_bsf_init(bsf_ctx);
else if (packet->stream_index == video_index) {
    if (av_bsf_send_packet(bsf_ctx, packet) == 0) {
        while (av_bsf_receive_packet(bsf_ctx, packet) == 0) {
            fwrite(packet->data, 1, packet->size, fvideo);
        }
    }
}

经过比特流过滤器的处理,每个AVPacket的data添加了H.264的NALU的起始码{0,0,0,1};每个IDR帧数据前面添加了SPS和PPS。

More:解析h264视频码流

视频播放效果:

原mp4文件:
image-20210514112106240

out.h264码流文件:
image-20210514112149236

out.aac文件:
image-20210514112333031

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/181225.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • mysql做pisa_群晖nas修改MariaDB配置文件

    mysql做pisa_群晖nas修改MariaDB配置文件家里的Nas使用率越来越高,平均每周手工重启一次,系统运行还算稳定。最近安装了WebStation,MariaDB等套件,用来作为家里的开发测试环境,使用下来还不错。理论上解析个动态域名到nas就能实现对外提供web服务了。100M电信光纤,上行2M,做个个人网站访问速度凑合着应该还是能用的。在导入数据时,因数据库包比较庞大(>100M),需要修改max_allowed_packet字段。…

  • Eclipse 的快捷键以及文档注释、多行注释的快捷键[通俗易懂]

    Eclipse 的快捷键以及文档注释、多行注释的快捷键[通俗易懂]原文地址:http://my.oschina.net/u/590763/blog/70166一、多行注释快捷键1.选中你要加注释的区域,用ctrl+shift+C或者ctrl+/会加上//注释2.先把你要注释的东西选中,用shit+ctrl+/会加上/*   */注释3.以上快捷在重复按一下就会去掉加上的注释4.要修改在eclispe中的命令的快捷键方式我们只需进

  • ducter运维平台_开源自动运维管理平台_自动化运维平台 开源「建议收藏」

    ducter运维平台_开源自动运维管理平台_自动化运维平台 开源「建议收藏」专访运维管理开源平台负责人刁文波:Ducter能550×364-47KB-JPEG专访运维管理开源平台负责人刁文波:Ducter能550×381-45KB-JPEG光宇游戏黄振:开源运维自动化平台架构实现与846×474-35KB-JPEGCheungSSH国产自动化运维工具开源Web界面811×525-89KB-PNGCheungSSH国产自动化运维工具开源Web…

  • mt4电脑版安装教程_mt4电脑版安装教程

    mt4电脑版安装教程_mt4电脑版安装教程首先是要下载个安装包,可以在qiejf.cn获取。然后按照下方步骤操作即可。步骤1.运行安装文件要安装MetaTrader4平台,您必须通过双击安装文件teletradecy4setup.exe来运行安装文件。步骤2.安装程序-欢迎屏幕安装程序将打开MetaTrader4TeleTradeEU。要继续安装,请单击“下一步”。步骤3.许可协议阅读并接受许可协议,然后单击“下一步”。步骤4.安装选项选择安装文件夹,然后单击“下一步”继续。步骤5.安装

  • 如何在html添加css样式表,网页中添加CSS样式表的四种方式

    如何在html添加css样式表,网页中添加CSS样式表的四种方式本文向大家描述一下网页中添加CSS样式表的四种方式,首先让我们来看一下CSS样式表文件的优势,主要体现在两个方面,请看下文详细介绍。CSS样式表文件的优势表现在两个方面:***,简化了网页的格式代码,外部的CSS样式表还会被浏览器保存在缓存里,加快了下载显示的速度,也减少了需要上传的代码数量(因为重复设置的格式将被只保存一次)。第二,只要修改保存着网站格式的CSS样式表文件就可以改变整个站点的风格…

  • PHP+Ajax点击加载更多内容 -这个效果好,速度快,只能点击更多加载,不能滚动自动加载…

    PHP+Ajax点击加载更多内容 -这个效果好,速度快,只能点击更多加载,不能滚动自动加载…

    2021年10月30日

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号