Toggle navigation
Toggle navigation
此项目
正在载入...
Sign in
胡斌
/
srs
转到一个项目
Toggle navigation
项目
群组
代码片段
帮助
Toggle navigation pinning
Project
Activity
Repository
Pipelines
Graphs
Issues
0
Merge Requests
0
Wiki
Network
Create a new issue
Builds
Commits
Authored by
winlin
8 years ago
Browse Files
Options
Browse Files
Download
Email Patches
Plain Diff
Commit
5a84b6ca941fac799714fd862d4d3ca94f58d614
5a84b6ca
1 parent
2ad265bd
for #738, complete all mp4 boxes codec.
隐藏空白字符变更
内嵌
并排对比
正在显示
2 个修改的文件
包含
207 行增加
和
20 行删除
trunk/src/kernel/srs_kernel_mp4.cpp
trunk/src/kernel/srs_kernel_mp4.hpp
trunk/src/kernel/srs_kernel_mp4.cpp
查看文件 @
5a84b6c
...
...
@@ -61,7 +61,9 @@ using namespace std;
#define SRS_MP4_BOX_STSS 0x73747373 // 'stss'
#define SRS_MP4_BOX_STSC 0x73747363 // 'stsc'
#define SRS_MP4_BOX_STCO 0x7374636f // 'stco'
#define SRS_MP4_BOX_CO64 0x636f3634 // 'co64'
#define SRS_MP4_BOX_STSZ 0x7374737a // 'stsz'
#define SRS_MP4_BOX_STZ2 0x73747a32 // 'stz2'
#define SRS_MP4_EOF_SIZE 0
#define SRS_MP4_USE_LARGE_SIZE 1
...
...
@@ -192,6 +194,7 @@ int SrsMp4Box::discovery(SrsBuffer* buf, SrsMp4Box** ppbox)
case
SRS_MP4_BOX_STSS
:
box
=
new
SrsMp4SyncSampleBox
();
break
;
case
SRS_MP4_BOX_STSC
:
box
=
new
SrsMp4Sample2ChunkBox
();
break
;
case
SRS_MP4_BOX_STCO
:
box
=
new
SrsMp4ChunkOffsetBox
();
break
;
case
SRS_MP4_BOX_CO64
:
box
=
new
SrsMp4ChunkLargeOffsetBox
();
break
;
case
SRS_MP4_BOX_STSZ
:
box
=
new
SrsMp4SampleSizeBox
();
break
;
default
:
ret
=
ERROR_MP4_BOX_ILLEGAL_TYPE
;
...
...
@@ -1420,18 +1423,16 @@ int SrsMp4DataReferenceBox::decode_header(SrsBuffer* buf)
return
ret
;
}
int
left
=
left_space
(
buf
);
while
(
left
>
0
)
{
uint32_t
nb_entries
=
buf
->
read_4bytes
();
for
(
uint32_t
i
=
0
;
i
<
nb_entries
;
i
++
)
{
SrsMp4Box
*
box
=
NULL
;
if
((
ret
=
SrsMp4Box
::
discovery
(
buf
,
&
box
))
!=
ERROR_SUCCESS
)
{
return
ret
;
}
int
pos
=
buf
->
pos
();
if
((
ret
=
box
->
decode
(
buf
))
!=
ERROR_SUCCESS
)
{
return
ret
;
}
left
-=
buf
->
pos
()
-
pos
;
SrsMp4FullBox
*
fbox
=
dynamic_cast
<
SrsMp4FullBox
*>
(
box
);
if
(
fbox
)
{
...
...
@@ -1660,6 +1661,8 @@ int SrsMp4SampleDescriptionBox::nb_header()
{
int
size
=
SrsMp4FullBox
::
nb_header
();
size
+=
4
;
vector
<
SrsMp4SampleEntry
*>::
iterator
it
;
for
(
it
=
entries
.
begin
();
it
!=
entries
.
end
();
++
it
)
{
SrsMp4SampleEntry
*
entry
=
*
it
;
...
...
@@ -1677,6 +1680,8 @@ int SrsMp4SampleDescriptionBox::encode_header(SrsBuffer* buf)
return
ret
;
}
buf
->
write_4bytes
(
entry_count
());
vector
<
SrsMp4SampleEntry
*>::
iterator
it
;
for
(
it
=
entries
.
begin
();
it
!=
entries
.
end
();
++
it
)
{
SrsMp4SampleEntry
*
entry
=
*
it
;
...
...
@@ -1696,18 +1701,16 @@ int SrsMp4SampleDescriptionBox::decode_header(SrsBuffer* buf)
return
ret
;
}
int
left
=
left_space
(
buf
);
while
(
left
>
0
)
{
uint32_t
nb_entries
=
buf
->
read_4bytes
();
for
(
uint32_t
i
=
0
;
i
<
nb_entries
;
i
++
)
{
SrsMp4Box
*
box
=
NULL
;
if
((
ret
=
SrsMp4Box
::
discovery
(
buf
,
&
box
))
!=
ERROR_SUCCESS
)
{
return
ret
;
}
int
pos
=
buf
->
pos
();
if
((
ret
=
box
->
decode
(
buf
))
!=
ERROR_SUCCESS
)
{
return
ret
;
}
left
-=
buf
->
pos
()
-
pos
;
SrsMp4SampleEntry
*
entry
=
dynamic_cast
<
SrsMp4SampleEntry
*>
(
box
);
if
(
entry
)
{
...
...
@@ -1741,7 +1744,7 @@ SrsMp4DecodingTime2SampleBox::~SrsMp4DecodingTime2SampleBox()
int
SrsMp4DecodingTime2SampleBox
::
nb_header
()
{
return
SrsMp4FullBox
::
nb_header
();
return
SrsMp4FullBox
::
nb_header
()
+
4
+
8
*
entry_count
;
}
int
SrsMp4DecodingTime2SampleBox
::
encode_header
(
SrsBuffer
*
buf
)
...
...
@@ -1752,6 +1755,13 @@ int SrsMp4DecodingTime2SampleBox::encode_header(SrsBuffer* buf)
return
ret
;
}
buf
->
write_4bytes
(
entry_count
);
for
(
uint32_t
i
=
0
;
i
<
entry_count
;
i
++
)
{
SrsMp4SttsEntry
&
entry
=
entries
[
i
];
buf
->
write_4bytes
(
entry
.
sample_count
);
buf
->
write_4bytes
(
entry
.
sample_delta
);
}
return
ret
;
}
...
...
@@ -1763,6 +1773,16 @@ int SrsMp4DecodingTime2SampleBox::decode_header(SrsBuffer* buf)
return
ret
;
}
entry_count
=
buf
->
read_4bytes
();
if
(
entry_count
)
{
entries
=
new
SrsMp4SttsEntry
[
entry_count
];
}
for
(
uint32_t
i
=
0
;
i
<
entry_count
;
i
++
)
{
SrsMp4SttsEntry
&
entry
=
entries
[
i
];
entry
.
sample_count
=
buf
->
read_4bytes
();
entry
.
sample_delta
=
buf
->
read_4bytes
();
}
return
ret
;
}
...
...
@@ -1787,7 +1807,7 @@ SrsMp4CompositionTime2SampleBox::~SrsMp4CompositionTime2SampleBox()
int
SrsMp4CompositionTime2SampleBox
::
nb_header
()
{
return
SrsMp4FullBox
::
nb_header
();
return
SrsMp4FullBox
::
nb_header
()
+
4
+
8
*
entry_count
;
}
int
SrsMp4CompositionTime2SampleBox
::
encode_header
(
SrsBuffer
*
buf
)
...
...
@@ -1798,6 +1818,17 @@ int SrsMp4CompositionTime2SampleBox::encode_header(SrsBuffer* buf)
return
ret
;
}
buf
->
write_4bytes
(
entry_count
);
for
(
uint32_t
i
=
0
;
i
<
entry_count
;
i
++
)
{
SrsMp4CttsEntry
&
entry
=
entries
[
i
];
buf
->
write_4bytes
(
entry
.
sample_count
);
if
(
version
==
0
)
{
buf
->
write_4bytes
((
uint32_t
)
entry
.
sample_offset
);
}
else
if
(
version
==
1
)
{
buf
->
write_4bytes
((
int32_t
)
entry
.
sample_offset
);
}
}
return
ret
;
}
...
...
@@ -1809,6 +1840,20 @@ int SrsMp4CompositionTime2SampleBox::decode_header(SrsBuffer* buf)
return
ret
;
}
entry_count
=
buf
->
read_4bytes
();
if
(
entry_count
)
{
entries
=
new
SrsMp4CttsEntry
[
entry_count
];
}
for
(
uint32_t
i
=
0
;
i
<
entry_count
;
i
++
)
{
SrsMp4CttsEntry
&
entry
=
entries
[
i
];
entry
.
sample_count
=
buf
->
read_4bytes
();
if
(
version
==
0
)
{
entry
.
sample_offset
=
(
uint32_t
)
buf
->
read_4bytes
();
}
else
if
(
version
==
1
)
{
entry
.
sample_offset
=
(
int32_t
)
buf
->
read_4bytes
();
}
}
return
ret
;
}
...
...
@@ -1827,7 +1872,7 @@ SrsMp4SyncSampleBox::~SrsMp4SyncSampleBox()
int
SrsMp4SyncSampleBox
::
nb_header
()
{
return
SrsMp4FullBox
::
nb_header
();
return
SrsMp4FullBox
::
nb_header
()
+
4
+
4
*
entry_count
;
}
int
SrsMp4SyncSampleBox
::
encode_header
(
SrsBuffer
*
buf
)
...
...
@@ -1838,6 +1883,12 @@ int SrsMp4SyncSampleBox::encode_header(SrsBuffer* buf)
return
ret
;
}
buf
->
write_4bytes
(
entry_count
);
for
(
uint32_t
i
=
0
;
i
<
entry_count
;
i
++
)
{
uint32_t
sample_number
=
sample_numbers
[
i
];
buf
->
write_4bytes
(
sample_number
);
}
return
ret
;
}
...
...
@@ -1849,6 +1900,15 @@ int SrsMp4SyncSampleBox::decode_header(SrsBuffer* buf)
return
ret
;
}
entry_count
=
buf
->
read_4bytes
();
if
(
entry_count
>
0
)
{
sample_numbers
=
new
uint32_t
[
entry_count
];
}
for
(
uint32_t
i
=
0
;
i
<
entry_count
;
i
++
)
{
uint32_t
sample_number
=
sample_numbers
[
i
];
buf
->
write_4bytes
(
sample_number
);
}
return
ret
;
}
...
...
@@ -1874,7 +1934,7 @@ SrsMp4Sample2ChunkBox::~SrsMp4Sample2ChunkBox()
int
SrsMp4Sample2ChunkBox
::
nb_header
()
{
return
SrsMp4FullBox
::
nb_header
();
return
SrsMp4FullBox
::
nb_header
()
+
4
+
12
*
entry_count
;
}
int
SrsMp4Sample2ChunkBox
::
encode_header
(
SrsBuffer
*
buf
)
...
...
@@ -1885,6 +1945,14 @@ int SrsMp4Sample2ChunkBox::encode_header(SrsBuffer* buf)
return
ret
;
}
buf
->
write_4bytes
(
entry_count
);
for
(
uint32_t
i
=
0
;
i
<
entry_count
;
i
++
)
{
SrsMp4StscEntry
&
entry
=
entries
[
i
];
buf
->
write_4bytes
(
entry
.
first_chunk
);
buf
->
write_4bytes
(
entry
.
samples_per_chunk
);
buf
->
write_4bytes
(
entry
.
sample_description_index
);
}
return
ret
;
}
...
...
@@ -1896,6 +1964,17 @@ int SrsMp4Sample2ChunkBox::decode_header(SrsBuffer* buf)
return
ret
;
}
entry_count
=
buf
->
read_4bytes
();
if
(
entry_count
)
{
entries
=
new
SrsMp4StscEntry
[
entry_count
];
}
for
(
uint32_t
i
=
0
;
i
<
entry_count
;
i
++
)
{
SrsMp4StscEntry
&
entry
=
entries
[
i
];
entry
.
first_chunk
=
buf
->
read_4bytes
();
entry
.
samples_per_chunk
=
buf
->
read_4bytes
();
entry
.
sample_description_index
=
buf
->
read_4bytes
();
}
return
ret
;
}
...
...
@@ -1914,7 +1993,7 @@ SrsMp4ChunkOffsetBox::~SrsMp4ChunkOffsetBox()
int
SrsMp4ChunkOffsetBox
::
nb_header
()
{
return
SrsMp4FullBox
::
nb_header
();
return
SrsMp4FullBox
::
nb_header
()
+
4
+
4
*
entry_count
;
}
int
SrsMp4ChunkOffsetBox
::
encode_header
(
SrsBuffer
*
buf
)
...
...
@@ -1925,6 +2004,11 @@ int SrsMp4ChunkOffsetBox::encode_header(SrsBuffer* buf)
return
ret
;
}
buf
->
write_4bytes
(
entry_count
);
for
(
uint32_t
i
=
0
;
i
<
entry_count
;
i
++
)
{
buf
->
write_4bytes
(
entries
[
i
]);
}
return
ret
;
}
...
...
@@ -1936,6 +2020,67 @@ int SrsMp4ChunkOffsetBox::decode_header(SrsBuffer* buf)
return
ret
;
}
entry_count
=
buf
->
read_4bytes
();
if
(
entry_count
)
{
entries
=
new
uint32_t
[
entry_count
];
}
for
(
uint32_t
i
=
0
;
i
<
entry_count
;
i
++
)
{
entries
[
i
]
=
buf
->
read_4bytes
();
}
return
ret
;
}
SrsMp4ChunkLargeOffsetBox
::
SrsMp4ChunkLargeOffsetBox
()
{
type
=
SRS_MP4_BOX_CO64
;
entry_count
=
0
;
entries
=
NULL
;
}
SrsMp4ChunkLargeOffsetBox
::~
SrsMp4ChunkLargeOffsetBox
()
{
srs_freepa
(
entries
);
}
int
SrsMp4ChunkLargeOffsetBox
::
nb_header
()
{
return
SrsMp4FullBox
::
nb_header
()
+
4
+
8
*
entry_count
;
}
int
SrsMp4ChunkLargeOffsetBox
::
encode_header
(
SrsBuffer
*
buf
)
{
int
ret
=
ERROR_SUCCESS
;
if
((
ret
=
SrsMp4FullBox
::
encode_header
(
buf
))
!=
ERROR_SUCCESS
)
{
return
ret
;
}
buf
->
write_4bytes
(
entry_count
);
for
(
uint32_t
i
=
0
;
i
<
entry_count
;
i
++
)
{
buf
->
write_8bytes
(
entries
[
i
]);
}
return
ret
;
}
int
SrsMp4ChunkLargeOffsetBox
::
decode_header
(
SrsBuffer
*
buf
)
{
int
ret
=
ERROR_SUCCESS
;
if
((
ret
=
SrsMp4FullBox
::
decode_header
(
buf
))
!=
ERROR_SUCCESS
)
{
return
ret
;
}
entry_count
=
buf
->
read_4bytes
();
if
(
entry_count
)
{
entries
=
new
uint64_t
[
entry_count
];
}
for
(
uint32_t
i
=
0
;
i
<
entry_count
;
i
++
)
{
entries
[
i
]
=
buf
->
read_8bytes
();
}
return
ret
;
}
...
...
@@ -1954,7 +2099,11 @@ SrsMp4SampleSizeBox::~SrsMp4SampleSizeBox()
int
SrsMp4SampleSizeBox
::
nb_header
()
{
return
SrsMp4FullBox
::
nb_header
();
int
size
=
SrsMp4FullBox
::
nb_header
()
+
4
+
4
;
if
(
sample_size
==
0
)
{
size
+=
4
*
sample_count
;
}
return
size
;
}
int
SrsMp4SampleSizeBox
::
encode_header
(
SrsBuffer
*
buf
)
...
...
@@ -1965,6 +2114,12 @@ int SrsMp4SampleSizeBox::encode_header(SrsBuffer* buf)
return
ret
;
}
buf
->
write_4bytes
(
sample_size
);
buf
->
write_4bytes
(
sample_count
);
for
(
uint32_t
i
=
0
;
i
<
sample_count
&&
sample_size
==
0
;
i
++
)
{
buf
->
write_4bytes
(
entry_sizes
[
i
]);
}
return
ret
;
}
...
...
@@ -1976,6 +2131,15 @@ int SrsMp4SampleSizeBox::decode_header(SrsBuffer* buf)
return
ret
;
}
sample_size
=
buf
->
read_4bytes
();
sample_count
=
buf
->
read_4bytes
();
if
(
sample_size
==
0
)
{
entry_sizes
=
new
uint32_t
[
sample_count
];
}
for
(
uint32_t
i
=
0
;
i
<
sample_count
&&
sample_size
==
0
;
i
++
)
{
entry_sizes
[
i
]
=
buf
->
read_4bytes
();
}
return
ret
;
}
...
...
trunk/src/kernel/srs_kernel_mp4.hpp
查看文件 @
5a84b6c
...
...
@@ -761,7 +761,6 @@ protected:
virtual
int
decode_header
(
SrsBuffer
*
buf
);
};
/**
* 8.6.1.3 Composition Time to Sample Box (ctts), for Video.
* ISO_IEC_14496-12-base-format-2012.pdf, page 49
...
...
@@ -872,7 +871,7 @@ protected:
};
/**
* 8.7.5 Chunk Offset Box (stco
or co64
), for Audio/Video.
* 8.7.5 Chunk Offset Box (stco), for Audio/Video.
* ISO_IEC_14496-12-base-format-2012.pdf, page 59
* The chunk offset table gives the index of each chunk into the containing file. There are two variants, permitting
* the use of 32-bit or 64-bit offsets. The latter is useful when managing very large presentations. At most one of
...
...
@@ -883,9 +882,9 @@ class SrsMp4ChunkOffsetBox : public SrsMp4FullBox
public
:
// an integer that gives the number of entries in the following table
uint32_t
entry_count
;
// a 32
or 64
bit integer that gives the offset of the start of a chunk into its containing
// a 32 bit integer that gives the offset of the start of a chunk into its containing
// media file.
uint
64
_t
*
entries
;
uint
32
_t
*
entries
;
public
:
SrsMp4ChunkOffsetBox
();
virtual
~
SrsMp4ChunkOffsetBox
();
...
...
@@ -896,8 +895,32 @@ protected:
};
/**
* 8.7.3 Sample Size Boxes (stsz or stz2), for Audio/Video.
* ISO_IEC_14496-12-base-format-2012.pdf, page 57
* 8.7.5 Chunk Large Offset Box (co64), for Audio/Video.
* ISO_IEC_14496-12-base-format-2012.pdf, page 59
* The chunk offset table gives the index of each chunk into the containing file. There are two variants, permitting
* the use of 32-bit or 64-bit offsets. The latter is useful when managing very large presentations. At most one of
* these variants will occur in any single instance of a sample table.
*/
class
SrsMp4ChunkLargeOffsetBox
:
public
SrsMp4FullBox
{
public
:
// an integer that gives the number of entries in the following table
uint32_t
entry_count
;
// a 64 bit integer that gives the offset of the start of a chunk into its containing
// media file.
uint64_t
*
entries
;
public
:
SrsMp4ChunkLargeOffsetBox
();
virtual
~
SrsMp4ChunkLargeOffsetBox
();
protected
:
virtual
int
nb_header
();
virtual
int
encode_header
(
SrsBuffer
*
buf
);
virtual
int
decode_header
(
SrsBuffer
*
buf
);
};
/**
* 8.7.3.2 Sample Size Box (stsz), for Audio/Video.
* ISO_IEC_14496-12-base-format-2012.pdf, page 58
* This box contains the sample count and a table giving the size in bytes of each sample. This allows the media data
* itself to be unframed. The total number of samples in the media is always indicated in the sample count.
*/
...
...
请
注册
或
登录
后发表评论