5、MP4解复用---AAC+H264

  • MP4
    MP4同样是一种容器格式,是由一个一个Box组成,每个Box又分为Header与Data,Data又包含很多子Box,具体的MP4文件结构也看过,内部Box结构比较复杂,一般不写MP4解释器的话,Box结构不用了解太细,对MP4封装有MP4V2库可以使用,当然也可以使用FFMPEG库。
    本文从代码的角度上来分析使用FFMPEG对MP4文件解复用。
    完整代码如下:
#include <stdio.h>#include "libavutil/log.h"
#include "libavformat/avformat.h"#define ERROR_STRING_SIZE 1024#define ADTS_HEADER_LEN  7;const int sampling_frequencies[] = {96000,88200,64000,48000,44100,32000,24000,22050,16000,12000,11025,8000
};int adts_header(char * const p_adts_header, const int data_length,const int profile, const int samplerate,const int channels)
{int sampling_frequency_index = 3;int adtsLen = data_length + 7;int frequencies_size = sizeof(sampling_frequencies) / sizeof(sampling_frequencies[0]);for(int i = 0; i < frequencies_size; i++){if(sampling_frequencies[i] == samplerate){sampling_frequency_index = i;break;}}p_adts_header[0] = 0xff;p_adts_header[1] = 0xf0;p_adts_header[1] |= (0 << 3);p_adts_header[1] |= (0 << 1);p_adts_header[1] |= 1;p_adts_header[2] = (profile)<<6;p_adts_header[2] |= (sampling_frequency_index & 0x0f)<<2;p_adts_header[2] |= (0 << 1);p_adts_header[2] |= (channels & 0x04)>>2;p_adts_header[3] = (channels & 0x03)<<6;p_adts_header[3] |= (0 << 5);p_adts_header[3] |= (0 << 4);p_adts_header[3] |= (0 << 3);p_adts_header[3] |= (0 << 2);p_adts_header[3] |= ((adtsLen & 0x1800) >> 11);p_adts_header[4] = (uint8_t)((adtsLen & 0x7f8) >> 3);p_adts_header[5] = (uint8_t)((adtsLen & 0x7) << 5);p_adts_header[5] |= 0x1f;p_adts_header[6] = 0xfc;return 0;
}int main(int argc, char **argv)
{char *in_filename = "/home/yx/media_file/believe.mp4";char *h264_filename = "/home/yx/media_file/believe.h264";char *aac_filename = "/home/yx/media_file/believe.aac";FILE *aac_fd = NULL;FILE *h264_fd = NULL;h264_fd = fopen(h264_filename, "wb");aac_fd = fopen(aac_filename, "wb");AVFormatContext *ifmt_ctx = NULL;int video_index = -1;int audio_index = -1;AVPacket *pkt = NULL;ifmt_ctx = avformat_alloc_context();avformat_open_input(&ifmt_ctx, in_filename, NULL, NULL);                                // 将媒体流与解复用器相关联video_index = av_find_best_stream(ifmt_ctx, AVMEDIA_TYPE_VIDEO, -1, -1, NULL, 0);       // 查找视频流标签audio_index = av_find_best_stream(ifmt_ctx, AVMEDIA_TYPE_AUDIO, -1, -1, NULL, 0);       // 查找音频流标签const AVBitStreamFilter *bsfilter = av_bsf_get_by_name("h264_mp4toannexb");             // 查找H264过滤器AVBSFContext *bsf_ctx = NULL;av_bsf_alloc(bsfilter, &bsf_ctx);avcodec_parameters_copy(bsf_ctx->par_in, ifmt_ctx->streams[video_index]->codecpar);av_bsf_init(bsf_ctx);                                                                   // 初始化过滤器pkt = av_packet_alloc();av_init_packet(pkt);while (1){if(av_read_frame(ifmt_ctx, pkt) < 0)                                                // 逐个包读取break;if(pkt->stream_index == video_index){av_bsf_send_packet(bsf_ctx, pkt);                                               // 视频包就将包发给过滤器while (1){if(av_bsf_receive_packet(bsf_ctx, pkt) != 0)                                // 从过滤器接收包break;size_t size = fwrite(pkt->data, 1, pkt->size, h264_fd);                     // 将包写到输出文件av_packet_unref(pkt);}}else if(pkt->stream_index == audio_index){char adts_header_buf[7] = {0};adts_header(adts_header_buf, pkt->size,ifmt_ctx->streams[audio_index]->codecpar->profile,ifmt_ctx->streams[audio_index]->codecpar->sample_rate,ifmt_ctx->streams[audio_index]->codecpar->channels);                // 音频包构建ADTS帧头部fwrite(adts_header_buf, 1, 7, aac_fd);                                          // 将头部写到输出文件size_t size = fwrite( pkt->data, 1, pkt->size, aac_fd);                         // 将AAC包写到输出文件av_packet_unref(pkt);                                                           // 引用计数--}else{av_packet_unref(pkt);}}printf("while finish\n");printf("Hello World!\n");return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/40942.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

.NET编程:C#下WinForms多语种切换的艺术

概述 在全球化的今天&#xff0c;软件的多语言支持已成为标配。.NET中的WinForms应用程序提供了多种方式来实现多语种切换&#xff0c;让软件能够跨越语言障碍&#xff0c;触及更广阔的用户群体。本文将带领大家探索C#下WinForms应用程序实现多语种切换的不同方法&#xff0c;通…

2.1 tmux和vim

文章目录 前言概述tmuxvim总结 前言 开始学习的时间是 2024.7.6 ,13&#xff1a;47 概述 最好多使用&#xff0c;练成条件反射式的 直接使用终端的工具&#xff0c;可以连接到服务器&#xff0c;不需要使用本地的软件 tmux 这个主要有两个功能&#xff0c;第一个功能是分…

Linux多进程和多线程(七)进程间通信-信号量

进程间通信之信号量 资源竞争 多个进程竞争同一资源时&#xff0c;会发生资源竞争。 资源竞争会导致进程的执行出现不可预测的结果。 临界资源 不允许同时有多个进程访问的资源, 包括硬件资源 (CPU、内存、存储器以及其他外 围设备) 与软件资源(共享代码段、共享数据结构) …

Redis Cluster 模式 的具体实施细节是什么样的?

概述 参考&#xff1a;What are Redis Cluster and How to setup Redis Cluster locally ? | by Rajat Pachauri | Medium Redis Cluster 的工作原理是将数据分布在多个节点上&#xff0c;同时确保高可用性和容错能力。以下是 Redis Cluster 运行方式的简要概述&#xff1a; …

读书到底有什么意义?从笨小孩到名人的逆袭之路

点击上方△腾阳 关注 作者 l 腾阳 转载请联系授权 读书到底有什么意义&#xff1f; 有一个鸟语花香的农场里&#xff0c;住着老农夫和他的小孙子。 老农夫经常在清晨会坐在窗边&#xff0c;捧着厚厚的《圣经》&#xff0c;沉浸在知识的海洋里。 小孙子问他&#xff1a;…

[终端安全]-1 总体介绍

有朋友一直在和笔者研讨智驾安全这个热门话题&#xff0c;笔者十多年工作从不离终端安全这个核心话题&#xff08;芯片安全、操作系统安全、应用安全&#xff09;&#xff0c;近来也一直在梳理终端安全体系&#xff1b;手机、汽车皆是我们生活中应用最普遍的智能终端&#xff0…

VSCode设置好看清晰的字体!中文用鸿蒙,英文用Jetbrains Mono

一、中文字体——HarmonyOS Sans SC 1、下载字体 官网地址&#xff1a;https://developer.huawei.com/consumer/cn/design/resource/ 直接下载&#xff1a;https://communityfile-drcn.op.dbankcloud.cn/FileServer/getFile/cmtyPub/011/111/111/0000000000011111111.20230517…

Redis分布式锁的应用场景有哪些

⼀ 、应⽤场景 在多线程并发的场景下 &#xff0c;Java Synchronized/Reentrantlock 锁能够实现同⼀个JVM进程内多线程 并发的安全性 &#xff0c;但⽆法保证多个JVM进程实例构成的集群环境在多线程下的安全性。在⼀些业务场景 下需要引⼊分布式锁。 1、缓存击穿 当某个热点缓…

加密(3)非对称加密

一、介绍 1、概念 非对称加密&#xff0c;又称现代加密算法&#xff0c;非对称加密是计算机通信安全的基石&#xff0c;保证了加密数据不会被破解。加密和解密使用的是两个不同的密钥&#xff0c;这种算法叫作非对称加密算法。 2、示例 首先生成密钥对, 公钥为(5,14)&#…

【分布式系统】ELK 企业级日志分析系统

目录 一.ELK概述 1.简介 1.1.可以添加的其他组件 1.2.filebeat 结合 logstash 带来好处 2.为什么使用ELK 3.完整日志系统基本特征 4.工作原理 二.部署ELK日志分析系统 1.初始化环境 2.完成JAVA部署 三. ELK Elasticsearch 集群部署 1.安装 2.修改配置文件 3.es 性…

latex英文转中文word,及一些latex相关工具分享

前言&#xff1a;想要转换latex生成的英文pdf文件为中文word文件 一、主要步骤 1、文字翻译&#xff1a;直接使用谷歌翻译等辅助将英文翻译成中文即可&#xff1b; **2、图片&#xff1a;**使用latex时一般保存的.png&#xff0c;.bmp格式图片可以直接插入word, 但是.eps或者…

Vue3:全局播放背景音乐

说明&#xff1a;一个全局播放的背景音乐&#xff0c;首页无音乐无音乐图标&#xff0c;在首页互动跳转页面并开始播放音乐&#xff0c;切换页面不需暂停音乐也不会重置音乐&#xff0c;可以通过音乐图标控制暂停或播放。 MusicPlay.vue&#xff08;音乐组件&#xff09; <…

实习手记(2):前端菜鸟的摸鱼与成长

在不断的学习&#xff08;摸鱼&#xff09;和实践中&#xff0c;第二周也快要结束了&#xff0c;这周总体来说还是蛮不错的比上周好很多&#xff08;没有那么拘谨&#xff1f;&#xff09;。前面两天一直在学习和摸鱼之后就修改了几个需求。这里记录一下学习到的新知识、小技巧…

Vue3.js“非原始值”响应式实现基本原理笔记(一)

如果您觉得这篇文章有帮助的话&#xff01;给个点赞和评论支持下吧&#xff0c;感谢~ 作者&#xff1a;前端小王hs 阿里云社区博客专家/清华大学出版社签约作者/csdn百万访问前端博主/B站千粉前端up主 此篇文章是博主于2022年学习《Vue.js设计与实现》时的笔记整理而来 书籍&a…

Sentinel限流算法总结

文章目录 一、线程隔离二、滑动窗口算法三、令牌桶算法四、漏桶算法 一、线程隔离 线程隔离有两种方式实现&#xff1a; 线程池隔离&#xff1a;给每个服务调用业务分配一个线程池&#xff0c;利用线程池本身实现隔离效果信号量隔离&#xff1a;不创建线程池&#xff0c;而是…

Xilinx FPGA:vivado关于同步fifo的两个小实验

一、实验一&#xff1a;在同步fifo里写一个读一个&#xff08;写入是8个位宽&#xff0c;读出是16个位宽&#xff09; 程序&#xff1a; timescale 1ns / 1ps //要求写一个读一个 //读写时钟一致&#xff0c;写是8个位宽&#xff0c;读是16个位宽 module sync_fifo_test(inpu…

QQ音乐Android一面凉经

最近面试了不少公司, 近期告一段落, 整理一下各家的面试问题, 打算陆续发布出来, 供有缘人参考。今天给大家带来的是QQ音乐Android一面凉经。 面试岗位: QQ音乐Android开发工程师面试时长: 50min(提问40min 反问10min)代码考核: 无 面试问题(40min) 自我介绍 工作经历, 重点…

银行信用卡风险大数据分析与挖掘2024

银行信用卡风险大数据分析与挖掘 使用excel数据挖掘功能完成 一、信用卡客户信用等级影响因素分析与挖掘 基于客户信用记录表 1. 数据预处理 浏览数据 客户等级占比&#xff0c;其中优质客户占比较少&#xff0c;风险客户很多&#xff0c;分析影响客户信用等级的原因 年…

vue3+ts项目中.env配置环境变量与情景配置

一、环境变量配置 官网https://cn.vitejs.dev/guide/env-and-mode.html#intellisense 1. 新建.env开头的文件在根目录 为了防止意外地将一些环境变量泄漏到客户端&#xff0c;只有以 VITE_ 为前缀的变量才会暴露给经过 vite 处理的代码 .env 所有环境默认加载 .env.developm…

数字化精益生产系统--MRP 需求管理系统

MRP&#xff08;Material Requirements Planning&#xff0c;物料需求计划&#xff09;需求管理系统是一种在制造业中广泛应用的计划工具&#xff0c;旨在通过分析和计划企业生产和库存需求&#xff0c;优化资源利用&#xff0c;提高生产效率。以下是对MRP需求管理系统的功能设…