深入介绍STBL——非常重要

iOS视频录制、压缩导出、取帧 首发博客:标哥的技术博客关注公众号:iOS开发技术分享概述花了点时间研究了一下常用的视频获取、录制、压缩并导出、保存到相册、取帧图功能,分享给大家了!相信阅读完本篇文章,会对你有很大的帮助的!记得关注微博、公众号哦,请到文章末尾跳转!本篇文章研究几下以个功能: 视频录制 从相册选择视频 保存视频到相册 获取视频帧图 压缩并导出视频 解决iOS8上录视频引起的偏移bug 需要真机测试,才能录制视频!效 阅读详情

http://www.cnblogs.com/lidabo/p/3754130.html


http://www.cnblogs.com/lidabo/p/3754130.html


前面介绍过的几种格式flv、mkv、asf等。他们音视频的数据包一般都是按照文件的顺序交叉安放。你解析完头部信息后。剩下的一般就按照文件顺序一个数据包一个数据包的解析就行了。但是MP4完全不是这种概念。他的媒体信息和数据是分开存放的。就是你想获得数据之前必须要解析出每个帧数据所有的位置。mp4存放这个帧信息的是放在stbl这个box里。而真实的数据放在mdat中。接下来就讲讲stbl与mdat的对应关系。

Sample Table Box(stbl)

来一张典型的stbl结构图:
常见子box

stts:    Decoding Time to Sample Box 时间戳和Sample映射表
stsd:   Sample Description Box
stsz, stz2: Sample Size Boxes 每个Sample大小的表。
stsc: Sample to chunk 的映射表。
‘stco’, ‘co64’: Chunk位置偏移表
stss:关键帧index。

1.解析stsd可获得coding类型、视频宽高、音频samplesize、channelcount这些和解码器有关信息。

 

[cpp]  view plain copy
  1. aligned(8) class SampleDescriptionBox (unsigned int(32) handler_type)  
  2. extends FullBox('stsd', 0, 0){  
  3. int i ;  
  4. unsigned int(32) entry_count;  
  5. for (i = 1 ; i u entry_count ; i++){  
  6. switch (handler_type){  
  7. case ‘soun’: // for audio tracks  
  8. AudioSampleEntry();  
  9. break;  
  10. case ‘vide’: // for video tracks  
  11. VisualSampleEntry();  
  12. break;  
  13. case ‘hint’: // Hint track  
  14. HintSampleEntry();  
  15. break;  
  16. }  
  17. }  
  18. }  

 

[cpp]  view plain copy
  1. aligned(8) abstract class SampleEntry (unsigned int(32) format)  
  2. extends Box(format){  
  3. const unsigned int(8)[6] reserved = 0;  
  4. unsigned int(16) data_reference_index;  
  5. }  
  6. class HintSampleEntry() extends SampleEntry (protocol) {  
  7. unsigned int(8) data [];  
  8. }  
  9. // Visual Sequences  
  10. class VisualSampleEntry(codingname) extends SampleEntry (codingname){  
  11. unsigned int(16) pre_defined = 0;  
  12. const unsigned int(16) reserved = 0;  
  13. unsigned int(32)[3] pre_defined = 0;  
  14. unsigned int(16) width;  
  15. unsigned int(16) height;  
  16. template unsigned int(32) horizresolution = 0x00480000; // 72 dpi  
  17. template unsigned int(32) vertresolution = 0x00480000; // 72 dpi  
  18. const unsigned int(32) reserved = 0;  
  19. template unsigned int(16) frame_count = 1;  
  20. string[32] compressorname;  
  21. template unsigned int(16) depth = 0x0018;  
  22. int(16) pre_defined = -1;  
  23. }  
  24. // Audio Sequences  
  25. class AudioSampleEntry(codingname) extends SampleEntry (codingname){  
  26. const unsigned int(32)[2] reserved = 0;  
  27. template unsigned int(16) channelcount = 2;  
  28. template unsigned int(16) samplesize = 16;  
  29. unsigned int(16) pre_defined = 0;  
  30. const unsigned int(16) reserved = 0 ;  
  31. template unsigned int(32) samplerate = {timescale of media}<<16;  
  32. }  

 

 

2.解析stsz box 可以获得一个sample size的表

 

