OSDN Git Service

Change subtitle position to prevent displaying within a 2% margin of the height of...
[handbrake-jp/handbrake-jp-git.git] / libhb / decsub.c
index da94ad1..209c1c8 100644 (file)
@@ -17,10 +17,12 @@ struct hb_work_private_s
     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];
@@ -52,6 +54,8 @@ int decsubWork( hb_work_object_t * w, hb_buffer_t ** buf_in,
 
     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];
 
@@ -91,6 +95,11 @@ int decsubWork( hb_work_object_t * w, hb_buffer_t ** buf_in,
         /* 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;
@@ -128,14 +137,21 @@ static void ParseControls( hb_work_object_t * w )
     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;
@@ -145,26 +161,59 @@ static void ParseControls( hb_work_object_t * w )
         {
             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;
 
@@ -198,20 +247,47 @@ static void ParseControls( hb_work_object_t * w )
                                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;
@@ -220,7 +296,7 @@ static void ParseControls( hb_work_object_t * w )
                     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;
@@ -228,6 +304,8 @@ static void ParseControls( hb_work_object_t * w )
                 }
             }
         }
+               
+
 
         if( i > next )
         {
@@ -385,12 +463,24 @@ static hb_buffer_t * Decode( hb_work_object_t * w )
     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 ) ) ); \