From bf30161a8db1c30583db0e57bbe978417a9eb301 Mon Sep 17 00:00:00 2001 From: Anshul Maheshwari Date: Fri, 6 Feb 2015 20:10:11 +0530 Subject: [PATCH] avcodec/ccaption_dec: Added Roll up functionality Signed-off-by: Anshul Maheshwari Signed-off-by: Michael Niedermayer --- libavcodec/ccaption_dec.c | 100 +++++++++++++++++++++++++++----------- 1 file changed, 71 insertions(+), 29 deletions(-) diff --git a/libavcodec/ccaption_dec.c b/libavcodec/ccaption_dec.c index 9e78ee5c89..d772cfc9bb 100644 --- a/libavcodec/ccaption_dec.c +++ b/libavcodec/ccaption_dec.c @@ -151,7 +151,6 @@ struct Screen { typedef struct CCaptionSubContext { AVClass *class; - int row_cnt; struct Screen screen[2]; int active_screen; uint8_t cursor_row; @@ -179,6 +178,7 @@ static av_cold int init_decoder(AVCodecContext *avctx) av_bprint_init(&ctx->buffer, 0, AV_BPRINT_SIZE_UNLIMITED); /* taking by default roll up to 2 */ + ctx->mode = CCMODE_ROLLUP_2; ctx->rollup = 2; ret = ff_ass_subtitle_header_default(avctx); /* allocate pkt buffer */ @@ -280,6 +280,68 @@ static struct Screen *get_writing_screen(CCaptionSubContext *ctx) return NULL; } +static void roll_up(CCaptionSubContext *ctx) +{ + struct Screen *screen; + int i, keep_lines; + + if(ctx->mode == CCMODE_TEXT) + return; + + screen = get_writing_screen(ctx); + + /* +1 signify cursor_row starts from 0 + * Can't keep lines less then row cursor pos + */ + keep_lines = FFMIN(ctx->cursor_row + 1, ctx->rollup); + + for( i = 0; i < ctx->cursor_row - keep_lines; i++ ) + UNSET_FLAG(screen->row_used, i); + + + for( i = 0; i < keep_lines && screen->row_used; i++ ) { + const int i_row = ctx->cursor_row - keep_lines + i + 1; + + memcpy( screen->characters[i_row], screen->characters[i_row+1], SCREEN_COLUMNS ); + memcpy( screen->colors[i_row], screen->colors[i_row+1], SCREEN_COLUMNS); + memcpy( screen->fonts[i_row], screen->fonts[i_row+1], SCREEN_COLUMNS); + if(CHECK_FLAG(screen->row_used, i_row + 1)) + SET_FLAG(screen->row_used, i_row); + + } + UNSET_FLAG(screen->row_used, ctx->cursor_row); + +} + +static int reap_screen(CCaptionSubContext *ctx, int64_t pts) +{ + int i; + int ret = 0; + struct Screen *screen = ctx->screen + ctx->active_screen; + ctx->start_time = ctx->startv_time; + + for( i = 0; screen->row_used && i < SCREEN_ROWS; i++) + { + if(CHECK_FLAG(screen->row_used,i)) { + char *str = screen->characters[i]; + /* skip space */ + while (*str == ' ') + str++; + + av_bprintf(&ctx->buffer, "%s\\N", str); + ret = av_bprint_is_complete(&ctx->buffer); + if( ret == 0) { + ret = AVERROR(ENOMEM); + break; + } + } + + } + ctx->startv_time = pts; + ctx->end_time = pts; + return ret; +} + static void handle_textattr( CCaptionSubContext *ctx, uint8_t hi, uint8_t lo ) { int i = lo - 0x20; @@ -333,32 +395,12 @@ static void handle_pac( CCaptionSubContext *ctx, uint8_t hi, uint8_t lo ) */ static int handle_edm(CCaptionSubContext *ctx,int64_t pts) { - int i; int ret = 0; struct Screen *screen = ctx->screen + ctx->active_screen; - ctx->start_time = ctx->startv_time; - for( i = 0; screen->row_used && i < SCREEN_ROWS; i++) - { - if(CHECK_FLAG(screen->row_used,i)) { - char *str = screen->characters[i]; - /* skip space */ - while (*str == ' ') - str++; - av_bprint_append_data(&ctx->buffer, str, strlen(str)); - av_bprint_append_data(&ctx->buffer, "\\N",2); - UNSET_FLAG(screen->row_used, i); - ret = av_bprint_is_complete(&ctx->buffer); - if( ret == 0) { - ret = AVERROR(ENOMEM); - break; - } - } - - } - ctx->startv_time = pts; + reap_screen(ctx, pts); + screen->row_used = 0; ctx->screen_changed = 1; - ctx->end_time = pts; return ret; } @@ -426,10 +468,13 @@ static int process_cc608(CCaptionSubContext *ctx, int64_t pts, uint8_t hi, uint8 handle_delete_end_of_row(ctx, hi, lo); } else if ( COR3(hi, 0x14, 0x15, 0x1C) && lo == 0x25 ) { ctx->rollup = 2; + ctx->mode = CCMODE_ROLLUP_2; } else if ( COR3(hi, 0x14, 0x15, 0x1C) && lo == 0x26 ) { ctx->rollup = 3; + ctx->mode = CCMODE_ROLLUP_3; } else if ( COR3(hi, 0x14, 0x15, 0x1C) && lo == 0x27 ) { ctx->rollup = 4; + ctx->mode = CCMODE_ROLLUP_4; } else if ( COR3(hi, 0x14, 0x15, 0x1C) && lo == 0x29 ) { /* resume direct captioning */ ctx->mode = CCMODE_PAINTON; @@ -441,12 +486,9 @@ static int process_cc608(CCaptionSubContext *ctx, int64_t pts, uint8_t hi, uint8 ret = handle_edm(ctx, pts); } else if ( COR3(hi, 0x14, 0x15, 0x1C) && lo == 0x2D ) { /* carriage return */ - ctx->row_cnt++; - if(ctx->row_cnt >= ctx->rollup) { - ctx->row_cnt = 0; - ret = handle_edm(ctx, pts); - ctx->active_screen = !ctx->active_screen; - } + reap_screen(ctx, pts); + roll_up(ctx); + ctx->screen_changed = 1; ctx->cursor_column = 0; } else if ( COR3(hi, 0x14, 0x15, 0x1C) && lo == 0x2F ) { /* end of caption */