[cpp]  view plain copy
  1. aligned(8) class SampleSizeBox extends FullBox(‘stsz’, version = 0, 0) {  
  2. unsigned int(32) sample_size;  
  3. unsigned int(32) sample_count;  
  4. if (sample_size==0) {  
  5. for (i=1; i u sample_count; i++) {  
  6. unsigned int(32) entry_size;  
  7. }  
  8. }  
  9. }  

3.解析stts 

 

 

[cpp]  view plain copy
  1. aligned(8) class TimeToSampleBox  
  2. extends FullBox(’stts’, version = 0, 0) {  
  3. unsigned int(32) entry_count;  
  4. int i;  
  5. for (i=0; i < entry_count; i++) {  
  6. unsigned int(32) sample_count;  
  7. unsigned int(32) sample_delta;  
  8. }  
  9. }  

 

4.解析stsc 还原Sample 与chunk的映射表 

 


Sample 是存储的最基本单元,mp4把Sample 存在chunk中。chunk的长度、chunk的大小、chunk中Sample的数量及大小都是不定的。

通过解析这部分box来还原这个映射表。

 

[cpp]  view plain copy
  1. aligned(8) class SampleToChunkBox  
  2. extends FullBox(‘stsc’, version = 0, 0) {  
  3. unsigned int(32) entry_count;  
  4. for (i=1; i u entry_count; i++) {  
  5. unsigned int(32) first_chunk;  
  6. unsigned int(32) samples_per_chunk;  
  7. unsigned int(32) sample_description_index;  
  8. }  
  9. }  


每个entry 表示着一组数据,entry_count 表示这数量。这一组其实是相同类型的chunk。

 

first_chunk 表示 这一组相同类型的chunk中 的第一个chunk数。

这些chunk 中包含的Sample 数量,即samples_per_chunk 是一致的。

每个Sample 可以通过sample_description_index 去stsd box 找到描述信息。

看ffmpeg中mov_read_stsc() 它把这些数据放在一个结构体数组中备用。

 

[cpp]  view plain copy
  1. static int mov_read_stsc(MOVContext *c, AVIOContext *pb, MOVAtom atom)  
  2. {  
  3.     AVStream *st;  
  4.     MOVStreamContext *sc;  
  5.     unsigned int i, entries;  
  6.   
  7.     if (c->fc->nb_streams < 1)  
  8.         return 0;  
  9.     st = c->fc->streams[c->fc->nb_streams-1];  
  10.     sc = st->priv_data;  
  11.   
  12.     avio_r8(pb); /* version */  
  13.     avio_rb24(pb); /* flags */  
  14.   
  15.     entries = avio_rb32(pb);  
  16.   
  17.     av_dlog(c->fc, "track[%i].stsc.entries = %i\n", c->fc->nb_streams-1, entries);  
  18.   
  19.     if (!entries)  
  20.         return 0;  
  21.     if (entries >= UINT_MAX / sizeof(*sc->stsc_data))  
  22.         return AVERROR_INVALIDDATA;  
  23.     sc->stsc_data = av_malloc(entries * sizeof(*sc->stsc_data));  
  24.     if (!sc->stsc_data)  
  25.         return AVERROR(ENOMEM);  
  26.   
  27.     for (i = 0; i < entries && !pb->eof_reached; i++) {  
  28.         sc->stsc_data[i].first = avio_rb32(pb);  
  29.         sc->stsc_data[i].count = avio_rb32(pb);  
  30.         sc->stsc_data[i].id = avio_rb32(pb);  
  31.     }  
  32.   
  33.     sc->stsc_count = i;  
  34.   
  35.     if (pb->eof_reached)  
  36.         return AVERROR_EOF;  
  37.   
  38.     return 0;  
  39. }  

在获得完整的映射表,我们还需要chunk总个数信息。这些信息放在‘stco’, ‘co64’中。

 

5.解析‘stco’, ‘co64’

“stco”定义了每个thunk在媒体流中的位置。位置有两种可能,32位的和64位的,后者对非常大的电影很有用。

32位

 

[cpp]  view plain copy
  1. aligned(8) class ChunkOffsetBox  
  2. extends FullBox(‘stco’, version = 0, 0) {  
  3. unsigned int(32) entry_count;  
  4. for (i=1; i u entry_count; i++) {  
  5. unsigned int(32) chunk_offset;  
  6. }  
  7. }  


