Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Contribute to GitLab
Sign in / Register
Toggle navigation
F
ffmpeg.wasm-core
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Linshizhi
ffmpeg.wasm-core
Commits
ca65932b
Commit
ca65932b
authored
Oct 11, 2011
by
Alex Converse
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
mpegts: MP4 SL support
parent
c5302670
Show whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
157 additions
and
21 deletions
+157
-21
isom.h
libavformat/isom.h
+1
-0
mpegts.c
libavformat/mpegts.c
+138
-21
mpegts.h
libavformat/mpegts.h
+18
-0
No files found.
libavformat/isom.h
View file @
ca65932b
...
...
@@ -153,6 +153,7 @@ void ff_mp4_parse_es_descr(AVIOContext *pb, int *es_id);
#define MP4ESDescrTag 0x03
#define MP4DecConfigDescrTag 0x04
#define MP4DecSpecificDescrTag 0x05
#define MP4SLDescrTag 0x06
int
ff_mov_read_esds
(
AVFormatContext
*
fc
,
AVIOContext
*
pb
,
MOVAtom
atom
);
enum
CodecID
ff_mov_get_lpcm_codec_id
(
int
bps
,
int
flags
);
...
...
libavformat/mpegts.c
View file @
ca65932b
...
...
@@ -28,6 +28,7 @@
#include "libavutil/mathematics.h"
#include "libavutil/opt.h"
#include "libavcodec/bytestream.h"
#include "libavcodec/get_bits.h"
#include "avformat.h"
#include "mpegts.h"
#include "internal.h"
...
...
@@ -175,6 +176,7 @@ typedef struct PESContext {
int64_t
ts_packet_pos
;
/**< position of first TS packet of this PES packet */
uint8_t
header
[
MAX_PES_HEADER_SIZE
];
uint8_t
*
buffer
;
SLConfigDescr
sl
;
}
PESContext
;
extern
AVInputFormat
ff_mpegts_demuxer
;
...
...
@@ -658,6 +660,83 @@ static void new_pes_packet(PESContext *pes, AVPacket *pkt)
pes
->
flags
=
0
;
}
static
uint64_t
get_bits64
(
GetBitContext
*
gb
,
int
bits
)
{
uint64_t
ret
=
0
;
while
(
bits
>
17
)
{
ret
<<=
17
;
ret
|=
get_bits
(
gb
,
17
);
bits
-=
17
;
}
ret
<<=
bits
;
ret
|=
get_bits
(
gb
,
bits
);
return
ret
;
}
static
int
read_sl_header
(
PESContext
*
pes
,
SLConfigDescr
*
sl
,
const
uint8_t
*
buf
,
int
buf_size
)
{
GetBitContext
gb
;
int
au_start_flag
=
0
,
au_end_flag
=
0
,
ocr_flag
=
0
,
idle_flag
=
0
;
int
padding_flag
=
0
,
padding_bits
=
0
,
inst_bitrate_flag
=
0
;
int
dts_flag
=
-
1
,
cts_flag
=
-
1
;
int64_t
dts
=
AV_NOPTS_VALUE
,
cts
=
AV_NOPTS_VALUE
;
init_get_bits
(
&
gb
,
buf
,
buf_size
*
8
);
if
(
sl
->
use_au_start
)
au_start_flag
=
get_bits1
(
&
gb
);
if
(
sl
->
use_au_end
)
au_end_flag
=
get_bits1
(
&
gb
);
if
(
!
sl
->
use_au_start
&&
!
sl
->
use_au_end
)
au_start_flag
=
au_end_flag
=
1
;
if
(
sl
->
ocr_len
>
0
)
ocr_flag
=
get_bits1
(
&
gb
);
if
(
sl
->
use_idle
)
idle_flag
=
get_bits1
(
&
gb
);
if
(
sl
->
use_padding
)
padding_flag
=
get_bits1
(
&
gb
);
if
(
padding_flag
)
padding_bits
=
get_bits
(
&
gb
,
3
);
if
(
!
idle_flag
&&
(
!
padding_flag
||
padding_bits
!=
0
))
{
if
(
sl
->
packet_seq_num_len
)
skip_bits_long
(
&
gb
,
sl
->
packet_seq_num_len
);
if
(
sl
->
degr_prior_len
)
if
(
get_bits1
(
&
gb
))
skip_bits
(
&
gb
,
sl
->
degr_prior_len
);
if
(
ocr_flag
)
skip_bits_long
(
&
gb
,
sl
->
ocr_len
);
if
(
au_start_flag
)
{
if
(
sl
->
use_rand_acc_pt
)
get_bits1
(
&
gb
);
if
(
sl
->
au_seq_num_len
>
0
)
skip_bits_long
(
&
gb
,
sl
->
au_seq_num_len
);
if
(
sl
->
use_timestamps
)
{
dts_flag
=
get_bits1
(
&
gb
);
cts_flag
=
get_bits1
(
&
gb
);
}
}
if
(
sl
->
inst_bitrate_len
)
inst_bitrate_flag
=
get_bits1
(
&
gb
);
if
(
dts_flag
==
1
)
dts
=
get_bits64
(
&
gb
,
sl
->
timestamp_len
);
if
(
cts_flag
==
1
)
cts
=
get_bits64
(
&
gb
,
sl
->
timestamp_len
);
if
(
sl
->
au_len
>
0
)
skip_bits_long
(
&
gb
,
sl
->
au_len
);
if
(
inst_bitrate_flag
)
skip_bits_long
(
&
gb
,
sl
->
inst_bitrate_len
);
}
if
(
dts
!=
AV_NOPTS_VALUE
)
pes
->
dts
=
dts
;
if
(
cts
!=
AV_NOPTS_VALUE
)
pes
->
pts
=
cts
;
av_set_pts_info
(
pes
->
st
,
sl
->
timestamp_len
,
1
,
sl
->
timestamp_res
);
return
(
get_bits_count
(
&
gb
)
+
7
)
>>
3
;
}
/* return non zero if a packet could be constructed */
static
int
mpegts_push_data
(
MpegTSFilter
*
filter
,
const
uint8_t
*
buf
,
int
buf_size
,
int
is_start
,
...
...
@@ -809,6 +888,12 @@ static int mpegts_push_data(MpegTSFilter *filter,
/* we got the full header. We parse it and get the payload */
pes
->
state
=
MPEGTS_PAYLOAD
;
pes
->
data_index
=
0
;
if
(
pes
->
stream_type
==
0x12
)
{
int
sl_header_bytes
=
read_sl_header
(
pes
,
&
pes
->
sl
,
p
,
buf_size
);
pes
->
pes_header_size
+=
sl_header_bytes
;
p
+=
sl_header_bytes
;
buf_size
-=
sl_header_bytes
;
}
}
break
;
case
MPEGTS_PAYLOAD
:
...
...
@@ -962,7 +1047,9 @@ static int parse_MP4ESDescrTag(MP4DescrParseContext *d, int64_t off, int len)
d
->
active_descr
->
es_id
=
es_id
;
update_offsets
(
&
d
->
pb
,
&
off
,
&
len
);
parse_mp4_descr
(
d
,
off
,
len
,
MP4DecConfigDescrTag
);
//SLConfigDescriptor
update_offsets
(
&
d
->
pb
,
&
off
,
&
len
);
if
(
len
>
0
)
parse_mp4_descr
(
d
,
off
,
len
,
MP4SLDescrTag
);
d
->
active_descr
=
NULL
;
return
0
;
}
...
...
@@ -980,6 +1067,39 @@ static int parse_MP4DecConfigDescrTag(MP4DescrParseContext *d, int64_t off, int
return
0
;
}
static
int
parse_MP4SLDescrTag
(
MP4DescrParseContext
*
d
,
int64_t
off
,
int
len
)
{
Mp4Descr
*
descr
=
d
->
active_descr
;
int
predefined
;
if
(
!
descr
)
return
-
1
;
predefined
=
avio_r8
(
&
d
->
pb
);
if
(
!
predefined
)
{
int
lengths
;
int
flags
=
avio_r8
(
&
d
->
pb
);
descr
->
sl
.
use_au_start
=
!!
(
flags
&
0x80
);
descr
->
sl
.
use_au_end
=
!!
(
flags
&
0x40
);
descr
->
sl
.
use_rand_acc_pt
=
!!
(
flags
&
0x20
);
descr
->
sl
.
use_padding
=
!!
(
flags
&
0x08
);
descr
->
sl
.
use_timestamps
=
!!
(
flags
&
0x04
);
descr
->
sl
.
use_idle
=
!!
(
flags
&
0x02
);
descr
->
sl
.
timestamp_res
=
avio_rb32
(
&
d
->
pb
);
avio_rb32
(
&
d
->
pb
);
descr
->
sl
.
timestamp_len
=
avio_r8
(
&
d
->
pb
);
descr
->
sl
.
ocr_len
=
avio_r8
(
&
d
->
pb
);
descr
->
sl
.
au_len
=
avio_r8
(
&
d
->
pb
);
descr
->
sl
.
inst_bitrate_len
=
avio_r8
(
&
d
->
pb
);
lengths
=
avio_rb16
(
&
d
->
pb
);
descr
->
sl
.
degr_prior_len
=
lengths
>>
12
;
descr
->
sl
.
au_seq_num_len
=
(
lengths
>>
7
)
&
0x1f
;
descr
->
sl
.
packet_seq_num_len
=
(
lengths
>>
2
)
&
0x1f
;
}
else
{
av_log_missing_feature
(
d
->
s
,
"Predefined SLConfigDescriptor
\n
"
,
0
);
}
return
0
;
}
static
int
parse_mp4_descr
(
MP4DescrParseContext
*
d
,
int64_t
off
,
int
len
,
int
target_tag
)
{
int
tag
;
...
...
@@ -1013,6 +1133,9 @@ static int parse_mp4_descr(MP4DescrParseContext *d, int64_t off, int len,
case
MP4DecConfigDescrTag
:
parse_MP4DecConfigDescrTag
(
d
,
off
,
len1
);
break
;
case
MP4SLDescrTag
:
parse_MP4SLDescrTag
(
d
,
off
,
len1
);
break
;
}
done:
...
...
@@ -1047,12 +1170,23 @@ static int mp4_read_od(AVFormatContext *s, const uint8_t *buf, unsigned size,
return
0
;
}
static
void
SL_packet
(
AVFormatContext
*
s
,
MpegTSContext
*
ts
,
const
uint8_t
*
p
,
const
uint8_t
*
p_end
)
static
void
m4sl_cb
(
MpegTSFilter
*
filter
,
const
uint8_t
*
section
,
int
section_len
)
{
MpegTSContext
*
ts
=
filter
->
u
.
section_filter
.
opaque
;
SectionHeader
h
;
const
uint8_t
*
p
,
*
p_end
;
AVIOContext
pb
;
Mp4Descr
mp4_descr
[
MAX_MP4_DESCR_COUNT
]
=
{{
0
}};
int
mp4_descr_count
=
0
;
int
i
,
pid
;
AVFormatContext
*
s
=
ts
->
stream
;
p_end
=
section
+
section_len
-
4
;
p
=
section
;
if
(
parse_section_header
(
&
h
,
&
p
,
p_end
)
<
0
)
return
;
if
(
h
.
tid
!=
M4OD_TID
)
return
;
mp4_read_od
(
s
,
p
,
(
unsigned
)(
p_end
-
p
),
mp4_descr
,
&
mp4_descr_count
,
MAX_MP4_DESCR_COUNT
);
...
...
@@ -1074,6 +1208,8 @@ static void SL_packet(AVFormatContext *s, MpegTSContext *ts, const uint8_t *p, c
continue
;
}
pes
->
sl
=
mp4_descr
[
i
].
sl
;
ffio_init_context
(
&
pb
,
mp4_descr
[
i
].
dec_config_descr
,
mp4_descr
[
i
].
dec_config_descr_len
,
0
,
NULL
,
NULL
,
NULL
,
NULL
);
ff_mp4_read_dec_config_descr
(
s
,
st
,
&
pb
);
...
...
@@ -1098,25 +1234,6 @@ static void SL_packet(AVFormatContext *s, MpegTSContext *ts, const uint8_t *p, c
av_free
(
mp4_descr
[
i
].
dec_config_descr
);
}
static
void
m4sl_cb
(
MpegTSFilter
*
filter
,
const
uint8_t
*
section
,
int
section_len
)
{
MpegTSContext
*
ts
=
filter
->
u
.
section_filter
.
opaque
;
SectionHeader
h1
,
*
h
=
&
h1
;
const
uint8_t
*
p
,
*
p_end
;
av_dlog
(
ts
->
stream
,
"m4SL/od:
\n
"
);
hex_dump_debug
(
ts
->
stream
,
(
uint8_t
*
)
section
,
section_len
);
p_end
=
section
+
section_len
-
4
;
p
=
section
;
if
(
parse_section_header
(
h
,
&
p
,
p_end
)
<
0
)
return
;
if
(
h
->
tid
!=
M4OD_TID
)
return
;
SL_packet
(
ts
->
stream
,
ts
,
p
,
p_end
);
}
int
ff_parse_mpeg2_descriptor
(
AVFormatContext
*
fc
,
AVStream
*
st
,
int
stream_type
,
const
uint8_t
**
pp
,
const
uint8_t
*
desc_list_end
,
Mp4Descr
*
mp4_descr
,
int
mp4_descr_count
,
int
pid
,
...
...
libavformat/mpegts.h
View file @
ca65932b
...
...
@@ -65,10 +65,28 @@ int ff_mpegts_parse_packet(MpegTSContext *ts, AVPacket *pkt,
const
uint8_t
*
buf
,
int
len
);
void
ff_mpegts_parse_close
(
MpegTSContext
*
ts
);
typedef
struct
{
int
use_au_start
;
int
use_au_end
;
int
use_rand_acc_pt
;
int
use_padding
;
int
use_timestamps
;
int
use_idle
;
int
timestamp_res
;
int
timestamp_len
;
int
ocr_len
;
int
au_len
;
int
inst_bitrate_len
;
int
degr_prior_len
;
int
au_seq_num_len
;
int
packet_seq_num_len
;
}
SLConfigDescr
;
typedef
struct
{
int
es_id
;
int
dec_config_descr_len
;
uint8_t
*
dec_config_descr
;
SLConfigDescr
sl
;
}
Mp4Descr
;
/**
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment