Re: [FFmpeg-devel] [PATCHv2 3/3] avformat/mpegtsenc: add support for service and provider names with utf8 encoding
On Tue, 19 Feb 2019, Marton Balint wrote: On Tue, 12 Feb 2019, Marton Balint wrote: Signed-off-by: Marton Balint --- libavformat/mpegtsenc.c | 88 + 1 file changed, 53 insertions(+), 35 deletions(-) Ping, will push soon. Pushed. Regards, Marton ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
Re: [FFmpeg-devel] [PATCHv2 3/3] avformat/mpegtsenc: add support for service and provider names with utf8 encoding
On Tue, 12 Feb 2019, Marton Balint wrote: Signed-off-by: Marton Balint --- libavformat/mpegtsenc.c | 88 + 1 file changed, 53 insertions(+), 35 deletions(-) Ping, will push soon. Regards, Marton diff --git a/libavformat/mpegtsenc.c b/libavformat/mpegtsenc.c index 4470b7120c..523ac65d55 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[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, 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(, 0x);/* metadata application format */ -putstr8(, tag, 0); +putbuf(, tag, strlen(tag)); *q++ = 0xff;/* metadata format */ -putstr8(, tag, 0); +putbuf(, 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(, service->provider_name, 1); -putstr8(, service->name, 1); +putbuf(, service->provider_name, service->provider_name[0] + 1); +putbuf(, 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([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([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
[FFmpeg-devel] [PATCHv2 3/3] avformat/mpegtsenc: add support for service and provider names with utf8 encoding
Signed-off-by: Marton Balint --- libavformat/mpegtsenc.c | 88 + 1 file changed, 53 insertions(+), 35 deletions(-) diff --git a/libavformat/mpegtsenc.c b/libavformat/mpegtsenc.c index 4470b7120c..523ac65d55 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[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, 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(, 0x);/* metadata application format */ -putstr8(, tag, 0); +putbuf(, tag, strlen(tag)); *q++ = 0xff;/* metadata format */ -putstr8(, tag, 0); +putbuf(, 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(, service->provider_name, 1); -putstr8(, service->name, 1); +putbuf(, service->provider_name, service->provider_name[0] + 1); +putbuf(, 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([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([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