From patchwork Mon Feb 11 22:42:06 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Marton Balint X-Patchwork-Id: 12044 Return-Path: X-Original-To: patchwork@ffaux-bg.ffmpeg.org Delivered-To: patchwork@ffaux-bg.ffmpeg.org Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org [79.124.17.100]) by ffaux.localdomain (Postfix) with ESMTP id AB2014495BD for ; Tue, 12 Feb 2019 00:42:22 +0200 (EET) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 9584C68A536; Tue, 12 Feb 2019 00:42:22 +0200 (EET) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from iq.passwd.hu (iq.passwd.hu [217.27.212.140]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 6B1E868A4F7 for ; Tue, 12 Feb 2019 00:42:16 +0200 (EET) Received: from localhost (localhost [127.0.0.1]) by iq.passwd.hu (Postfix) with ESMTP id 56731E160F; Mon, 11 Feb 2019 23:42:16 +0100 (CET) X-Virus-Scanned: amavisd-new at passwd.hu Received: from iq.passwd.hu ([127.0.0.1]) by localhost (iq.passwd.hu [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id zVOFtqde11dH; Mon, 11 Feb 2019 23:42:15 +0100 (CET) Received: from bluegene.passwd.hu (localhost [127.0.0.1]) by iq.passwd.hu (Postfix) with ESMTP id 0C3F1E1661; Mon, 11 Feb 2019 23:42:15 +0100 (CET) From: Marton Balint To: ffmpeg-devel@ffmpeg.org Date: Mon, 11 Feb 2019 23:42:06 +0100 Message-Id: <20190211224206.30345-3-cus@passwd.hu> X-Mailer: git-send-email 2.16.4 In-Reply-To: <20190211224206.30345-1-cus@passwd.hu> References: <20190211224206.30345-1-cus@passwd.hu> Subject: [FFmpeg-devel] [PATCH 3/3] avformat/mpegtsenc: add support for service and provider names with utf8 encoding X-BeenThere: ffmpeg-devel@ffmpeg.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: FFmpeg development discussions and patches List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-To: FFmpeg development discussions and patches Cc: Marton Balint MIME-Version: 1.0 Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" Signed-off-by: Marton Balint --- 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)