summaryrefslogtreecommitdiff
authoryan yan <yan.yan@amlogic.com>2017-12-16 14:09:08 (GMT)
committer yan yan <yan.yan@amlogic.com>2017-12-16 14:09:08 (GMT)
commit06ec359bd1c5014b6721f423bb6eb4387de42c3f (patch)
treeed82ea4fb07fd70e324a5c1bd3bb7e3f3b37b8ae
parentec8488499943085490b280b7065e20e8a14c4319 (diff)
downloadlibzvbi-06ec359bd1c5014b6721f423bb6eb4387de42c3f.zip
libzvbi-06ec359bd1c5014b6721f423bb6eb4387de42c3f.tar.gz
libzvbi-06ec359bd1c5014b6721f423bb6eb4387de42c3f.tar.bz2
ATVCC: Fix no flash effect after end-of-caption received.
PD# NONE Change-Id: I5adf09f3e7d239eeb5b539d7b16d7f1f6f946b02
Diffstat
-rw-r--r--src/caption.c172
-rw-r--r--src/cc.h4
2 files changed, 35 insertions, 141 deletions
diff --git a/src/caption.c b/src/caption.c
index d7aca7b..110175a 100644
--- a/src/caption.c
+++ b/src/caption.c
@@ -750,88 +750,22 @@ itv_separator(vbi_decoder *vbi, struct caption *cc, char c)
#define COLUMNS 34
static void
-render(vbi_page *pg)
+render(cc_channel *ch)
{
vbi_event event;
-#if 0
- if (row < 0 || pg->dirty.roll) {
- /* no particular row or not fetched
- since last roll/clear, redraw all */
- pg->dirty.y0 = 0;
- pg->dirty.y1 = ROWS - 1;
- pg->dirty.roll = 0;
- } else {
- pg->dirty.y0 = MIN(row, pg->dirty.y0);
- pg->dirty.y1 = MAX(row, pg->dirty.y1);
- }
-#endif
- event.type = VBI_EVENT_CAPTION;
- event.ev.caption.pgno = pg->pgno;
-
- caption_send_event(pg->vbi, &event);
-}
-
-#if 0
-static void
-clear(vbi_page *pg)
-{
- vbi_event event;
-
- pg->dirty.y0 = 0;
- pg->dirty.y1 = ROWS - 1;
- pg->dirty.roll = -ROWS;
-
- event.type = VBI_EVENT_CAPTION;
- event.ev.caption.pgno = pg->pgno;
- caption_send_event(pg->vbi, &event);
-}
-
-static void
-roll_up(vbi_page *pg, int first_row, int last_row)
-{
- vbi_event event;
-
- if (pg->dirty.roll != 0 || pg->dirty.y0 <= pg->dirty.y1) {
- /* not fetched since last update, redraw all */
- pg->dirty.roll = 0;
- pg->dirty.y0 = MIN(first_row, pg->dirty.y0);
- pg->dirty.y1 = MAX(last_row, pg->dirty.y1);
- } else {
- pg->dirty.roll = -1;
- pg->dirty.y0 = first_row;
- pg->dirty.y1 = last_row;
- }
+ ch->pg[2] = ch->pg[ch->hidden ^ 1];
event.type = VBI_EVENT_CAPTION;
- event.ev.caption.pgno = pg->pgno;
+ event.ev.caption.pgno = ch->pg[0].pgno;
- caption_send_event(pg->vbi, &event);
+ caption_send_event(ch->pg[0].vbi, &event);
}
-#endif
static inline void
-update_all(cc_channel *ch)
+update(cc_channel *ch)
{
- memcpy(&ch->pg[ch->hidden ^ 1].text, &ch->pg[ch->hidden].text, ROWS * COLUMNS * sizeof(vbi_char));
ch->update_flag = 1;
- ch->update_all_flag = 0;
-}
-
-static inline void
-update_line(cc_channel *ch)
-{
- vbi_char *acp;
-
- if (ch->update_all_flag) {
- update_all(ch);
- return;
- }
-
- acp = ch->line - ch->pg[ch->hidden].text + ch->pg[ch->hidden ^ 1].text;
-
- memcpy(acp, ch->line, sizeof(vbi_char) * COLUMNS);
- ch->update_flag = 1;
}
static void
@@ -873,7 +807,7 @@ word_break(struct caption *cc, cc_channel *ch, int upd)
* XXX should not render if space follows space,
* but force in long words.
*/
- update_line(ch);
+ update(ch);
}
static void
@@ -885,14 +819,14 @@ clear_roll(cc_channel *ch)
if ((i >= ch->row1) && (i < ch->row1 + ch->roll))
continue;
- memset(ch->pg[ch->hidden].text + i * COLUMNS, 0, sizeof(vbi_char) * COLUMNS);
+ memset(ch->pg[ch->hidden ^ 1].text + i * COLUMNS, 0, sizeof(vbi_char) * COLUMNS);
}
}
static void
roll_up (cc_channel *ch, int roll)
{
- vbi_char *acp = ch->pg[ch->hidden].text;
+ vbi_char *acp = ch->pg[ch->hidden ^ 1].text;
memmove(acp, acp + roll * COLUMNS, (ROWS - roll) * COLUMNS * sizeof(vbi_char));
memset(acp + (ROWS - roll) * COLUMNS, 0, roll * COLUMNS * sizeof(vbi_char));
@@ -910,23 +844,26 @@ roll_up (cc_channel *ch, int roll)
static inline void
set_cursor(cc_channel *ch, int col, int row)
{
+ int p;
if (row < ch->row1) {
ch->row1 = row;
if (ch->mode == MODE_ROLL_UP) {
clear_roll(ch);
- update_all(ch);
+ update(ch);
}
} else if (row >= ch->row1 + ch->roll) {
ch->row1 = row - ch->roll + 1;
if (ch->mode == MODE_ROLL_UP) {
clear_roll(ch);
- update_all(ch);
+ update(ch);
}
}
ch->col = ch->col1 = col;
ch->row = row;
- ch->line = ch->pg[ch->hidden].text + row * COLUMNS;
+
+ p = (ch->mode == MODE_POP_ON) ? ch->hidden : (ch->hidden ^ 1);
+ ch->line = ch->pg[p].text + row * COLUMNS;
}
static void
@@ -936,7 +873,6 @@ set_char(cc_channel *ch, int col, vbi_char c)
return;
ch->line[col] = c;
- ch->edm_flag = 0;
}
static void
@@ -956,14 +892,12 @@ put_char(struct caption *cc, cc_channel *ch, vbi_char c)
if (ch->mode == MODE_POP_ON)
return;
- update_line(ch);
+ update(ch);
}
static inline cc_channel *
switch_channel(struct caption *cc, cc_channel *ch, int new_chan)
{
- //word_break(cc, ch, 1); // we leave for a number of frames
-
return &cc->channel[cc->curr_chan = new_chan];
}
@@ -973,7 +907,6 @@ erase_memory(struct caption *cc, cc_channel *ch, int page)
vbi_page *pg = ch->pg + page;
memset(pg->text, 0, ROWS * COLUMNS * sizeof(vbi_char));
- ch->update_all_flag = 1;
}
static const vbi_color
@@ -1030,7 +963,7 @@ caption_command(vbi_decoder *vbi, struct caption *cc,
roll = ch->row1 - row1;
if (roll > 0) {
roll_up(ch, ch->row1 - row1);
- update_all(ch);
+ update(ch);
}
}
@@ -1154,13 +1087,7 @@ caption_command(vbi_decoder *vbi, struct caption *cc,
case 0: /* Resume Caption Loading 001 c10f 010 0000 */
ch = switch_channel(cc, ch, chan & 3);
- if (ch->mode != MODE_POP_ON) {
- erase_memory(cc, ch, ch->hidden);
- erase_memory(cc, ch, ch->hidden ^ 1);
- }
-
ch->mode = MODE_POP_ON;
-
return;
/* case 4: reserved */
@@ -1173,27 +1100,21 @@ caption_command(vbi_decoder *vbi, struct caption *cc,
ch = switch_channel(cc, ch, chan & 3);
- if (ch->mode == MODE_ROLL_UP && ch->roll == roll && !ch->edm_flag)
+ if (ch->mode == MODE_ROLL_UP && ch->roll == roll)
return;
- if (ch->edm_flag) {
- erase_memory(cc, ch, ch->hidden);
- erase_memory(cc, ch, ch->hidden ^ 1);
- ch->update_flag = 1;
- }
-
ch->mode = MODE_ROLL_UP;
ch->roll = roll;
+ ch->row1 = ch->row - roll + 1;
+ if (ch->row1 < 0)
+ ch->row1 = 0;
return;
}
case 9: /* Resume Direct Captioning 001 c10f 010 1001 */
// not verified
ch = switch_channel(cc, ch, chan & 3);
- if (ch->edm_flag) {
- erase_memory(cc, ch, ch->hidden);
- }
ch->mode = MODE_PAINT_ON;
return;
@@ -1220,8 +1141,7 @@ caption_command(vbi_decoder *vbi, struct caption *cc,
ch->hidden ^= 1;
erase_memory(cc, ch, ch->hidden); // yes?
-
- ch->update_flag = 1;
+ update(ch);
/*
* A Preamble Address Code should follow,
@@ -1247,9 +1167,10 @@ caption_command(vbi_decoder *vbi, struct caption *cc,
ch->col --;
} else if (ch->row > 0) {
vbi_char *acp;
+ int p = (ch->mode == MODE_POP_ON) ? ch->hidden : (ch->hidden ^ 1);
ch->row --;
- ch->line = ch->pg[ch->hidden].text + ch->row * COLUMNS;
+ ch->line = ch->pg[p].text + ch->row * COLUMNS;
ch->col1 = 1;
ch->col = COLUMNS - 1;
acp = ch->line + COLUMNS - 1;
@@ -1270,7 +1191,7 @@ caption_command(vbi_decoder *vbi, struct caption *cc,
if (ch->col < ch->col1)
ch->col1 = ch->col;
- update_line(ch);
+ update(ch);
}
return;
@@ -1282,15 +1203,15 @@ caption_command(vbi_decoder *vbi, struct caption *cc,
if ((ch->row >= ROWS - 1) && (ch->mode == MODE_ROLL_UP)) {
roll_up(ch, 1);
set_cursor(ch, 1, ROWS - 1);
- update_all(ch);
+ update(ch);
} else if (ch->row >= ROWS - 1) {
set_cursor(ch, 1, ROWS - 1);
if (ch->mode != MODE_POP_ON)
- update_line(ch);
+ update(ch);
} else {
set_cursor(ch, 1, ch->row + 1);
if (ch->mode != MODE_POP_ON)
- update_line(ch);
+ update(ch);
}
ch->attr.underline = FALSE;
@@ -1314,44 +1235,18 @@ caption_command(vbi_decoder *vbi, struct caption *cc,
word_break(cc, ch, 0);
if (ch->mode != MODE_POP_ON) {
- update_line(ch);
+ update(ch);
}
return;
case 12: /* Erase Displayed Memory 001 c10f 010 1100 */
-// s1, s4: EDM always before EOC
- /* Received in text mode */
- /*
- if (cc->curr_chan >= 4)
- {
- for (i = 0; i < 2; i++ )
- {
- ch = &cc->channel[i + (cc->curr_chan - 4)/2];
- erase_memory(cc, ch, 0);
- erase_memory(cc, ch, 1);
- }
- }
- else
- {
-
- if (ch->mode != MODE_POP_ON)
- erase_memory(cc, ch, ch->hidden);
-
- erase_memory(cc, ch, ch->hidden ^ 1);
-
-
- clear(ch->pg + (ch->hidden ^ 1));
- }*/
-
if (cc->curr_chan < 4) {
erase_memory(cc, ch, ch->hidden ^ 1);
- ch->update_flag = 1;
- ch->edm_flag = 1;
+ update(ch);
}
return;
case 14: /* Erase Non-Displayed Memory 001 c10f 010 1110 */
-// not verified
erase_memory(cc, ch, ch->hidden);
return;
}
@@ -1420,7 +1315,7 @@ update_display (vbi_decoder *vbi)
cc_channel *ch = &cc->channel[i];
if (ch->update_flag == 1) {
- render(&ch->pg[ch->hidden ^ 1]);
+ render(ch);
ch->update_flag = 0;
}
}
@@ -1773,6 +1668,7 @@ vbi_caption_init(vbi_decoder *vbi)
ch->pg[0].font[1] = vbi_font_descriptors;
memcpy(&ch->pg[1], &ch->pg[0], sizeof(ch->pg[1]));
+ memcpy(&ch->pg[2], &ch->pg[0], sizeof(ch->pg[2]));
if (i >= 4)
ch->pos_flag = 1;
@@ -1830,7 +1726,7 @@ vbi_fetch_cc_page(vbi_decoder *vbi, vbi_page *pg, vbi_pgno pgno, vbi_bool reset)
pthread_mutex_lock(&vbi->cc.mutex);
- spg = ch->pg + (ch->hidden ^ 1);
+ spg = ch->pg + 2;
memcpy(pg, spg, sizeof(*pg)); /* shortcut? */
@@ -1864,12 +1760,12 @@ void vbi_refresh_cc(vbi_decoder *vbi)
for (i = 0; i < 8; i++)
{
ch = &vbi->cc.channel[i];
- spg = ch->pg + (ch->hidden ^ 1);
+ spg = ch->pg + 2;
for (j = 0; j < ROWS * COLUMNS; j++)
{
if (spg->text[j].flash)
{
- ch->update_flag = 1;
+ update(ch);
break;
}
}
diff --git a/src/cc.h b/src/cc.h
index 5f3eb5d..fa4d72f 100644
--- a/src/cc.h
+++ b/src/cc.h
@@ -55,8 +55,6 @@ typedef struct {
int row, row1;
int roll;
int update_flag;
- int update_all_flag;
- int edm_flag;
int pos_flag;
int nul_ct; // XXX should be 'silence count'
@@ -67,7 +65,7 @@ typedef struct {
vbi_char * line;
int hidden;
- vbi_page pg[2];
+ vbi_page pg[3];
int update;
} cc_channel;