00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include <errno.h>
00022 #include "config.h"
00023 #include "avformat.h"
00024 #include "framehook.h"
00025
00026 #ifdef HAVE_DLFCN_H
00027 #include <dlfcn.h>
00028 #endif
00029
00030
00031 typedef struct FrameHookEntry {
00032 struct FrameHookEntry *next;
00033 FrameHookConfigureFn Configure;
00034 FrameHookProcessFn Process;
00035 FrameHookReleaseFn Release;
00036 void *ctx;
00037 } FrameHookEntry;
00038
00039 static FrameHookEntry *first_hook;
00040
00041
00042 int frame_hook_add(int argc, char *argv[])
00043 {
00044 #ifdef CONFIG_VHOOK
00045 void *loaded;
00046 FrameHookEntry *fhe, **fhep;
00047
00048 if (argc < 1) {
00049 return ENOENT;
00050 }
00051
00052 loaded = dlopen(argv[0], RTLD_NOW);
00053 if (!loaded) {
00054 av_log(NULL, AV_LOG_ERROR, "%s\n", dlerror());
00055 return -1;
00056 }
00057
00058 fhe = av_mallocz(sizeof(*fhe));
00059 if (!fhe) {
00060 return AVERROR(ENOMEM);
00061 }
00062
00063 fhe->Configure = dlsym(loaded, "Configure");
00064 fhe->Process = dlsym(loaded, "Process");
00065 fhe->Release = dlsym(loaded, "Release");
00066
00067 if (!fhe->Process) {
00068 av_log(NULL, AV_LOG_ERROR, "Failed to find Process entrypoint in %s\n", argv[0]);
00069 return AVERROR(ENOENT);
00070 }
00071
00072 if (!fhe->Configure && argc > 1) {
00073 av_log(NULL, AV_LOG_ERROR, "Failed to find Configure entrypoint in %s\n", argv[0]);
00074 return AVERROR(ENOENT);
00075 }
00076
00077 if (argc > 1 || fhe->Configure) {
00078 if (fhe->Configure(&fhe->ctx, argc, argv)) {
00079 av_log(NULL, AV_LOG_ERROR, "Failed to Configure %s\n", argv[0]);
00080 return AVERROR(EINVAL);
00081 }
00082 }
00083
00084 for (fhep = &first_hook; *fhep; fhep = &((*fhep)->next)) {
00085 }
00086
00087 *fhep = fhe;
00088
00089 return 0;
00090 #else
00091 av_log(NULL, AV_LOG_ERROR, "Video hooking not compiled into this version\n");
00092 return 1;
00093 #endif
00094 }
00095
00096 void frame_hook_process(AVPicture *pict, enum PixelFormat pix_fmt, int width, int height, int64_t pts)
00097 {
00098 if (first_hook) {
00099 FrameHookEntry *fhe;
00100
00101 for (fhe = first_hook; fhe; fhe = fhe->next) {
00102 fhe->Process(fhe->ctx, pict, pix_fmt, width, height, pts);
00103 }
00104 }
00105 }
00106
00107 void frame_hook_release(void)
00108 {
00109 FrameHookEntry *fhe;
00110 FrameHookEntry *fhenext;
00111
00112 for (fhe = first_hook; fhe; fhe = fhenext) {
00113 fhenext = fhe->next;
00114 if (fhe->Release)
00115 fhe->Release(fhe->ctx);
00116 av_free(fhe);
00117 }
00118
00119 first_hook = NULL;
00120 }