[MPlayer-users] Key Caching?

Jason Lunz j at falooley.org
Thu Oct 18 19:14:03 CEST 2001


david.harrigan at kmsoftware.com said:
> I was wondering how possible it is to cache keys after they have been
> decoded by the css libraries? I've had a look around some of

Yes, the patch below to libdvdcss-0.0.3 makes it cache keys from the
last-read dvd in ~/.csskeys. It isn't perfect, it should be able to
cache keys for every dvd, but I can't find a way to do that reliably
without changing the interface to libdvdread.

At least this way, you can play the same dvd more than once and all but
the first time will be fast. you should rm ~/.csskeys when you use a
different dvd.

Jason


diff -ur libdvdcss-0.0.3/extras/libdvdcss/libdvdcss.c libdvdcss-0.0.3-jl0/extras/libdvdcss/libdvdcss.c
--- libdvdcss-0.0.3/extras/libdvdcss/libdvdcss.c	Mon Aug  6 09:28:00 2001
+++ libdvdcss-0.0.3-jl0/extras/libdvdcss/libdvdcss.c	Thu Oct 11 22:28:46 2001
@@ -153,6 +153,89 @@
     return _dvdcss_seek( dvdcss, i_blocks );
 }
 
+static char *key_cache_filename(void)
+{
+    static char cached_name[PATH_MAX];
+
+    if( '\0' == cached_name[0] ) {
+	char *home_dir;
+
+	home_dir = getenv("HOME");
+	if( NULL != home_dir ) {
+	    snprintf(cached_name, sizeof(cached_name), "%s/.csskeys", home_dir);
+	}
+    }
+
+    return cached_name;
+}
+
+static void print_key( dvd_key_t key, FILE *fp )
+{
+    int i;
+    for( i = 0; i < KEY_SIZE; i++ ) {
+	if(i)
+	    fputc( ' ', fp );
+	fprintf( fp, "%2x", key[i] );
+    }
+}
+
+static void write_key_cache( dvd_title_t *p_title )
+{
+    char *cache_name = key_cache_filename();
+    FILE *cache_file;
+
+    cache_file = fopen(cache_name, "w");
+    if( NULL == cache_file ) {
+	perror(cache_name);
+	return;
+    }
+    for( ; NULL != p_title; p_title = p_title->p_next )
+    {
+	fprintf( cache_file, "%d: ", p_title->i_startlb );
+	print_key( p_title->p_key, cache_file );
+	fputc('\n', cache_file);
+    }
+    fclose(cache_file);
+}
+
+static void read_key_cache(dvd_title_t **p_title)
+{
+    char *cache_name = key_cache_filename();
+    FILE *cache_file;
+    if(NULL == cache_name || NULL == (cache_file = fopen(cache_name, "r"))) {
+	perror(cache_name);
+	return;
+    }
+    for(;;) {
+	int i_block;
+	int i_tokens;
+	unsigned int ia[KEY_SIZE];
+
+	i_tokens = fscanf( cache_file, "%d: %2x %2x %2x %2x %2x\n",
+		    &i_block, &ia[0], &ia[1], &ia[2], &ia[3], &ia[4]);
+	if( EOF == i_tokens ) {
+	    break;
+	} else if( 6 == i_tokens ) {
+	    dvd_title_t **p_tmp = p_title;
+	    dvd_title_t *p_new;
+	    int i;
+	    while( (NULL != *p_tmp) && ((*p_tmp)->i_startlb <= i_block)) {
+		p_tmp = &(*p_tmp)->p_next;
+	    }
+	    if(NULL == (p_new = malloc( sizeof(*p_new) ))) {
+		break;
+	    }
+	    p_new->i_startlb = i_block;
+	    for( i = 0; i < KEY_SIZE; i++ ) {
+		p_new->p_key[i] = ia[i];
+	    }
+	    p_new->p_next = *p_tmp;
+	    *p_tmp = p_new;
+	}
+    }
+    fclose( cache_file );
+}
+
 /*****************************************************************************
  * dvdcss_title: crack the current title key if needed
  *****************************************************************************/
@@ -167,9 +250,10 @@
         return 0;
     }
 
-    //fprintf( stderr, "looking for a key for offset %i\n", i_block );
-
     /* Check if we've already cracked this key */
+    if( NULL == dvdcss->p_titles ) {
+	read_key_cache( &dvdcss->p_titles );
+    }
     p_title = dvdcss->p_titles;
     while( p_title != NULL
             && p_title->p_next != NULL
@@ -199,9 +283,6 @@
         return -1;
     }
 
-    //fprintf( stderr, "cracked key is %.2x %.2x %.2x %.2x %.2x\n",
-    //         p_key[0], p_key[1], p_key[2], p_key[3], p_key[4] );
-
     /* Add key to keytable if it isn't empty */
     if( p_key[0] | p_key[1] | p_key[2] | p_key[3] | p_key[4] )
     {
@@ -238,6 +319,8 @@
         }
     }
 
+    write_key_cache( dvdcss->p_titles );
+
     return 0;
 }
 
@@ -850,3 +933,4 @@
 
 #endif
 
+// vim: sw=4



More information about the MPlayer-users mailing list