[FFmpeg-devel] [RFC] cryptokey options

Reimar Döffinger Reimar.Doeffinger
Sun Dec 2 20:13:56 CET 2007


Hello,
On Fri, Oct 19, 2007 at 03:24:38PM +0200, Reimar D?ffinger wrote:
> On Fri, Oct 19, 2007 at 02:45:45PM +0200, Baptiste Coudurier wrote:
> > Reimar D?ffinger wrote:
> > > On Fri, Oct 19, 2007 at 03:00:20PM +0300, Kostya wrote:
> > >> On Fri, Oct 19, 2007 at 12:29:44PM +0200, Reimar D?ffinger wrote:
> > >>> I tried to implement this via a generic "binary" option type, but it
> > >>> does not seem to work, avfc->key stays NULL in the demuxer.
> > >>> Maybe that is just because I don't know how to use ffmpeg though...
> > >>> Fixes welcome.
> > >> Preserve original 'bin' variable pointer.
> > >> You seem to memcpy data _after_ decoded string.
> > > 
> > > Ouch, obviously. But that does not explain why key kept being NULL in
> > > the demuxer...
> > > 
> > 
> > I think problem is in opt_input_file:
> > 
> >  for(i=0; i<opt_name_count; i++){
> >         const AVOption *opt;
> >         double d= av_get_double(avformat_opts, opt_names[i], &opt);
> >         if(!isnan(d) && (opt->flags&AV_OPT_FLAG_DECODING_PARAM))
> >             av_set_double(ic, opt_names[i], d);
> >     }
> > 
> > Here av_get_double for cryptokey returns nan.
> 
> Grmpf. That code does not even handle the existing string and
> AVRational stuff correctly (though the later at least works "mostly").

Kostya fixed most of the problems, so here is an updated patch.
Does it look okay? (I do not really know much about how this option
stuff is supposed to work in the details)

Greetings,
Reimar D?ffinger
-------------- next part --------------
Index: ffmpeg.c
===================================================================
--- ffmpeg.c	(revision 11086)
+++ ffmpeg.c	(working copy)
@@ -2681,6 +2681,12 @@
         double d= av_get_double(avformat_opts, opt_names[i], &opt);
         if(!isnan(d) && (opt->flags&AV_OPT_FLAG_DECODING_PARAM))
             av_set_double(ic, opt_names[i], d);
+        else if((opt->flags&AV_OPT_FLAG_DECODING_PARAM) && opt->type == FF_OPT_TYPE_BINARY){
+            char str[256];
+            int strlen = 256;
+            if(av_get_string(avformat_opts, opt_names[i], &opt, str, strlen) != NULL)
+                av_set_string(ic, opt_names[i], str);
+        }
     }
     /* open the input file with generic libav function */
     err = av_open_input_file(&ic, filename, file_iformat, 0, ap);
Index: libavcodec/opt.c
===================================================================
--- libavcodec/opt.c	(revision 11089)
+++ libavcodec/opt.c	(working copy)
@@ -69,6 +69,7 @@
     case FF_OPT_TYPE_RATIONAL:
         if((int)num == num) *(AVRational*)dst= (AVRational){num*intnum, den};
         else                *(AVRational*)dst= av_d2q(num*intnum/den, 1<<24);
+        break;
     default:
         return NULL;
     }
@@ -107,6 +108,13 @@
     0
 };
 
