Release 0.12.0

This commit is contained in:
matze19999 committed 2026-10-06 22:01:38 +02:00
1 parent f74a658097
commit 7f6eeab39e
48 files changed
+3617 -1266

No files matched your search

+79 -33
View File
@@ -5,43 +5,89 @@
#include <string.h>
#include <dlfcn.h>
typedef struct {
void *lib;void *(*parse)(const char*);int (*get)(const void*,const char*,void**);
int (*type)(const void*);size_t (*length)(const void*);void *(*at)(const void*,size_t);
const char *(*string)(const void*);int (*boolean)(const void*);int (*put)(void*);
void *lib;
void *(*parse)(const char *);
int (*get)(const void *, const char *, void **);
int (*type)(const void *);
size_t (*length)(const void *);
void *(*at)(const void *, size_t);
const char *(*string)(const void *);
int (*boolean)(const void *);
int (*put)(void *);
} PlaybackJson;
static inline bool playback_json_init(PlaybackJson *j){
j->lib=dlopen("libjson-c.so.5",RTLD_NOW);if(!j->lib)return false;
j->parse=dlsym(j->lib,"json_tokener_parse");j->get=dlsym(j->lib,"json_object_object_get_ex");
j->type=dlsym(j->lib,"json_object_get_type");j->length=dlsym(j->lib,"json_object_array_length");
j->at=dlsym(j->lib,"json_object_array_get_idx");j->string=dlsym(j->lib,"json_object_get_string");
j->boolean=dlsym(j->lib,"json_object_get_boolean");j->put=dlsym(j->lib,"json_object_put");
if(!j->parse||!j->get||!j->type||!j->length||!j->at||!j->string||!j->boolean||!j->put){dlclose(j->lib);j->lib=NULL;return false;}return true;
static inline bool playback_json_init(PlaybackJson *j) {
j->lib = dlopen("libjson-c.so.5", RTLD_NOW);
if (!j->lib)
return false;
j->parse = dlsym(j->lib, "json_tokener_parse");
j->get = dlsym(j->lib, "json_object_object_get_ex");
j->type = dlsym(j->lib, "json_object_get_type");
j->length = dlsym(j->lib, "json_object_array_length");
j->at = dlsym(j->lib, "json_object_array_get_idx");
j->string = dlsym(j->lib, "json_object_get_string");
j->boolean = dlsym(j->lib, "json_object_get_boolean");
j->put = dlsym(j->lib, "json_object_put");
if (!j->parse || !j->get || !j->type || !j->length || !j->at || !j->string || !j->boolean ||
!j->put) {
dlclose(j->lib);
j->lib = NULL;
return false;
}
return true;
}
static inline void *playback_field(PlaybackJson *j,void *o,const char *key){void *v=NULL;return o && j->type(o)==4 && j->get(o,key,&v)?v:NULL;}
static inline bool playback_true(PlaybackJson *j,void *o,const char *key){void *v=playback_field(j,o,key);return v && j->type(v)==1 && j->boolean(v);}
static inline bool playback_is(PlaybackJson *j,void *o,const char *key,const char *value){void *v=playback_field(j,o,key);return v && j->type(v)==6 && strcmp(j->string(v),value)==0;}
typedef enum {PLAYBACK_UNKNOWN,PLAYBACK_CLEAR,PLAYBACK_PROTECTED} PlaybackProtection;
static inline void *playback_field(PlaybackJson *j, void *o, const char *key) {
void *v = NULL;
return o && j->type(o) == 4 && j->get(o, key, &v) ? v : NULL;
}
static inline bool playback_true(PlaybackJson *j, void *o, const char *key) {
void *v = playback_field(j, o, key);
return v && j->type(v) == 1 && j->boolean(v);
}
static inline bool playback_is(PlaybackJson *j, void *o, const char *key, const char *value) {
void *v = playback_field(j, o, key);
return v && j->type(v) == 6 && strcmp(j->string(v), value) == 0;
}
typedef enum { PLAYBACK_UNKNOWN, PLAYBACK_CLEAR, PLAYBACK_PROTECTED } PlaybackProtection;
/* G4 resource-state classification, not black-frame or app-name guessing.
* Any active Secure Video Path wins. Only a foreground media decoder without
* a secure resource is eligible; HDMI, idle and malformed replies are unknown. */
static inline PlaybackProtection playback_classify(PlaybackJson *j,const char *text){
void *root=j->parse(text);if(!root)return PLAYBACK_UNKNOWN;
bool clear=false,invalid=j->type(root)!=5,secure=false;
size_t n=invalid?0:j->length(root);
for(size_t i=0;i<n;i++){
void *p=j->at(root,i);if(!p || j->type(p)!=4){invalid=true;continue;}
void *resources=playback_field(j,p,"resource");if(!resources)resources=playback_field(j,p,"resources");
if(!resources || j->type(resources)!=5){invalid=true;continue;}
bool decoder=false;
for(size_t k=0;k<j->length(resources);k++){
void *resource=j->at(resources,k);void *name=playback_field(j,resource,"resource");
if(!name || j->type(name)!=6){invalid=true;continue;}
const char *s=j->string(name);
if(strcmp(s,"SVP_CPB")==0)secure=true;
if(strcmp(s,"VDEC")==0)decoder=true;
}
if(decoder && playback_true(j,p,"is_foreground") && playback_is(j,p,"type","media"))clear=true;
}
j->put(root);return secure?PLAYBACK_PROTECTED:clear&&!invalid?PLAYBACK_CLEAR:PLAYBACK_UNKNOWN;
static inline PlaybackProtection playback_classify(PlaybackJson *j, const char *text) {
void *root = j->parse(text);
if (!root)
return PLAYBACK_UNKNOWN;
bool clear = false, invalid = j->type(root) != 5, secure = false;
size_t n = invalid ? 0 : j->length(root);
for (size_t i = 0; i < n; i++) {
void *p = j->at(root, i);
if (!p || j->type(p) != 4) {
invalid = true;
continue;
}
void *resources = playback_field(j, p, "resource");
if (!resources)
resources = playback_field(j, p, "resources");
if (!resources || j->type(resources) != 5) {
invalid = true;
continue;
}
bool decoder = false;
for (size_t k = 0; k < j->length(resources); k++) {
void *resource = j->at(resources, k);
void *name = playback_field(j, resource, "resource");
if (!name || j->type(name) != 6) {
invalid = true;
continue;
}
const char *s = j->string(name);
if (strcmp(s, "SVP_CPB") == 0)
secure = true;
if (strcmp(s, "VDEC") == 0)
decoder = true;
}
if (decoder && playback_true(j, p, "is_foreground") && playback_is(j, p, "type", "media"))
clear = true;
}
j->put(root);
return secure ? PLAYBACK_PROTECTED : clear && !invalid ? PLAYBACK_CLEAR : PLAYBACK_UNKNOWN;
}
#endif