64位

 

 

[cpp]  view plain copy
  1. aligned(8) class ChunkLargeOffsetBox  
  2. extends FullBox(‘co64’, version = 0, 0) {  
  3. unsigned int(32) entry_count;  
  4. for (i=1; i u entry_count; i++) {  
  5. unsigned int(64) chunk_offset;  
  6. }  
  7. }  

从这个box我们就可以获得 chunk 的总数量,entry_count。

 

 from:http://blog.youkuaiyun.com/tx3344/article/details/8506131

1.解析‘stco’, ‘co64’我们有了chunk 表,知道了chunk 的总数及每个chunk所在文件的位置。

2.解析stsc 配合着上面的chunk表,我们就能弄个Sample与chunk的关系表。我们也就能获得每个Sample的位置信息。

3.配合上面的stts 时间表和解码器信息等。搞出ES流已经不成问题了。

4.想获得关键帧的index,需要解析stss’

 

[cpp]  view plain copy
    1. aligned(8) class SyncSampleBox  
    2. extends FullBox(‘stss’, version = 0, 0) {  
    3. unsigned int(32) entry_count;  
    4. int i;  
    5. for (i=0; i < entry_count; i++) {  
    6. unsigned int(32) sample_number;  
    7. }  
    8. }  

深入理解nginx mp4流媒体模块[下] 本文通过对nginx mp4模块的源码分析,来学习nginx mp4模块的功能和实现原理。 并对mp4格式的分析有一个更加深入的了解。 阅读详情

相关推荐

stm32 的Flash Loader Demonstrator改写

本来是写在了baidu的blog上的,不知触犯了什么规矩,居然发布失败,只能改在这里了,我觉得我的一些想法,一些工作中的闪光的发现,能告诉大家,挺好的。     因为让设备Boot0 = 1后,设备一直狂发00,所以,st的那个Flash Loader demo无法Next成功。 实际上,这个ISP的协议早已经公开了,大家可以自己编写下载工具的。 首先先说一下,我使用的是V2.6.0的版

xboboboy的专栏 8139

3344avd_AVD生根

3344avdSetting up Android testing environment if you’re looking for a platform other than Genymotion by creating rooted AVD in Android Studio 如果您要通过在Android Studio中创建植根的AVD来寻找Genymotion以外的平台,则可以设置Andr...

weixin_26739079的博客 7527

AV1依赖软件.zip

主要是编译AOM工程需要的软件(Perl、nasm/yasm)

AV不识爱卖克,便看三弟也枉然

阿凡达,已然无人不知无人不晓。江湖流传:“AV不识爱卖克,便看三弟也枉然”。此处AV自然指的就是Avatar,这句话意思是说,如果你没有看iMax的阿凡达,就算是看了3D版也等于没看过。因此,对于全国只有11块的iMax屏幕,大家自然就是疯抢了。而上海这边,只有位于人民广场的和平影都有这条件,试想全上海有这想法的人都涌到同一个地方,抢这个每日一千多(350 * 4场)人次的机会……是什么景象。 ...

weixin_33811961的博客 3586

ArcMap安装与配置全攻略:从下载到实战应用

本文提供了ArcMap 10.4.1从系统准备、详细安装到破解激活的完整指南,并包含首次启动的界面介绍与一个实战GIS分析项目。针对初学者,文章强调了在ArcGIS Pro成为趋势的当下,学习经典ArcMap对于理解核心概念和兼容现有工作流仍有重要价值,帮助用户避开安装常见陷阱,快速上手实战应用。

weixin_29200741的博客 338

SBM与超效率SBM模型实战:从原始面板数据到MATLAB高效实现

本文详细介绍了SBM模型与超效率SBM模型的核心原理,并提供了从原始面板数据预处理到MATLAB高效实现的完整实战指南。通过具体代码解析,帮助研究者掌握如何利用MATLAB进行数据标准化、模型构建、效率求解及结果可视化,从而精准评估决策单元的相对效率,尤其适用于在高效单元中进一步精细排名的场景。

weixin_29100399的博客 478

