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
2ad265bd5a2f8b5d07f8a7c26ac9ecc35b14eb76
2ad265bd
1 parent
b6bb3f24
develop
...
3mdev
for #738, implements boxes codec
隐藏空白字符变更
内嵌
并排对比
正在显示
6 个修改的文件
包含
1885 行增加
和
82 行删除
trunk/src/kernel/srs_kernel_buffer.hpp
trunk/src/kernel/srs_kernel_error.hpp
trunk/src/kernel/srs_kernel_flv.cpp
trunk/src/kernel/srs_kernel_io.hpp
trunk/src/kernel/srs_kernel_mp4.cpp
trunk/src/kernel/srs_kernel_mp4.hpp
trunk/src/kernel/srs_kernel_buffer.hpp
查看文件 @
2ad265b
...
...
@@ -69,6 +69,7 @@ public:
/**
* get the number of bytes to code to.
*/
// TODO: FIXME: change to uint64_t.
virtual
int
nb_bytes
()
=
0
;
/**
* encode object to bytes in SrsBuffer.
...
...
trunk/src/kernel/srs_kernel_error.hpp
查看文件 @
2ad265b
...
...
@@ -242,6 +242,11 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#define ERROR_REQUEST_DATA 3066
#define ERROR_EDGE_PORT_INVALID 3067
#define ERROR_EXPECT_FILE_IO 3068
#define ERROR_MP4_BOX_OVERFLOW 3069
#define ERROR_MP4_BOX_REQUIRE_SPACE 3070
#define ERROR_MP4_BOX_ILLEGAL_TYPE 3071
#define ERROR_MP4_BOX_ILLEGAL_SCHEMA 3072
#define ERROR_MP4_BOX_STRING 3073
///////////////////////////////////////////////////////
// HTTP/StreamCaster/KAFKA protocol error.
...
...
trunk/src/kernel/srs_kernel_flv.cpp
查看文件 @
2ad265b
...
...
@@ -721,6 +721,7 @@ int SrsFlvDecoder::read_header(char header[9])
srs_assert
(
header
);
// TODO: FIXME: Should use readfully.
if
((
ret
=
reader
->
read
(
header
,
9
,
NULL
))
!=
ERROR_SUCCESS
)
{
return
ret
;
}
...
...
@@ -746,6 +747,7 @@ int SrsFlvDecoder::read_tag_header(char* ptype, int32_t* pdata_size, uint32_t* p
char
th
[
11
];
// tag header
// read tag header
// TODO: FIXME: Should use readfully.
if
((
ret
=
reader
->
read
(
th
,
11
,
NULL
))
!=
ERROR_SUCCESS
)
{
if
(
ret
!=
ERROR_SYSTEM_FILE_EOF
)
{
srs_error
(
"read flv tag header failed. ret=%d"
,
ret
);
...
...
@@ -783,6 +785,7 @@ int SrsFlvDecoder::read_tag_data(char* data, int32_t size)
srs_assert
(
data
);
// TODO: FIXME: Should use readfully.
if
((
ret
=
reader
->
read
(
data
,
size
,
NULL
))
!=
ERROR_SUCCESS
)
{
if
(
ret
!=
ERROR_SYSTEM_FILE_EOF
)
{
srs_error
(
"read flv tag header failed. ret=%d"
,
ret
);
...
...
@@ -801,6 +804,7 @@ int SrsFlvDecoder::read_previous_tag_size(char previous_tag_size[4])
srs_assert
(
previous_tag_size
);
// ignore 4bytes tag size.
// TODO: FIXME: Should use readfully.
if
((
ret
=
reader
->
read
(
previous_tag_size
,
4
,
NULL
))
!=
ERROR_SUCCESS
)
{
if
(
ret
!=
ERROR_SYSTEM_FILE_EOF
)
{
srs_error
(
"read flv previous tag size failed. ret=%d"
,
ret
);
...
...
trunk/src/kernel/srs_kernel_io.hpp
查看文件 @
2ad265b
...
...
@@ -44,6 +44,10 @@ public:
ISrsReader
();
virtual
~
ISrsReader
();
public
:
/**
* Read bytes from reader.
* @param nread How many bytes read from channel. NULL to ignore.
*/
virtual
int
read
(
void
*
buf
,
size_t
size
,
ssize_t
*
nread
)
=
0
;
};
...
...
trunk/src/kernel/srs_kernel_mp4.cpp
查看文件 @
2ad265b
...
...
@@ -23,19 +23,380 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include <srs_kernel_mp4.hpp>
#include <string.h>
#include <srs_kernel_log.hpp>
#include <srs_kernel_error.hpp>
#include <srs_kernel_stream.hpp>
#include <srs_core_autofree.hpp>
#include <srs_kernel_io.hpp>
#include <srs_kernel_buffer.hpp>
#include <string.h>
using
namespace
std
;
#define SRS_MP4_BOX_UUID 0x75756964 // 'uuid'
#define SRS_MP4_BOX_FTYP 0x66747970 // 'ftyp'
#define SRS_MP4_BOX_MDAT 0x6d646174 // 'mdat'
#define SRS_MP4_BOX_FREE 0x66726565 // 'free'
#define SRS_MP4_BOX_SKIP 0x736b6970 // 'skip'
#define SRS_MP4_BOX_MOOV 0x6d6f6f76 // 'moov'
#define SRS_MP4_BOX_MVHD 0x6d766864 // 'mvhd'
#define SRS_MP4_BOX_TRAK 0x7472616b // 'trak'
#define SRS_MP4_BOX_TKHD 0x746b6864 // 'tkhd'
#define SRS_MP4_BOX_EDTS 0x65647473 // 'edts'
#define SRS_MP4_BOX_ELST 0x656c7374 // 'elst'
#define SRS_MP4_BOX_MDIA 0x6d646961 // 'mdia'
#define SRS_MP4_BOX_MDHD 0x6d646864 // 'mdhd'
#define SRS_MP4_BOX_HDLR 0x68646c72 // 'hdlr'
#define SRS_MP4_BOX_MINF 0x6d696e66 // 'minf'
#define SRS_MP4_BOX_VMHD 0x766d6864 // 'vmhd'
#define SRS_MP4_BOX_SMHD 0x736d6864 // 'smhd'
#define SRS_MP4_BOX_DINF 0x64696e66 // 'dinf'
#define SRS_MP4_BOX_URL 0x75726c20 // 'url '
#define SRS_MP4_BOX_URN 0x75726e20 // 'urn '
#define SRS_MP4_BOX_DREF 0x64726566 // 'dref'
#define SRS_MP4_BOX_STBL 0x7374626c // 'stbl'
#define SRS_MP4_BOX_STSD 0x73747364 // 'stsd'
#define SRS_MP4_BOX_STTS 0x73747473 // 'stts'
#define SRS_MP4_BOX_CTTS 0x63747473 // 'ctts'
#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_STSZ 0x7374737a // 'stsz'
#define SRS_MP4_EOF_SIZE 0
#define SRS_MP4_USE_LARGE_SIZE 1
int
srs_mp4_string_length
(
const
string
&
v
)
{
return
(
int
)
v
.
length
()
+
1
;
}
void
srs_mp4_string_write
(
SrsBuffer
*
buf
,
const
string
&
v
)
{
if
(
!
v
.
empty
())
{
buf
->
write_bytes
((
char
*
)
v
.
data
(),
(
int
)
v
.
length
());
}
buf
->
write_1bytes
(
0x00
);
}
int
srs_mp4_string_read
(
SrsBuffer
*
buf
,
string
&
v
,
int
left
)
{
int
ret
=
ERROR_SUCCESS
;
char
*
p
=
buf
->
data
()
+
buf
->
pos
();
char
*
start
=
p
;
while
(
p
<
start
+
left
)
{
if
(
*
p
==
0x00
)
{
v
.
append
(
start
,
p
-
start
);
buf
->
skip
((
int
)(
p
-
start
));
return
ret
;
}
}
ret
=
ERROR_MP4_BOX_STRING
;
srs_error
(
"MP4 string corrupt, left=%d. ret=%d"
,
left
,
ret
);
return
ret
;
}
SrsMp4Box
::
SrsMp4Box
()
{
size
=
0
;
smallsize
=
0
;
largesize
=
0
;
usertype
=
NULL
;
start_pos
=
0
;
type
=
0
;
}
SrsMp4Box
::~
SrsMp4Box
()
{
vector
<
SrsMp4Box
*>::
iterator
it
;
for
(
it
=
boxes
.
begin
();
it
!=
boxes
.
end
();
++
it
)
{
SrsMp4Box
*
box
=
*
it
;
srs_freep
(
box
);
}
boxes
.
clear
();
srs_freepa
(
usertype
);
}
uint64_t
SrsMp4Box
::
sz
()
{
return
smallsize
==
SRS_MP4_USE_LARGE_SIZE
?
largesize
:
smallsize
;
}
int
SrsMp4Box
::
left_space
(
SrsBuffer
*
buf
)
{
return
(
int
)
sz
()
-
(
buf
->
pos
()
-
start_pos
);
}
int
SrsMp4Box
::
discovery
(
SrsBuffer
*
buf
,
SrsMp4Box
**
ppbox
)
{
*
ppbox
=
NULL
;
int
ret
=
ERROR_SUCCESS
;
if
(
!
buf
->
require
(
8
))
{
ret
=
ERROR_MP4_BOX_REQUIRE_SPACE
;
srs_error
(
"MP4 discovery require 8 bytes space. ret=%d"
,
ret
);
return
ret
;
}
// Discovery the size and type.
uint64_t
largesize
=
0
;
uint32_t
smallsize
=
(
uint32_t
)
buf
->
read_4bytes
();
uint32_t
type
=
(
uint32_t
)
buf
->
read_4bytes
();
if
(
smallsize
==
SRS_MP4_USE_LARGE_SIZE
)
{
if
(
!
buf
->
require
(
8
))
{
ret
=
ERROR_MP4_BOX_REQUIRE_SPACE
;
srs_error
(
"MP4 discovery require 16 bytes space. ret=%d"
,
ret
);
return
ret
;
}
largesize
=
(
uint64_t
)
buf
->
read_8bytes
();
buf
->
skip
(
-
8
);
}
buf
->
skip
(
-
8
);
// Only support 31bits size.
if
(
largesize
>
0x7fffffff
)
{
ret
=
ERROR_MP4_BOX_OVERFLOW
;
srs_error
(
"MP4 discovery overflow 31bits, size=%"
PRId64
". ret=%d"
,
largesize
,
ret
);
return
ret
;
}
SrsMp4Box
*
box
=
NULL
;
switch
(
type
)
{
case
SRS_MP4_BOX_FTYP
:
box
=
new
SrsMp4FileTypeBox
();
break
;
case
SRS_MP4_BOX_MDAT
:
box
=
new
SrsMp4MediaDataBox
();
break
;
case
SRS_MP4_BOX_FREE
:
case
SRS_MP4_BOX_SKIP
:
box
=
new
SrsMp4FreeSpaceBox
();
break
;
case
SRS_MP4_BOX_MOOV
:
box
=
new
SrsMp4MovieBox
();
break
;
case
SRS_MP4_BOX_MVHD
:
box
=
new
SrsMp4MovieHeaderBox
();
break
;
case
SRS_MP4_BOX_TRAK
:
box
=
new
SrsMp4TrackBox
();
break
;
case
SRS_MP4_BOX_TKHD
:
box
=
new
SrsMp4TrackHeaderBox
();
break
;
case
SRS_MP4_BOX_EDTS
:
box
=
new
SrsMp4EditBox
();
break
;
case
SRS_MP4_BOX_ELST
:
box
=
new
SrsMp4EditListBox
();
break
;
case
SRS_MP4_BOX_MDIA
:
box
=
new
SrsMp4MediaBox
();
break
;
case
SRS_MP4_BOX_MDHD
:
box
=
new
SrsMp4MediaHeaderBox
();
break
;
case
SRS_MP4_BOX_HDLR
:
box
=
new
SrsMp4HandlerReferenceBox
();
break
;
case
SRS_MP4_BOX_MINF
:
box
=
new
SrsMp4MediaInformationBox
();
break
;
case
SRS_MP4_BOX_VMHD
:
box
=
new
SrsMp4VideoMeidaHeaderBox
();
break
;
case
SRS_MP4_BOX_SMHD
:
box
=
new
SrsMp4SoundMeidaHeaderBox
();
break
;
case
SRS_MP4_BOX_DINF
:
box
=
new
SrsMp4DataInformationBox
();
break
;
case
SRS_MP4_BOX_URL
:
box
=
new
SrsMp4DataEntryUrlBox
();
break
;
case
SRS_MP4_BOX_URN
:
box
=
new
SrsMp4DataEntryUrnBox
();
break
;
case
SRS_MP4_BOX_DREF
:
box
=
new
SrsMp4DataReferenceBox
();
break
;
case
SRS_MP4_BOX_STBL
:
box
=
new
SrsMp4SampleTableBox
();
break
;
case
SRS_MP4_BOX_STSD
:
box
=
new
SrsMp4SampleDescriptionBox
();
break
;
case
SRS_MP4_BOX_STTS
:
box
=
new
SrsMp4DecodingTime2SampleBox
();
break
;
case
SRS_MP4_BOX_CTTS
:
box
=
new
SrsMp4CompositionTime2SampleBox
();
break
;
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_STSZ
:
box
=
new
SrsMp4SampleSizeBox
();
break
;
default
:
ret
=
ERROR_MP4_BOX_ILLEGAL_TYPE
;
srs_error
(
"MP4 illegal box type=%d. ret=%d"
,
type
,
ret
);
break
;
}
if
(
box
)
{
box
->
smallsize
=
smallsize
;
box
->
largesize
=
largesize
;
box
->
type
=
type
;
*
ppbox
=
box
;
}
return
ret
;
}
int
SrsMp4Box
::
nb_bytes
()
{
int
sz
=
nb_header
();
vector
<
SrsMp4Box
*>::
iterator
it
;
for
(
it
=
boxes
.
begin
();
it
!=
boxes
.
end
();
++
it
)
{
SrsMp4Box
*
box
=
*
it
;
sz
+=
box
->
nb_bytes
();
}
return
sz
;
}
int
SrsMp4Box
::
encode
(
SrsBuffer
*
buf
)
{
int
ret
=
ERROR_SUCCESS
;
if
((
ret
=
encode_header
(
buf
))
!=
ERROR_SUCCESS
)
{
srs_error
(
"MP4 encode box header failed. ret=%d"
,
ret
);
return
ret
;
}
if
((
ret
=
encode_boxes
(
buf
))
!=
ERROR_SUCCESS
)
{
srs_error
(
"MP4 encode contained boxes failed. ret=%d"
,
ret
);
return
ret
;
}
return
ret
;
}
int
SrsMp4Box
::
decode
(
SrsBuffer
*
buf
)
{
int
ret
=
ERROR_SUCCESS
;
start_pos
=
buf
->
pos
();
if
((
ret
=
decode_header
(
buf
))
!=
ERROR_SUCCESS
)
{
srs_error
(
"MP4 decode box header failed. ret=%d"
,
ret
);
return
ret
;
}
if
((
ret
=
decode_boxes
(
buf
))
!=
ERROR_SUCCESS
)
{
srs_error
(
"MP4 decode contained boxes failed. ret=%d"
,
ret
);
return
ret
;
}
return
ret
;
}
int
SrsMp4Box
::
encode_boxes
(
SrsBuffer
*
buf
)
{
int
ret
=
ERROR_SUCCESS
;
vector
<
SrsMp4Box
*>::
iterator
it
;
for
(
it
=
boxes
.
begin
();
it
!=
boxes
.
end
();
++
it
)
{
SrsMp4Box
*
box
=
*
it
;
if
((
ret
=
box
->
encode
(
buf
))
!=
ERROR_SUCCESS
)
{
srs_error
(
"MP4 encode contained box failed. ret=%d"
,
ret
);
return
ret
;
}
}
return
ret
;
}
int
SrsMp4Box
::
decode_boxes
(
SrsBuffer
*
buf
)
{
int
ret
=
ERROR_SUCCESS
;
int
left
=
left_space
(
buf
);
while
(
left
>
0
)
{
SrsMp4Box
*
box
=
NULL
;
if
((
ret
=
discovery
(
buf
,
&
box
))
!=
ERROR_SUCCESS
)
{
srs_error
(
"MP4 discovery contained box failed. ret=%d"
,
ret
);
return
ret
;
}
srs_assert
(
box
);
if
((
ret
=
box
->
decode
(
buf
))
!=
ERROR_SUCCESS
)
{
srs_freep
(
box
);
srs_error
(
"MP4 decode contained box failed. ret=%d"
,
ret
);
return
ret
;
}
boxes
.
push_back
(
box
);
left
-=
box
->
sz
();
}
return
ret
;
}
int
SrsMp4Box
::
nb_header
()
{
int
size
=
8
;
if
(
smallsize
==
SRS_MP4_USE_LARGE_SIZE
)
{
size
+=
8
;
}
if
(
type
==
SRS_MP4_BOX_UUID
)
{
size
+=
16
;
}
return
size
;
}
int
SrsMp4Box
::
encode_header
(
SrsBuffer
*
buf
)
{
int
ret
=
ERROR_SUCCESS
;
// Only support 31bits size.
if
(
sz
()
>
0x7fffffff
)
{
ret
=
ERROR_MP4_BOX_OVERFLOW
;
srs_error
(
"MP4 box size overflow 31bits, size=%"
PRId64
". ret=%d"
,
sz
(),
ret
);
return
ret
;
}
int
size
=
nb_header
();
if
(
!
buf
->
require
(
size
))
{
ret
=
ERROR_MP4_BOX_REQUIRE_SPACE
;
srs_error
(
"MP4 box require %d bytes space. ret=%d"
,
size
,
ret
);
return
ret
;
}
buf
->
write_4bytes
(
smallsize
);
if
(
smallsize
==
SRS_MP4_USE_LARGE_SIZE
)
{
buf
->
write_8bytes
(
largesize
);
}
buf
->
write_4bytes
(
type
);
if
(
type
==
SRS_MP4_BOX_UUID
)
{
buf
->
write_bytes
((
char
*
)
usertype
,
16
);
}
return
ret
;
}
int
SrsMp4Box
::
decode_header
(
SrsBuffer
*
buf
)
{
int
ret
=
ERROR_SUCCESS
;
if
(
!
buf
->
require
(
8
))
{
ret
=
ERROR_MP4_BOX_REQUIRE_SPACE
;
srs_error
(
"MP4 box require 8 bytes space. ret=%d"
,
ret
);
return
ret
;
}
smallsize
=
(
uint32_t
)
buf
->
read_4bytes
();
type
=
(
uint32_t
)
buf
->
read_4bytes
();
if
(
smallsize
==
SRS_MP4_EOF_SIZE
)
{
srs_warn
(
"MP4 box EOF."
);
return
ret
;
}
if
(
smallsize
==
SRS_MP4_USE_LARGE_SIZE
)
{
if
(
!
buf
->
require
(
8
))
{
ret
=
ERROR_MP4_BOX_REQUIRE_SPACE
;
srs_error
(
"MP4 box require 8 bytes space. ret=%d"
,
ret
);
return
ret
;
}
largesize
=
(
uint64_t
)
buf
->
read_8bytes
();
}
// Only support 31bits size.
if
(
sz
()
>
0x7fffffff
)
{
ret
=
ERROR_MP4_BOX_OVERFLOW
;
srs_error
(
"MP4 box size overflow 31bits, size=%"
PRId64
". ret=%d"
,
sz
(),
ret
);
return
ret
;
}
if
(
type
==
SRS_MP4_BOX_UUID
)
{
if
(
!
buf
->
require
(
16
))
{
ret
=
ERROR_MP4_BOX_REQUIRE_SPACE
;
srs_error
(
"MP4 box requires 16 bytes space. ret=%d"
,
ret
);
return
ret
;
}
usertype
=
new
uint8_t
[
16
];
buf
->
read_bytes
((
char
*
)
usertype
,
16
);
}
// The left required size, determined by the default version(0).
int
lrsz
=
nb_header
()
-
SrsMp4Box
::
nb_header
();
if
(
!
buf
->
require
(
lrsz
))
{
ret
=
ERROR_MP4_BOX_REQUIRE_SPACE
;
srs_error
(
"MP4 box requires %d bytes space. ret=%d"
,
lrsz
,
ret
);
return
ret
;
}
return
ret
;
}
SrsMp4FullBox
::
SrsMp4FullBox
()
...
...
@@ -48,9 +409,58 @@ SrsMp4FullBox::~SrsMp4FullBox()
{
}
int
SrsMp4FullBox
::
nb_header
()
{
return
SrsMp4Box
::
nb_header
()
+
1
+
3
;
}
int
SrsMp4FullBox
::
encode_header
(
SrsBuffer
*
buf
)
{
int
ret
=
ERROR_SUCCESS
;
if
((
ret
=
SrsMp4Box
::
encode_header
(
buf
))
!=
ERROR_SUCCESS
)
{
return
ret
;
}
buf
->
write_1bytes
(
version
);
buf
->
write_3bytes
(
flags
);
return
ret
;
}
int
SrsMp4FullBox
::
decode_header
(
SrsBuffer
*
buf
)
{
int
ret
=
ERROR_SUCCESS
;
if
((
ret
=
SrsMp4Box
::
decode_header
(
buf
))
!=
ERROR_SUCCESS
)
{
return
ret
;
}
if
(
!
buf
->
require
(
4
))
{
ret
=
ERROR_MP4_BOX_REQUIRE_SPACE
;
srs_error
(
"MP4 full box requires 4 bytes space. ret=%d"
,
ret
);
return
ret
;
}
flags
=
(
uint32_t
)
buf
->
read_4bytes
();
version
=
(
uint8_t
)((
flags
>>
24
)
&
0xff
);
flags
&=
0x00ffffff
;
// The left required size, determined by the version.
int
lrsz
=
nb_header
()
-
SrsMp4FullBox
::
nb_header
();
if
(
!
buf
->
require
(
lrsz
))
{
ret
=
ERROR_MP4_BOX_REQUIRE_SPACE
;
srs_error
(
"MP4 full box requires %d bytes space. ret=%d"
,
lrsz
,
ret
);
return
ret
;
}
return
ret
;
}
SrsMp4FileTypeBox
::
SrsMp4FileTypeBox
()
{
type
=
0x66747970
;
// 'ftyp'
type
=
SRS_MP4_BOX_FTYP
;
nb_compatible_brands
=
0
;
compatible_brands
=
NULL
;
major_brand
=
minor_version
=
0
;
...
...
@@ -61,9 +471,60 @@ SrsMp4FileTypeBox::~SrsMp4FileTypeBox()
srs_freepa
(
compatible_brands
);
}
int
SrsMp4FileTypeBox
::
nb_header
()
{
return
SrsMp4Box
::
nb_header
()
+
8
+
nb_compatible_brands
*
4
;
}
int
SrsMp4FileTypeBox
::
encode_header
(
SrsBuffer
*
buf
)
{
int
ret
=
ERROR_SUCCESS
;
if
((
ret
=
SrsMp4Box
::
encode_header
(
buf
))
!=
ERROR_SUCCESS
)
{
return
ret
;
}
buf
->
write_4bytes
(
major_brand
);
buf
->
write_4bytes
(
minor_version
);
for
(
int
i
=
0
;
i
<
nb_compatible_brands
;
i
++
)
{
uint32_t
&
cb
=
compatible_brands
[
i
];
buf
->
write_4bytes
(
cb
);
}
return
ret
;
}
int
SrsMp4FileTypeBox
::
decode_header
(
SrsBuffer
*
buf
)
{
int
ret
=
ERROR_SUCCESS
;
if
((
ret
=
SrsMp4Box
::
decode_header
(
buf
))
!=
ERROR_SUCCESS
)
{
return
ret
;
}
major_brand
=
buf
->
read_4bytes
();
minor_version
=
buf
->
read_4bytes
();
// Compatible brands to the end of the box.
int
left
=
left_space
(
buf
);
if
(
left
>
0
)
{
nb_compatible_brands
=
left
/
4
;
compatible_brands
=
new
uint32_t
[
nb_compatible_brands
];
}
for
(
int
i
=
0
;
left
>
0
;
i
++
,
left
-=
4
){
uint32_t
cb
=
buf
->
read_4bytes
();
compatible_brands
[
i
]
=
cb
;
}
return
ret
;
}
SrsMp4MediaDataBox
::
SrsMp4MediaDataBox
()
{
type
=
0x6d646174
;
// 'mdat'
type
=
SRS_MP4_BOX_MDAT
;
data
=
NULL
;
nb_data
=
0
;
}
...
...
@@ -73,18 +534,95 @@ SrsMp4MediaDataBox::~SrsMp4MediaDataBox()
srs_freepa
(
data
);
}
int
SrsMp4MediaDataBox
::
nb_header
()
{
return
SrsMp4Box
::
nb_header
()
+
nb_data
;
}
int
SrsMp4MediaDataBox
::
encode_header
(
SrsBuffer
*
buf
)
{
int
ret
=
ERROR_SUCCESS
;
if
((
ret
=
SrsMp4Box
::
encode_header
(
buf
))
!=
ERROR_SUCCESS
)
{
return
ret
;
}
if
(
nb_data
)
{
buf
->
write_bytes
((
char
*
)
data
,
nb_data
);
}
return
ret
;
}
int
SrsMp4MediaDataBox
::
decode_header
(
SrsBuffer
*
buf
)
{
int
ret
=
ERROR_SUCCESS
;
if
((
ret
=
SrsMp4Box
::
decode_header
(
buf
))
!=
ERROR_SUCCESS
)
{
return
ret
;
}
int
left
=
left_space
(
buf
);
if
(
left
)
{
data
=
new
uint8_t
[
left
];
buf
->
read_bytes
((
char
*
)
data
,
left
);
}
return
ret
;
}
SrsMp4FreeSpaceBox
::
SrsMp4FreeSpaceBox
()
{
type
=
0x66726565
;
// ‘free’ or ‘skip’
type
=
SRS_MP4_BOX_FREE
;
// 'free' or 'skip'
data
=
NULL
;
nb_data
=
0
;
}
SrsMp4FreeSpaceBox
::~
SrsMp4FreeSpaceBox
()
{
srs_freepa
(
data
);
}
int
SrsMp4FreeSpaceBox
::
nb_header
()
{
return
SrsMp4Box
::
nb_header
()
+
nb_data
;
}
int
SrsMp4FreeSpaceBox
::
encode_header
(
SrsBuffer
*
buf
)
{
int
ret
=
ERROR_SUCCESS
;
if
((
ret
=
SrsMp4Box
::
encode_header
(
buf
))
!=
ERROR_SUCCESS
)
{
return
ret
;
}
if
(
nb_data
)
{
buf
->
write_bytes
((
char
*
)
data
,
nb_data
);
}
return
ret
;
}
int
SrsMp4FreeSpaceBox
::
decode_header
(
SrsBuffer
*
buf
)
{
int
ret
=
ERROR_SUCCESS
;
if
((
ret
=
SrsMp4Box
::
decode_header
(
buf
))
!=
ERROR_SUCCESS
)
{
return
ret
;
}
int
left
=
left_space
(
buf
);
if
(
left
)
{
data
=
new
uint8_t
[
left
];
buf
->
read_bytes
((
char
*
)
data
,
left
);
}
return
ret
;
}
SrsMp4MovieBox
::
SrsMp4MovieBox
()
{
type
=
0x6d6f6f76
;
// 'moov'
type
=
SRS_MP4_BOX_MOOV
;
}
SrsMp4MovieBox
::~
SrsMp4MovieBox
()
...
...
@@ -93,7 +631,7 @@ SrsMp4MovieBox::~SrsMp4MovieBox()
SrsMp4MovieHeaderBox
::
SrsMp4MovieHeaderBox
()
{
type
=
0x6d766864
;
// 'mvhd'
type
=
SRS_MP4_BOX_MVHD
;
rate
=
0x00010000
;
// typically 1.0
volume
=
0x0100
;
// typically, full volume
...
...
@@ -110,9 +648,92 @@ SrsMp4MovieHeaderBox::~SrsMp4MovieHeaderBox()
{
}
int
SrsMp4MovieHeaderBox
::
nb_header
()
{
int
size
=
SrsMp4FullBox
::
nb_header
();
if
(
version
==
1
)
{
size
+=
8
+
8
+
4
+
8
;
}
else
{
size
+=
4
+
4
+
4
+
4
;
}
size
+=
4
+
2
+
2
+
8
+
36
+
24
+
4
;
return
size
;
}
int
SrsMp4MovieHeaderBox
::
encode_header
(
SrsBuffer
*
buf
)
{
int
ret
=
ERROR_SUCCESS
;
if
((
ret
=
SrsMp4FullBox
::
encode_header
(
buf
))
!=
ERROR_SUCCESS
)
{
return
ret
;
}
if
(
version
==
1
)
{
buf
->
write_8bytes
(
creation_time
);
buf
->
write_8bytes
(
modification_time
);
buf
->
write_4bytes
(
timescale
);
buf
->
write_8bytes
(
duration
);
}
else
{
buf
->
write_4bytes
((
uint32_t
)
creation_time
);
buf
->
write_4bytes
((
uint32_t
)
modification_time
);
buf
->
write_4bytes
(
timescale
);
buf
->
write_4bytes
((
uint32_t
)
duration
);
}
buf
->
write_4bytes
(
rate
);
buf
->
write_2bytes
(
volume
);
buf
->
write_2bytes
(
reserved0
);
buf
->
write_8bytes
(
reserved1
);
for
(
int
i
=
0
;
i
<
9
;
i
++
)
{
buf
->
write_4bytes
(
matrix
[
i
]);
}
for
(
int
i
=
0
;
i
<
6
;
i
++
)
{
buf
->
write_4bytes
(
pre_defined
[
i
]);
}
buf
->
write_4bytes
(
next_track_ID
);
return
ret
;
}
int
SrsMp4MovieHeaderBox
::
decode_header
(
SrsBuffer
*
buf
)
{
int
ret
=
ERROR_SUCCESS
;
if
((
ret
=
SrsMp4FullBox
::
decode_header
(
buf
))
!=
ERROR_SUCCESS
)
{
return
ret
;
}
if
(
version
==
1
)
{
creation_time
=
buf
->
read_8bytes
();
modification_time
=
buf
->
read_8bytes
();
timescale
=
buf
->
read_4bytes
();
duration
=
buf
->
read_8bytes
();
}
else
{
creation_time
=
buf
->
read_4bytes
();
modification_time
=
buf
->
read_4bytes
();
timescale
=
buf
->
read_4bytes
();
duration
=
buf
->
read_4bytes
();
}
rate
=
buf
->
read_4bytes
();
volume
=
buf
->
read_4bytes
();
buf
->
skip
(
2
);
buf
->
skip
(
8
);
for
(
int
i
=
0
;
i
<
9
;
i
++
)
{
matrix
[
i
]
=
buf
->
read_4bytes
();
}
buf
->
skip
(
24
);
next_track_ID
=
buf
->
read_4bytes
();
return
ret
;
}
SrsMp4TrackBox
::
SrsMp4TrackBox
()
{
type
=
0x7472616b
;
// 'trak'
type
=
SRS_MP4_BOX_TRAK
;
}
SrsMp4TrackBox
::~
SrsMp4TrackBox
()
...
...
@@ -121,13 +742,13 @@ SrsMp4TrackBox::~SrsMp4TrackBox()
SrsMp4TrackHeaderBox
::
SrsMp4TrackHeaderBox
()
{
type
=
0x746b6864
;
// 'tkhd'
type
=
SRS_MP4_BOX_TKHD
;
reserved0
=
0
;
reserved1
=
0
;
reserved2
=
0
;
layer
=
alternate_group
=
0
;
volume
=
0
x0100
;
// if track_is_audio 0x0100 else 0
volume
=
0
;
// if track_is_audio 0x0100 else 0
int32_t
v
[]
=
{
0x00010000
,
0
,
0
,
0
,
0x00010000
,
0
,
0
,
0
,
0x40000000
};
memcpy
(
matrix
,
v
,
36
);
...
...
@@ -137,9 +758,96 @@ SrsMp4TrackHeaderBox::~SrsMp4TrackHeaderBox()
{
}
int
SrsMp4TrackHeaderBox
::
nb_header
()
{
int
size
=
SrsMp4FullBox
::
nb_header
();
if
(
version
==
1
)
{
size
+=
8
+
8
+
4
+
4
+
8
;
}
else
{
size
+=
4
+
4
+
4
+
4
+
4
;
}
size
+=
8
+
2
+
2
+
2
+
2
+
36
+
4
+
4
;
return
size
;
}
int
SrsMp4TrackHeaderBox
::
encode_header
(
SrsBuffer
*
buf
)
{
int
ret
=
ERROR_SUCCESS
;
if
((
ret
=
SrsMp4FullBox
::
encode_header
(
buf
))
!=
ERROR_SUCCESS
)
{
return
ret
;
}
if
(
version
==
1
)
{
buf
->
write_8bytes
(
creation_time
);
buf
->
write_8bytes
(
modification_time
);
buf
->
write_4bytes
(
track_ID
);
buf
->
write_4bytes
(
reserved0
);
buf
->
write_8bytes
(
duration
);
}
else
{
buf
->
write_4bytes
((
uint32_t
)
creation_time
);
buf
->
write_4bytes
((
uint32_t
)
modification_time
);
buf
->
write_4bytes
(
track_ID
);
buf
->
write_4bytes
(
reserved0
);
buf
->
write_4bytes
((
uint32_t
)
duration
);
}
buf
->
write_8bytes
(
reserved1
);
buf
->
write_2bytes
(
layer
);
buf
->
write_2bytes
(
alternate_group
);
buf
->
write_2bytes
(
volume
);
buf
->
write_2bytes
(
reserved2
);
for
(
int
i
=
0
;
i
<
9
;
i
++
)
{
buf
->
write_4bytes
(
matrix
[
i
]);
}
buf
->
write_4bytes
(
width
);
buf
->
write_4bytes
(
height
);
return
ret
;
}
int
SrsMp4TrackHeaderBox
::
decode_header
(
SrsBuffer
*
buf
)
{
int
ret
=
ERROR_SUCCESS
;
if
((
ret
=
SrsMp4FullBox
::
decode_header
(
buf
))
!=
ERROR_SUCCESS
)
{
return
ret
;
}
if
(
version
==
1
)
{
creation_time
=
buf
->
read_8bytes
();
modification_time
=
buf
->
read_8bytes
();
track_ID
=
buf
->
read_4bytes
();
buf
->
skip
(
4
);
duration
=
buf
->
read_8bytes
();
}
else
{
creation_time
=
buf
->
read_4bytes
();
modification_time
=
buf
->
read_4bytes
();
track_ID
=
buf
->
read_4bytes
();
buf
->
skip
(
4
);
duration
=
buf
->
read_4bytes
();
}
buf
->
skip
(
8
);
layer
=
buf
->
read_2bytes
();
alternate_group
=
buf
->
read_2bytes
();
volume
=
buf
->
read_2bytes
();
buf
->
skip
(
2
);
for
(
int
i
=
0
;
i
<
9
;
i
++
)
{
matrix
[
i
]
=
buf
->
read_4bytes
();
}
width
=
buf
->
read_4bytes
();
height
=
buf
->
read_4bytes
();
return
ret
;
}
SrsMp4EditBox
::
SrsMp4EditBox
()
{
type
=
0x65647473
;
// 'edts'
type
=
SRS_MP4_BOX_EDTS
;
}
SrsMp4EditBox
::~
SrsMp4EditBox
()
...
...
@@ -151,9 +859,56 @@ SrsMp4ElstEntry::SrsMp4ElstEntry()
media_rate_fraction
=
0
;
}
int
SrsMp4ElstEntry
::
nb_header
(
uint32_t
version
)
{
int
size
=
0
;
if
(
version
==
1
)
{
size
+=
8
+
8
;
}
else
{
size
+=
4
+
4
;
}
size
+=
2
+
2
;
return
size
;
}
int
SrsMp4ElstEntry
::
encode_header
(
SrsBuffer
*
buf
,
uint32_t
version
)
{
if
(
version
==
1
)
{
buf
->
write_8bytes
(
segment_duration
);
buf
->
write_8bytes
(
media_time
);
}
else
{
buf
->
write_4bytes
((
uint32_t
)
segment_duration
);
buf
->
write_4bytes
((
int32_t
)
media_time
);
}
buf
->
write_2bytes
(
media_rate_integer
);
buf
->
write_2bytes
(
media_rate_fraction
);
return
ERROR_SUCCESS
;
}
int
SrsMp4ElstEntry
::
decode_header
(
SrsBuffer
*
buf
,
uint32_t
version
)
{
if
(
version
==
1
)
{
segment_duration
=
buf
->
read_8bytes
();
media_time
=
buf
->
read_8bytes
();
}
else
{
segment_duration
=
buf
->
read_4bytes
();
media_time
=
buf
->
read_4bytes
();
}
media_rate_integer
=
buf
->
read_2bytes
();
media_rate_fraction
=
buf
->
read_2bytes
();
return
ERROR_SUCCESS
;
}
SrsMp4EditListBox
::
SrsMp4EditListBox
()
{
type
=
0x656c7374
;
// 'elst'
type
=
SRS_MP4_BOX_ELST
;
entry_count
=
0
;
entries
=
NULL
;
...
...
@@ -164,9 +919,62 @@ SrsMp4EditListBox::~SrsMp4EditListBox()
srs_freepa
(
entries
);
}
int
SrsMp4EditListBox
::
nb_header
()
{
int
size
=
SrsMp4FullBox
::
nb_header
();
for
(
uint32_t
i
=
0
;
i
<
entry_count
;
i
++
)
{
SrsMp4ElstEntry
&
entry
=
entries
[
i
];
size
+=
entry
.
nb_header
(
version
);
}
return
size
;
}
int
SrsMp4EditListBox
::
encode_header
(
SrsBuffer
*
buf
)
{
int
ret
=
ERROR_SUCCESS
;
if
((
ret
=
SrsMp4FullBox
::
encode_header
(
buf
))
!=
ERROR_SUCCESS
)
{
return
ret
;
}
for
(
uint32_t
i
=
0
;
i
<
entry_count
;
i
++
)
{
SrsMp4ElstEntry
&
entry
=
entries
[
i
];
if
((
ret
=
entry
.
encode_header
(
buf
,
version
))
!=
ERROR_SUCCESS
)
{
return
ret
;
}
}
return
ret
;
}
int
SrsMp4EditListBox
::
decode_header
(
SrsBuffer
*
buf
)
{
int
ret
=
ERROR_SUCCESS
;
if
((
ret
=
SrsMp4FullBox
::
decode_header
(
buf
))
!=
ERROR_SUCCESS
)
{
return
ret
;
}
int
left
=
left_space
(
buf
);
entry_count
=
left
/
SrsMp4ElstEntry
().
nb_header
(
version
);
if
(
entry_count
>
0
)
{
entries
=
new
SrsMp4ElstEntry
[
entry_count
];
}
for
(
int
i
=
0
;
i
<
entry_count
;
i
++
)
{
SrsMp4ElstEntry
&
entry
=
entries
[
i
];
if
((
ret
=
entry
.
decode_header
(
buf
,
version
))
!=
ERROR_SUCCESS
)
{
return
ret
;
}
}
return
ret
;
}
SrsMp4MediaBox
::
SrsMp4MediaBox
()
{
type
=
0x6d646961
;
// 'mdia'
type
=
SRS_MP4_BOX_MDIA
;
}
SrsMp4MediaBox
::~
SrsMp4MediaBox
()
...
...
@@ -175,9 +983,8 @@ SrsMp4MediaBox::~SrsMp4MediaBox()
SrsMp4MediaHeaderBox
::
SrsMp4MediaHeaderBox
()
{
type
=
0x6d646864
;
// 'mdhd'
pad
=
0
;
type
=
SRS_MP4_BOX_MDHD
;
language
=
0
;
pre_defined
=
0
;
}
...
...
@@ -185,90 +992,468 @@ SrsMp4MediaHeaderBox::~SrsMp4MediaHeaderBox()
{
}
uint8_t
SrsMp4MediaHeaderBox
::
language0
()
{
return
(
language
>>
10
)
&
0x1f
;
}
void
SrsMp4MediaHeaderBox
::
set_language0
(
uint8_t
v
)
{
language
|=
uint16_t
(
v
&
0x1f
)
<<
10
;
}
uint8_t
SrsMp4MediaHeaderBox
::
language1
()
{
return
(
language
>>
5
)
&
0x1f
;
}
void
SrsMp4MediaHeaderBox
::
set_language1
(
uint8_t
v
)
{
language
|=
uint16_t
(
v
&
0x1f
)
<<
5
;
}
uint8_t
SrsMp4MediaHeaderBox
::
language2
()
{
return
language
&
0x1f
;
}
void
SrsMp4MediaHeaderBox
::
set_language2
(
uint8_t
v
)
{
language
|=
uint16_t
(
v
&
0x1f
);
}
int
SrsMp4MediaHeaderBox
::
nb_header
()
{
int
size
=
SrsMp4FullBox
::
nb_header
();
if
(
version
==
1
)
{
size
+=
8
+
8
+
4
+
8
;
}
else
{
size
+=
4
+
4
+
4
+
4
;
}
size
+=
2
+
2
;
return
size
;
}
int
SrsMp4MediaHeaderBox
::
encode_header
(
SrsBuffer
*
buf
)
{
int
ret
=
ERROR_SUCCESS
;
if
((
ret
=
SrsMp4FullBox
::
encode_header
(
buf
))
!=
ERROR_SUCCESS
)
{
return
ret
;
}
if
(
version
==
1
)
{
buf
->
write_8bytes
(
creation_time
);
buf
->
write_8bytes
(
modification_time
);
buf
->
write_4bytes
(
timescale
);
buf
->
write_8bytes
(
duration
);
}
else
{
buf
->
write_4bytes
((
uint32_t
)
creation_time
);
buf
->
write_4bytes
((
uint32_t
)
modification_time
);
buf
->
write_4bytes
(
timescale
);
buf
->
write_4bytes
((
uint32_t
)
duration
);
}
buf
->
write_2bytes
(
language
);
buf
->
write_2bytes
(
pre_defined
);
return
ret
;
}
int
SrsMp4MediaHeaderBox
::
decode_header
(
SrsBuffer
*
buf
)
{
int
ret
=
ERROR_SUCCESS
;
if
((
ret
=
SrsMp4FullBox
::
decode_header
(
buf
))
!=
ERROR_SUCCESS
)
{
return
ret
;
}
if
(
version
==
1
)
{
creation_time
=
buf
->
read_8bytes
();
modification_time
=
buf
->
read_8bytes
();
timescale
=
buf
->
read_4bytes
();
duration
=
buf
->
read_8bytes
();
}
else
{
creation_time
=
buf
->
read_4bytes
();
modification_time
=
buf
->
read_4bytes
();
timescale
=
buf
->
read_4bytes
();
duration
=
buf
->
read_4bytes
();
}
language
=
buf
->
read_2bytes
();
buf
->
skip
(
2
);
return
ret
;
}
SrsMp4HandlerReferenceBox
::
SrsMp4HandlerReferenceBox
()
{
type
=
0x68646c72
;
// 'hdlr'
type
=
SRS_MP4_BOX_HDLR
;
pre_defined
=
0
;
memset
(
reserved
,
0
,
12
);
}
SrsMp4HandlerReferenceBox
::~
SrsMp4HandlerReferenceBox
()
{
}
int
SrsMp4HandlerReferenceBox
::
nb_header
()
{
return
SrsMp4FullBox
::
nb_header
()
+
4
+
4
+
12
+
srs_mp4_string_length
(
name
);
}
int
SrsMp4HandlerReferenceBox
::
encode_header
(
SrsBuffer
*
buf
)
{
int
ret
=
ERROR_SUCCESS
;
if
((
ret
=
SrsMp4FullBox
::
encode_header
(
buf
))
!=
ERROR_SUCCESS
)
{
return
ret
;
}
buf
->
write_4bytes
(
pre_defined
);
buf
->
write_4bytes
(
handler_type
);
buf
->
write_4bytes
(
reserved
[
0
]);
buf
->
write_4bytes
(
reserved
[
1
]);
buf
->
write_4bytes
(
reserved
[
2
]);
srs_mp4_string_write
(
buf
,
name
);
return
ret
;
}
int
SrsMp4HandlerReferenceBox
::
decode_header
(
SrsBuffer
*
buf
)
{
int
ret
=
ERROR_SUCCESS
;
if
((
ret
=
SrsMp4FullBox
::
decode_header
(
buf
))
!=
ERROR_SUCCESS
)
{
return
ret
;
}
buf
->
skip
(
4
);
handler_type
=
buf
->
read_4bytes
();
buf
->
skip
(
12
);
if
((
ret
=
srs_mp4_string_read
(
buf
,
name
,
left_space
(
buf
)))
!=
ERROR_SUCCESS
)
{
srs_error
(
"MP4 hdlr read string failed. ret=%d"
,
ret
);
return
ret
;
}
return
ret
;
}
SrsMp4MediaInformationBox
::
SrsMp4MediaInformationBox
()
{
type
=
SRS_MP4_BOX_MINF
;
}
SrsMp4MediaInformationBox
::~
SrsMp4MediaInformationBox
()
{
}
SrsMp4VideoMeidaHeaderBox
::
SrsMp4VideoMeidaHeaderBox
()
{
type
=
SRS_MP4_BOX_VMHD
;
version
=
0
;
flags
=
1
;
graphicsmode
=
0
;
memset
(
opcolor
,
0
,
6
);
}
SrsMp4VideoMeidaHeaderBox
::~
SrsMp4VideoMeidaHeaderBox
()
{
}
int
SrsMp4VideoMeidaHeaderBox
::
nb_header
()
{
return
SrsMp4FullBox
::
nb_header
()
+
2
+
6
;
}
int
SrsMp4VideoMeidaHeaderBox
::
encode_header
(
SrsBuffer
*
buf
)
{
int
ret
=
ERROR_SUCCESS
;
if
((
ret
=
SrsMp4FullBox
::
encode_header
(
buf
))
!=
ERROR_SUCCESS
)
{
return
ret
;
}
buf
->
write_2bytes
(
graphicsmode
);
buf
->
write_2bytes
(
opcolor
[
0
]);
buf
->
write_2bytes
(
opcolor
[
1
]);
buf
->
write_2bytes
(
opcolor
[
2
]);
return
ret
;
}
int
SrsMp4VideoMeidaHeaderBox
::
decode_header
(
SrsBuffer
*
buf
)
{
int
ret
=
ERROR_SUCCESS
;
if
((
ret
=
SrsMp4FullBox
::
decode_header
(
buf
))
!=
ERROR_SUCCESS
)
{
return
ret
;
}
graphicsmode
=
buf
->
read_2bytes
();
opcolor
[
0
]
=
buf
->
read_2bytes
();
opcolor
[
1
]
=
buf
->
read_2bytes
();
opcolor
[
2
]
=
buf
->
read_2bytes
();
return
ret
;
}
SrsMp4SoundMeidaHeaderBox
::
SrsMp4SoundMeidaHeaderBox
()
{
type
=
SRS_MP4_BOX_SMHD
;
reserved
=
balance
=
0
;
}
SrsMp4SoundMeidaHeaderBox
::~
SrsMp4SoundMeidaHeaderBox
()
{
}
int
SrsMp4SoundMeidaHeaderBox
::
nb_header
()
{
return
SrsMp4FullBox
::
nb_header
()
+
2
+
2
;
}
int
SrsMp4SoundMeidaHeaderBox
::
encode_header
(
SrsBuffer
*
buf
)
{
int
ret
=
ERROR_SUCCESS
;
if
((
ret
=
SrsMp4FullBox
::
encode_header
(
buf
))
!=
ERROR_SUCCESS
)
{
return
ret
;
}
buf
->
write_2bytes
(
balance
);
buf
->
write_2bytes
(
reserved
);
return
ret
;
}
int
SrsMp4SoundMeidaHeaderBox
::
decode_header
(
SrsBuffer
*
buf
)
{
int
ret
=
ERROR_SUCCESS
;
if
((
ret
=
SrsMp4FullBox
::
decode_header
(
buf
))
!=
ERROR_SUCCESS
)
{
return
ret
;
}
balance
=
buf
->
read_2bytes
();
buf
->
skip
(
2
);
return
ret
;
}
SrsMp4DataInformationBox
::
SrsMp4DataInformationBox
()
{
type
=
SRS_MP4_BOX_DINF
;
}
SrsMp4DataInformationBox
::~
SrsMp4DataInformationBox
()
{
}
SrsMp4DataEntryBox
::
SrsMp4DataEntryBox
()
{
}
SrsMp4DataEntryBox
::~
SrsMp4DataEntryBox
()
{
}
int
SrsMp4DataEntryBox
::
nb_header
()
{
return
SrsMp4FullBox
::
nb_header
()
+
srs_mp4_string_length
(
location
);
}
int
SrsMp4DataEntryBox
::
encode_header
(
SrsBuffer
*
buf
)
{
int
ret
=
ERROR_SUCCESS
;
if
((
ret
=
SrsMp4FullBox
::
encode_header
(
buf
))
!=
ERROR_SUCCESS
)
{
return
ret
;
}
srs_mp4_string_write
(
buf
,
location
);
return
ret
;
}
int
SrsMp4DataEntryBox
::
decode_header
(
SrsBuffer
*
buf
)
{
int
ret
=
ERROR_SUCCESS
;
pre_defined
=
0
;
memset
(
reserved
,
0
,
12
);
if
((
ret
=
SrsMp4FullBox
::
decode_header
(
buf
))
!=
ERROR_SUCCESS
)
{
return
ret
;
}
if
((
ret
=
srs_mp4_string_read
(
buf
,
location
,
left_space
(
buf
)))
!=
ERROR_SUCCESS
)
{
srs_error
(
"MP4 urx read string failed. ret=%d"
,
ret
);
return
ret
;
}
return
ret
;
}
SrsMp4
HandlerReferenceBox
::~
SrsMp4HandlerReference
Box
()
SrsMp4
DataEntryUrlBox
::
SrsMp4DataEntryUrl
Box
()
{
type
=
SRS_MP4_BOX_URL
;
}
SrsMp4
MediaInformationBox
::
SrsMp4MediaInformation
Box
()
SrsMp4
DataEntryUrlBox
::~
SrsMp4DataEntryUrl
Box
()
{
type
=
0x6d696e66
;
// 'minf'
}
SrsMp4
MediaInformationBox
::~
SrsMp4MediaInformatio
nBox
()
SrsMp4
DataEntryUrnBox
::
SrsMp4DataEntryUr
nBox
()
{
type
=
SRS_MP4_BOX_URN
;
}
SrsMp4
VideoMeidaHeaderBox
::
SrsMp4VideoMeidaHeader
Box
()
SrsMp4
DataEntryUrnBox
::~
SrsMp4DataEntryUrn
Box
()
{
type
=
0x766d6864
;
// 'vmhd'
version
=
0
;
flags
=
1
;
graphicsmode
=
0
;
memset
(
opcolor
,
0
,
6
);
}
SrsMp4VideoMeidaHeaderBox
::~
SrsMp4VideoMeidaHeaderBox
()
int
SrsMp4DataEntryUrnBox
::
nb_header
()
{
return
SrsMp4DataEntryBox
::
nb_header
()
+
srs_mp4_string_length
(
name
);
}
SrsMp4SoundMeidaHeaderBox
::
SrsMp4SoundMeidaHeaderBox
(
)
int
SrsMp4DataEntryUrnBox
::
encode_header
(
SrsBuffer
*
buf
)
{
type
=
0x736d6864
;
// 'smhd'
int
ret
=
ERROR_SUCCESS
;
reserved
=
balance
=
0
;
if
((
ret
=
SrsMp4DataEntryBox
::
encode_header
(
buf
))
!=
ERROR_SUCCESS
)
{
return
ret
;
}
srs_mp4_string_write
(
buf
,
name
);
return
ret
;
}
SrsMp4SoundMeidaHeaderBox
::~
SrsMp4SoundMeidaHeaderBox
(
)
int
SrsMp4DataEntryUrnBox
::
decode_header
(
SrsBuffer
*
buf
)
{
int
ret
=
ERROR_SUCCESS
;
if
((
ret
=
SrsMp4DataEntryBox
::
decode_header
(
buf
))
!=
ERROR_SUCCESS
)
{
return
ret
;
}
if
((
ret
=
srs_mp4_string_read
(
buf
,
name
,
left_space
(
buf
)))
!=
ERROR_SUCCESS
)
{
srs_error
(
"MP4 urn read string failed. ret=%d"
,
ret
);
return
ret
;
}
return
ret
;
}
SrsMp4Data
InformationBox
::
SrsMp4DataInformation
Box
()
SrsMp4Data
ReferenceBox
::
SrsMp4DataReference
Box
()
{
type
=
0x64696e66
;
// 'dinf'
type
=
SRS_MP4_BOX_DREF
;
}
SrsMp4Data
InformationBox
::~
SrsMp4DataInformation
Box
()
SrsMp4Data
ReferenceBox
::~
SrsMp4DataReference
Box
()
{
vector
<
SrsMp4DataEntryBox
*>::
iterator
it
;
for
(
it
=
entries
.
begin
();
it
!=
entries
.
end
();
++
it
)
{
SrsMp4DataEntryBox
*
entry
=
*
it
;
srs_freep
(
entry
);
}
entries
.
clear
();
}
SrsMp4DataEntryBox
::
SrsMp4DataEntryBox
()
uint32_t
SrsMp4DataReferenceBox
::
entry_count
()
{
return
(
uint32_t
)
entries
.
size
();
}
SrsMp4DataEntry
UrlBox
::
SrsMp4DataEntryUrlBox
(
)
SrsMp4DataEntry
Box
*
SrsMp4DataReferenceBox
::
entry_at
(
int
index
)
{
type
=
0x75726c20
;
// 'url '
return
entries
.
at
(
index
);
}
SrsMp4DataEntryUrnBox
::
SrsMp4DataEntryUrnBox
()
int
SrsMp4DataReferenceBox
::
nb_header
()
{
type
=
0x75726e20
;
// 'urn '
int
size
=
SrsMp4FullBox
::
nb_header
();
size
+=
4
;
vector
<
SrsMp4DataEntryBox
*>::
iterator
it
;
for
(
it
=
entries
.
begin
();
it
!=
entries
.
end
();
++
it
)
{
SrsMp4DataEntryBox
*
entry
=
*
it
;
size
+=
entry
->
nb_bytes
();
}
return
size
;
}
SrsMp4DataReferenceBox
::
SrsMp4DataReferenceBox
(
)
int
SrsMp4DataReferenceBox
::
encode_header
(
SrsBuffer
*
buf
)
{
type
=
0x64726566
;
// 'dref'
int
ret
=
ERROR_SUCCESS
;
entry_count
=
0
;
entries
=
NULL
;
if
((
ret
=
SrsMp4FullBox
::
encode_header
(
buf
))
!=
ERROR_SUCCESS
)
{
return
ret
;
}
buf
->
write_4bytes
((
int32_t
)
entries
.
size
());
vector
<
SrsMp4DataEntryBox
*>::
iterator
it
;
for
(
it
=
entries
.
begin
();
it
!=
entries
.
end
();
++
it
)
{
SrsMp4DataEntryBox
*
entry
=
*
it
;
if
((
ret
=
entry
->
encode
(
buf
))
!=
ERROR_SUCCESS
)
{
return
ret
;
}
}
return
ret
;
}
SrsMp4DataReferenceBox
::~
SrsMp4DataReferenceBox
(
)
int
SrsMp4DataReferenceBox
::
decode_header
(
SrsBuffer
*
buf
)
{
int
ret
=
ERROR_SUCCESS
;
if
((
ret
=
SrsMp4FullBox
::
decode_header
(
buf
))
!=
ERROR_SUCCESS
)
{
return
ret
;
}
int
left
=
left_space
(
buf
);
while
(
left
>
0
)
{
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
)
{
fbox
->
version
=
version
;
fbox
->
flags
=
flags
;
}
if
(
box
->
type
==
SRS_MP4_BOX_URL
)
{
entries
.
push_back
(
dynamic_cast
<
SrsMp4DataEntryUrlBox
*>
(
box
));
}
else
if
(
box
->
type
==
SRS_MP4_BOX_URN
)
{
entries
.
push_back
(
dynamic_cast
<
SrsMp4DataEntryUrnBox
*>
(
box
));
}
else
{
srs_freep
(
box
);
}
}
return
ret
;
}
SrsMp4SampleTableBox
::
SrsMp4SampleTableBox
()
{
type
=
0x7374626c
;
// 'stbl'
type
=
SRS_MP4_BOX_STBL
;
}
SrsMp4SampleTableBox
::~
SrsMp4SampleTableBox
()
...
...
@@ -284,6 +1469,41 @@ SrsMp4SampleEntry::~SrsMp4SampleEntry()
{
}
int
SrsMp4SampleEntry
::
nb_header
()
{
return
SrsMp4Box
::
nb_header
()
+
6
+
2
;
}
int
SrsMp4SampleEntry
::
encode_header
(
SrsBuffer
*
buf
)
{
int
ret
=
ERROR_SUCCESS
;
if
((
ret
=
SrsMp4Box
::
encode_header
(
buf
))
!=
ERROR_SUCCESS
)
{
return
ret
;
}
for
(
int
i
=
0
;
i
<
6
;
i
++
)
{
buf
->
write_1bytes
(
reserved
[
i
]);
}
buf
->
write_2bytes
(
data_reference_index
);
return
ret
;
}
int
SrsMp4SampleEntry
::
decode_header
(
SrsBuffer
*
buf
)
{
int
ret
=
ERROR_SUCCESS
;
if
((
ret
=
SrsMp4Box
::
decode_header
(
buf
))
!=
ERROR_SUCCESS
)
{
return
ret
;
}
buf
->
skip
(
6
);
data_reference_index
=
buf
->
read_2bytes
();
return
ret
;
}
SrsMp4VisualSampleEntry
::
SrsMp4VisualSampleEntry
()
{
pre_defined0
=
0
;
...
...
@@ -302,9 +1522,64 @@ SrsMp4VisualSampleEntry::~SrsMp4VisualSampleEntry()
{
}
int
SrsMp4VisualSampleEntry
::
nb_header
()
{
return
SrsMp4SampleEntry
::
nb_header
()
+
2
+
2
+
12
+
2
+
2
+
4
+
4
+
4
+
2
+
32
+
2
+
2
;
}
int
SrsMp4VisualSampleEntry
::
encode_header
(
SrsBuffer
*
buf
)
{
int
ret
=
ERROR_SUCCESS
;
if
((
ret
=
SrsMp4SampleEntry
::
encode_header
(
buf
))
!=
ERROR_SUCCESS
)
{
return
ret
;
}
buf
->
write_2bytes
(
pre_defined0
);
buf
->
write_2bytes
(
reserved0
);
buf
->
write_4bytes
(
pre_defined1
[
0
]);
buf
->
write_4bytes
(
pre_defined1
[
1
]);
buf
->
write_4bytes
(
pre_defined1
[
2
]);
buf
->
write_2bytes
(
width
);
buf
->
write_2bytes
(
height
);
buf
->
write_4bytes
(
horizresolution
);
buf
->
write_4bytes
(
vertresolution
);
buf
->
write_4bytes
(
reserved1
);
buf
->
write_2bytes
(
frame_count
);
buf
->
write_bytes
(
compressorname
,
32
);
buf
->
write_2bytes
(
depth
);
buf
->
write_2bytes
(
pre_defined2
);
return
ret
;
}
int
SrsMp4VisualSampleEntry
::
decode_header
(
SrsBuffer
*
buf
)
{
int
ret
=
ERROR_SUCCESS
;
if
((
ret
=
SrsMp4SampleEntry
::
decode_header
(
buf
))
!=
ERROR_SUCCESS
)
{
return
ret
;
}
buf
->
skip
(
2
);
buf
->
skip
(
2
);
buf
->
skip
(
12
);
width
=
buf
->
read_2bytes
();
height
=
buf
->
read_2bytes
();
horizresolution
=
buf
->
read_4bytes
();
vertresolution
=
buf
->
read_4bytes
();
buf
->
skip
(
4
);
frame_count
=
buf
->
read_2bytes
();
buf
->
read_bytes
(
compressorname
,
32
);
depth
=
buf
->
read_2bytes
();
buf
->
skip
(
2
);
return
ret
;
}
SrsMp4AudioSampleEntry
::
SrsMp4AudioSampleEntry
()
{
memset
(
reserved0
,
0
,
8
)
;
reserved0
=
0
;
pre_defined0
=
0
;
reserved1
=
0
;
channelcount
=
2
;
...
...
@@ -315,17 +1590,134 @@ SrsMp4AudioSampleEntry::~SrsMp4AudioSampleEntry()
{
}
SrsMp4SampleDescriptionBox
::
SrsMp4SampleDescriptionBox
()
int
SrsMp4AudioSampleEntry
::
nb_header
()
{
return
SrsMp4SampleEntry
::
nb_header
()
+
8
+
2
+
2
+
2
+
2
+
4
;
}
int
SrsMp4AudioSampleEntry
::
encode_header
(
SrsBuffer
*
buf
)
{
type
=
0x73747364
;
// 'stsd'
int
ret
=
ERROR_SUCCESS
;
entry_count
=
0
;
entries
=
NULL
;
if
((
ret
=
SrsMp4SampleEntry
::
encode_header
(
buf
))
!=
ERROR_SUCCESS
)
{
return
ret
;
}
buf
->
write_8bytes
(
reserved0
);
buf
->
write_2bytes
(
channelcount
);
buf
->
write_2bytes
(
samplesize
);
buf
->
write_2bytes
(
pre_defined0
);
buf
->
write_2bytes
(
reserved1
);
buf
->
write_4bytes
(
samplerate
);
return
ret
;
}
int
SrsMp4AudioSampleEntry
::
decode_header
(
SrsBuffer
*
buf
)
{
int
ret
=
ERROR_SUCCESS
;
if
((
ret
=
SrsMp4SampleEntry
::
decode_header
(
buf
))
!=
ERROR_SUCCESS
)
{
return
ret
;
}
buf
->
skip
(
8
);
channelcount
=
buf
->
read_2bytes
();
samplesize
=
buf
->
read_2bytes
();
buf
->
skip
(
2
);
buf
->
skip
(
2
);
samplerate
=
buf
->
read_4bytes
();
return
ret
;
}
SrsMp4SampleDescriptionBox
::
SrsMp4SampleDescriptionBox
()
{
type
=
SRS_MP4_BOX_STSD
;
}
SrsMp4SampleDescriptionBox
::~
SrsMp4SampleDescriptionBox
()
{
srs_freepa
(
entries
);
vector
<
SrsMp4SampleEntry
*>::
iterator
it
;
for
(
it
=
entries
.
begin
();
it
!=
entries
.
end
();
++
it
)
{
SrsMp4SampleEntry
*
entry
=
*
it
;
srs_freep
(
entry
);
}
entries
.
clear
();
}
uint32_t
SrsMp4SampleDescriptionBox
::
entry_count
()
{
return
(
uint32_t
)
entries
.
size
();
}
SrsMp4SampleEntry
*
SrsMp4SampleDescriptionBox
::
entrie_at
(
int
index
)
{
return
entries
.
at
(
index
);
}
int
SrsMp4SampleDescriptionBox
::
nb_header
()
{
int
size
=
SrsMp4FullBox
::
nb_header
();
vector
<
SrsMp4SampleEntry
*>::
iterator
it
;
for
(
it
=
entries
.
begin
();
it
!=
entries
.
end
();
++
it
)
{
SrsMp4SampleEntry
*
entry
=
*
it
;
size
+=
entry
->
nb_bytes
();
}
return
size
;
}
int
SrsMp4SampleDescriptionBox
::
encode_header
(
SrsBuffer
*
buf
)
{
int
ret
=
ERROR_SUCCESS
;
if
((
ret
=
SrsMp4FullBox
::
encode_header
(
buf
))
!=
ERROR_SUCCESS
)
{
return
ret
;
}
vector
<
SrsMp4SampleEntry
*>::
iterator
it
;
for
(
it
=
entries
.
begin
();
it
!=
entries
.
end
();
++
it
)
{
SrsMp4SampleEntry
*
entry
=
*
it
;
if
((
ret
=
entry
->
encode
(
buf
))
!=
ERROR_SUCCESS
)
{
return
ret
;
}
}
return
ret
;
}
int
SrsMp4SampleDescriptionBox
::
decode_header
(
SrsBuffer
*
buf
)
{
int
ret
=
ERROR_SUCCESS
;
if
((
ret
=
SrsMp4FullBox
::
decode_header
(
buf
))
!=
ERROR_SUCCESS
)
{
return
ret
;
}
int
left
=
left_space
(
buf
);
while
(
left
>
0
)
{
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
)
{
entries
.
push_back
(
entry
);
}
else
{
srs_freep
(
box
);
}
}
return
ret
;
}
SrsMp4SttsEntry
::
SrsMp4SttsEntry
()
...
...
@@ -336,7 +1728,7 @@ SrsMp4SttsEntry::SrsMp4SttsEntry()
SrsMp4DecodingTime2SampleBox
::
SrsMp4DecodingTime2SampleBox
()
{
type
=
0x73747473
;
// 'stts'
type
=
SRS_MP4_BOX_STTS
;
entry_count
=
0
;
entries
=
NULL
;
...
...
@@ -347,6 +1739,33 @@ SrsMp4DecodingTime2SampleBox::~SrsMp4DecodingTime2SampleBox()
srs_freepa
(
entries
);
}
int
SrsMp4DecodingTime2SampleBox
::
nb_header
()
{
return
SrsMp4FullBox
::
nb_header
();
}
int
SrsMp4DecodingTime2SampleBox
::
encode_header
(
SrsBuffer
*
buf
)
{
int
ret
=
ERROR_SUCCESS
;
if
((
ret
=
SrsMp4FullBox
::
encode_header
(
buf
))
!=
ERROR_SUCCESS
)
{
return
ret
;
}
return
ret
;
}
int
SrsMp4DecodingTime2SampleBox
::
decode_header
(
SrsBuffer
*
buf
)
{
int
ret
=
ERROR_SUCCESS
;
if
((
ret
=
SrsMp4FullBox
::
decode_header
(
buf
))
!=
ERROR_SUCCESS
)
{
return
ret
;
}
return
ret
;
}
SrsMp4CttsEntry
::
SrsMp4CttsEntry
()
{
sample_count
=
0
;
...
...
@@ -355,7 +1774,7 @@ SrsMp4CttsEntry::SrsMp4CttsEntry()
SrsMp4CompositionTime2SampleBox
::
SrsMp4CompositionTime2SampleBox
()
{
type
=
0x63747473
;
// 'ctts'
type
=
SRS_MP4_BOX_CTTS
;
entry_count
=
0
;
entries
=
NULL
;
...
...
@@ -366,9 +1785,36 @@ SrsMp4CompositionTime2SampleBox::~SrsMp4CompositionTime2SampleBox()
srs_freepa
(
entries
);
}
int
SrsMp4CompositionTime2SampleBox
::
nb_header
()
{
return
SrsMp4FullBox
::
nb_header
();
}
int
SrsMp4CompositionTime2SampleBox
::
encode_header
(
SrsBuffer
*
buf
)
{
int
ret
=
ERROR_SUCCESS
;
if
((
ret
=
SrsMp4FullBox
::
encode_header
(
buf
))
!=
ERROR_SUCCESS
)
{
return
ret
;
}
return
ret
;
}
int
SrsMp4CompositionTime2SampleBox
::
decode_header
(
SrsBuffer
*
buf
)
{
int
ret
=
ERROR_SUCCESS
;
if
((
ret
=
SrsMp4FullBox
::
decode_header
(
buf
))
!=
ERROR_SUCCESS
)
{
return
ret
;
}
return
ret
;
}
SrsMp4SyncSampleBox
::
SrsMp4SyncSampleBox
()
{
type
=
0x73747373
;
// 'stss'
type
=
SRS_MP4_BOX_STSS
;
entry_count
=
0
;
sample_numbers
=
NULL
;
...
...
@@ -379,6 +1825,33 @@ SrsMp4SyncSampleBox::~SrsMp4SyncSampleBox()
srs_freepa
(
sample_numbers
);
}
int
SrsMp4SyncSampleBox
::
nb_header
()
{
return
SrsMp4FullBox
::
nb_header
();
}
int
SrsMp4SyncSampleBox
::
encode_header
(
SrsBuffer
*
buf
)
{
int
ret
=
ERROR_SUCCESS
;
if
((
ret
=
SrsMp4FullBox
::
encode_header
(
buf
))
!=
ERROR_SUCCESS
)
{
return
ret
;
}
return
ret
;
}
int
SrsMp4SyncSampleBox
::
decode_header
(
SrsBuffer
*
buf
)
{
int
ret
=
ERROR_SUCCESS
;
if
((
ret
=
SrsMp4FullBox
::
decode_header
(
buf
))
!=
ERROR_SUCCESS
)
{
return
ret
;
}
return
ret
;
}
SrsMp4StscEntry
::
SrsMp4StscEntry
()
{
first_chunk
=
0
;
...
...
@@ -388,7 +1861,7 @@ SrsMp4StscEntry::SrsMp4StscEntry()
SrsMp4Sample2ChunkBox
::
SrsMp4Sample2ChunkBox
()
{
type
=
0x73747363
;
// 'stsc'
type
=
SRS_MP4_BOX_STSC
;
entry_count
=
0
;
entries
=
NULL
;
...
...
@@ -399,9 +1872,36 @@ SrsMp4Sample2ChunkBox::~SrsMp4Sample2ChunkBox()
srs_freepa
(
entries
);
}
int
SrsMp4Sample2ChunkBox
::
nb_header
()
{
return
SrsMp4FullBox
::
nb_header
();
}
int
SrsMp4Sample2ChunkBox
::
encode_header
(
SrsBuffer
*
buf
)
{
int
ret
=
ERROR_SUCCESS
;
if
((
ret
=
SrsMp4FullBox
::
encode_header
(
buf
))
!=
ERROR_SUCCESS
)
{
return
ret
;
}
return
ret
;
}
int
SrsMp4Sample2ChunkBox
::
decode_header
(
SrsBuffer
*
buf
)
{
int
ret
=
ERROR_SUCCESS
;
if
((
ret
=
SrsMp4FullBox
::
decode_header
(
buf
))
!=
ERROR_SUCCESS
)
{
return
ret
;
}
return
ret
;
}
SrsMp4ChunkOffsetBox
::
SrsMp4ChunkOffsetBox
()
{
type
=
0x7374636f
;
// 'stco'
type
=
SRS_MP4_BOX_STCO
;
entry_count
=
0
;
entries
=
NULL
;
...
...
@@ -412,9 +1912,36 @@ SrsMp4ChunkOffsetBox::~SrsMp4ChunkOffsetBox()
srs_freepa
(
entries
);
}
int
SrsMp4ChunkOffsetBox
::
nb_header
()
{
return
SrsMp4FullBox
::
nb_header
();
}
int
SrsMp4ChunkOffsetBox
::
encode_header
(
SrsBuffer
*
buf
)
{
int
ret
=
ERROR_SUCCESS
;
if
((
ret
=
SrsMp4FullBox
::
encode_header
(
buf
))
!=
ERROR_SUCCESS
)
{
return
ret
;
}
return
ret
;
}
int
SrsMp4ChunkOffsetBox
::
decode_header
(
SrsBuffer
*
buf
)
{
int
ret
=
ERROR_SUCCESS
;
if
((
ret
=
SrsMp4FullBox
::
decode_header
(
buf
))
!=
ERROR_SUCCESS
)
{
return
ret
;
}
return
ret
;
}
SrsMp4SampleSizeBox
::
SrsMp4SampleSizeBox
()
{
type
=
0x7374737a
;
// 'stsz'
type
=
SRS_MP4_BOX_STSZ
;
sample_size
=
sample_count
=
0
;
entry_sizes
=
NULL
;
...
...
@@ -425,12 +1952,44 @@ SrsMp4SampleSizeBox::~SrsMp4SampleSizeBox()
srs_freepa
(
entry_sizes
);
}
int
SrsMp4SampleSizeBox
::
nb_header
()
{
return
SrsMp4FullBox
::
nb_header
();
}
int
SrsMp4SampleSizeBox
::
encode_header
(
SrsBuffer
*
buf
)
{
int
ret
=
ERROR_SUCCESS
;
if
((
ret
=
SrsMp4FullBox
::
encode_header
(
buf
))
!=
ERROR_SUCCESS
)
{
return
ret
;
}
return
ret
;
}
int
SrsMp4SampleSizeBox
::
decode_header
(
SrsBuffer
*
buf
)
{
int
ret
=
ERROR_SUCCESS
;
if
((
ret
=
SrsMp4FullBox
::
decode_header
(
buf
))
!=
ERROR_SUCCESS
)
{
return
ret
;
}
return
ret
;
}
SrsMp4Decoder
::
SrsMp4Decoder
()
{
reader
=
NULL
;
next
=
NULL
;
stream
=
new
SrsSimpleStream
();
}
SrsMp4Decoder
::~
SrsMp4Decoder
()
{
srs_freep
(
next
);
srs_freep
(
stream
);
}
int
SrsMp4Decoder
::
initialize
(
ISrsReader
*
r
)
...
...
@@ -440,6 +1999,67 @@ int SrsMp4Decoder::initialize(ISrsReader* r)
srs_assert
(
r
);
reader
=
r
;
if
((
ret
=
load_next_box
(
&
next
))
!=
ERROR_SUCCESS
)
{
return
ret
;
}
if
(
next
->
type
!=
SRS_MP4_BOX_FTYP
)
{
ret
=
ERROR_MP4_BOX_ILLEGAL_SCHEMA
;
srs_error
(
"MP4 first box must be FTYP, not %d. ret=%d"
,
next
->
type
,
ret
);
return
ret
;
}
return
ret
;
}
int
SrsMp4Decoder
::
load_next_box
(
SrsMp4Box
**
ppbox
)
{
int
ret
=
ERROR_SUCCESS
;
// Ignore for already loaded.
if
(
next
)
{
return
ret
;
}
char
*
buf
=
new
char
[
4096
];
SrsAutoFreeA
(
char
,
buf
);
while
(
true
)
{
uint64_t
required
=
next
?
next
->
sz
()
:
4
;
while
(
stream
->
length
()
<
required
)
{
ssize_t
nread
;
if
((
ret
=
reader
->
read
(
buf
,
4096
,
&
nread
))
!=
ERROR_SUCCESS
)
{
srs_error
(
"MP4 load failed, nread=%d, required=%d. ret=%d"
,
nread
,
required
,
ret
);
return
ret
;
}
srs_assert
(
nread
>
0
);
stream
->
append
(
buf
,
(
int
)
nread
);
}
SrsBuffer
*
buffer
=
new
SrsBuffer
(
stream
->
bytes
(),
stream
->
length
());
SrsAutoFree
(
SrsBuffer
,
buffer
);
// Discovery the box with basic header.
if
(
!
next
&&
(
ret
=
SrsMp4Box
::
discovery
(
buffer
,
ppbox
))
!=
ERROR_SUCCESS
)
{
if
(
ret
==
ERROR_MP4_BOX_REQUIRE_SPACE
)
{
continue
;
}
srs_error
(
"MP4 load box failed. ret=%d"
,
ret
);
return
ret
;
}
// Decode util we can demux the whole box.
if
(
!
buffer
->
require
((
int
)
next
->
sz
()))
{
continue
;
}
ret
=
next
->
decode
(
buffer
);
// Remove the consumed bytes.
stream
->
erase
((
int
)
next
->
sz
());
break
;
}
return
ret
;
}
...
...
trunk/src/kernel/srs_kernel_mp4.hpp
查看文件 @
2ad265b
...
...
@@ -29,30 +29,77 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include <srs_core.hpp>
#include <srs_kernel_buffer.hpp>
#include <string>
#include <vector>
class
ISrsReader
;
class
SrsSimpleStream
;
/**
* 4.2 Object Structure
* ISO_IEC_14496-12-base-format-2012.pdf, page 16
*/
class
SrsMp4Box
class
SrsMp4Box
:
public
ISrsCodec
{
public
:
private
:
// The size is the entire size of the box, including the size and type header, fields,
// and all contained boxes. This facilitates general parsing of the file.
//
// if size is 1 then the actual size is in the field largesize;
// if size is 0, then this box is the last one in the file, and its contents
// extend to the end of the file (normally only used for a Media Data Box)
uint32_t
size
;
uint32_t
smallsize
;
uint64_t
largesize
;
public
:
// identifies the box type; standard boxes use a compact type, which is normally four printable
// characters, to permit ease of identification, and is shown so in the boxes below. User extensions use
// an extended type; in this case, the type field is set to ‘uuid’.
uint32_t
type
;
// For box 'uuid'.
uint8_t
*
usertype
;
private
:
std
::
vector
<
SrsMp4Box
*>
boxes
;
private
:
// The position at buffer to start demux the box.
int
start_pos
;
public
:
SrsMp4Box
();
virtual
~
SrsMp4Box
();
public
:
// Get the size of box, whatever small or large size.
virtual
uint64_t
sz
();
// Get the left space of box, for decoder.
virtual
int
left_space
(
SrsBuffer
*
buf
);
/**
* Discovery the box from buffer.
* @param ppbox Output the discoveried box, which user must free it.
*/
static
int
discovery
(
SrsBuffer
*
buf
,
SrsMp4Box
**
ppbox
);
// Interface ISrsCodec
public:
virtual
int
nb_bytes
();
virtual
int
encode
(
SrsBuffer
*
buf
);
virtual
int
decode
(
SrsBuffer
*
buf
);
protected
:
virtual
int
encode_boxes
(
SrsBuffer
*
buf
);
virtual
int
decode_boxes
(
SrsBuffer
*
buf
);
// Sub classes can override these functions for special codec.
protected:
// The size of header, not including the contained boxes.
virtual
int
nb_header
();
// It's not necessary to check the buffer, because we already know the size in parent function,
// so we have checked the buffer is ok to write.
virtual
int
encode_header
(
SrsBuffer
*
buf
);
// It's not necessary to check the buffer, unless the box is not only determined by the verson.
// Generally, it's not necessary, that is, all boxes is determinated by version.
virtual
int
decode_header
(
SrsBuffer
*
buf
);
};
/**
* 4.2 Object Structure
* ISO_IEC_14496-12-base-format-2012.pdf, page 1
6
* ISO_IEC_14496-12-base-format-2012.pdf, page 1
7
*/
class
SrsMp4FullBox
:
public
SrsMp4Box
{
...
...
@@ -64,6 +111,10 @@ public:
public
:
SrsMp4FullBox
();
virtual
~
SrsMp4FullBox
();
protected
:
virtual
int
nb_header
();
virtual
int
encode_header
(
SrsBuffer
*
buf
);
virtual
int
decode_header
(
SrsBuffer
*
buf
);
};
/**
...
...
@@ -88,6 +139,10 @@ private:
public
:
SrsMp4FileTypeBox
();
virtual
~
SrsMp4FileTypeBox
();
protected
:
virtual
int
nb_header
();
virtual
int
encode_header
(
SrsBuffer
*
buf
);
virtual
int
decode_header
(
SrsBuffer
*
buf
);
};
/**
...
...
@@ -101,11 +156,16 @@ public:
class
SrsMp4MediaDataBox
:
public
SrsMp4Box
{
private
:
// the contained media data
int
nb_data
;
uint8_t
*
data
;
public
:
SrsMp4MediaDataBox
();
virtual
~
SrsMp4MediaDataBox
();
protected
:
virtual
int
nb_header
();
virtual
int
encode_header
(
SrsBuffer
*
buf
);
virtual
int
decode_header
(
SrsBuffer
*
buf
);
};
/**
...
...
@@ -114,9 +174,16 @@ public:
*/
class
SrsMp4FreeSpaceBox
:
public
SrsMp4Box
{
private
:
int
nb_data
;
uint8_t
*
data
;
public
:
SrsMp4FreeSpaceBox
();
virtual
~
SrsMp4FreeSpaceBox
();
protected
:
virtual
int
nb_header
();
virtual
int
encode_header
(
SrsBuffer
*
buf
);
virtual
int
decode_header
(
SrsBuffer
*
buf
);
};
/**
...
...
@@ -172,6 +239,10 @@ public:
public
:
SrsMp4MovieHeaderBox
();
virtual
~
SrsMp4MovieHeaderBox
();
protected
:
virtual
int
nb_header
();
virtual
int
encode_header
(
SrsBuffer
*
buf
);
virtual
int
decode_header
(
SrsBuffer
*
buf
);
};
/**
...
...
@@ -201,10 +272,6 @@ public:
// an integer that declares the most recent time the presentation was modified (in
// seconds since midnight, Jan. 1, 1904, in UTC time)
uint64_t
modification_time
;
// an integer that specifies the time-scale for the entire presentation; this is the number of
// time units that pass in one second. For example, a time coordinate system that measures time in
// sixtieths of a second has a time scale of 60.
uint32_t
timescale
;
// an integer that uniquely identifies this track over the entire life-time of this presentation.
// Track IDs are never re-used and cannot be zero.
uint32_t
track_ID
;
...
...
@@ -244,6 +311,10 @@ public:
public
:
SrsMp4TrackHeaderBox
();
virtual
~
SrsMp4TrackHeaderBox
();
protected
:
virtual
int
nb_header
();
virtual
int
encode_header
(
SrsBuffer
*
buf
);
virtual
int
decode_header
(
SrsBuffer
*
buf
);
};
/**
...
...
@@ -282,6 +353,10 @@ public:
int16_t
media_rate_fraction
;
public
:
SrsMp4ElstEntry
();
public
:
virtual
int
nb_header
(
uint32_t
version
);
virtual
int
encode_header
(
SrsBuffer
*
buf
,
uint32_t
version
);
virtual
int
decode_header
(
SrsBuffer
*
buf
,
uint32_t
version
);
};
/**
...
...
@@ -300,6 +375,10 @@ public:
public
:
SrsMp4EditListBox
();
virtual
~
SrsMp4EditListBox
();
protected
:
virtual
int
nb_header
();
virtual
int
encode_header
(
SrsBuffer
*
buf
);
virtual
int
decode_header
(
SrsBuffer
*
buf
);
};
/**
...
...
@@ -338,16 +417,29 @@ public:
// is derived from the presentation’s tracks: the value of this field corresponds to the duration of the
// longest track in the presentation. If the duration cannot be determined then duration is set to all 1s.
uint64_t
duration
;
public
:
uint8_t
pad
:
1
;
private
:
// the language code for this media. See ISO 639-2/T for the set of three character
// codes. Each character is packed as the difference between its ASCII value and 0x60. Since the code
// is confined to being three lower-case letters, these values are strictly positive.
uint16_t
language
:
15
;
uint16_t
language
;
uint16_t
pre_defined
;
public
:
SrsMp4MediaHeaderBox
();
virtual
~
SrsMp4MediaHeaderBox
();
public
:
// the language code for this media. See ISO 639-2/T for the set of three character
// codes. Each character is packed as the difference between its ASCII value and 0x60. Since the code
// is confined to being three lower-case letters, these values are strictly positive.
virtual
uint8_t
language0
();
virtual
void
set_language0
(
uint8_t
v
);
virtual
uint8_t
language1
();
virtual
void
set_language1
(
uint8_t
v
);
virtual
uint8_t
language2
();
virtual
void
set_language2
(
uint8_t
v
);
protected
:
virtual
int
nb_header
();
virtual
int
encode_header
(
SrsBuffer
*
buf
);
virtual
int
decode_header
(
SrsBuffer
*
buf
);
};
/**
...
...
@@ -371,6 +463,10 @@ public:
public
:
SrsMp4HandlerReferenceBox
();
virtual
~
SrsMp4HandlerReferenceBox
();
protected
:
virtual
int
nb_header
();
virtual
int
encode_header
(
SrsBuffer
*
buf
);
virtual
int
decode_header
(
SrsBuffer
*
buf
);
};
/**
...
...
@@ -403,6 +499,10 @@ public:
public
:
SrsMp4VideoMeidaHeaderBox
();
virtual
~
SrsMp4VideoMeidaHeaderBox
();
protected
:
virtual
int
nb_header
();
virtual
int
encode_header
(
SrsBuffer
*
buf
);
virtual
int
decode_header
(
SrsBuffer
*
buf
);
};
/**
...
...
@@ -421,6 +521,10 @@ public:
public
:
SrsMp4SoundMeidaHeaderBox
();
virtual
~
SrsMp4SoundMeidaHeaderBox
();
protected
:
virtual
int
nb_header
();
virtual
int
encode_header
(
SrsBuffer
*
buf
);
virtual
int
decode_header
(
SrsBuffer
*
buf
);
};
/**
...
...
@@ -445,6 +549,11 @@ public:
std
::
string
location
;
public
:
SrsMp4DataEntryBox
();
virtual
~
SrsMp4DataEntryBox
();
protected
:
virtual
int
nb_header
();
virtual
int
encode_header
(
SrsBuffer
*
buf
);
virtual
int
decode_header
(
SrsBuffer
*
buf
);
};
/**
...
...
@@ -455,6 +564,7 @@ class SrsMp4DataEntryUrlBox : public SrsMp4DataEntryBox
{
public
:
SrsMp4DataEntryUrlBox
();
virtual
~
SrsMp4DataEntryUrlBox
();
};
/**
...
...
@@ -467,6 +577,11 @@ public:
std
::
string
name
;
public
:
SrsMp4DataEntryUrnBox
();
virtual
~
SrsMp4DataEntryUrnBox
();
protected
:
virtual
int
nb_header
();
virtual
int
encode_header
(
SrsBuffer
*
buf
);
virtual
int
decode_header
(
SrsBuffer
*
buf
);
};
/**
...
...
@@ -478,13 +593,18 @@ public:
*/
class
SrsMp4DataReferenceBox
:
public
SrsMp4FullBox
{
public
:
// an integer that counts the actual entries
uint32_t
entry_count
;
SrsMp4DataEntryBox
*
entries
;
private
:
std
::
vector
<
SrsMp4DataEntryBox
*>
entries
;
public
:
SrsMp4DataReferenceBox
();
virtual
~
SrsMp4DataReferenceBox
();
public
:
virtual
uint32_t
entry_count
();
virtual
SrsMp4DataEntryBox
*
entry_at
(
int
index
);
protected
:
virtual
int
nb_header
();
virtual
int
encode_header
(
SrsBuffer
*
buf
);
virtual
int
decode_header
(
SrsBuffer
*
buf
);
};
/**
...
...
@@ -516,6 +636,10 @@ public:
public
:
SrsMp4SampleEntry
();
virtual
~
SrsMp4SampleEntry
();
protected
:
virtual
int
nb_header
();
virtual
int
encode_header
(
SrsBuffer
*
buf
);
virtual
int
decode_header
(
SrsBuffer
*
buf
);
};
/**
...
...
@@ -549,6 +673,10 @@ public:
public
:
SrsMp4VisualSampleEntry
();
virtual
~
SrsMp4VisualSampleEntry
();
protected
:
virtual
int
nb_header
();
virtual
int
encode_header
(
SrsBuffer
*
buf
);
virtual
int
decode_header
(
SrsBuffer
*
buf
);
};
/**
...
...
@@ -558,7 +686,7 @@ public:
class
SrsMp4AudioSampleEntry
:
public
SrsMp4SampleEntry
{
public
:
uint
32_t
reserved0
[
2
]
;
uint
64_t
reserved0
;
uint16_t
channelcount
;
uint16_t
samplesize
;
uint16_t
pre_defined0
;
...
...
@@ -567,6 +695,10 @@ public:
public
:
SrsMp4AudioSampleEntry
();
virtual
~
SrsMp4AudioSampleEntry
();
protected
:
virtual
int
nb_header
();
virtual
int
encode_header
(
SrsBuffer
*
buf
);
virtual
int
decode_header
(
SrsBuffer
*
buf
);
};
/**
...
...
@@ -577,13 +709,18 @@ public:
*/
class
SrsMp4SampleDescriptionBox
:
public
SrsMp4FullBox
{
public
:
// an integer that gives the number of entries in the following table
uint32_t
entry_count
;
SrsMp4SampleEntry
*
entries
;
private
:
std
::
vector
<
SrsMp4SampleEntry
*>
entries
;
public
:
SrsMp4SampleDescriptionBox
();
virtual
~
SrsMp4SampleDescriptionBox
();
public
:
virtual
uint32_t
entry_count
();
virtual
SrsMp4SampleEntry
*
entrie_at
(
int
index
);
protected
:
virtual
int
nb_header
();
virtual
int
encode_header
(
SrsBuffer
*
buf
);
virtual
int
decode_header
(
SrsBuffer
*
buf
);
};
/**
...
...
@@ -618,6 +755,10 @@ public:
public
:
SrsMp4DecodingTime2SampleBox
();
virtual
~
SrsMp4DecodingTime2SampleBox
();
protected
:
virtual
int
nb_header
();
virtual
int
encode_header
(
SrsBuffer
*
buf
);
virtual
int
decode_header
(
SrsBuffer
*
buf
);
};
...
...
@@ -657,6 +798,10 @@ public:
public
:
SrsMp4CompositionTime2SampleBox
();
virtual
~
SrsMp4CompositionTime2SampleBox
();
protected
:
virtual
int
nb_header
();
virtual
int
encode_header
(
SrsBuffer
*
buf
);
virtual
int
decode_header
(
SrsBuffer
*
buf
);
};
/**
...
...
@@ -676,6 +821,10 @@ public:
public
:
SrsMp4SyncSampleBox
();
virtual
~
SrsMp4SyncSampleBox
();
protected
:
virtual
int
nb_header
();
virtual
int
encode_header
(
SrsBuffer
*
buf
);
virtual
int
decode_header
(
SrsBuffer
*
buf
);
};
/**
...
...
@@ -716,6 +865,10 @@ public:
public
:
SrsMp4Sample2ChunkBox
();
virtual
~
SrsMp4Sample2ChunkBox
();
protected
:
virtual
int
nb_header
();
virtual
int
encode_header
(
SrsBuffer
*
buf
);
virtual
int
decode_header
(
SrsBuffer
*
buf
);
};
/**
...
...
@@ -736,6 +889,10 @@ public:
public
:
SrsMp4ChunkOffsetBox
();
virtual
~
SrsMp4ChunkOffsetBox
();
protected
:
virtual
int
nb_header
();
virtual
int
encode_header
(
SrsBuffer
*
buf
);
virtual
int
decode_header
(
SrsBuffer
*
buf
);
};
/**
...
...
@@ -760,6 +917,10 @@ public:
public
:
SrsMp4SampleSizeBox
();
virtual
~
SrsMp4SampleSizeBox
();
protected
:
virtual
int
nb_header
();
virtual
int
encode_header
(
SrsBuffer
*
buf
);
virtual
int
decode_header
(
SrsBuffer
*
buf
);
};
/**
...
...
@@ -768,7 +929,13 @@ public:
class
SrsMp4Decoder
{
private
:
// Underlayer reader.
ISrsReader
*
reader
;
// The stream used to demux the boxes.
// TODO: FIXME: refine for performance issue.
SrsSimpleStream
*
stream
;
// Always load next box.
SrsMp4Box
*
next
;
public
:
SrsMp4Decoder
();
virtual
~
SrsMp4Decoder
();
...
...
@@ -779,6 +946,8 @@ public:
* the decoder just read data from the reader.
*/
virtual
int
initialize
(
ISrsReader
*
r
);
private
:
virtual
int
load_next_box
(
SrsMp4Box
**
ppbox
);
};
#endif
...
...
请
注册
或
登录
后发表评论