changeset 24244:e446bad0872c

Implement X/27/0 packet decoding. It contains information about navigation links. Modified patch from Otvos Attila oattila at chello dot hu
author voroshil
date Tue, 28 Aug 2007 14:10:47 +0000
parents aeffa880c7d6
children 188964a48302
files DOCS/tech/slave.txt command.c input/input.c stream/tv.h stream/tvi_vbi.c
diffstat 5 files changed, 81 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
--- a/DOCS/tech/slave.txt	Tue Aug 28 13:54:27 2007 +0000
+++ b/DOCS/tech/slave.txt	Tue Aug 28 14:10:47 2007 +0000
@@ -330,6 +330,9 @@
     -    - Delete last digit from page number. (Backspace emulation, works only
            in page number editing mode.)
 
+teletext_go_link <1-6>
+    Follow given link on current teletext page
+
 tv_start_scan
     Start automatic tv channels scaning
 
--- a/command.c	Tue Aug 28 13:54:27 2007 +0000
+++ b/command.c	Tue Aug 28 14:10:47 2007 +0000
@@ -2452,6 +2452,13 @@
 		tvh->functions->control(tvh->priv,TV_VBI_CONTROL_ADD_DEC,&(cmd->args[0].v.s));
 	    break;
 	}
+	case MP_CMD_TV_TELETEXT_GO_LINK:
+	{
+	    tvi_handle_t* tvh=(tvi_handle_t *)(mpctx->demuxer->priv);
+	    if (mpctx->file_format == DEMUXER_TYPE_TV)
+		tvh->functions->control(tvh->priv,TV_VBI_CONTROL_GO_LINK,&(cmd->args[0].v.i));
+	    break;
+	}
 #endif /* HAVE_TV_TELETEXT */
 #endif				/* USE_TV */
 
--- a/input/input.c	Tue Aug 28 13:54:27 2007 +0000
+++ b/input/input.c	Tue Aug 28 14:10:47 2007 +0000
@@ -146,6 +146,7 @@
   { MP_CMD_VF_CHANGE_RECTANGLE, "change_rectangle", 2, { {MP_CMD_ARG_INT,{0}}, {MP_CMD_ARG_INT,{0}}, {-1,{0}}}},
 #ifdef HAVE_TV_TELETEXT
   { MP_CMD_TV_TELETEXT_ADD_DEC, "teletext_add_dec", 1, { {MP_CMD_ARG_STRING,{0}}, {-1,{0}} } },
+  { MP_CMD_TV_TELETEXT_GO_LINK, "teletext_go_link", 1, { {MP_CMD_ARG_INT,{0}}, {-1,{0}} } },
 #endif
 
 #ifdef HAVE_NEW_GUI  
--- a/stream/tv.h	Tue Aug 28 13:54:27 2007 +0000
+++ b/stream/tv.h	Tue Aug 28 14:10:47 2007 +0000
@@ -280,6 +280,11 @@
     unsigned char raw; ///< raw character (as received from device)
 } tt_char;
 
