From patchwork Tue Jan 26 21:50:04 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: levi@snapstream.com X-Patchwork-Id: 25209 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 7E0D64492E5 for ; Tue, 26 Jan 2021 23:51:00 +0200 (EET) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 5C06B68A2CF; Tue, 26 Jan 2021 23:51:00 +0200 (EET) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-oo1-f53.google.com (mail-oo1-f53.google.com [209.85.161.53]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id B307F68814C for ; Tue, 26 Jan 2021 23:50:53 +0200 (EET) Received: by mail-oo1-f53.google.com with SMTP id q3so30453oog.4 for ; Tue, 26 Jan 2021 13:50:53 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=snapstream-com.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id:mime-version :content-transfer-encoding; bh=41kDx6AidQ2RA9ZxAbDbITyYC0jLDi0yY7XLaGtSUfY=; b=0zqU2BY8GQtIUwx6x9irc+KWnRjeKW9f1mvo2XvqvohM3rNc3dXN9L9OXjWmbO/Gx6 o/gdRjXa+LQ7Ce5/kEz3qlNo2s+VhKr8JP/mJe4iIIHKNyy0jN1B99nUnnTNhlkcRnsE bsg2KVDpZ1oLnl0LVJkJ2Kwu9/8LwCB7tCkDefAS9S4MkMtn3K2YS6OGHOOi+MzNuM2f qX8m91aPe3AHnhKshWz0xUIS4mM3K9XyP/r66cT4b5yrehvAjA2GCwR3l0S8rEJHLD3y Mjnqeiknw5tyi+PdW63ycihD36gFLSuNDNYI5tesRm7FU5yOKMjeMrXnmoTNYvRNt99B ojhg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:mime-version :content-transfer-encoding; bh=41kDx6AidQ2RA9ZxAbDbITyYC0jLDi0yY7XLaGtSUfY=; b=QGMxRog46R5ixCKEixUksfRCBQHleRMIk9RHm/IAvb6xTjX47DQLxiws0+q4Npy08b UckvCcA3O7ew2qrvIY/8pZLpyVpyFM1Umt8TnKqncZgLgugNh5OUmAlSBrTBr+/Urjj7 ozBd15wV0b55rPc3aTh0CI2nZyHh6PTnXuNyoU5xS8WWp9T5nArxf0wvEwJC14guO6Zw Af0Uh0gSnGiziRAOW7Am9BX6Ct2a924S4etB2ZFgMsGBNFzC6ihQ5XpNhZvQbcd+OC2/ dDJ5cyAv75aq//Bg5P1uykBWCVQvzBpTUmPwpBk4z7RE/xM6OcrgVXcyBBS4YTNu+5yo MA2A== X-Gm-Message-State: AOAM530mIx2Ehr3fPd+BShnkElQJRlumBN3GUG6nXaZ/3s/PYbwnJV92 yF4o4EZOc7GRH2hg74Bv5DK6NH0UsP54gwSM X-Google-Smtp-Source: ABdhPJwgLQJDNZSsMffWIeDFns5FXZeqPz+/jJXjWtthJPOiefihscI1bdOyjxjD4MlBISKAourzLQ== X-Received: by 2002:a4a:1e42:: with SMTP id 63mr5472806ooq.57.1611697851553; Tue, 26 Jan 2021 13:50:51 -0800 (PST) Received: from a-VirtualBox.hsd1.tx.comcast.net (c-73-77-190-16.hsd1.tx.comcast.net. [73.77.190.16]) by smtp.gmail.com with ESMTPSA id r1sm42952ooq.16.2021.01.26.13.50.50 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 26 Jan 2021 13:50:51 -0800 (PST) From: levi@snapstream.com To: ffmpeg-devel@ffmpeg.org Date: Tue, 26 Jan 2021 15:50:04 -0600 Message-Id: <20210126215003.178259-1-levi@snapstream.com> X-Mailer: git-send-email 2.25.1 MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH] libavcodec/ccaption_dec.c: Fixed indentation overwriting text in the cea608 caption decoder. 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: i.am.stickfigure@gmail.com Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" From: Levi Dooley There was an assumption in the existing code that indentation would not occur more than once on the same row. This was a bad assumption. There are examples of 608 streams which call handle_pac multiple times on the same row with different indentation. As the code was before this change, the new indentation would overwrite existing text with spaces. These changes make indentation skip over columns instead. Text gets cleared with spaces on handle_edm. Instead of relying on the null character, trailing spaces are trimmed off the end of a row. This is necessary so that a null character doesn't end up between two words. Signed-off-by: Levi Dooley --- libavcodec/ccaption_dec.c | 39 ++++++++++++++++++++++++--------------- 1 file changed, 24 insertions(+), 15 deletions(-) diff --git a/libavcodec/ccaption_dec.c b/libavcodec/ccaption_dec.c index a208e19b95..6a3018dd4e 100644 --- a/libavcodec/ccaption_dec.c +++ b/libavcodec/ccaption_dec.c @@ -459,6 +459,7 @@ static int capture_screen(CCaptionSubContext *ctx) if (CHECK_FLAG(screen->row_used, i)) { const char *row = screen->characters[i]; const char *charset = screen->charsets[i]; + j = 0; while (row[j] == ' ' && charset[j] == CCSET_BASIC_AMERICAN) j++; @@ -476,13 +477,19 @@ static int capture_screen(CCaptionSubContext *ctx) const char *color = screen->colors[i]; const char *charset = screen->charsets[i]; const char *override; - int x, y, seen_char = 0; + int x, y, row_end, seen_char = 0; j = 0; /* skip leading space */ while (row[j] == ' ' && charset[j] == CCSET_BASIC_AMERICAN && j < tab) j++; + /* skip trailing space */ + row_end = SCREEN_COLUMNS-1; + while (row_end >= 0 && row[row_end] == ' ' && charset[row_end] == CCSET_BASIC_AMERICAN) { + row_end--; + } + x = ASS_DEFAULT_PLAYRESX * (0.1 + 0.0250 * j); y = ASS_DEFAULT_PLAYRESY * (0.1 + 0.0533 * i); av_bprintf(&ctx->buffer[bidx], "{\\an7}{\\pos(%d,%d)}", x, y); @@ -490,7 +497,7 @@ static int capture_screen(CCaptionSubContext *ctx) for (; j < SCREEN_COLUMNS; j++) { const char *e_tag = "", *s_tag = "", *c_tag = "", *b_tag = ""; - if (row[j] == 0) + if (j > row_end || row[j] == 0) break; if (prev_font != font[j]) { @@ -624,7 +631,8 @@ static void handle_textattr(CCaptionSubContext *ctx, uint8_t hi, uint8_t lo) ctx->cursor_font = pac2_attribs[i][1]; SET_FLAG(screen->row_used, ctx->cursor_row); - write_char(ctx, screen, ' '); + + ctx->cursor_column++; } static void handle_pac(CCaptionSubContext *ctx, uint8_t hi, uint8_t lo) @@ -633,8 +641,7 @@ static void handle_pac(CCaptionSubContext *ctx, uint8_t hi, uint8_t lo) 11, -1, 1, 2, 3, 4, 12, 13, 14, 15, 5, 6, 7, 8, 9, 10 }; const int index = ( (hi<<1) & 0x0e) | ( (lo>>5) & 0x01 ); - struct Screen *screen = get_writing_screen(ctx); - int indent, i; + int indent; if (row_map[index] <= 0) { av_log(ctx, AV_LOG_DEBUG, "Invalid pac index encountered\n"); @@ -644,14 +651,11 @@ static void handle_pac(CCaptionSubContext *ctx, uint8_t hi, uint8_t lo) lo &= 0x1f; ctx->cursor_row = row_map[index] - 1; - ctx->cursor_color = pac2_attribs[lo][0]; + ctx->cursor_color = pac2_attribs[lo][0]; ctx->cursor_font = pac2_attribs[lo][1]; ctx->cursor_charset = CCSET_BASIC_AMERICAN; - ctx->cursor_column = 0; indent = pac2_attribs[lo][2]; - for (i = 0; i < indent; i++) { - write_char(ctx, screen, ' '); - } + ctx->cursor_column = indent; } static int handle_edm(CCaptionSubContext *ctx) @@ -667,6 +671,14 @@ static int handle_edm(CCaptionSubContext *ctx) screen->row_used = 0; ctx->bg_color = CCCOL_BLACK; + for (int i = 0; i < SCREEN_ROWS+1; ++i) { + memset(screen->characters[i], ' ', SCREEN_COLUMNS); + memset(screen->colors[i], CCCOL_WHITE, SCREEN_COLUMNS); + memset(screen->bgs[i], CCCOL_BLACK, SCREEN_COLUMNS); + memset(screen->charsets[i], CCSET_BASIC_AMERICAN, SCREEN_COLUMNS); + memset(screen->fonts[i], CCFONT_REGULAR, SCREEN_COLUMNS); + } + // In realtime mode, emit an empty caption so the last one doesn't // stay on the screen. if (ctx->real_time) @@ -687,6 +699,7 @@ static int handle_eoc(CCaptionSubContext *ctx) ret = handle_edm(ctx); ctx->cursor_column = 0; + ctx->cursor_row = 0; // In realtime mode, we display the buffered contents (after // flipping the buffer to active above) as soon as EOC arrives. @@ -731,7 +744,6 @@ static void handle_char(CCaptionSubContext *ctx, char hi, char lo) if (lo) { write_char(ctx, screen, lo); } - write_char(ctx, screen, 0); if (ctx->mode != CCMODE_POPON) ctx->screen_touched = 1; @@ -823,11 +835,8 @@ static int process_cc608(CCaptionSubContext *ctx, uint8_t hi, uint8_t lo) handle_char(ctx, hi, lo); ctx->prev_cmd[0] = ctx->prev_cmd[1] = 0; } else if (hi == 0x17 && lo >= 0x21 && lo <= 0x23) { - int i; /* Tab offsets (spacing) */ - for (i = 0; i < lo - 0x20; i++) { - handle_char(ctx, ' ', 0); - } + ctx->cursor_column += lo - 0x20; } else { /* Ignoring all other non data code */ ff_dlog(ctx, "Unknown command 0x%hhx 0x%hhx\n", hi, lo);