+static int hexchar2int(char c) {
+    if (c >= '0' && c <= '9') return c - '0';
+    if (c >= 'a' && c <= 'f') return c - 'a' + 10;
+    if (c >= 'A' && c <= 'F') return c - 'A' + 10;
+    return -1;
+}
+
 const AVOption *av_set_string(void *obj, const char *name, const char *val){
     const AVOption *o= av_find_opt(obj, name, NULL, 0, 0);
     if(o && o->offset==0 && o->type == FF_OPT_TYPE_CONST && o->unit){
@@ -114,6 +122,25 @@
     }
     if(!o || !val || o->offset<=0)
         return NULL;
+    if(o->type == FF_OPT_TYPE_BINARY){
+        uint8_t *bin, *ptr;
+        int len = strlen(val);
+        if (len & 1) return NULL;
+        len /= 2;
+        ptr = bin = av_malloc(len);
+        while (*val) {
+            int a = hexchar2int(*val++);
+            int b = hexchar2int(*val++);
+            if (a < 0 || b < 0) {
+                av_free(bin);
+                return NULL;
+            }
+            *ptr++ = (a << 4) | b;
+        }
+        memcpy(((uint8_t*)obj) + o->offset , &bin, sizeof(bin));
+        memcpy(((uint8_t*)obj) + o->offset2, &len, sizeof(len));
+        return o;
+    }
     if(o->type != FF_OPT_TYPE_STRING){
         for(;;){
             int i;
@@ -183,6 +210,8 @@
 const char *av_get_string(void *obj, const char *name, const AVOption **o_out, char *buf, int buf_len){
     const AVOption *o= av_find_opt(obj, name, NULL, 0, 0);
     void *dst;
+    uint8_t *bin;
+    int len, i;
     if(!o || o->offset<=0)
         return NULL;
     if(o->type != FF_OPT_TYPE_STRING && (!buf || !buf_len))
@@ -201,6 +230,12 @@
     case FF_OPT_TYPE_FLOAT:     snprintf(buf, buf_len, "%f" , *(float  *)dst);break;
     case FF_OPT_TYPE_DOUBLE:    snprintf(buf, buf_len, "%f" , *(double *)dst);break;
     case FF_OPT_TYPE_RATIONAL:  snprintf(buf, buf_len, "%d/%d", ((AVRational*)dst)->num, ((AVRational*)dst)->den);break;
+    case FF_OPT_TYPE_BINARY:
+        len = *(int*)(((uint8_t*)obj) + o->offset2);
+        if(len >= (buf_len + 1)/2) return NULL;
+        bin = *(uint8_t**)dst;
+        for(i = 0; i < len; i++) snprintf(buf + i*2, 3, "%02X", bin[i]);
+        break;
     default: return NULL;
     }
     return buf;
@@ -307,6 +342,9 @@
             case FF_OPT_TYPE_RATIONAL:
                 av_log( av_log_obj, AV_LOG_INFO, "%-7s ", "<rational>" );
                 break;
+            case FF_OPT_TYPE_BINARY:
+                av_log( av_log_obj, AV_LOG_INFO, "%-7s ", "<binary>" );
+                break;
             case FF_OPT_TYPE_CONST:
             default:
                 av_log( av_log_obj, AV_LOG_INFO, "%-7s ", "" );
@@ -374,6 +412,7 @@
             }
             break;
             case FF_OPT_TYPE_STRING:
+            case FF_OPT_TYPE_BINARY:
                 /* Cannot set default for string as default_val is of type * double */
             break;
             default:
Index: libavcodec/opt.h
===================================================================
--- libavcodec/opt.h	(revision 11089)
+++ libavcodec/opt.h	(working copy)
@@ -37,6 +37,7 @@
     FF_OPT_TYPE_FLOAT,
     FF_OPT_TYPE_STRING,
     FF_OPT_TYPE_RATIONAL,
+    FF_OPT_TYPE_BINARY,
     FF_OPT_TYPE_CONST=128,
 };
 
@@ -67,6 +68,7 @@
 #define AV_OPT_FLAG_SUBTITLE_PARAM  32
 //FIXME think about enc-audio, ... style flags
     const char *unit;
+    int offset2;
 } AVOption;
 
 
Index: libavformat/utils.c
===================================================================
--- libavformat/utils.c	(revision 11086)
+++ libavformat/utils.c	(working copy)
@@ -311,6 +311,7 @@
 {"track", " set the track number", OFFSET(track), FF_OPT_TYPE_INT, DEFAULT, 0, INT_MAX, E},
 {"year", "set the year", OFFSET(year), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX, E},
 {"analyzeduration", "how many microseconds are analyzed to estimate duration", OFFSET(max_analyze_duration), FF_OPT_TYPE_INT, 3*AV_TIME_BASE, 0, INT_MAX, D},
+{"cryptokey", "decryption key", OFFSET(key), FF_OPT_TYPE_BINARY, 0, 0, 0, D, NULL, OFFSET(keylen)},
 {NULL},
 };
 



More information about the ffmpeg-devel mailing list