不怕死就上这些网站

 1. hxxp:///www.dj3344.com 打开后,重启时你的主页就变成它的,并通过QQ向他人传播,现在正飙行,奇坏无比!2. hxxp:///www.qq168.net 打开后,重启时你的主页就变成它的,并通过QQ向他人传播,而且传波病毒,还狠些!现在正在飙行!3. hxxp:///www.777888.com  4. hxxp:///WWW.5dsoft.com  5. hx

临时工 Temporary's Space 23万+

Linux内核同步原语之队列自旋锁(Queued Spin Lock)深度解析

本文深度解析了Linux内核中的队列自旋锁(Queued Spin Lock)机制。通过对比传统自旋锁的瓶颈,详细阐述了队列自旋锁如何利用紧凑的4字节结构、每CPU节点数组和pending位优化,有效解决多核(SMP)系统中的缓存行乒乓和惊群效应,实现公平、高效的锁等待队列,从而显著提升内核在高并发场景下的可扩展性与性能。

weixin_29205061的博客 303

stbl与mdat的对应关系

stbl与mdat的对应关系。MP4中box的关系

Shauna_Wu的博客 1171

Python爬虫实战:5分钟搞定政府网站公开数据抓取(附完整代码)

本文详细介绍了如何使用Python爬虫快速抓取政府网站公开数据,包括环境配置、网站结构分析、请求头构建、数据处理与存储等关键步骤。通过实战案例和完整代码,帮助开发者高效获取结构化数据,适用于数据分析、市场研究等场景。

weixin_29057065的博客 941

FPGA新手必看:用USB转TTL实现串口通信的完整流程(附CH340G电路详解)

本文为FPGA新手提供了通过USB转TTL模块实现串口通信的完整实战指南。详细解析了CH340G电路设计要点、硬件连接方法,并分享了经过验证的Verilog代码框架,帮助读者快速掌握FPGA与PC通信的核心技术,解决电平匹配与波特率设置等常见问题。

cake8的博客 1049

【Mp4】Stbl box

Sample Table Box(stbl)     sample是媒体数据存储的单位,存储在media的chunk中,chunk和sample的长度均可互不相同,如下图所示。     “stbl”包含了关于track中sample所有时间和位置的信息,以及sample的编解码等信息。利用这个表,可以解释sample的时序、类型、大小以及在各自存储容器中的位置。“stbl”是一个conta

产业互联网&消费类电子 1379

【GD32F407】i2c主机发送,从机中断接收

