[FFmpeg-devel] [PATCH 3/3] avformat/mpegtsenc: add support for service and provider names with utf8 encoding
Marton Balint
cus at passwd.hu
Tue Feb 12 00:42:06 EET 2019
Signed-off-by: Marton Balint <cus at passwd.hu>
---
libavformat/mpegtsenc.c | 76 +++++++++++++++++++++++++++++++------------------
1 file changed, 49 insertions(+), 27 deletions(-)
diff --git a/libavformat/mpegtsenc.c b/libavformat/mpegtsenc.c
index 4470b7120c..a600394619 100644
--- a/libavformat/mpegtsenc.c
+++ b/libavformat/mpegtsenc.c
@@ -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;
+ uint8_t *provider_name;
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, int 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 */
- putstr8(&q, tag, 0);
+ putbuf(&q, tag, strlen(tag));
*q++ = 0xff; /* metadata format */
- putstr8(&q, tag, 0);
+ putbuf(&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;
- putstr8(&q, service->provider_name, 1);
- putstr8(&q, service->name, 1);
+ putbuf(&q, service->provider_name, service->provider_name[0] + 1);
+ putbuf(&q, service->name, service->name[0] + 1);
desc_len_ptr[0] = q - desc_len_ptr - 1;
/* fill descriptor length */
@@ -709,6 +693,44 @@ static void mpegts_write_sdt(AVFormatContext *s)
data, q - data);
}
+/* This allocates a buffer with a string 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 uint8_t *encode_str8(const char *str)
+{
+ size_t str_len;
+ uint8_t *buf = av_malloc(256);
+ if (!buf)
+ return NULL;
+ 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! */
+ str_len = FFMIN(str_len, 254);
+ buf[0] = str_len + 1;
+ buf[1] = 0x15;
+ memcpy(&buf[2], str, str_len);
+ return buf;
+ }
+ }
+invalid:
+ /* Otherwise let's just encode the string as is! */
+ str_len = FFMIN(255, str_len);
+ buf[0] = str_len;
+ memcpy(&buf[1], str, str_len);
+ return buf;
+}
+
static MpegTSService *mpegts_add_service(MpegTSWrite *ts, int sid,
const char *provider_name,
const char *name)
@@ -721,8 +743,8 @@ 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);
+ service->provider_name = encode_str8(provider_name);
+ service->name = encode_str8(name);
if (!service->provider_name || !service->name)
goto fail;
if (av_dynarray_add_nofree(&ts->services, &ts->nb_services, service) < 0)
--
2.16.4
More information about the ffmpeg-devel
mailing list