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
b7b1bf91
Commit
b7b1bf91
authored
Aug 06, 2014
by
Diego Biurrun
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
mpegts: K&R formatting cosmetics
parent
bb789016
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
216 additions
and
196 deletions
+216
-196
mpegtsenc.c
libavformat/mpegtsenc.c
+216
-196
No files found.
libavformat/mpegtsenc.c
View file @
b7b1bf91
...
@@ -25,7 +25,9 @@
...
@@ -25,7 +25,9 @@
#include "libavutil/intreadwrite.h"
#include "libavutil/intreadwrite.h"
#include "libavutil/mathematics.h"
#include "libavutil/mathematics.h"
#include "libavutil/opt.h"
#include "libavutil/opt.h"
#include "libavcodec/internal.h"
#include "libavcodec/internal.h"
#include "avformat.h"
#include "avformat.h"
#include "internal.h"
#include "internal.h"
#include "mpegts.h"
#include "mpegts.h"
...
@@ -86,7 +88,7 @@ typedef struct MpegTSWrite {
...
@@ -86,7 +88,7 @@ typedef struct MpegTSWrite {
}
MpegTSWrite
;
}
MpegTSWrite
;
/* a PES packet header is generated every DEFAULT_PES_HEADER_FREQ packets */
/* a PES packet header is generated every DEFAULT_PES_HEADER_FREQ packets */
#define DEFAULT_PES_HEADER_FREQ 16
#define DEFAULT_PES_HEADER_FREQ
16
#define DEFAULT_PES_PAYLOAD_SIZE ((DEFAULT_PES_HEADER_FREQ - 1) * 184 + 170)
#define DEFAULT_PES_PAYLOAD_SIZE ((DEFAULT_PES_HEADER_FREQ - 1) * 184 + 170)
/* The section length is 12 bits. The first 2 are set to 0, the remaining
/* The section length is 12 bits. The first 2 are set to 0, the remaining
...
@@ -102,25 +104,27 @@ static void mpegts_write_section(MpegTSSection *s, uint8_t *buf, int len)
...
@@ -102,25 +104,27 @@ static void mpegts_write_section(MpegTSSection *s, uint8_t *buf, int len)
unsigned
char
*
q
;
unsigned
char
*
q
;
int
first
,
b
,
len1
,
left
;
int
first
,
b
,
len1
,
left
;
crc
=
av_bswap32
(
av_crc
(
av_crc_get_table
(
AV_CRC_32_IEEE
),
-
1
,
buf
,
len
-
4
));
crc
=
av_bswap32
(
av_crc
(
av_crc_get_table
(
AV_CRC_32_IEEE
),
-
1
,
buf
,
len
-
4
));
buf
[
len
-
4
]
=
(
crc
>>
24
)
&
0xff
;
buf
[
len
-
4
]
=
(
crc
>>
24
)
&
0xff
;
buf
[
len
-
3
]
=
(
crc
>>
16
)
&
0xff
;
buf
[
len
-
3
]
=
(
crc
>>
16
)
&
0xff
;
buf
[
len
-
2
]
=
(
crc
>>
8
)
&
0xff
;
buf
[
len
-
2
]
=
(
crc
>>
8
)
&
0xff
;
buf
[
len
-
1
]
=
(
crc
)
&
0xff
;
buf
[
len
-
1
]
=
(
crc
)
&
0xff
;
/* send each packet */
/* send each packet */
buf_ptr
=
buf
;
buf_ptr
=
buf
;
while
(
len
>
0
)
{
while
(
len
>
0
)
{
first
=
(
buf
==
buf_ptr
);
first
=
(
buf
==
buf_ptr
);
q
=
packet
;
q
=
packet
;
*
q
++
=
0x47
;
*
q
++
=
0x47
;
b
=
(
s
->
pid
>>
8
);
b
=
(
s
->
pid
>>
8
);
if
(
first
)
if
(
first
)
b
|=
0x40
;
b
|=
0x40
;
*
q
++
=
b
;
*
q
++
=
b
;
*
q
++
=
s
->
pid
;
*
q
++
=
s
->
pid
;
s
->
cc
=
(
s
->
cc
+
1
)
&
0xf
;
s
->
cc
=
(
s
->
cc
+
1
)
&
0xf
;
*
q
++
=
0x10
|
s
->
cc
;
*
q
++
=
0x10
|
s
->
cc
;
if
(
first
)
if
(
first
)
*
q
++
=
0
;
/* 0 offset */
*
q
++
=
0
;
/* 0 offset */
len1
=
TS_PACKET_SIZE
-
(
q
-
packet
);
len1
=
TS_PACKET_SIZE
-
(
q
-
packet
);
...
@@ -136,22 +140,22 @@ static void mpegts_write_section(MpegTSSection *s, uint8_t *buf, int len)
...
@@ -136,22 +140,22 @@ static void mpegts_write_section(MpegTSSection *s, uint8_t *buf, int len)
s
->
write_packet
(
s
,
packet
);
s
->
write_packet
(
s
,
packet
);
buf_ptr
+=
len1
;
buf_ptr
+=
len1
;
len
-=
len1
;
len
-=
len1
;
}
}
}
}
static
inline
void
put16
(
uint8_t
**
q_ptr
,
int
val
)
static
inline
void
put16
(
uint8_t
**
q_ptr
,
int
val
)
{
{
uint8_t
*
q
;
uint8_t
*
q
;
q
=
*
q_ptr
;
q
=
*
q_ptr
;
*
q
++
=
val
>>
8
;
*
q
++
=
val
>>
8
;
*
q
++
=
val
;
*
q
++
=
val
;
*
q_ptr
=
q
;
*
q_ptr
=
q
;
}
}
static
int
mpegts_write_section1
(
MpegTSSection
*
s
,
int
tid
,
int
id
,
static
int
mpegts_write_section1
(
MpegTSSection
*
s
,
int
tid
,
int
id
,
int
version
,
int
sec_num
,
int
last_sec_num
,
int
version
,
int
sec_num
,
int
last_sec_num
,
uint8_t
*
buf
,
int
len
)
uint8_t
*
buf
,
int
len
)
{
{
uint8_t
section
[
1024
],
*
q
;
uint8_t
section
[
1024
],
*
q
;
unsigned
int
tot_len
;
unsigned
int
tot_len
;
...
@@ -163,7 +167,7 @@ static int mpegts_write_section1(MpegTSSection *s, int tid, int id,
...
@@ -163,7 +167,7 @@ static int mpegts_write_section1(MpegTSSection *s, int tid, int id,
if
(
tot_len
>
1024
)
if
(
tot_len
>
1024
)
return
-
1
;
return
-
1
;
q
=
section
;
q
=
section
;
*
q
++
=
tid
;
*
q
++
=
tid
;
put16
(
&
q
,
flags
|
(
len
+
5
+
4
));
/* 5 byte header + 4 byte CRC */
put16
(
&
q
,
flags
|
(
len
+
5
+
4
));
/* 5 byte header + 4 byte CRC */
put16
(
&
q
,
id
);
put16
(
&
q
,
id
);
...
@@ -209,7 +213,7 @@ static void mpegts_write_pat(AVFormatContext *s)
...
@@ -209,7 +213,7 @@ static void mpegts_write_pat(AVFormatContext *s)
int
i
;
int
i
;
q
=
data
;
q
=
data
;
for
(
i
=
0
;
i
<
ts
->
nb_services
;
i
++
)
{
for
(
i
=
0
;
i
<
ts
->
nb_services
;
i
++
)
{
service
=
ts
->
services
[
i
];
service
=
ts
->
services
[
i
];
put16
(
&
q
,
service
->
sid
);
put16
(
&
q
,
service
->
sid
);
put16
(
&
q
,
0xe000
|
service
->
pmt
.
pid
);
put16
(
&
q
,
0xe000
|
service
->
pmt
.
pid
);
...
@@ -236,11 +240,11 @@ static void mpegts_write_pmt(AVFormatContext *s, MpegTSService *service)
...
@@ -236,11 +240,11 @@ static void mpegts_write_pmt(AVFormatContext *s, MpegTSService *service)
program_info_length_ptr
[
0
]
=
val
>>
8
;
program_info_length_ptr
[
0
]
=
val
>>
8
;
program_info_length_ptr
[
1
]
=
val
;
program_info_length_ptr
[
1
]
=
val
;
for
(
i
=
0
;
i
<
s
->
nb_streams
;
i
++
)
{
for
(
i
=
0
;
i
<
s
->
nb_streams
;
i
++
)
{
AVStream
*
st
=
s
->
streams
[
i
];
AVStream
*
st
=
s
->
streams
[
i
];
MpegTSWriteStream
*
ts_st
=
st
->
priv_data
;
MpegTSWriteStream
*
ts_st
=
st
->
priv_data
;
AVDictionaryEntry
*
lang
=
av_dict_get
(
st
->
metadata
,
"language"
,
NULL
,
0
);
AVDictionaryEntry
*
lang
=
av_dict_get
(
st
->
metadata
,
"language"
,
NULL
,
0
);
switch
(
st
->
codec
->
codec_id
)
{
switch
(
st
->
codec
->
codec_id
)
{
case
AV_CODEC_ID_MPEG1VIDEO
:
case
AV_CODEC_ID_MPEG1VIDEO
:
case
AV_CODEC_ID_MPEG2VIDEO
:
case
AV_CODEC_ID_MPEG2VIDEO
:
stream_type
=
STREAM_TYPE_VIDEO_MPEG2
;
stream_type
=
STREAM_TYPE_VIDEO_MPEG2
;
...
@@ -265,7 +269,9 @@ static void mpegts_write_pmt(AVFormatContext *s, MpegTSService *service)
...
@@ -265,7 +269,9 @@ static void mpegts_write_pmt(AVFormatContext *s, MpegTSService *service)
stream_type
=
STREAM_TYPE_AUDIO_MPEG1
;
stream_type
=
STREAM_TYPE_AUDIO_MPEG1
;
break
;
break
;
case
AV_CODEC_ID_AAC
:
case
AV_CODEC_ID_AAC
:
stream_type
=
(
ts
->
flags
&
MPEGTS_FLAG_AAC_LATM
)
?
STREAM_TYPE_AUDIO_AAC_LATM
:
STREAM_TYPE_AUDIO_AAC
;
stream_type
=
(
ts
->
flags
&
MPEGTS_FLAG_AAC_LATM
)
?
STREAM_TYPE_AUDIO_AAC_LATM
:
STREAM_TYPE_AUDIO_AAC
;
break
;
break
;
case
AV_CODEC_ID_AAC_LATM
:
case
AV_CODEC_ID_AAC_LATM
:
stream_type
=
STREAM_TYPE_AUDIO_AAC_LATM
;
stream_type
=
STREAM_TYPE_AUDIO_AAC_LATM
;
...
@@ -283,15 +289,15 @@ static void mpegts_write_pmt(AVFormatContext *s, MpegTSService *service)
...
@@ -283,15 +289,15 @@ static void mpegts_write_pmt(AVFormatContext *s, MpegTSService *service)
q
+=
2
;
/* patched after */
q
+=
2
;
/* patched after */
/* write optional descriptors here */
/* write optional descriptors here */
switch
(
st
->
codec
->
codec_type
)
{
switch
(
st
->
codec
->
codec_type
)
{
case
AVMEDIA_TYPE_AUDIO
:
case
AVMEDIA_TYPE_AUDIO
:
if
(
lang
)
{
if
(
lang
)
{
char
*
p
;
char
*
p
;
char
*
next
=
lang
->
value
;
char
*
next
=
lang
->
value
;
uint8_t
*
len_ptr
;
uint8_t
*
len_ptr
;
*
q
++
=
0x0a
;
/* ISO 639 language descriptor */
*
q
++
=
0x0a
;
/* ISO 639 language descriptor */
len_ptr
=
q
++
;
len_ptr
=
q
++
;
*
len_ptr
=
0
;
*
len_ptr
=
0
;
for
(
p
=
lang
->
value
;
next
&&
*
len_ptr
<
255
/
4
*
4
;
p
=
next
+
1
)
{
for
(
p
=
lang
->
value
;
next
&&
*
len_ptr
<
255
/
4
*
4
;
p
=
next
+
1
)
{
...
@@ -303,14 +309,14 @@ static void mpegts_write_pmt(AVFormatContext *s, MpegTSService *service)
...
@@ -303,14 +309,14 @@ static void mpegts_write_pmt(AVFormatContext *s, MpegTSService *service)
*
q
++
=
*
p
++
;
*
q
++
=
*
p
++
;
*
q
++
=
*
p
++
;
*
q
++
=
*
p
++
;
if
(
st
->
disposition
&
AV_DISPOSITION_CLEAN_EFFECTS
)
if
(
st
->
disposition
&
AV_DISPOSITION_CLEAN_EFFECTS
)
*
q
++
=
0x01
;
*
q
++
=
0x01
;
else
if
(
st
->
disposition
&
AV_DISPOSITION_HEARING_IMPAIRED
)
else
if
(
st
->
disposition
&
AV_DISPOSITION_HEARING_IMPAIRED
)
*
q
++
=
0x02
;
*
q
++
=
0x02
;
else
if
(
st
->
disposition
&
AV_DISPOSITION_VISUAL_IMPAIRED
)
else
if
(
st
->
disposition
&
AV_DISPOSITION_VISUAL_IMPAIRED
)
*
q
++
=
0x03
;
*
q
++
=
0x03
;
else
else
*
q
++
=
0
;
/* undefined type */
*
q
++
=
0
;
/* undefined type */
*
len_ptr
+=
4
;
*
len_ptr
+=
4
;
}
}
...
@@ -320,24 +326,24 @@ static void mpegts_write_pmt(AVFormatContext *s, MpegTSService *service)
...
@@ -320,24 +326,24 @@ static void mpegts_write_pmt(AVFormatContext *s, MpegTSService *service)
}
}
break
;
break
;
case
AVMEDIA_TYPE_SUBTITLE
:
case
AVMEDIA_TYPE_SUBTITLE
:
{
{
const
char
*
language
;
const
char
*
language
;
language
=
lang
&&
strlen
(
lang
->
value
)
==
3
?
lang
->
value
:
"eng"
;
language
=
lang
&&
strlen
(
lang
->
value
)
==
3
?
lang
->
value
:
"eng"
;
*
q
++
=
0x59
;
*
q
++
=
0x59
;
*
q
++
=
8
;
*
q
++
=
8
;
*
q
++
=
language
[
0
];
*
q
++
=
language
[
0
];
*
q
++
=
language
[
1
];
*
q
++
=
language
[
1
];
*
q
++
=
language
[
2
];
*
q
++
=
language
[
2
];
*
q
++
=
0x10
;
/* normal subtitles (0x20 = if hearing pb) */
*
q
++
=
0x10
;
/* normal subtitles (0x20 = if hearing pb) */
if
(
st
->
codec
->
extradata_size
==
4
)
{
if
(
st
->
codec
->
extradata_size
==
4
)
{
memcpy
(
q
,
st
->
codec
->
extradata
,
4
);
memcpy
(
q
,
st
->
codec
->
extradata
,
4
);
q
+=
4
;
q
+=
4
;
}
else
{
}
else
{
put16
(
&
q
,
1
);
/* page id */
put16
(
&
q
,
1
);
/* page id */
put16
(
&
q
,
1
);
/* ancillary page id */
put16
(
&
q
,
1
);
/* ancillary page id */
}
}
}
break
;
}
break
;
case
AVMEDIA_TYPE_VIDEO
:
case
AVMEDIA_TYPE_VIDEO
:
if
(
stream_type
==
STREAM_TYPE_VIDEO_DIRAC
)
{
if
(
stream_type
==
STREAM_TYPE_VIDEO_DIRAC
)
{
*
q
++
=
0x05
;
/*MPEG-2 registration descriptor*/
*
q
++
=
0x05
;
/*MPEG-2 registration descriptor*/
...
@@ -371,7 +377,7 @@ static void putstr8(uint8_t **q_ptr, const char *str)
...
@@ -371,7 +377,7 @@ static void putstr8(uint8_t **q_ptr, const char *str)
len
=
strlen
(
str
);
len
=
strlen
(
str
);
*
q
++
=
len
;
*
q
++
=
len
;
memcpy
(
q
,
str
,
len
);
memcpy
(
q
,
str
,
len
);
q
+=
len
;
q
+=
len
;
*
q_ptr
=
q
;
*
q_ptr
=
q
;
}
}
...
@@ -385,27 +391,27 @@ static void mpegts_write_sdt(AVFormatContext *s)
...
@@ -385,27 +391,27 @@ static void mpegts_write_sdt(AVFormatContext *s)
q
=
data
;
q
=
data
;
put16
(
&
q
,
ts
->
onid
);
put16
(
&
q
,
ts
->
onid
);
*
q
++
=
0xff
;
*
q
++
=
0xff
;
for
(
i
=
0
;
i
<
ts
->
nb_services
;
i
++
)
{
for
(
i
=
0
;
i
<
ts
->
nb_services
;
i
++
)
{
service
=
ts
->
services
[
i
];
service
=
ts
->
services
[
i
];
put16
(
&
q
,
service
->
sid
);
put16
(
&
q
,
service
->
sid
);
*
q
++
=
0xfc
|
0x00
;
/* currently no EIT info */
*
q
++
=
0xfc
|
0x00
;
/* currently no EIT info */
desc_list_len_ptr
=
q
;
desc_list_len_ptr
=
q
;
q
+=
2
;
q
+=
2
;
running_status
=
4
;
/* running */
running_status
=
4
;
/* running */
free_ca_mode
=
0
;
free_ca_mode
=
0
;
/* write only one descriptor for the service name and provider */
/* write only one descriptor for the service name and provider */
*
q
++
=
0x48
;
*
q
++
=
0x48
;
desc_len_ptr
=
q
;
desc_len_ptr
=
q
;
q
++
;
q
++
;
*
q
++
=
0x01
;
/* digital television service */
*
q
++
=
0x01
;
/* digital television service */
putstr8
(
&
q
,
service
->
provider_name
);
putstr8
(
&
q
,
service
->
provider_name
);
putstr8
(
&
q
,
service
->
name
);
putstr8
(
&
q
,
service
->
name
);
desc_len_ptr
[
0
]
=
q
-
desc_len_ptr
-
1
;
desc_len_ptr
[
0
]
=
q
-
desc_len_ptr
-
1
;
/* fill descriptor length */
/* fill descriptor length */
val
=
(
running_status
<<
13
)
|
(
free_ca_mode
<<
12
)
|
val
=
(
running_status
<<
13
)
|
(
free_ca_mode
<<
12
)
|
(
q
-
desc_list_len_ptr
-
2
);
(
q
-
desc_list_len_ptr
-
2
);
desc_list_len_ptr
[
0
]
=
val
>>
8
;
desc_list_len_ptr
[
0
]
=
val
>>
8
;
desc_list_len_ptr
[
1
]
=
val
;
desc_list_len_ptr
[
1
]
=
val
;
}
}
...
@@ -413,8 +419,7 @@ static void mpegts_write_sdt(AVFormatContext *s)
...
@@ -413,8 +419,7 @@ static void mpegts_write_sdt(AVFormatContext *s)
data
,
q
-
data
);
data
,
q
-
data
);
}
}
static
MpegTSService
*
mpegts_add_service
(
MpegTSWrite
*
ts
,
static
MpegTSService
*
mpegts_add_service
(
MpegTSWrite
*
ts
,
int
sid
,
int
sid
,
const
char
*
provider_name
,
const
char
*
provider_name
,
const
char
*
name
)
const
char
*
name
)
{
{
...
@@ -423,11 +428,11 @@ static MpegTSService *mpegts_add_service(MpegTSWrite *ts,
...
@@ -423,11 +428,11 @@ static MpegTSService *mpegts_add_service(MpegTSWrite *ts,
service
=
av_mallocz
(
sizeof
(
MpegTSService
));
service
=
av_mallocz
(
sizeof
(
MpegTSService
));
if
(
!
service
)
if
(
!
service
)
return
NULL
;
return
NULL
;
service
->
pmt
.
pid
=
ts
->
pmt_start_pid
+
ts
->
nb_services
;
service
->
pmt
.
pid
=
ts
->
pmt_start_pid
+
ts
->
nb_services
;
service
->
sid
=
sid
;
service
->
sid
=
sid
;
service
->
provider_name
=
av_strdup
(
provider_name
);
service
->
provider_name
=
av_strdup
(
provider_name
);
service
->
name
=
av_strdup
(
name
);
service
->
name
=
av_strdup
(
name
);
service
->
pcr_pid
=
0x1fff
;
service
->
pcr_pid
=
0x1fff
;
dynarray_add
(
&
ts
->
services
,
&
ts
->
nb_services
,
service
);
dynarray_add
(
&
ts
->
services
,
&
ts
->
nb_services
,
service
);
return
service
;
return
service
;
}
}
...
@@ -463,30 +468,34 @@ static int mpegts_write_header(AVFormatContext *s)
...
@@ -463,30 +468,34 @@ static int mpegts_write_header(AVFormatContext *s)
title
=
av_dict_get
(
s
->
metadata
,
"service_name"
,
NULL
,
0
);
title
=
av_dict_get
(
s
->
metadata
,
"service_name"
,
NULL
,
0
);
if
(
!
title
)
if
(
!
title
)
title
=
av_dict_get
(
s
->
metadata
,
"title"
,
NULL
,
0
);
title
=
av_dict_get
(
s
->
metadata
,
"title"
,
NULL
,
0
);
service_name
=
title
?
title
->
value
:
DEFAULT_SERVICE_NAME
;
service_name
=
title
?
title
->
value
:
DEFAULT_SERVICE_NAME
;
provider
=
av_dict_get
(
s
->
metadata
,
"service_provider"
,
NULL
,
0
);
provider
=
av_dict_get
(
s
->
metadata
,
"service_provider"
,
NULL
,
0
);
provider_name
=
provider
?
provider
->
value
:
DEFAULT_PROVIDER_NAME
;
provider_name
=
provider
?
provider
->
value
:
DEFAULT_PROVIDER_NAME
;
service
=
mpegts_add_service
(
ts
,
ts
->
service_id
,
provider_name
,
service_name
);
service
=
mpegts_add_service
(
ts
,
ts
->
service_id
,
provider_name
,
service_name
);
service
->
pmt
.
write_packet
=
section_write_packet
;
service
->
pmt
.
write_packet
=
section_write_packet
;
service
->
pmt
.
opaque
=
s
;
service
->
pmt
.
opaque
=
s
;
service
->
pmt
.
cc
=
15
;
service
->
pmt
.
cc
=
15
;
ts
->
pat
.
pid
=
PAT_PID
;
ts
->
pat
.
pid
=
PAT_PID
;
ts
->
pat
.
cc
=
15
;
// Initialize at 15 so that it wraps and be equal to 0 for the first packet we write
/* Initialize at 15 so that it wraps and is equal to 0 for the
* first packet we write. */
ts
->
pat
.
cc
=
15
;
ts
->
pat
.
write_packet
=
section_write_packet
;
ts
->
pat
.
write_packet
=
section_write_packet
;
ts
->
pat
.
opaque
=
s
;
ts
->
pat
.
opaque
=
s
;
ts
->
sdt
.
pid
=
SDT_PID
;
ts
->
sdt
.
pid
=
SDT_PID
;
ts
->
sdt
.
cc
=
15
;
ts
->
sdt
.
cc
=
15
;
ts
->
sdt
.
write_packet
=
section_write_packet
;
ts
->
sdt
.
write_packet
=
section_write_packet
;
ts
->
sdt
.
opaque
=
s
;
ts
->
sdt
.
opaque
=
s
;
pids
=
av_malloc
(
s
->
nb_streams
*
sizeof
(
*
pids
));
pids
=
av_malloc
(
s
->
nb_streams
*
sizeof
(
*
pids
));
if
(
!
pids
)
if
(
!
pids
)
return
AVERROR
(
ENOMEM
);
return
AVERROR
(
ENOMEM
);
/* assign pids to each stream */
/* assign pids to each stream */
for
(
i
=
0
;
i
<
s
->
nb_streams
;
i
++
)
{
for
(
i
=
0
;
i
<
s
->
nb_streams
;
i
++
)
{
st
=
s
->
streams
[
i
];
st
=
s
->
streams
[
i
];
ts_st
=
av_mallocz
(
sizeof
(
MpegTSWriteStream
));
ts_st
=
av_mallocz
(
sizeof
(
MpegTSWriteStream
));
...
@@ -512,7 +521,8 @@ static int mpegts_write_header(AVFormatContext *s)
...
@@ -512,7 +521,8 @@ static int mpegts_write_header(AVFormatContext *s)
}
else
if
(
st
->
id
<
0x1FFF
)
{
}
else
if
(
st
->
id
<
0x1FFF
)
{
ts_st
->
pid
=
st
->
id
;
ts_st
->
pid
=
st
->
id
;
}
else
{
}
else
{
av_log
(
s
,
AV_LOG_ERROR
,
"Invalid stream id %d, must be less than 8191
\n
"
,
st
->
id
);
av_log
(
s
,
AV_LOG_ERROR
,
"Invalid stream id %d, must be less than 8191
\n
"
,
st
->
id
);
ret
=
AVERROR
(
EINVAL
);
ret
=
AVERROR
(
EINVAL
);
goto
fail
;
goto
fail
;
}
}
...
@@ -521,33 +531,35 @@ static int mpegts_write_header(AVFormatContext *s)
...
@@ -521,33 +531,35 @@ static int mpegts_write_header(AVFormatContext *s)
ret
=
AVERROR
(
EINVAL
);
ret
=
AVERROR
(
EINVAL
);
goto
fail
;
goto
fail
;
}
}
for
(
j
=
0
;
j
<
i
;
j
++
)
for
(
j
=
0
;
j
<
i
;
j
++
)
{
if
(
pids
[
j
]
==
ts_st
->
pid
)
{
if
(
pids
[
j
]
==
ts_st
->
pid
)
{
av_log
(
s
,
AV_LOG_ERROR
,
"Duplicate stream id %d
\n
"
,
ts_st
->
pid
);
av_log
(
s
,
AV_LOG_ERROR
,
"Duplicate stream id %d
\n
"
,
ts_st
->
pid
);
ret
=
AVERROR
(
EINVAL
);
ret
=
AVERROR
(
EINVAL
);
goto
fail
;
goto
fail
;
}
}
pids
[
i
]
=
ts_st
->
pid
;
}
ts_st
->
payload_pts
=
AV_NOPTS_VALUE
;
pids
[
i
]
=
ts_st
->
pid
;
ts_st
->
payload_dts
=
AV_NOPTS_VALUE
;
ts_st
->
payload_pts
=
AV_NOPTS_VALUE
;
ts_st
->
payload_dts
=
AV_NOPTS_VALUE
;
ts_st
->
first_pts_check
=
1
;
ts_st
->
first_pts_check
=
1
;
ts_st
->
cc
=
15
;
ts_st
->
cc
=
15
;
/* update PCR pid by using the first video stream */
/* update PCR pid by using the first video stream */
if
(
st
->
codec
->
codec_type
==
AVMEDIA_TYPE_VIDEO
&&
if
(
st
->
codec
->
codec_type
==
AVMEDIA_TYPE_VIDEO
&&
service
->
pcr_pid
==
0x1fff
)
{
service
->
pcr_pid
==
0x1fff
)
{
service
->
pcr_pid
=
ts_st
->
pid
;
service
->
pcr_pid
=
ts_st
->
pid
;
pcr_st
=
st
;
pcr_st
=
st
;
}
}
if
(
st
->
codec
->
codec_id
==
AV_CODEC_ID_AAC
&&
if
(
st
->
codec
->
codec_id
==
AV_CODEC_ID_AAC
&&
st
->
codec
->
extradata_size
>
0
)
st
->
codec
->
extradata_size
>
0
)
{
{
AVStream
*
ast
;
AVStream
*
ast
;
ts_st
->
amux
=
avformat_alloc_context
();
ts_st
->
amux
=
avformat_alloc_context
();
if
(
!
ts_st
->
amux
)
{
if
(
!
ts_st
->
amux
)
{
ret
=
AVERROR
(
ENOMEM
);
ret
=
AVERROR
(
ENOMEM
);
goto
fail
;
goto
fail
;
}
}
ts_st
->
amux
->
oformat
=
av_guess_format
((
ts
->
flags
&
MPEGTS_FLAG_AAC_LATM
)
?
"latm"
:
"adts"
,
NULL
,
NULL
);
ts_st
->
amux
->
oformat
=
av_guess_format
((
ts
->
flags
&
MPEGTS_FLAG_AAC_LATM
)
?
"latm"
:
"adts"
,
NULL
,
NULL
);
if
(
!
ts_st
->
amux
->
oformat
)
{
if
(
!
ts_st
->
amux
->
oformat
)
{
ret
=
AVERROR
(
EINVAL
);
ret
=
AVERROR
(
EINVAL
);
goto
fail
;
goto
fail
;
...
@@ -566,19 +578,19 @@ static int mpegts_write_header(AVFormatContext *s)
...
@@ -566,19 +578,19 @@ static int mpegts_write_header(AVFormatContext *s)
/* if no video stream, use the first stream as PCR */
/* if no video stream, use the first stream as PCR */
if
(
service
->
pcr_pid
==
0x1fff
&&
s
->
nb_streams
>
0
)
{
if
(
service
->
pcr_pid
==
0x1fff
&&
s
->
nb_streams
>
0
)
{
pcr_st
=
s
->
streams
[
0
];
pcr_st
=
s
->
streams
[
0
];
ts_st
=
pcr_st
->
priv_data
;
ts_st
=
pcr_st
->
priv_data
;
service
->
pcr_pid
=
ts_st
->
pid
;
service
->
pcr_pid
=
ts_st
->
pid
;
}
else
}
else
ts_st
=
pcr_st
->
priv_data
;
ts_st
=
pcr_st
->
priv_data
;
if
(
ts
->
mux_rate
>
1
)
{
if
(
ts
->
mux_rate
>
1
)
{
service
->
pcr_packet_period
=
(
ts
->
mux_rate
*
ts
->
pcr_period
)
/
service
->
pcr_packet_period
=
(
ts
->
mux_rate
*
ts
->
pcr_period
)
/
(
TS_PACKET_SIZE
*
8
*
1000
);
(
TS_PACKET_SIZE
*
8
*
1000
);
ts
->
sdt_packet_period
=
(
ts
->
mux_rate
*
SDT_RETRANS_TIME
)
/
ts
->
sdt_packet_period
=
(
ts
->
mux_rate
*
SDT_RETRANS_TIME
)
/
(
TS_PACKET_SIZE
*
8
*
1000
);
(
TS_PACKET_SIZE
*
8
*
1000
);
ts
->
pat_packet_period
=
(
ts
->
mux_rate
*
PAT_RETRANS_TIME
)
/
ts
->
pat_packet_period
=
(
ts
->
mux_rate
*
PAT_RETRANS_TIME
)
/
(
TS_PACKET_SIZE
*
8
*
1000
);
(
TS_PACKET_SIZE
*
8
*
1000
);
ts
->
first_pcr
=
av_rescale
(
s
->
max_delay
,
PCR_TIME_BASE
,
AV_TIME_BASE
);
ts
->
first_pcr
=
av_rescale
(
s
->
max_delay
,
PCR_TIME_BASE
,
AV_TIME_BASE
);
}
else
{
}
else
{
...
@@ -589,10 +601,10 @@ static int mpegts_write_header(AVFormatContext *s)
...
@@ -589,10 +601,10 @@ static int mpegts_write_header(AVFormatContext *s)
if
(
!
pcr_st
->
codec
->
frame_size
)
{
if
(
!
pcr_st
->
codec
->
frame_size
)
{
av_log
(
s
,
AV_LOG_WARNING
,
"frame size not set
\n
"
);
av_log
(
s
,
AV_LOG_WARNING
,
"frame size not set
\n
"
);
service
->
pcr_packet_period
=
service
->
pcr_packet_period
=
pcr_st
->
codec
->
sample_rate
/
(
10
*
512
);
pcr_st
->
codec
->
sample_rate
/
(
10
*
512
);
}
else
{
}
else
{
service
->
pcr_packet_period
=
service
->
pcr_packet_period
=
pcr_st
->
codec
->
sample_rate
/
(
10
*
pcr_st
->
codec
->
frame_size
);
pcr_st
->
codec
->
sample_rate
/
(
10
*
pcr_st
->
codec
->
frame_size
);
}
}
}
else
{
}
else
{
// max delta PCR 0.1s
// max delta PCR 0.1s
...
@@ -604,15 +616,15 @@ static int mpegts_write_header(AVFormatContext *s)
...
@@ -604,15 +616,15 @@ static int mpegts_write_header(AVFormatContext *s)
// output a PCR as soon as possible
// output a PCR as soon as possible
service
->
pcr_packet_count
=
service
->
pcr_packet_period
;
service
->
pcr_packet_count
=
service
->
pcr_packet_period
;
ts
->
pat_packet_count
=
ts
->
pat_packet_period
-
1
;
ts
->
pat_packet_count
=
ts
->
pat_packet_period
-
1
;
ts
->
sdt_packet_count
=
ts
->
sdt_packet_period
-
1
;
ts
->
sdt_packet_count
=
ts
->
sdt_packet_period
-
1
;
if
(
ts
->
mux_rate
==
1
)
if
(
ts
->
mux_rate
==
1
)
av_log
(
s
,
AV_LOG_VERBOSE
,
"muxrate VBR, "
);
av_log
(
s
,
AV_LOG_VERBOSE
,
"muxrate VBR, "
);
else
else
av_log
(
s
,
AV_LOG_VERBOSE
,
"muxrate %d, "
,
ts
->
mux_rate
);
av_log
(
s
,
AV_LOG_VERBOSE
,
"muxrate %d, "
,
ts
->
mux_rate
);
av_log
(
s
,
AV_LOG_VERBOSE
,
"pcr every %d pkts, "
av_log
(
s
,
AV_LOG_VERBOSE
,
"sdt every %d, pat/pmt every %d pkts
\n
"
,
"
pcr every %d pkts,
sdt every %d, pat/pmt every %d pkts
\n
"
,
service
->
pcr_packet_period
,
service
->
pcr_packet_period
,
ts
->
sdt_packet_period
,
ts
->
pat_packet_period
);
ts
->
sdt_packet_period
,
ts
->
pat_packet_period
);
...
@@ -620,11 +632,11 @@ static int mpegts_write_header(AVFormatContext *s)
...
@@ -620,11 +632,11 @@ static int mpegts_write_header(AVFormatContext *s)
return
0
;
return
0
;
fail:
fail:
av_free
(
pids
);
av_free
(
pids
);
for
(
i
=
0
;
i
<
s
->
nb_streams
;
i
++
)
{
for
(
i
=
0
;
i
<
s
->
nb_streams
;
i
++
)
{
MpegTSWriteStream
*
ts_st
;
MpegTSWriteStream
*
ts_st
;
st
=
s
->
streams
[
i
];
st
=
s
->
streams
[
i
];
ts_st
=
st
->
priv_data
;
ts_st
=
st
->
priv_data
;
if
(
ts_st
)
{
if
(
ts_st
)
{
av_freep
(
&
ts_st
->
payload
);
av_freep
(
&
ts_st
->
payload
);
...
@@ -651,9 +663,8 @@ static void retransmit_si_info(AVFormatContext *s)
...
@@ -651,9 +663,8 @@ static void retransmit_si_info(AVFormatContext *s)
if
(
++
ts
->
pat_packet_count
==
ts
->
pat_packet_period
)
{
if
(
++
ts
->
pat_packet_count
==
ts
->
pat_packet_period
)
{
ts
->
pat_packet_count
=
0
;
ts
->
pat_packet_count
=
0
;
mpegts_write_pat
(
s
);
mpegts_write_pat
(
s
);
for
(
i
=
0
;
i
<
ts
->
nb_services
;
i
++
)
{
for
(
i
=
0
;
i
<
ts
->
nb_services
;
i
++
)
mpegts_write_pmt
(
s
,
ts
->
services
[
i
]);
mpegts_write_pmt
(
s
,
ts
->
services
[
i
]);
}
}
}
}
}
...
@@ -669,9 +680,9 @@ static int write_pcr_bits(uint8_t *buf, int64_t pcr)
...
@@ -669,9 +680,9 @@ static int write_pcr_bits(uint8_t *buf, int64_t pcr)
*
buf
++
=
pcr_high
>>
25
;
*
buf
++
=
pcr_high
>>
25
;
*
buf
++
=
pcr_high
>>
17
;
*
buf
++
=
pcr_high
>>
17
;
*
buf
++
=
pcr_high
>>
9
;
*
buf
++
=
pcr_high
>>
9
;
*
buf
++
=
pcr_high
>>
1
;
*
buf
++
=
pcr_high
>>
1
;
*
buf
++
=
pcr_high
<<
7
|
pcr_low
>>
8
|
0x7e
;
*
buf
++
=
pcr_high
<<
7
|
pcr_low
>>
8
|
0x7e
;
*
buf
++
=
pcr_low
;
*
buf
++
=
pcr_low
;
return
6
;
return
6
;
...
@@ -683,7 +694,7 @@ static void mpegts_insert_null_packet(AVFormatContext *s)
...
@@ -683,7 +694,7 @@ static void mpegts_insert_null_packet(AVFormatContext *s)
uint8_t
*
q
;
uint8_t
*
q
;
uint8_t
buf
[
TS_PACKET_SIZE
];
uint8_t
buf
[
TS_PACKET_SIZE
];
q
=
buf
;
q
=
buf
;
*
q
++
=
0x47
;
*
q
++
=
0x47
;
*
q
++
=
0x00
|
0x1f
;
*
q
++
=
0x00
|
0x1f
;
*
q
++
=
0xff
;
*
q
++
=
0xff
;
...
@@ -700,7 +711,7 @@ static void mpegts_insert_pcr_only(AVFormatContext *s, AVStream *st)
...
@@ -700,7 +711,7 @@ static void mpegts_insert_pcr_only(AVFormatContext *s, AVStream *st)
uint8_t
*
q
;
uint8_t
*
q
;
uint8_t
buf
[
TS_PACKET_SIZE
];
uint8_t
buf
[
TS_PACKET_SIZE
];
q
=
buf
;
q
=
buf
;
*
q
++
=
0x47
;
*
q
++
=
0x47
;
*
q
++
=
ts_st
->
pid
>>
8
;
*
q
++
=
ts_st
->
pid
>>
8
;
*
q
++
=
ts_st
->
pid
;
*
q
++
=
ts_st
->
pid
;
...
@@ -721,12 +732,12 @@ static void write_pts(uint8_t *q, int fourbits, int64_t pts)
...
@@ -721,12 +732,12 @@ static void write_pts(uint8_t *q, int fourbits, int64_t pts)
{
{
int
val
;
int
val
;
val
=
fourbits
<<
4
|
(((
pts
>>
30
)
&
0x07
)
<<
1
)
|
1
;
val
=
fourbits
<<
4
|
(((
pts
>>
30
)
&
0x07
)
<<
1
)
|
1
;
*
q
++
=
val
;
*
q
++
=
val
;
val
=
(((
pts
>>
15
)
&
0x7fff
)
<<
1
)
|
1
;
val
=
(((
pts
>>
15
)
&
0x7fff
)
<<
1
)
|
1
;
*
q
++
=
val
>>
8
;
*
q
++
=
val
>>
8
;
*
q
++
=
val
;
*
q
++
=
val
;
val
=
(((
pts
)
&
0x7fff
)
<<
1
)
|
1
;
val
=
(((
pts
)
&
0x7fff
)
<<
1
)
|
1
;
*
q
++
=
val
>>
8
;
*
q
++
=
val
>>
8
;
*
q
++
=
val
;
*
q
++
=
val
;
}
}
...
@@ -764,11 +775,10 @@ static uint8_t *get_ts_payload_start(uint8_t *pkt)
...
@@ -764,11 +775,10 @@ static uint8_t *get_ts_payload_start(uint8_t *pkt)
return
pkt
+
4
;
return
pkt
+
4
;
}
}
/* Add a pes header to the front of payload, and segment into an integer number of
/* Add a PES header to the front of the payload, and segment into an integer
* ts packets. The final ts packet is padded using an over-sized adaptation header
* number of TS packets. The final TS packet is padded using an oversized
* to exactly fill the last ts packet.
* adaptation header to exactly fill the last TS packet.
* NOTE: 'payload' contains a complete PES payload.
* NOTE: 'payload' contains a complete PES payload. */
*/
static
void
mpegts_write_pes
(
AVFormatContext
*
s
,
AVStream
*
st
,
static
void
mpegts_write_pes
(
AVFormatContext
*
s
,
AVStream
*
st
,
const
uint8_t
*
payload
,
int
payload_size
,
const
uint8_t
*
payload
,
int
payload_size
,
int64_t
pts
,
int64_t
dts
,
int
key
)
int64_t
pts
,
int64_t
dts
,
int
key
)
...
@@ -798,25 +808,26 @@ static void mpegts_write_pes(AVFormatContext *s, AVStream *st,
...
@@ -798,25 +808,26 @@ static void mpegts_write_pes(AVFormatContext *s, AVStream *st,
}
}
if
(
ts
->
mux_rate
>
1
&&
dts
!=
AV_NOPTS_VALUE
&&
if
(
ts
->
mux_rate
>
1
&&
dts
!=
AV_NOPTS_VALUE
&&
(
dts
-
get_pcr
(
ts
,
s
->
pb
)
/
300
)
>
delay
)
{
(
dts
-
get_pcr
(
ts
,
s
->
pb
)
/
300
)
>
delay
)
{
/* pcr insert gets priority over null packet insert */
/* pcr insert gets priority over null packet insert */
if
(
write_pcr
)
if
(
write_pcr
)
mpegts_insert_pcr_only
(
s
,
st
);
mpegts_insert_pcr_only
(
s
,
st
);
else
else
mpegts_insert_null_packet
(
s
);
mpegts_insert_null_packet
(
s
);
continue
;
/* recalculate write_pcr and possibly retransmit si_info */
/* recalculate write_pcr and possibly retransmit si_info */
continue
;
}
}
/* prepare packet header */
/* prepare packet header */
q
=
buf
;
q
=
buf
;
*
q
++
=
0x47
;
*
q
++
=
0x47
;
val
=
(
ts_st
->
pid
>>
8
);
val
=
(
ts_st
->
pid
>>
8
);
if
(
is_start
)
if
(
is_start
)
val
|=
0x40
;
val
|=
0x40
;
*
q
++
=
val
;
*
q
++
=
val
;
*
q
++
=
ts_st
->
pid
;
*
q
++
=
ts_st
->
pid
;
ts_st
->
cc
=
(
ts_st
->
cc
+
1
)
&
0xf
;
ts_st
->
cc
=
(
ts_st
->
cc
+
1
)
&
0xf
;
*
q
++
=
0x10
|
ts_st
->
cc
;
// payload indicator + CC
*
q
++
=
0x10
|
ts_st
->
cc
;
// payload indicator + CC
if
(
key
&&
is_start
&&
pts
!=
AV_NOPTS_VALUE
)
{
if
(
key
&&
is_start
&&
pts
!=
AV_NOPTS_VALUE
)
{
// set Random Access for key frames
// set Random Access for key frames
if
(
ts_st
->
pid
==
ts_st
->
service
->
pcr_pid
)
if
(
ts_st
->
pid
==
ts_st
->
service
->
pcr_pid
)
...
@@ -831,7 +842,7 @@ static void mpegts_write_pes(AVFormatContext *s, AVStream *st,
...
@@ -831,7 +842,7 @@ static void mpegts_write_pes(AVFormatContext *s, AVStream *st,
if
(
ts
->
mux_rate
>
1
)
if
(
ts
->
mux_rate
>
1
)
pcr
=
get_pcr
(
ts
,
s
->
pb
);
pcr
=
get_pcr
(
ts
,
s
->
pb
);
else
else
pcr
=
(
dts
-
delay
)
*
300
;
pcr
=
(
dts
-
delay
)
*
300
;
if
(
dts
!=
AV_NOPTS_VALUE
&&
dts
<
pcr
/
300
)
if
(
dts
!=
AV_NOPTS_VALUE
&&
dts
<
pcr
/
300
)
av_log
(
s
,
AV_LOG_WARNING
,
"dts < pcr, TS is invalid
\n
"
);
av_log
(
s
,
AV_LOG_WARNING
,
"dts < pcr, TS is invalid
\n
"
);
extend_af
(
buf
,
write_pcr_bits
(
q
,
pcr
));
extend_af
(
buf
,
write_pcr_bits
(
q
,
pcr
));
...
@@ -845,9 +856,9 @@ static void mpegts_write_pes(AVFormatContext *s, AVStream *st,
...
@@ -845,9 +856,9 @@ static void mpegts_write_pes(AVFormatContext *s, AVStream *st,
*
q
++
=
0x01
;
*
q
++
=
0x01
;
private_code
=
0
;
private_code
=
0
;
if
(
st
->
codec
->
codec_type
==
AVMEDIA_TYPE_VIDEO
)
{
if
(
st
->
codec
->
codec_type
==
AVMEDIA_TYPE_VIDEO
)
{
if
(
st
->
codec
->
codec_id
==
AV_CODEC_ID_DIRAC
)
{
if
(
st
->
codec
->
codec_id
==
AV_CODEC_ID_DIRAC
)
*
q
++
=
0xfd
;
*
q
++
=
0xfd
;
}
else
else
*
q
++
=
0xe0
;
*
q
++
=
0xe0
;
}
else
if
(
st
->
codec
->
codec_type
==
AVMEDIA_TYPE_AUDIO
&&
}
else
if
(
st
->
codec
->
codec_type
==
AVMEDIA_TYPE_AUDIO
&&
(
st
->
codec
->
codec_id
==
AV_CODEC_ID_MP2
||
(
st
->
codec
->
codec_id
==
AV_CODEC_ID_MP2
||
...
@@ -856,31 +867,28 @@ static void mpegts_write_pes(AVFormatContext *s, AVStream *st,
...
@@ -856,31 +867,28 @@ static void mpegts_write_pes(AVFormatContext *s, AVStream *st,
*
q
++
=
0xc0
;
*
q
++
=
0xc0
;
}
else
{
}
else
{
*
q
++
=
0xbd
;
*
q
++
=
0xbd
;
if
(
st
->
codec
->
codec_type
==
AVMEDIA_TYPE_SUBTITLE
)
{
if
(
st
->
codec
->
codec_type
==
AVMEDIA_TYPE_SUBTITLE
)
private_code
=
0x20
;
private_code
=
0x20
;
}
}
}
header_len
=
0
;
header_len
=
0
;
flags
=
0
;
flags
=
0
;
if
(
pts
!=
AV_NOPTS_VALUE
)
{
if
(
pts
!=
AV_NOPTS_VALUE
)
{
header_len
+=
5
;
header_len
+=
5
;
flags
|=
0x80
;
flags
|=
0x80
;
}
}
if
(
dts
!=
AV_NOPTS_VALUE
&&
pts
!=
AV_NOPTS_VALUE
&&
dts
!=
pts
)
{
if
(
dts
!=
AV_NOPTS_VALUE
&&
pts
!=
AV_NOPTS_VALUE
&&
dts
!=
pts
)
{
header_len
+=
5
;
header_len
+=
5
;
flags
|=
0x40
;
flags
|=
0x40
;
}
}
if
(
st
->
codec
->
codec_type
==
AVMEDIA_TYPE_VIDEO
&&
if
(
st
->
codec
->
codec_type
==
AVMEDIA_TYPE_VIDEO
&&
st
->
codec
->
codec_id
==
AV_CODEC_ID_DIRAC
)
{
st
->
codec
->
codec_id
==
AV_CODEC_ID_DIRAC
)
{
/* set PES_extension_flag */
/* set PES_extension_flag */
pes_extension
=
1
;
pes_extension
=
1
;
flags
|=
0x01
;
flags
|=
0x01
;
/*
/* One byte for PES2 extension flag +
* One byte for PES2 extension flag +
* one byte for extension length +
* one byte for extension length +
* one byte for extension id */
* one byte for extension id
*/
header_len
+=
3
;
header_len
+=
3
;
}
}
len
=
payload_size
+
header_len
+
3
;
len
=
payload_size
+
header_len
+
3
;
...
@@ -890,7 +898,7 @@ static void mpegts_write_pes(AVFormatContext *s, AVStream *st,
...
@@ -890,7 +898,7 @@ static void mpegts_write_pes(AVFormatContext *s, AVStream *st,
len
=
0
;
len
=
0
;
*
q
++
=
len
>>
8
;
*
q
++
=
len
>>
8
;
*
q
++
=
len
;
*
q
++
=
len
;
val
=
0x80
;
val
=
0x80
;
/* data alignment indicator is required for subtitle data */
/* data alignment indicator is required for subtitle data */
if
(
st
->
codec
->
codec_type
==
AVMEDIA_TYPE_SUBTITLE
)
if
(
st
->
codec
->
codec_type
==
AVMEDIA_TYPE_SUBTITLE
)
val
|=
0x04
;
val
|=
0x04
;
...
@@ -907,12 +915,10 @@ static void mpegts_write_pes(AVFormatContext *s, AVStream *st,
...
@@ -907,12 +915,10 @@ static void mpegts_write_pes(AVFormatContext *s, AVStream *st,
}
}
if
(
pes_extension
&&
st
->
codec
->
codec_id
==
AV_CODEC_ID_DIRAC
)
{
if
(
pes_extension
&&
st
->
codec
->
codec_id
==
AV_CODEC_ID_DIRAC
)
{
flags
=
0x01
;
/* set PES_extension_flag_2 */
flags
=
0x01
;
/* set PES_extension_flag_2 */
*
q
++
=
flags
;
*
q
++
=
flags
;
*
q
++
=
0x80
|
0x01
;
/* marker bit + extension length */
*
q
++
=
0x80
|
0x01
;
/* marker bit + extension length */
/*
/* Set the stream ID extension flag bit to 0 and
* Set the stream id extension flag bit to 0 and
* write the extended stream ID. */
* write the extended stream id
*/
*
q
++
=
0x00
|
0x60
;
*
q
++
=
0x00
|
0x60
;
}
}
if
(
private_code
!=
0
)
if
(
private_code
!=
0
)
...
@@ -940,7 +946,7 @@ static void mpegts_write_pes(AVFormatContext *s, AVStream *st,
...
@@ -940,7 +946,7 @@ static void mpegts_write_pes(AVFormatContext *s, AVStream *st,
/* add stuffing */
/* add stuffing */
memmove
(
buf
+
4
+
stuffing_len
,
buf
+
4
,
header_len
-
4
);
memmove
(
buf
+
4
+
stuffing_len
,
buf
+
4
,
header_len
-
4
);
buf
[
3
]
|=
0x20
;
buf
[
3
]
|=
0x20
;
buf
[
4
]
=
stuffing_len
-
1
;
buf
[
4
]
=
stuffing_len
-
1
;
if
(
stuffing_len
>=
2
)
{
if
(
stuffing_len
>=
2
)
{
buf
[
5
]
=
0x00
;
buf
[
5
]
=
0x00
;
memset
(
buf
+
6
,
0xff
,
stuffing_len
-
2
);
memset
(
buf
+
6
,
0xff
,
stuffing_len
-
2
);
...
@@ -948,7 +954,7 @@ static void mpegts_write_pes(AVFormatContext *s, AVStream *st,
...
@@ -948,7 +954,7 @@ static void mpegts_write_pes(AVFormatContext *s, AVStream *st,
}
}
}
}
memcpy
(
buf
+
TS_PACKET_SIZE
-
len
,
payload
,
len
);
memcpy
(
buf
+
TS_PACKET_SIZE
-
len
,
payload
,
len
);
payload
+=
len
;
payload
+=
len
;
payload_size
-=
len
;
payload_size
-=
len
;
avio_write
(
s
->
pb
,
buf
,
TS_PACKET_SIZE
);
avio_write
(
s
->
pb
,
buf
,
TS_PACKET_SIZE
);
}
}
...
@@ -959,23 +965,24 @@ static int mpegts_write_packet_internal(AVFormatContext *s, AVPacket *pkt)
...
@@ -959,23 +965,24 @@ static int mpegts_write_packet_internal(AVFormatContext *s, AVPacket *pkt)
{
{
AVStream
*
st
=
s
->
streams
[
pkt
->
stream_index
];
AVStream
*
st
=
s
->
streams
[
pkt
->
stream_index
];
int
size
=
pkt
->
size
;
int
size
=
pkt
->
size
;
uint8_t
*
buf
=
pkt
->
data
;
uint8_t
*
buf
=
pkt
->
data
;
uint8_t
*
data
=
NULL
;
uint8_t
*
data
=
NULL
;
MpegTSWrite
*
ts
=
s
->
priv_data
;
MpegTSWrite
*
ts
=
s
->
priv_data
;
MpegTSWriteStream
*
ts_st
=
st
->
priv_data
;
MpegTSWriteStream
*
ts_st
=
st
->
priv_data
;
const
uint64_t
delay
=
av_rescale
(
s
->
max_delay
,
90000
,
AV_TIME_BASE
)
*
2
;
const
uint64_t
delay
=
av_rescale
(
s
->
max_delay
,
90000
,
AV_TIME_BASE
)
*
2
;
int64_t
dts
=
AV_NOPTS_VALUE
,
pts
=
AV_NOPTS_VALUE
;
int64_t
dts
=
AV_NOPTS_VALUE
,
pts
=
AV_NOPTS_VALUE
;
if
(
ts
->
reemit_pat_pmt
)
{
if
(
ts
->
reemit_pat_pmt
)
{
av_log
(
s
,
AV_LOG_WARNING
,
"resend_headers option is deprecated, use -mpegts_flags resend_headers
\n
"
);
av_log
(
s
,
AV_LOG_WARNING
,
"resend_headers option is deprecated, use -mpegts_flags resend_headers
\n
"
);
ts
->
reemit_pat_pmt
=
0
;
ts
->
reemit_pat_pmt
=
0
;
ts
->
flags
|=
MPEGTS_FLAG_REEMIT_PAT_PMT
;
ts
->
flags
|=
MPEGTS_FLAG_REEMIT_PAT_PMT
;
}
}
if
(
ts
->
flags
&
MPEGTS_FLAG_REEMIT_PAT_PMT
)
{
if
(
ts
->
flags
&
MPEGTS_FLAG_REEMIT_PAT_PMT
)
{
ts
->
pat_packet_count
=
ts
->
pat_packet_period
-
1
;
ts
->
pat_packet_count
=
ts
->
pat_packet_period
-
1
;
ts
->
sdt_packet_count
=
ts
->
sdt_packet_period
-
1
;
ts
->
sdt_packet_count
=
ts
->
sdt_packet_period
-
1
;
ts
->
flags
&=
~
MPEGTS_FLAG_REEMIT_PAT_PMT
;
ts
->
flags
&=
~
MPEGTS_FLAG_REEMIT_PAT_PMT
;
}
}
if
(
pkt
->
pts
!=
AV_NOPTS_VALUE
)
if
(
pkt
->
pts
!=
AV_NOPTS_VALUE
)
...
@@ -990,7 +997,7 @@ static int mpegts_write_packet_internal(AVFormatContext *s, AVPacket *pkt)
...
@@ -990,7 +997,7 @@ static int mpegts_write_packet_internal(AVFormatContext *s, AVPacket *pkt)
ts_st
->
first_pts_check
=
0
;
ts_st
->
first_pts_check
=
0
;
if
(
st
->
codec
->
codec_id
==
AV_CODEC_ID_H264
)
{
if
(
st
->
codec
->
codec_id
==
AV_CODEC_ID_H264
)
{
const
uint8_t
*
p
=
buf
,
*
buf_end
=
p
+
size
;
const
uint8_t
*
p
=
buf
,
*
buf_end
=
p
+
size
;
uint32_t
state
=
-
1
;
uint32_t
state
=
-
1
;
if
(
pkt
->
size
<
5
||
AV_RB32
(
pkt
->
data
)
!=
0x0000001
)
{
if
(
pkt
->
size
<
5
||
AV_RB32
(
pkt
->
data
)
!=
0x0000001
)
{
...
@@ -1006,15 +1013,15 @@ static int mpegts_write_packet_internal(AVFormatContext *s, AVPacket *pkt)
...
@@ -1006,15 +1013,15 @@ static int mpegts_write_packet_internal(AVFormatContext *s, AVPacket *pkt)
(
state
&
0x1f
)
!=
5
&&
(
state
&
0x1f
)
!=
1
);
(
state
&
0x1f
)
!=
5
&&
(
state
&
0x1f
)
!=
1
);
if
((
state
&
0x1f
)
!=
9
)
{
// AUD NAL
if
((
state
&
0x1f
)
!=
9
)
{
// AUD NAL
data
=
av_malloc
(
pkt
->
size
+
6
);
data
=
av_malloc
(
pkt
->
size
+
6
);
if
(
!
data
)
if
(
!
data
)
return
AVERROR
(
ENOMEM
);
return
AVERROR
(
ENOMEM
);
memcpy
(
data
+
6
,
pkt
->
data
,
pkt
->
size
);
memcpy
(
data
+
6
,
pkt
->
data
,
pkt
->
size
);
AV_WB32
(
data
,
0x00000001
);
AV_WB32
(
data
,
0x00000001
);
data
[
4
]
=
0x09
;
data
[
4
]
=
0x09
;
data
[
5
]
=
0xf0
;
// any slice type (0xe) + rbsp stop one bit
data
[
5
]
=
0xf0
;
// any slice type (0xe) + rbsp stop one bit
buf
=
data
;
buf
=
data
;
size
=
pkt
->
size
+
6
;
size
=
pkt
->
size
+
6
;
}
}
}
else
if
(
st
->
codec
->
codec_id
==
AV_CODEC_ID_AAC
)
{
}
else
if
(
st
->
codec
->
codec_id
==
AV_CODEC_ID_AAC
)
{
if
(
pkt
->
size
<
2
)
{
if
(
pkt
->
size
<
2
)
{
...
@@ -1027,13 +1034,14 @@ static int mpegts_write_packet_internal(AVFormatContext *s, AVPacket *pkt)
...
@@ -1027,13 +1034,14 @@ static int mpegts_write_packet_internal(AVFormatContext *s, AVPacket *pkt)
if
(
!
ts_st
->
amux
)
{
if
(
!
ts_st
->
amux
)
{
av_log
(
s
,
AV_LOG_ERROR
,
"AAC bitstream not in ADTS format "
av_log
(
s
,
AV_LOG_ERROR
,
"AAC bitstream not in ADTS format "
"and extradata missing
\n
"
);
"and extradata missing
\n
"
);
return
AVERROR
(
EINVAL
);
return
AVERROR
(
EINVAL
);
}
}
av_init_packet
(
&
pkt2
);
av_init_packet
(
&
pkt2
);
pkt2
.
data
=
pkt
->
data
;
pkt2
.
data
=
pkt
->
data
;
pkt2
.
size
=
pkt
->
size
;
pkt2
.
size
=
pkt
->
size
;
ret
=
avio_open_dyn_buf
(
&
ts_st
->
amux
->
pb
);
ret
=
avio_open_dyn_buf
(
&
ts_st
->
amux
->
pb
);
if
(
ret
<
0
)
if
(
ret
<
0
)
return
AVERROR
(
ENOMEM
);
return
AVERROR
(
ENOMEM
);
...
@@ -1045,15 +1053,16 @@ static int mpegts_write_packet_internal(AVFormatContext *s, AVPacket *pkt)
...
@@ -1045,15 +1053,16 @@ static int mpegts_write_packet_internal(AVFormatContext *s, AVPacket *pkt)
av_free
(
data
);
av_free
(
data
);
return
ret
;
return
ret
;
}
}
size
=
avio_close_dyn_buf
(
ts_st
->
amux
->
pb
,
&
data
);
size
=
avio_close_dyn_buf
(
ts_st
->
amux
->
pb
,
&
data
);
ts_st
->
amux
->
pb
=
NULL
;
ts_st
->
amux
->
pb
=
NULL
;
buf
=
data
;
buf
=
data
;
}
}
}
}
if
(
st
->
codec
->
codec_type
!=
AVMEDIA_TYPE_AUDIO
)
{
if
(
st
->
codec
->
codec_type
!=
AVMEDIA_TYPE_AUDIO
)
{
// for video and subtitle, write a single pes packet
// for video and subtitle, write a single pes packet
mpegts_write_pes
(
s
,
st
,
buf
,
size
,
pts
,
dts
,
pkt
->
flags
&
AV_PKT_FLAG_KEY
);
mpegts_write_pes
(
s
,
st
,
buf
,
size
,
pts
,
dts
,
pkt
->
flags
&
AV_PKT_FLAG_KEY
);
av_free
(
data
);
av_free
(
data
);
return
0
;
return
0
;
}
}
...
@@ -1074,8 +1083,8 @@ static int mpegts_write_packet_internal(AVFormatContext *s, AVPacket *pkt)
...
@@ -1074,8 +1083,8 @@ static int mpegts_write_packet_internal(AVFormatContext *s, AVPacket *pkt)
}
}
if
(
!
ts_st
->
payload_size
)
{
if
(
!
ts_st
->
payload_size
)
{
ts_st
->
payload_pts
=
pts
;
ts_st
->
payload_pts
=
pts
;
ts_st
->
payload_dts
=
dts
;
ts_st
->
payload_dts
=
dts
;
ts_st
->
payload_flags
=
pkt
->
flags
;
ts_st
->
payload_flags
=
pkt
->
flags
;
}
}
...
@@ -1092,7 +1101,7 @@ static void mpegts_write_flush(AVFormatContext *s)
...
@@ -1092,7 +1101,7 @@ static void mpegts_write_flush(AVFormatContext *s)
int
i
;
int
i
;
/* flush current packets */
/* flush current packets */
for
(
i
=
0
;
i
<
s
->
nb_streams
;
i
++
)
{
for
(
i
=
0
;
i
<
s
->
nb_streams
;
i
++
)
{
AVStream
*
st
=
s
->
streams
[
i
];
AVStream
*
st
=
s
->
streams
[
i
];
MpegTSWriteStream
*
ts_st
=
st
->
priv_data
;
MpegTSWriteStream
*
ts_st
=
st
->
priv_data
;
if
(
ts_st
->
payload_size
>
0
)
{
if
(
ts_st
->
payload_size
>
0
)
{
...
@@ -1123,7 +1132,7 @@ static int mpegts_write_end(AVFormatContext *s)
...
@@ -1123,7 +1132,7 @@ static int mpegts_write_end(AVFormatContext *s)
mpegts_write_flush
(
s
);
mpegts_write_flush
(
s
);
for
(
i
=
0
;
i
<
s
->
nb_streams
;
i
++
)
{
for
(
i
=
0
;
i
<
s
->
nb_streams
;
i
++
)
{
AVStream
*
st
=
s
->
streams
[
i
];
AVStream
*
st
=
s
->
streams
[
i
];
MpegTSWriteStream
*
ts_st
=
st
->
priv_data
;
MpegTSWriteStream
*
ts_st
=
st
->
priv_data
;
av_freep
(
&
ts_st
->
payload
);
av_freep
(
&
ts_st
->
payload
);
...
@@ -1133,7 +1142,7 @@ static int mpegts_write_end(AVFormatContext *s)
...
@@ -1133,7 +1142,7 @@ static int mpegts_write_end(AVFormatContext *s)
}
}
}
}
for
(
i
=
0
;
i
<
ts
->
nb_services
;
i
++
)
{
for
(
i
=
0
;
i
<
ts
->
nb_services
;
i
++
)
{
service
=
ts
->
services
[
i
];
service
=
ts
->
services
[
i
];
av_freep
(
&
service
->
provider_name
);
av_freep
(
&
service
->
provider_name
);
av_freep
(
&
service
->
name
);
av_freep
(
&
service
->
name
);
...
@@ -1146,52 +1155,63 @@ static int mpegts_write_end(AVFormatContext *s)
...
@@ -1146,52 +1155,63 @@ static int mpegts_write_end(AVFormatContext *s)
static
const
AVOption
options
[]
=
{
static
const
AVOption
options
[]
=
{
{
"mpegts_transport_stream_id"
,
"Set transport_stream_id field."
,
{
"mpegts_transport_stream_id"
,
"Set transport_stream_id field."
,
offsetof
(
MpegTSWrite
,
transport_stream_id
),
AV_OPT_TYPE_INT
,
{.
i64
=
0x0001
},
0x0001
,
0xffff
,
AV_OPT_FLAG_ENCODING_PARAM
},
offsetof
(
MpegTSWrite
,
transport_stream_id
),
AV_OPT_TYPE_INT
,
{
.
i64
=
0x0001
},
0x0001
,
0xffff
,
AV_OPT_FLAG_ENCODING_PARAM
},
{
"mpegts_original_network_id"
,
"Set original_network_id field."
,
{
"mpegts_original_network_id"
,
"Set original_network_id field."
,
offsetof
(
MpegTSWrite
,
original_network_id
),
AV_OPT_TYPE_INT
,
{.
i64
=
0x0001
},
0x0001
,
0xffff
,
AV_OPT_FLAG_ENCODING_PARAM
},
offsetof
(
MpegTSWrite
,
original_network_id
),
AV_OPT_TYPE_INT
,
{
.
i64
=
0x0001
},
0x0001
,
0xffff
,
AV_OPT_FLAG_ENCODING_PARAM
},
{
"mpegts_service_id"
,
"Set service_id field."
,
{
"mpegts_service_id"
,
"Set service_id field."
,
offsetof
(
MpegTSWrite
,
service_id
),
AV_OPT_TYPE_INT
,
{.
i64
=
0x0001
},
0x0001
,
0xffff
,
AV_OPT_FLAG_ENCODING_PARAM
},
offsetof
(
MpegTSWrite
,
service_id
),
AV_OPT_TYPE_INT
,
{
.
i64
=
0x0001
},
0x0001
,
0xffff
,
AV_OPT_FLAG_ENCODING_PARAM
},
{
"mpegts_pmt_start_pid"
,
"Set the first pid of the PMT."
,
{
"mpegts_pmt_start_pid"
,
"Set the first pid of the PMT."
,
offsetof
(
MpegTSWrite
,
pmt_start_pid
),
AV_OPT_TYPE_INT
,
{.
i64
=
0x1000
},
0x1000
,
0x1f00
,
AV_OPT_FLAG_ENCODING_PARAM
},
offsetof
(
MpegTSWrite
,
pmt_start_pid
),
AV_OPT_TYPE_INT
,
{
.
i64
=
0x1000
},
0x1000
,
0x1f00
,
AV_OPT_FLAG_ENCODING_PARAM
},
{
"mpegts_start_pid"
,
"Set the first pid."
,
{
"mpegts_start_pid"
,
"Set the first pid."
,
offsetof
(
MpegTSWrite
,
start_pid
),
AV_OPT_TYPE_INT
,
{.
i64
=
0x0100
},
0x0100
,
0x0f00
,
AV_OPT_FLAG_ENCODING_PARAM
},
offsetof
(
MpegTSWrite
,
start_pid
),
AV_OPT_TYPE_INT
,
{
"muxrate"
,
NULL
,
offsetof
(
MpegTSWrite
,
mux_rate
),
AV_OPT_TYPE_INT
,
{.
i64
=
1
},
0
,
INT_MAX
,
AV_OPT_FLAG_ENCODING_PARAM
},
{
.
i64
=
0x0100
},
0x0100
,
0x0f00
,
AV_OPT_FLAG_ENCODING_PARAM
},
{
"muxrate"
,
NULL
,
offsetof
(
MpegTSWrite
,
mux_rate
),
AV_OPT_TYPE_INT
,
{
.
i64
=
1
},
0
,
INT_MAX
,
AV_OPT_FLAG_ENCODING_PARAM
},
{
"pes_payload_size"
,
"Minimum PES packet payload in bytes"
,
{
"pes_payload_size"
,
"Minimum PES packet payload in bytes"
,
offsetof
(
MpegTSWrite
,
pes_payload_size
),
AV_OPT_TYPE_INT
,
{.
i64
=
DEFAULT_PES_PAYLOAD_SIZE
},
0
,
INT_MAX
,
AV_OPT_FLAG_ENCODING_PARAM
},
offsetof
(
MpegTSWrite
,
pes_payload_size
),
AV_OPT_TYPE_INT
,
{
"mpegts_flags"
,
"MPEG-TS muxing flags"
,
offsetof
(
MpegTSWrite
,
flags
),
AV_OPT_TYPE_FLAGS
,
{.
i64
=
0
},
0
,
INT_MAX
,
{
.
i64
=
DEFAULT_PES_PAYLOAD_SIZE
},
0
,
INT_MAX
,
AV_OPT_FLAG_ENCODING_PARAM
},
{
"mpegts_flags"
,
"MPEG-TS muxing flags"
,
offsetof
(
MpegTSWrite
,
flags
),
AV_OPT_TYPE_FLAGS
,
{
.
i64
=
0
},
0
,
INT_MAX
,
AV_OPT_FLAG_ENCODING_PARAM
,
"mpegts_flags"
},
AV_OPT_FLAG_ENCODING_PARAM
,
"mpegts_flags"
},
{
"resend_headers"
,
"Reemit PAT/PMT before writing the next packet"
,
{
"resend_headers"
,
"Reemit PAT/PMT before writing the next packet"
,
0
,
AV_OPT_TYPE_CONST
,
{
.
i64
=
MPEGTS_FLAG_REEMIT_PAT_PMT
},
0
,
INT_MAX
,
0
,
AV_OPT_TYPE_CONST
,
{
.
i64
=
MPEGTS_FLAG_REEMIT_PAT_PMT
},
0
,
INT_MAX
,
AV_OPT_FLAG_ENCODING_PARAM
,
"mpegts_flags"
},
AV_OPT_FLAG_ENCODING_PARAM
,
"mpegts_flags"
},
{
"latm"
,
"Use LATM packetization for AAC"
,
{
"latm"
,
"Use LATM packetization for AAC"
,
0
,
AV_OPT_TYPE_CONST
,
{
.
i64
=
MPEGTS_FLAG_AAC_LATM
},
0
,
INT_MAX
,
0
,
AV_OPT_TYPE_CONST
,
{
.
i64
=
MPEGTS_FLAG_AAC_LATM
},
0
,
INT_MAX
,
AV_OPT_FLAG_ENCODING_PARAM
,
"mpegts_flags"
},
AV_OPT_FLAG_ENCODING_PARAM
,
"mpegts_flags"
},
// backward compatibility
// backward compatibility
{
"resend_headers"
,
"Reemit PAT/PMT before writing the next packet"
,
{
"resend_headers"
,
"Reemit PAT/PMT before writing the next packet"
,
offsetof
(
MpegTSWrite
,
reemit_pat_pmt
),
AV_OPT_TYPE_INT
,
{.
i64
=
0
},
0
,
INT_MAX
,
AV_OPT_FLAG_ENCODING_PARAM
},
offsetof
(
MpegTSWrite
,
reemit_pat_pmt
),
AV_OPT_TYPE_INT
,
{
.
i64
=
0
},
0
,
INT_MAX
,
AV_OPT_FLAG_ENCODING_PARAM
},
{
"pcr_period"
,
"PCR retransmission time"
,
{
"pcr_period"
,
"PCR retransmission time"
,
offsetof
(
MpegTSWrite
,
pcr_period
),
AV_OPT_TYPE_INT
,
{
.
i64
=
PCR_RETRANS_TIME
},
0
,
INT_MAX
,
AV_OPT_FLAG_ENCODING_PARAM
},
offsetof
(
MpegTSWrite
,
pcr_period
),
AV_OPT_TYPE_INT
,
{
.
i64
=
PCR_RETRANS_TIME
},
0
,
INT_MAX
,
AV_OPT_FLAG_ENCODING_PARAM
},
{
NULL
},
{
NULL
},
};
};
static
const
AVClass
mpegts_muxer_class
=
{
static
const
AVClass
mpegts_muxer_class
=
{
.
class_name
=
"MPEGTS muxer"
,
.
class_name
=
"MPEGTS muxer"
,
.
item_name
=
av_default_item_name
,
.
item_name
=
av_default_item_name
,
.
option
=
options
,
.
option
=
options
,
.
version
=
LIBAVUTIL_VERSION_INT
,
.
version
=
LIBAVUTIL_VERSION_INT
,
};
};
AVOutputFormat
ff_mpegts_muxer
=
{
AVOutputFormat
ff_mpegts_muxer
=
{
.
name
=
"mpegts"
,
.
name
=
"mpegts"
,
.
long_name
=
NULL_IF_CONFIG_SMALL
(
"MPEG-TS (MPEG-2 Transport Stream)"
),
.
long_name
=
NULL_IF_CONFIG_SMALL
(
"MPEG-TS (MPEG-2 Transport Stream)"
),
.
mime_type
=
"video/x-mpegts"
,
.
mime_type
=
"video/x-mpegts"
,
.
extensions
=
"ts,m2t"
,
.
extensions
=
"ts,m2t"
,
.
priv_data_size
=
sizeof
(
MpegTSWrite
),
.
priv_data_size
=
sizeof
(
MpegTSWrite
),
.
audio_codec
=
AV_CODEC_ID_MP2
,
.
audio_codec
=
AV_CODEC_ID_MP2
,
.
video_codec
=
AV_CODEC_ID_MPEG2VIDEO
,
.
video_codec
=
AV_CODEC_ID_MPEG2VIDEO
,
.
write_header
=
mpegts_write_header
,
.
write_header
=
mpegts_write_header
,
.
write_packet
=
mpegts_write_packet
,
.
write_packet
=
mpegts_write_packet
,
.
write_trailer
=
mpegts_write_end
,
.
write_trailer
=
mpegts_write_end
,
.
flags
=
AVFMT_ALLOW_FLUSH
,
.
flags
=
AVFMT_ALLOW_FLUSH
,
.
priv_class
=
&
mpegts_muxer_class
,
.
priv_class
=
&
mpegts_muxer_class
,
};
};
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