前言 现在手里负责的一个项目需要用i2c和主芯片进行通信主动发送,中断接收,这就需要支持i2c主机模式和从机模式,先查看原理图 这里我们用到了两条i2c总线进行数据的交替传输,避免在使用一条总线是发送数据和接收数据冲突 初始化i2c控制器 s32_k i2cDevInit(u8 byBusId, TI2cBus *pTI2cBus) { //PCLK = 36000000 BOOL retFlg = FALSE; int I2xSCL = pTI2cBus->byFastMode ?

Enosji的博客 6246

mp4格式介绍

时间基 系统默认的H264的time_base= num=1/den=90000        mp4文件的time_base= num=1/den=12800  flv文件的time_base=num=1/den=1000 本节重点讲stbl,跟实践两部分。       详细结构如下: 常见概念 box MP4文件中的所有数据都装在box(QuickTime中为a...

evsqiezi 3238

Vscode+ROS/ROS2 开发调试基于ROS/ROS2应用环境配置

在ROS操作系统开发应用程序时,我们常常需要调试代码,验证程序的正确性。但是在用rosrun或者roslaunch启动节点后,若程序运行过程中发生错误而导致发生出错停止工作,这时候终端并不会输出具体的信息指出在何处发生了错误,具体错误的原因又是什么。往往仅仅是core dump 或者segmentation fault 等等一类的模糊提示。

Chasinglight的博客 5800

【Java面试题汇总】JVM篇(2026版)

JVM内存模型、双亲委派模型、类加载机制、内存溢出、垃圾回收机制、内存泄漏、垃圾回收流程、垃圾回收器、G1、CMS、JVM调优

种一棵树最好的时间是十年前,其次是现在 3万+

封装格式分析-MP4

声明:MP4 的封装格式是比较复杂的,本文不会把 MP4 的各个字段,各种场景用法都罗列出来,那样会形成一个手册。 文本主要讲解 MP4 这种封装格式在音视频开发中比较常用的字段,还有一些关键的知识点。让初学者掌握 MP4 的一些基本概念,然后学会看MP4标准文档深入了解。 资源下载: a.mp4下载链接:百度网盘,提取码:nl0s 。 Mp4Explorer.exe 下载链接:百度网盘,提取码:039r 。 MP4 格式 是一个 box 的格式,box 容器 套 box 子容器,box 子容器 再

u012117034的博客 3825

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

mp4格式分析

mp4文件格式又被称为 MPEG-4 Part 14,出自 MPEG-4标准第14部分。他是一种多媒体格式工具,广泛用于包装视频和音频数据流、海报、字幕和元数据等。(顺便⼀提,⽬前流⾏的视频编码格式AVC/H264定义在MPEG-4 Part 10)mp4文件格式基于 Apple 公司的 QuickTime 格式,因此,QuickTime File Format Specification 也可以作为我们研究 mp4的重要参考。

Lenn Louis' Scribe 1878

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

mp4结构

mp4结构分析

knowledgebao的博客 1865

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

MP4学习(三)ts-mp4源码阅读(1)介绍

MP4Parse源码阅读 为了加深对mp4文件格式的理解,接下来介绍一个开源的MP4解析器MP4Parse,下载地址:https://github.com/macmade/MP4Parse 把工程下载下来之后,进入source目录就可以看见源代码了,有很多cpp文件,最重要的是MP4.Parser.cpp,其他文件大部分都是各个box的解析代码,代码量不是很多。 box的定义

NB_vol_1的专栏 1412

mp4文件格式详细解析(三)

4.2.2.3.1 Media Information Header Box(vmhd、smhd、hmhd、nmhd)Video Media Header Box(vmhd) 字段字节数意义box size4box大小box type4box类型

naonaodog的专栏 1359

MP4格式解析---M4A是MP4中的音频部分

MP4格式解析

一个专研技术的小蜜蜂的博客 3011

MP4文件格式分析及分割实现(附源码)

               MP4文件格式分析   MP4(MPEG-4 Part 14)是一种常见的多媒体容器格式,它是在“ISO/IEC 14496-14”标准文件中定义的,属于MPEG-4的一部分,是“ISO/IEC 14496-12(MPEG-4 Part 12 ISO base media file format)”标准中所定义的媒体格式的一种实现...

u013700432的博客 107

H264文件封装MP4文件

推荐一篇优秀的博文.对于MP4的初学者很有用:http://blog.youkuaiyun.com/chenchong_219/article/details/44263691对于这篇博文最后Sample Table Box部分我想做一些补充,如有不足之处请大家指出.这篇文章以h264的数据封装到MP4为例子.“stbl”包含了关于track中sample所有时间和位置的信息,以及sample的编解码等信息...

Xietong Blog 1791

sap abap alv画面项目编辑设值之后,自动刷新编辑值到alv画面

DATA: tem_grid        TYPE REF TO cl_gui_alv_grid.     DATA: stbl        TYPE lvc_s_stbl. *   stbl-row = 'X'." 基于行的稳定刷新   stbl-col = 'X'." 基于列稳定刷新   CALL METHOD tem_grid->refresh_table_display

forever_crazy的专栏 5945

SAP ABAP 中 function-alv的刷新方式,GET_GLOBALS_FROM_SLVC_FULLSCR

CLASS:CL_GUI_ALV_GRID FUNCTION:GET_GLOBALS_FROM_SLVC_FULLSCR function-alv 刷新,使用OO 的刷新方式,先使用GET_GLOBALS_FROM_SLVC_FULLSCR接收屏幕ALV,放置容器,再调用刷新方法 DATA LS_STBL TYPE LVC_S_STBL. DATA: LO_GRID TYPE REF TO CL_GUI_ALV_GRID. CALL FUNCTION 'GET_GLOBALS.

SAP自学之路 4119
上一篇: srs中时间戳抖动处理
下一篇: 我们也说说Android.mk(1) - 从函数说起
STN_LCD
博客等级 码龄15年 384粉丝 54原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值