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
5adc4a98
Commit
5adc4a98
authored
Feb 10, 2019
by
Marton Balint
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
avformat/mpegtsenc: add support for service and provider names with utf8 encoding
Signed-off-by:
Marton Balint
<
cus@passwd.hu
>
parent
8cf757ee
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
53 additions
and
35 deletions
+53
-35
mpegtsenc.c
libavformat/mpegtsenc.c
+53
-35
No files found.
libavformat/mpegtsenc.c
View file @
5adc4a98
...
...
@@ -54,8 +54,8 @@ typedef struct MpegTSSection {
typedef
struct
MpegTSService
{
MpegTSSection
pmt
;
/* MPEG-2 PMT table context */
int
sid
;
/* service ID */
char
*
name
;
char
*
provider_name
;
uint8_t
name
[
256
]
;
uint8_t
provider_name
[
256
]
;
int
pcr_pid
;
int
pcr_packet_count
;
int
pcr_packet_period
;
...
...
@@ -264,26 +264,10 @@ static void mpegts_write_pat(AVFormatContext *s)
data
,
q
-
data
);
}
/* NOTE: !str is accepted for an empty string */
static
void
putstr8
(
uint8_t
**
q_ptr
,
const
char
*
str
,
int
write_len
)
static
void
putbuf
(
uint8_t
**
q_ptr
,
const
uint8_t
*
buf
,
size_t
len
)
{
uint8_t
*
q
;
int
len
;
q
=
*
q_ptr
;
if
(
!
str
)
len
=
0
;
else
len
=
strlen
(
str
);
if
(
write_len
)
*
q
++
=
len
;
if
(
!
str
)
{
*
q_ptr
=
q
;
return
;
}
memcpy
(
q
,
str
,
len
);
q
+=
len
;
*
q_ptr
=
q
;
memcpy
(
*
q_ptr
,
buf
,
len
);
*
q_ptr
+=
len
;
}
static
int
mpegts_write_pmt
(
AVFormatContext
*
s
,
MpegTSService
*
service
)
...
...
@@ -646,9 +630,9 @@ static int mpegts_write_pmt(AVFormatContext *s, MpegTSService *service)
*
q
++
=
0x26
;
/* metadata descriptor */
*
q
++
=
13
;
put16
(
&
q
,
0xffff
);
/* metadata application format */
put
str8
(
&
q
,
tag
,
0
);
put
buf
(
&
q
,
tag
,
strlen
(
tag
)
);
*
q
++
=
0xff
;
/* metadata format */
put
str8
(
&
q
,
tag
,
0
);
put
buf
(
&
q
,
tag
,
strlen
(
tag
)
);
*
q
++
=
0
;
/* metadata service ID */
*
q
++
=
0xF
;
/* metadata_locator_record_flag|MPEG_carriage_flags|reserved */
}
...
...
@@ -695,8 +679,8 @@ static void mpegts_write_sdt(AVFormatContext *s)
desc_len_ptr
=
q
;
q
++
;
*
q
++
=
ts
->
service_type
;
put
str8
(
&
q
,
service
->
provider_name
,
1
);
put
str8
(
&
q
,
service
->
name
,
1
);
put
buf
(
&
q
,
service
->
provider_name
,
service
->
provider_name
[
0
]
+
1
);
put
buf
(
&
q
,
service
->
name
,
service
->
name
[
0
]
+
1
);
desc_len_ptr
[
0
]
=
q
-
desc_len_ptr
-
1
;
/* fill descriptor length */
...
...
@@ -709,10 +693,47 @@ static void mpegts_write_sdt(AVFormatContext *s)
data
,
q
-
data
);
}
static
MpegTSService
*
mpegts_add_service
(
MpegTSWrite
*
ts
,
int
sid
,
/* This stores a string in buf with the correct encoding and also sets the
* first byte as the length. !str is accepted for an empty string.
* If the string is already encoded, invalid UTF-8 or has no multibyte sequence
* then we keep it as is, otherwise we signal UTF-8 encoding. */
static
int
encode_str8
(
uint8_t
*
buf
,
const
char
*
str
)
{
size_t
str_len
;
if
(
!
str
)
str
=
""
;
str_len
=
strlen
(
str
);
if
(
str
[
0
]
&&
(
unsigned
)
str
[
0
]
>=
0x20
)
{
/* Make sure the string is not already encoded. */
const
uint8_t
*
q
=
str
;
int
has_multibyte
=
0
;
while
(
*
q
)
{
uint32_t
code
;
GET_UTF8
(
code
,
*
q
++
,
goto
invalid
;)
/* Is it valid UTF-8? */
has_multibyte
|=
(
code
>
127
);
/* Does it have multibyte UTF-8 chars in it? */
}
if
(
has_multibyte
)
{
/* If we have multibyte chars and valid UTF-8, then encode as such! */
if
(
str_len
>
254
)
return
AVERROR
(
EINVAL
);
buf
[
0
]
=
str_len
+
1
;
buf
[
1
]
=
0x15
;
memcpy
(
&
buf
[
2
],
str
,
str_len
);
return
0
;
}
}
invalid:
/* Otherwise let's just encode the string as is! */
if
(
str_len
>
255
)
return
AVERROR
(
EINVAL
);
buf
[
0
]
=
str_len
;
memcpy
(
&
buf
[
1
],
str
,
str_len
);
return
0
;
}
static
MpegTSService
*
mpegts_add_service
(
AVFormatContext
*
s
,
int
sid
,
const
char
*
provider_name
,
const
char
*
name
)
{
MpegTSWrite
*
ts
=
s
->
priv_data
;
MpegTSService
*
service
;
service
=
av_mallocz
(
sizeof
(
MpegTSService
));
...
...
@@ -721,17 +742,16 @@ static MpegTSService *mpegts_add_service(MpegTSWrite *ts, int sid,
service
->
pmt
.
pid
=
ts
->
pmt_start_pid
+
ts
->
nb_services
;
service
->
sid
=
sid
;
service
->
pcr_pid
=
0x1fff
;
service
->
provider_name
=
av_strdup
(
provider_name
);
service
->
name
=
av_strdup
(
name
);
if
(
!
service
->
provider_name
||
!
service
->
name
)
if
(
encode_str8
(
service
->
provider_name
,
provider_name
)
<
0
||
encode_str8
(
service
->
name
,
name
)
<
0
)
{
av_log
(
s
,
AV_LOG_ERROR
,
"Too long service or provider name
\n
"
);
goto
fail
;
}
if
(
av_dynarray_add_nofree
(
&
ts
->
services
,
&
ts
->
nb_services
,
service
)
<
0
)
goto
fail
;
return
service
;
fail:
av_freep
(
&
service
->
provider_name
);
av_freep
(
&
service
->
name
);
av_free
(
service
);
return
NULL
;
}
...
...
@@ -790,7 +810,7 @@ static int mpegts_init(AVFormatContext *s)
service_name
=
title
?
title
->
value
:
DEFAULT_SERVICE_NAME
;
provider
=
av_dict_get
(
s
->
metadata
,
"service_provider"
,
NULL
,
0
);
provider_name
=
provider
?
provider
->
value
:
DEFAULT_PROVIDER_NAME
;
service
=
mpegts_add_service
(
t
s
,
ts
->
service_id
,
service
=
mpegts_add_service
(
s
,
ts
->
service_id
,
provider_name
,
service_name
);
if
(
!
service
)
...
...
@@ -809,7 +829,7 @@ static int mpegts_init(AVFormatContext *s)
service_name
=
title
?
title
->
value
:
DEFAULT_SERVICE_NAME
;
provider
=
av_dict_get
(
program
->
metadata
,
"service_provider"
,
NULL
,
0
);
provider_name
=
provider
?
provider
->
value
:
DEFAULT_PROVIDER_NAME
;
service
=
mpegts_add_service
(
t
s
,
program
->
id
,
service
=
mpegts_add_service
(
s
,
program
->
id
,
provider_name
,
service_name
);
if
(
!
service
)
...
...
@@ -1839,8 +1859,6 @@ static void mpegts_deinit(AVFormatContext *s)
for
(
i
=
0
;
i
<
ts
->
nb_services
;
i
++
)
{
service
=
ts
->
services
[
i
];
av_freep
(
&
service
->
provider_name
);
av_freep
(
&
service
->
name
);
av_freep
(
&
service
);
}
av_freep
(
&
ts
->
services
);
...
...
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