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
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