Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
小白菜888
Ffmpeg
提交
61aedb0f
F
Ffmpeg
项目概览
小白菜888
/
Ffmpeg
通知
3
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
F
Ffmpeg
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
61aedb0f
编写于
3月 21, 2008
作者:
B
Baptiste Coudurier
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
mp4 fragments support
Originally committed as revision 12541 to
svn://svn.ffmpeg.org/ffmpeg/trunk
上级
9e8e6d31
变更
1
隐藏空白更改
内联
并排
Showing
1 changed file
with
155 addition
and
0 deletion
+155
-0
libavformat/mov.c
libavformat/mov.c
+155
-0
未找到文件。
libavformat/mov.c
浏览文件 @
61aedb0f
...
...
@@ -82,6 +82,24 @@ typedef struct {
struct
MOVParseTableEntry
;
typedef
struct
{
unsigned
track_id
;
uint64_t
base_data_offset
;
uint64_t
moof_offset
;
unsigned
stsd_id
;
unsigned
duration
;
unsigned
size
;
unsigned
flags
;
}
MOVFragment
;
typedef
struct
{
unsigned
track_id
;
unsigned
stsd_id
;
unsigned
duration
;
unsigned
size
;
unsigned
flags
;
}
MOVTrackExt
;
typedef
struct
MOVStreamContext
{
ByteIOContext
*
pb
;
int
ffindex
;
/* the ffmpeg stream id */
...
...
@@ -125,6 +143,9 @@ typedef struct MOVContext {
DVDemuxContext
*
dv_demux
;
AVFormatContext
*
dv_fctx
;
int
isom
;
/* 1 if file is ISO Media (mp4/3gp) */
MOVFragment
fragment
;
///< current fragment in moof atom
MOVTrackExt
*
trex_data
;
unsigned
trex_count
;
}
MOVContext
;
...
...
@@ -416,6 +437,12 @@ static int mov_read_moov(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
return
0
;
/* now go for mdat */
}
static
int
mov_read_moof
(
MOVContext
*
c
,
ByteIOContext
*
pb
,
MOV_atom_t
atom
)
{
c
->
fragment
.
moof_offset
=
url_ftell
(
pb
)
-
8
;
dprintf
(
c
->
fc
,
"moof offset %llx
\n
"
,
c
->
fragment
.
moof_offset
);
return
mov_read_default
(
c
,
pb
,
atom
);
}
static
int
mov_read_mdhd
(
MOVContext
*
c
,
ByteIOContext
*
pb
,
MOV_atom_t
atom
)
{
...
...
@@ -1359,6 +1386,127 @@ static int mov_read_tkhd(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
return
0
;
}
static
int
mov_read_tfhd
(
MOVContext
*
c
,
ByteIOContext
*
pb
,
MOV_atom_t
atom
)
{
MOVFragment
*
frag
=
&
c
->
fragment
;
MOVTrackExt
*
trex
=
NULL
;
int
flags
,
track_id
,
i
;
get_byte
(
pb
);
/* version */
flags
=
get_be24
(
pb
);
track_id
=
get_be32
(
pb
);
if
(
!
track_id
||
track_id
>
c
->
fc
->
nb_streams
)
return
-
1
;
frag
->
track_id
=
track_id
;
for
(
i
=
0
;
i
<
c
->
trex_count
;
i
++
)
if
(
c
->
trex_data
[
i
].
track_id
==
frag
->
track_id
)
{
trex
=
&
c
->
trex_data
[
i
];
break
;
}
if
(
!
trex
)
{
av_log
(
c
->
fc
,
AV_LOG_ERROR
,
"could not find corresponding trex
\n
"
);
return
-
1
;
}
if
(
flags
&
0x01
)
frag
->
base_data_offset
=
get_be64
(
pb
);
else
frag
->
base_data_offset
=
frag
->
moof_offset
;
if
(
flags
&
0x02
)
frag
->
stsd_id
=
get_be32
(
pb
);
else
frag
->
stsd_id
=
trex
->
stsd_id
;
frag
->
duration
=
flags
&
0x08
?
get_be32
(
pb
)
:
trex
->
duration
;
frag
->
size
=
flags
&
0x10
?
get_be32
(
pb
)
:
trex
->
size
;
frag
->
flags
=
flags
&
0x20
?
get_be32
(
pb
)
:
trex
->
flags
;
dprintf
(
c
->
fc
,
"frag flags 0x%x
\n
"
,
frag
->
flags
);
return
0
;
}
static
int
mov_read_trex
(
MOVContext
*
c
,
ByteIOContext
*
pb
,
MOV_atom_t
atom
)
{
MOVTrackExt
*
trex
;
if
((
uint64_t
)
c
->
trex_count
+
1
>=
UINT_MAX
/
sizeof
(
*
c
->
trex_data
))
return
-
1
;
c
->
trex_data
=
av_realloc
(
c
->
trex_data
,
(
c
->
trex_count
+
1
)
*
sizeof
(
*
c
->
trex_data
));
if
(
!
c
->
trex_data
)
return
AVERROR
(
ENOMEM
);
trex
=
&
c
->
trex_data
[
c
->
trex_count
++
];
get_byte
(
pb
);
/* version */
get_be24
(
pb
);
/* flags */
trex
->
track_id
=
get_be32
(
pb
);
trex
->
stsd_id
=
get_be32
(
pb
);
trex
->
duration
=
get_be32
(
pb
);
trex
->
size
=
get_be32
(
pb
);
trex
->
flags
=
get_be32
(
pb
);
return
0
;
}
static
int
mov_read_trun
(
MOVContext
*
c
,
ByteIOContext
*
pb
,
MOV_atom_t
atom
)
{
MOVFragment
*
frag
=
&
c
->
fragment
;
AVStream
*
st
=
c
->
fc
->
streams
[
frag
->
track_id
-
1
];
MOVStreamContext
*
sc
=
st
->
priv_data
;
uint64_t
offset
;
int64_t
dts
;
int
data_offset
=
0
;
unsigned
entries
,
first_sample_flags
=
frag
->
flags
;
int
flags
,
distance
,
i
;
if
(
sc
->
pseudo_stream_id
+
1
!=
frag
->
stsd_id
)
return
0
;
if
(
!
st
->
nb_index_entries
)
return
-
1
;
get_byte
(
pb
);
/* version */
flags
=
get_be24
(
pb
);
entries
=
get_be32
(
pb
);
dprintf
(
c
->
fc
,
"flags 0x%x entries %d
\n
"
,
flags
,
entries
);
if
(
flags
&
0x001
)
data_offset
=
get_be32
(
pb
);
if
(
flags
&
0x004
)
first_sample_flags
=
get_be32
(
pb
);
if
(
flags
&
0x800
)
{
if
((
uint64_t
)
entries
+
sc
->
ctts_count
>=
UINT_MAX
/
sizeof
(
*
sc
->
ctts_data
))
return
-
1
;
sc
->
ctts_data
=
av_realloc
(
sc
->
ctts_data
,
(
entries
+
sc
->
ctts_count
)
*
sizeof
(
*
sc
->
ctts_data
));
if
(
!
sc
->
ctts_data
)
return
AVERROR
(
ENOMEM
);
}
dts
=
st
->
duration
;
offset
=
frag
->
base_data_offset
+
data_offset
;
distance
=
0
;
dprintf
(
c
->
fc
,
"first sample flags 0x%x
\n
"
,
first_sample_flags
);
for
(
i
=
0
;
i
<
entries
;
i
++
)
{
unsigned
sample_size
=
frag
->
size
;
int
sample_flags
=
i
?
frag
->
flags
:
first_sample_flags
;
unsigned
sample_duration
=
frag
->
duration
;
int
keyframe
;
if
(
flags
&
0x100
)
sample_duration
=
get_be32
(
pb
);
if
(
flags
&
0x200
)
sample_size
=
get_be32
(
pb
);
if
(
flags
&
0x400
)
sample_flags
=
get_be32
(
pb
);
if
(
flags
&
0x800
)
{
sc
->
ctts_data
[
sc
->
ctts_count
].
count
=
1
;
sc
->
ctts_data
[
sc
->
ctts_count
].
duration
=
get_be32
(
pb
);
sc
->
ctts_count
++
;
}
if
((
keyframe
=
st
->
codec
->
codec_type
==
CODEC_TYPE_AUDIO
||
(
flags
&
0x004
&&
!
i
&&
!
sample_flags
)
||
sample_flags
&
0x2000000
))
distance
=
0
;
av_add_index_entry
(
st
,
offset
,
dts
,
sample_size
,
distance
,
keyframe
?
AVINDEX_KEYFRAME
:
0
);
dprintf
(
c
->
fc
,
"AVIndex stream %d, sample %d, offset %"
PRIx64
", dts %"
PRId64
", "
"size %d, distance %d, keyframe %d
\n
"
,
st
->
index
,
sc
->
sample_count
+
i
,
offset
,
dts
,
sample_size
,
distance
,
keyframe
);
distance
++
;
assert
(
sample_duration
%
sc
->
time_rate
==
0
);
dts
+=
sample_duration
/
sc
->
time_rate
;
offset
+=
sample_size
;
}
frag
->
moof_offset
=
offset
;
sc
->
sample_count
=
st
->
nb_index_entries
;
st
->
duration
=
dts
;
return
0
;
}
/* this atom should be null (from specs), but some buggy files put the 'moov' atom inside it... */
/* like the files created with Adobe Premiere 5.0, for samples see */
/* http://graphics.tudelft.nl/~wouter/publications/soundtests/ */
...
...
@@ -1474,7 +1622,9 @@ static const MOVParseTableEntry mov_default_parse_table[] = {
{
MKTAG
(
'm'
,
'd'
,
'h'
,
'd'
),
mov_read_mdhd
},
{
MKTAG
(
'm'
,
'd'
,
'i'
,
'a'
),
mov_read_default
},
{
MKTAG
(
'm'
,
'i'
,
'n'
,
'f'
),
mov_read_default
},
{
MKTAG
(
'm'
,
'o'
,
'o'
,
'f'
),
mov_read_moof
},
{
MKTAG
(
'm'
,
'o'
,
'o'
,
'v'
),
mov_read_moov
},
{
MKTAG
(
'm'
,
'v'
,
'e'
,
'x'
),
mov_read_default
},
{
MKTAG
(
'm'
,
'v'
,
'h'
,
'd'
),
mov_read_mvhd
},
{
MKTAG
(
'S'
,
'M'
,
'I'
,
' '
),
mov_read_smi
},
/* Sorenson extension ??? */
{
MKTAG
(
'a'
,
'l'
,
'a'
,
'c'
),
mov_read_extradata
},
/* alac specific atom */
...
...
@@ -1487,7 +1637,11 @@ static const MOVParseTableEntry mov_default_parse_table[] = {
{
MKTAG
(
's'
,
't'
,
's'
,
'z'
),
mov_read_stsz
},
/* sample size */
{
MKTAG
(
's'
,
't'
,
't'
,
's'
),
mov_read_stts
},
{
MKTAG
(
't'
,
'k'
,
'h'
,
'd'
),
mov_read_tkhd
},
/* track header */
{
MKTAG
(
't'
,
'f'
,
'h'
,
'd'
),
mov_read_tfhd
},
/* track fragment header */
{
MKTAG
(
't'
,
'r'
,
'a'
,
'k'
),
mov_read_trak
},
{
MKTAG
(
't'
,
'r'
,
'a'
,
'f'
),
mov_read_default
},
{
MKTAG
(
't'
,
'r'
,
'e'
,
'x'
),
mov_read_trex
},
{
MKTAG
(
't'
,
'r'
,
'u'
,
'n'
),
mov_read_trun
},
{
MKTAG
(
'u'
,
'd'
,
't'
,
'a'
),
mov_read_udta
},
{
MKTAG
(
'w'
,
'a'
,
'v'
,
'e'
),
mov_read_wave
},
{
MKTAG
(
'e'
,
's'
,
'd'
,
's'
),
mov_read_esds
},
...
...
@@ -1712,6 +1866,7 @@ static int mov_read_close(AVFormatContext *s)
av_freep
(
&
mov
->
dv_fctx
);
av_freep
(
&
mov
->
dv_demux
);
}
av_freep
(
&
mov
->
trex_data
);
return
0
;
}
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录