int64_t pts;
int64_t pts_start;
int64_t pts_stop;
+ int pts_forced;
int x;
int y;
int width;
int height;
+ int stream_id;
int offsets[2];
uint8_t lum[4];
int size_sub, size_rle;
+ pv->stream_id = in->id;
+
size_sub = ( in->data[0] << 8 ) | in->data[1];
size_rle = ( in->data[2] << 8 ) | in->data[3];
/* We got a complete subtitle, decode it */
*buf_out = Decode( w );
+ if( buf_out && *buf_out )
+ {
+ (*buf_out)->sequence = in->sequence;
+ }
+
/* Wait for the next one */
pv->size_sub = 0;
pv->size_got = 0;
hb_work_private_t * pv = w->private_data;
hb_job_t * job = pv->job;
hb_title_t * title = job->title;
+ hb_subtitle_t * subtitle;
- int i;
+ int i, n;
int command;
int date, next;
pv->pts_start = 0;
pv->pts_stop = 0;
-
+ pv->pts_forced = 0;
+
+ pv->alpha[3] = 0;
+ pv->alpha[2] = 0;
+ pv->alpha[1] = 0;
+ pv->alpha[0] = 0;
+
for( i = pv->size_rle; ; )
{
date = ( pv->buf[i] << 8 ) | pv->buf[i+1]; i += 2;
{
command = pv->buf[i++];
- if( command == 0xFF )
+ /*
+ * There are eight commands available for
+ * Sub-Pictures. The first SP_DCSQ should contain, as a
+ * minimum, SET_COLOR, SET_CONTR, SET_DAREA, and
+ * SET_DSPXA
+ */
+
+ if( command == 0xFF ) // 0xFF - CMD_END - ends one SP_DCSQ
{
break;
}
switch( command )
{
- case 0x00:
+ case 0x00: // 0x00 - FSTA_DSP - Forced Start Display, no arguments
+ pv->pts_start = pv->pts + date * 900;
+ pv->pts_forced = 1;
+
+ /*
+ * If we are doing a subtitle scan then note down
+ */
+ if( job->indepth_scan )
+ {
+ for( n=0; n < hb_list_count(title->list_subtitle); n++ )
+ {
+ subtitle = hb_list_item( title->list_subtitle, n);
+ if( pv->stream_id == subtitle->id ) {
+ /*
+ * A hit, count it.
+ */
+ subtitle->forced_hits++;
+ }
+ }
+ }
break;
- case 0x01:
+ case 0x01: // 0x01 - STA_DSP - Start Display, no arguments
pv->pts_start = pv->pts + date * 900;
+ pv->pts_forced = 0;
break;
- case 0x02:
- pv->pts_stop = pv->pts + date * 900;
+ case 0x02: // 0x02 - STP_DSP - Stop Display, no arguments
+ if(!pv->pts_stop)
+ pv->pts_stop = pv->pts + date * 900;
break;
- case 0x03:
- {
+ case 0x03: // 0x03 - SET_COLOR - Set Colour indices
+ {
+ /*
+ * SET_COLOR - provides four indices into the CLUT
+ * for the current PGC to associate with the four
+ * pixel values
+ */
int colors[4];
int j;
pv->chromaU[3-j],
pv->chromaV[3-j]);
*/
- }
+ }
i += 2;
break;
}
- case 0x04:
+ case 0x04: // 0x04 - SET_CONTR - Set Contrast
{
- pv->alpha[3] = (pv->buf[i+0]>>4)&0x0f;
- pv->alpha[2] = (pv->buf[i+0])&0x0f;
- pv->alpha[1] = (pv->buf[i+1]>>4)&0x0f;
- pv->alpha[0] = (pv->buf[i+1])&0x0f;
+ /*
+ * SET_CONTR - directly provides the four contrast
+ * (alpha blend) values to associate with the four
+ * pixel values
+ */
+ uint8_t alpha[4];
+
+ alpha[3] = (pv->buf[i+0]>>4)&0x0f;
+ alpha[2] = (pv->buf[i+0])&0x0f;
+ alpha[1] = (pv->buf[i+1]>>4)&0x0f;
+ alpha[0] = (pv->buf[i+1])&0x0f;
+
+
+ int lastAlpha = pv->alpha[3] + pv->alpha[2] + pv->alpha[1] + pv->alpha[0];
+ int currAlpha = alpha[3] + alpha[2] + alpha[1] + alpha[0];
+
+ // fading-in, save the highest alpha value
+ if( currAlpha > lastAlpha )
+ {
+ pv->alpha[3] = alpha[3];
+ pv->alpha[2] = alpha[2];
+ pv->alpha[1] = alpha[1];
+ pv->alpha[0] = alpha[0];
+ }
+
+ // fading-out
+ if( currAlpha < lastAlpha && !pv->pts_stop )
+ {
+ pv->pts_stop = pv->pts + date * 900;
+ }
+
i += 2;
break;
}
- case 0x05:
+ case 0x05: // 0x05 - SET_DAREA - defines the display area
{
pv->x = (pv->buf[i+0]<<4) | ((pv->buf[i+1]>>4)&0x0f);
pv->width = (((pv->buf[i+1]&0x0f)<<8)| pv->buf[i+2]) - pv->x + 1;
i += 6;
break;
}
- case 0x06:
+ case 0x06: // 0x06 - SET_DSPXA - defines the pixel data addresses
{
pv->offsets[0] = ( pv->buf[i] << 8 ) | pv->buf[i+1]; i += 2;
pv->offsets[1] = ( pv->buf[i] << 8 ) | pv->buf[i+1]; i += 2;
}
}
}
+
+
if( i > next )
{
int * offset;
hb_buffer_t * buf;
uint8_t * buf_raw = NULL;
+ hb_job_t * job = pv->job;
/* Get infos about the subtitle */
ParseControls( w );
+ if( job->indepth_scan || ( job->subtitle_force && pv->pts_forced == 0 ) )
+ {
+ /*
+ * Don't encode subtitles when doing a scan.
+ *
+ * When forcing subtitles, ignore all those that don't
+ * have the forced flag set.
+ */
+ return NULL;
+ }
+
/* Do the actual decoding now */
- buf_raw = malloc( pv->width * pv->height * 4 );
+ buf_raw = malloc( ( pv->width * pv->height ) * 4 );
#define GET_NEXT_NIBBLE code = ( code << 4 ) | ( ( ( *offset & 1 ) ? \
( pv->buf[((*offset)>>1)] & 0xF ) : ( pv->buf[((*offset)>>1)] >> 4 ) ) ); \