+typedef struct tt_link_s{
+    int pagenum;          ///< page number
+    int subpagenum;       ///< subpage number
+} tt_link_t;    
+
 typedef struct tt_page_s{
     int pagenum;          ///< page number
     int subpagenum;       ///< subpage number
@@ -288,6 +293,7 @@
     unsigned char flags;  ///< page flags, not used
     unsigned char raw[VBI_ROWS*VBI_COLUMNS]; ///< page data
     struct tt_page_s* next_subpage;
+    struct tt_link_s links[6];
 }  tt_page;
 
 typedef struct tt_stream_props_s{
--- a/stream/tvi_vbi.c	Tue Aug 28 13:54:27 2007 +0000
+++ b/stream/tvi_vbi.c	Tue Aug 28 14:10:47 2007 +0000
@@ -376,7 +376,7 @@
  */
 static void put_to_cache(priv_vbi_t* priv,tt_page* pg,int line){
     tt_page* pgc; //page in cache
-    int i,count;
+    int i,j,count;
 
     if(line<0){
         i=0;
@@ -406,6 +406,8 @@
     pgc->subpagenum=pg->subpagenum;
     pgc->lang=pg->lang;
     pgc->flags=pg->flags;
+    for(j=0;j<6;++j)
+        pgc->links[j]=pg->links[j];
     //instead of copying entire page into cache, copy only undamaged
     //symbols into cache
     for(;i<count;i++){
@@ -1015,6 +1017,42 @@
 }
 
 /**
+ * \brief decode packets 27 (teletext links)
+ * \param priv private data structure
+ * \param data raw teletext data
+ * \param magAddr teletext page's magazine address
+ */
+static int decode_pkt27(priv_vbi_t* priv,unsigned char* data,int magAddr){
+    int i,hpg;
+
+    if (!priv->mag[magAddr].pt)
+        return 0;
+    for(i=0;i<38;++i)
+        if ((data[i] = corrHamm48[ data[i] ]) & 0x80){
+            pll_add(priv,2,4);
+            return 0;
+        }
+
+    /* 
+      Not a X/27/0 Format 1 packet or
+      flag "show links on row 24" is not set.
+    */
+    if (data[0] || !(data[37] & 8))
+        return 1;
+    for(i=0;i<6;++i) {
+        hpg = (magAddr<<8) ^ ((data[4+i*6]&0x8)<<5 | (data[6+i*6]&0xc)<<7);
+        if (!hpg) hpg=0x800;
+        priv->mag[magAddr].pt->links[i].pagenum = (data[1+i*6] & 0xf) |
+                ((data[2+i*6] & 0xf) << 4) | hpg;
+        priv->mag[magAddr].pt->links[i].subpagenum = ((data[3+i*6] & 0xf) |
+                (data[4+i*6] & 0xf) << 4 | (data[5+i*6] & 0xf) << 8 |
+                (data[6+i*6] & 0xf) << 12) & 0x3f7f;
+    }
+    put_to_cache(priv,priv->mag[magAddr].pt,-1);
+    return 1;
+}
+
+/**
  * \brief decodes raw vbi data (signal amplitudes) into sequence of bytes
  * \param priv private data structure
  * \param buf raw vbi data (one line of frame)
@@ -1205,6 +1243,8 @@
         }else if(pkt>0 && pkt<VBI_ROWS){
             if(!priv->mag[magAddr].pt) continue;
             decode_pkt_page(priv,data+2,magAddr,pkt);//skip MRGA
+        }else if(pkt==27) {
+            decode_pkt27(priv,data+2,magAddr);
         }else if(pkt==30){
             decode_pkt30(priv,data+2,magAddr);
         } else {
@@ -1339,6 +1379,7 @@
 {
     int fine_tune=99;
     priv_vbi_t* priv=(priv_vbi_t*)p;
+    tt_page* pgc;
 
     if (!priv && cmd!=TV_VBI_CONTROL_START)
         return TVI_CONTROL_FALSE;
@@ -1424,6 +1465,28 @@
         pthread_mutex_unlock(&(priv->buffer_mutex));
         return TVI_CONTROL_TRUE;
     }
+    case TV_VBI_CONTROL_GO_LINK:
+    {
+        int val=*(int *) arg;
+        if(val<1 || val>6)
+            return TVI_CONTROL_FALSE;
+        pthread_mutex_lock(&(priv->buffer_mutex));
+        if (!(pgc = priv->ptt_cache[priv->pagenum])) {
+            pthread_mutex_unlock(&(priv->buffer_mutex));
+            return TVI_CONTROL_FALSE;
+        }
+        if (!pgc->links[val-1].pagenum || pgc->links[val-1].pagenum>0x7ff) {
+            pthread_mutex_unlock(&(priv->buffer_mutex));
+            return TVI_CONTROL_FALSE;
+        }
+        priv->pagenum=pgc->links[val-1].pagenum;
+        if(pgc->links[val-1].subpagenum!=0x3f7f)
+            priv->subpagenum=pgc->links[val-1].subpagenum;
+        else
+            priv->subpagenum=get_subpagenum_from_cache(priv,priv->pagenum);
+        pthread_mutex_unlock(&(priv->buffer_mutex));
+        return TVI_CONTROL_TRUE;
+    }
     case TV_VBI_CONTROL_SET_PAGE:
     {
         int val=*(int *) arg;