Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in / Register
Toggle navigation
F
ffmpeg
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
Packages
Packages
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
submodule
ffmpeg
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
Hide 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);
...
@@ -153,6 +153,7 @@ void ff_mp4_parse_es_descr(AVIOContext *pb, int *es_id);
#define MP4ESDescrTag 0x03
#define MP4ESDescrTag 0x03
#define MP4DecConfigDescrTag 0x04
#define MP4DecConfigDescrTag 0x04
#define MP4DecSpecificDescrTag 0x05
#define MP4DecSpecificDescrTag 0x05
#define MP4SLDescrTag 0x06
int
ff_mov_read_esds
(
AVFormatContext
*
fc
,
AVIOContext
*
pb
,
MOVAtom
atom
);
int
ff_mov_read_esds
(
AVFormatContext
*
fc
,
AVIOContext
*
pb
,
MOVAtom
atom
);
enum
CodecID
ff_mov_get_lpcm_codec_id
(
int
bps
,
int
flags
);
enum
CodecID
ff_mov_get_lpcm_codec_id
(
int
bps
,
int
flags
);
...
...
libavformat/mpegts.c
View file @
ca65932b
...
@@ -28,6 +28,7 @@
...
@@ -28,6 +28,7 @@
#include "libavutil/mathematics.h"
#include "libavutil/mathematics.h"
#include "libavutil/opt.h"
#include "libavutil/opt.h"
#include "libavcodec/bytestream.h"
#include "libavcodec/bytestream.h"
#include "libavcodec/get_bits.h"
#include "avformat.h"
#include "avformat.h"
#include "mpegts.h"
#include "mpegts.h"
#include "internal.h"
#include "internal.h"
...
@@ -175,6 +176,7 @@ typedef struct PESContext {
...
@@ -175,6 +176,7 @@ typedef struct PESContext {
int64_t
ts_packet_pos
;
/**< position of first TS packet of this PES packet */
int64_t
ts_packet_pos
;
/**< position of first TS packet of this PES packet */
uint8_t
header
[
MAX_PES_HEADER_SIZE
];
uint8_t
header
[
MAX_PES_HEADER_SIZE
];
uint8_t
*
buffer
;
uint8_t
*
buffer
;
SLConfigDescr
sl
;
}
PESContext
;
}
PESContext
;
extern
AVInputFormat
ff_mpegts_demuxer
;
extern
AVInputFormat
ff_mpegts_demuxer
;
...
@@ -658,6 +660,83 @@ static void new_pes_packet(PESContext *pes, AVPacket *pkt)
...
@@ -658,6 +660,83 @@ static void new_pes_packet(PESContext *pes, AVPacket *pkt)
pes
->
flags
=
0
;
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 */
/* return non zero if a packet could be constructed */
static
int
mpegts_push_data
(
MpegTSFilter
*
filter
,
static
int
mpegts_push_data
(
MpegTSFilter
*
filter
,
const
uint8_t
*
buf
,
int
buf_size
,
int
is_start
,
const
uint8_t
*
buf
,
int
buf_size
,
int
is_start
,
...
@@ -809,6 +888,12 @@ static int mpegts_push_data(MpegTSFilter *filter,
...
@@ -809,6 +888,12 @@ static int mpegts_push_data(MpegTSFilter *filter,
/* we got the full header. We parse it and get the payload */
/* we got the full header. We parse it and get the payload */
pes
->
state
=
MPEGTS_PAYLOAD
;
pes
->
state
=
MPEGTS_PAYLOAD
;
pes
->
data_index
=
0
;
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
;
break
;
case
MPEGTS_PAYLOAD
:
case
MPEGTS_PAYLOAD
:
...
@@ -962,7 +1047,9 @@ static int parse_MP4ESDescrTag(MP4DescrParseContext *d, int64_t off, int len)
...
@@ -962,7 +1047,9 @@ static int parse_MP4ESDescrTag(MP4DescrParseContext *d, int64_t off, int len)
d
->
active_descr
->
es_id
=
es_id
;
d
->
active_descr
->
es_id
=
es_id
;
update_offsets
(
&
d
->
pb
,
&
off
,
&
len
);
update_offsets
(
&
d
->
pb
,
&
off
,
&
len
);
parse_mp4_descr
(
d
,
off
,
len
,
MP4DecConfigDescrTag
);
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
;
d
->
active_descr
=
NULL
;
return
0
;
return
0
;
}
}
...
@@ -980,6 +1067,39 @@ static int parse_MP4DecConfigDescrTag(MP4DescrParseContext *d, int64_t off, int
...
@@ -980,6 +1067,39 @@ static int parse_MP4DecConfigDescrTag(MP4DescrParseContext *d, int64_t off, int
return
0
;
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
,
static
int
parse_mp4_descr
(
MP4DescrParseContext
*
d
,
int64_t
off
,
int
len
,
int
target_tag
)
{
int
target_tag
)
{
int
tag
;
int
tag
;
...
@@ -1013,6 +1133,9 @@ static int parse_mp4_descr(MP4DescrParseContext *d, int64_t off, int len,
...
@@ -1013,6 +1133,9 @@ static int parse_mp4_descr(MP4DescrParseContext *d, int64_t off, int len,
case
MP4DecConfigDescrTag
:
case
MP4DecConfigDescrTag
:
parse_MP4DecConfigDescrTag
(
d
,
off
,
len1
);
parse_MP4DecConfigDescrTag
(
d
,
off
,
len1
);
break
;
break
;
case
MP4SLDescrTag
:
parse_MP4SLDescrTag
(
d
,
off
,
len1
);
break
;
}
}
done:
done:
...
@@ -1047,12 +1170,23 @@ static int mp4_read_od(AVFormatContext *s, const uint8_t *buf, unsigned size,
...
@@ -1047,12 +1170,23 @@ static int mp4_read_od(AVFormatContext *s, const uint8_t *buf, unsigned size,
return
0
;
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
;
AVIOContext
pb
;
Mp4Descr
mp4_descr
[
MAX_MP4_DESCR_COUNT
]
=
{{
0
}};
Mp4Descr
mp4_descr
[
MAX_MP4_DESCR_COUNT
]
=
{{
0
}};
int
mp4_descr_count
=
0
;
int
mp4_descr_count
=
0
;
int
i
,
pid
;
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
);
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
...
@@ -1074,6 +1208,8 @@ static void SL_packet(AVFormatContext *s, MpegTSContext *ts, const uint8_t *p, c
continue
;
continue
;
}
}
pes
->
sl
=
mp4_descr
[
i
].
sl
;
ffio_init_context
(
&
pb
,
mp4_descr
[
i
].
dec_config_descr
,
ffio_init_context
(
&
pb
,
mp4_descr
[
i
].
dec_config_descr
,
mp4_descr
[
i
].
dec_config_descr_len
,
0
,
NULL
,
NULL
,
NULL
,
NULL
);
mp4_descr
[
i
].
dec_config_descr_len
,
0
,
NULL
,
NULL
,
NULL
,
NULL
);
ff_mp4_read_dec_config_descr
(
s
,
st
,
&
pb
);
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
...
@@ -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
);
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
,
int
ff_parse_mpeg2_descriptor
(
AVFormatContext
*
fc
,
AVStream
*
st
,
int
stream_type
,
const
uint8_t
**
pp
,
const
uint8_t
*
desc_list_end
,
const
uint8_t
**
pp
,
const
uint8_t
*
desc_list_end
,
Mp4Descr
*
mp4_descr
,
int
mp4_descr_count
,
int
pid
,
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,
...
@@ -65,10 +65,28 @@ int ff_mpegts_parse_packet(MpegTSContext *ts, AVPacket *pkt,
const
uint8_t
*
buf
,
int
len
);
const
uint8_t
*
buf
,
int
len
);
void
ff_mpegts_parse_close
(
MpegTSContext
*
ts
);
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
{
typedef
struct
{
int
es_id
;
int
es_id
;
int
dec_config_descr_len
;
int
dec_config_descr_len
;
uint8_t
*
dec_config_descr
;
uint8_t
*
dec_config_descr
;
SLConfigDescr
sl
;
}
Mp4Descr
;
}
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