当前位置:  编程技术>移动开发
本页文章导读:
    ▪【多媒体打包格式详解】-MP4【4】        【多媒体封装格式详解】---MP4【4】前面介绍过的几种格式flv、mkv、asf等。他们音视频的数据包一般都是按照文件的顺序交叉安放。你解析完头部信息后。剩下的一般就按照文件顺序一个数据.........
    ▪ object-c 利用scanf 兑现终端的输入输出缓冲        object-c 利用scanf 实现终端的输入输出缓冲#import <Foundation/Foundation.h> int main(int argc, char *argv[]) { @autoreleasepool { NSLog(@"请输入您的帐号"); int i;     scanf("%d",&i); NSLog(@"您输入的是%d",i); } } ......
    ▪ jquerymobile-10 替list添加数字气泡(count bubbles)       jquerymobile-10 为list添加数字气泡(count bubbles)在项目中,我们一般使用list显示一个列表,如果这个列表还有子项的时候,有时候我们需要在上面加上子项的数目,这时候我们就可以使用jquerymobil.........

[1]【多媒体打包格式详解】-MP4【4】
    来源: 互联网  发布时间: 2014-02-18
【多媒体封装格式详解】---MP4【4】

前面介绍过的几种格式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这些和解码器有关信息。

aligned(8) class SampleDescriptionBox (unsigned int(32) handler_type)
extends FullBox('stsd', 0, 0){
int i ;
unsigned int(32) entry_count;
for (i = 1 ; i u entry_count ; i++){
switch (handler_type){
case ‘soun’: // for audio tracks
AudioSampleEntry();
break;
case ‘vide’: // for video tracks
VisualSampleEntry();
break;
case ‘hint’: // Hint track
HintSampleEntry();
break;
}
}
}

aligned(8) abstract class SampleEntry (unsigned int(32) format)
extends Box(format){
const unsigned int(8)[6] reserved = 0;
unsigned int(16) data_reference_index;
}
class HintSampleEntry() extends SampleEntry (protocol) {
unsigned int(8) data [];
}
// Visual Sequences
class VisualSampleEntry(codingname) extends SampleEntry (codingname){
unsigned int(16) pre_defined = 0;
const unsigned int(16) reserved = 0;
unsigned int(32)[3] pre_defined = 0;
unsigned int(16) width;
unsigned int(16) height;
template unsigned int(32) horizresolution = 0x00480000; // 72 dpi
template unsigned int(32) vertresolution = 0x00480000; // 72 dpi
const unsigned int(32) reserved = 0;
template unsigned int(16) frame_count = 1;
string[32] compressorname;
template unsigned int(16) depth = 0x0018;
int(16) pre_defined = -1;
}
// Audio Sequences
class AudioSampleEntry(codingname) extends SampleEntry (codingname){
const unsigned int(32)[2] reserved = 0;
template unsigned int(16) channelcount = 2;
template unsigned int(16) samplesize = 16;
unsigned int(16) pre_defined = 0;
const unsigned int(16) reserved = 0 ;
template unsigned int(32) samplerate = {timescale of media}<<16;
}


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

aligned(8) class SampleSizeBox extends FullBox(‘stsz’, version = 0, 0) {
unsigned int(32) sample_size;
unsigned int(32) sample_count;
if (sample_size==0) {
for (i=1; i u sample_count; i++) {
unsigned int(32) entry_size;
}
}
}
3.解析stts 

aligned(8) class TimeToSampleBox
extends FullBox(’stts’, version = 0, 0) {
unsigned int(32) entry_count;
int i;
for (i=0; i < entry_count; i++) {
unsigned int(32) sample_count;
unsigned int(32) sample_delta;
}
}

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



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

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

aligned(8) class SampleToChunkBox
extends FullBox(‘stsc’, version = 0, 0) {
unsigned int(32) entry_count;
for (i=1; i u entry_count; i++) {
unsigned int(32) first_chunk;
unsigned int(32) samples_per_chunk;
unsigned int(32) sample_description_index;
}
}

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

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

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

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

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

static int mov_read_stsc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
{
    AVStream *st;
    MOVStreamContext *sc;
    unsigned int i, entries;

    if (c->fc->nb_streams < 1)
        return 0;
    st = c->fc->streams[c->fc->nb_streams-1];
    sc = st->priv_data;

    avio_r8(pb); /* version */
    avio_rb24(pb); /* flags */

    entries = avio_rb32(pb);

    av_dlog(c->fc, "track[%i].stsc.entries = %i\n", c->fc->nb_streams-1, entries);

    if (!entries)
        return 0;
    if (entries >= UINT_MAX / sizeof(*sc->stsc_data))
        return AVERROR_INVALIDDATA;
    sc->stsc_data = av_malloc(entries * sizeof(*sc->stsc_data));
    if (!sc->stsc_data)
        return AVERROR(ENOMEM);

    for (i = 0; i < entries && !pb->eof_reached; i++) {
        sc->stsc_data[i].first = avio_rb32(pb);
        sc->stsc_data[i].count = avio_rb32(pb);
        sc->stsc_data[i].id = avio_rb32(pb);
    }

    sc->stsc_count = i;

    if (pb->eof_reached)
        return AVERROR_EOF;

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

5.解析‘stco’, ‘co64’

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

32位

aligned(8) class ChunkOffsetBox
extends FullBox(‘stco’, version = 0, 0) {
unsigned int(32) entry_count;
for (i=1; i u entry_count; i++) {
unsigned int(32) chunk_offset;
}
}

64位

aligned(8) class ChunkLargeOffsetBox
extends FullBox(‘co64’, version = 0, 0) {
unsigned int(32) entry_count;
for (i=1; i u entry_count; i++) {
unsigned int(64) chunk_offset;
}
}
从这个box我们就可以获得 chunk 的总数量,entry_count。


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

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

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

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

aligned(8) class SyncSampleBox
extends FullBox(‘stss’, version = 0, 0) {
unsigned int(32) entry_count;
int i;
for (i=0; i < entry_count; i++) {
unsigned int(32) sample_number;
}
}












    
[2] object-c 利用scanf 兑现终端的输入输出缓冲
    来源: 互联网  发布时间: 2014-02-18
object-c 利用scanf 实现终端的输入输出缓冲

#import <Foundation/Foundation.h>

int main(int argc, char *argv[]) {

@autoreleasepool {

NSLog(@"请输入您的帐号");

int i;

    scanf("%d",&i);

NSLog(@"您输入的是%d",i);

}

}


    
[3] jquerymobile-10 替list添加数字气泡(count bubbles)
    来源: 互联网  发布时间: 2014-02-18
jquerymobile-10 为list添加数字气泡(count bubbles)

在项目中,我们一般使用list显示一个列表,如果这个列表还有子项的时候,有时候我们需要在上面加上子项的数目,这时候我们就可以使用jquerymobile提供的CSS类中的ui-li-count类实现这样的效果。一段例子代码如下:

<!DOCTYPE html>
<html>
<head>
<title>Count Bubble Example</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="http://code.jquery.com/mobile/latest/jquery.mobile.min.css" />
<script src="http://code.jquery.com/jquery-1.7.1.min.js"></script>
<script src="http://code.jquery.com/mobile/latest/jquery.mobile.min.js"></script>
</head>

<body>

<div data-role="page">

	<div data-role="header">
		<h1>My Header</h1>
	</div>
	
	<div data-role="content">
		<ul data-role="listview" data-inset="true">
		<li data-role="list-divider">Cookies Eaten</li>
		<li>A <span >9</span></li>
		<li>B <span >4</span></li>
		<li>C <span >13</span></li>
		<li>D <span >8</span></li>
		</ul>
	</div>

	<div data-role="footer">
		<h4>My Footer</h4>
	</div>
		
</div>

</body>
</html>

我们只要添加一个span并且给起添加ui-li-count类就可以实现了。效果如下:


如果哪里写错了,还请指出。


    
最新技术文章:
▪Android开发之登录验证实例教程
▪Android开发之注册登录方法示例
▪Android获取手机SIM卡运营商信息的方法
▪Android实现将已发送的短信写入短信数据库的...
▪Android发送短信功能代码
▪Android根据电话号码获得联系人头像实例代码
▪Android中GPS定位的用法实例
▪Android实现退出时关闭所有Activity的方法
▪Android实现文件的分割和组装
▪Android录音应用实例教程
▪Android双击返回键退出程序的实现方法
▪Android实现侦听电池状态显示、电量及充电动...
▪Android获取当前已连接的wifi信号强度的方法
▪Android实现动态显示或隐藏密码输入框的内容
▪根据USER-AGENT判断手机类型并跳转到相应的app...
▪Android Touch事件分发过程详解
▪Android中实现为TextView添加多个可点击的文本
▪Android程序设计之AIDL实例详解
▪Android显式启动与隐式启动Activity的区别介绍
▪Android按钮单击事件的四种常用写法总结
▪Android消息处理机制Looper和Handler详解
▪Android实现Back功能代码片段总结
▪Android实用的代码片段 常用代码总结
▪Android实现弹出键盘的方法
▪Android中通过view方式获取当前Activity的屏幕截...
▪Android提高之自定义Menu(TabMenu)实现方法
▪Android提高之多方向抽屉实现方法
▪Android提高之MediaPlayer播放网络音频的实现方法...
▪Android提高之MediaPlayer播放网络视频的实现方法...
▪Android提高之手游转电视游戏的模拟操控
 


站内导航:


特别声明:169IT网站部分信息来自互联网,如果侵犯您的权利,请及时告知,本站将立即删除!

©2012-2021,,E-mail:www_#163.com(请将#改为@)

浙ICP备11055608号-3