Change license headers to say 'FFmpeg' instead of 'this program/this library'
[ffmpeg.git] / libavformat / framehook.c
1 /*
2  * Video processing hooks
3  * Copyright (c) 2000, 2001 Fabrice Bellard.
4  *
5  * This file is part of FFmpeg.
6  *
7  * FFmpeg is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * FFmpeg is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with FFmpeg; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20  */
21 #include <errno.h>
22 #include "config.h"
23 #include "avformat.h"
24 #include "framehook.h"
25
26 #ifdef CONFIG_HAVE_DLFCN
27 #include <dlfcn.h>
28 #endif
29
30
31 typedef struct _FrameHookEntry {
32     struct _FrameHookEntry *next;
33     FrameHookConfigureFn Configure;
34     FrameHookProcessFn Process;
35     FrameHookReleaseFn Release;
36     void *ctx;
37 } FrameHookEntry;
38
39 static FrameHookEntry *first_hook;
40
41 /* Returns 0 on OK */
42 int frame_hook_add(int argc, char *argv[])
43 {
44 #ifdef HAVE_VHOOK
45     void *loaded;
46     FrameHookEntry *fhe, **fhep;
47
48     if (argc < 1) {
49         return ENOENT;
50     }
51
52     loaded = dlopen(argv[0], RTLD_NOW);
53     if (!loaded) {
54         av_log(NULL, AV_LOG_ERROR, "%s\n", dlerror());
55         return -1;
56     }
57
58     fhe = av_mallocz(sizeof(*fhe));
59     if (!fhe) {
60         return errno;
61     }
62
63     fhe->Configure = dlsym(loaded, "Configure");
64     fhe->Process = dlsym(loaded, "Process");
65     fhe->Release = dlsym(loaded, "Release");    /* Optional */
66
67     if (!fhe->Process) {
68         av_log(NULL, AV_LOG_ERROR, "Failed to find Process entrypoint in %s\n", argv[0]);
69         return -1;
70     }
71
72     if (!fhe->Configure && argc > 1) {
73         av_log(NULL, AV_LOG_ERROR, "Failed to find Configure entrypoint in %s\n", argv[0]);
74         return -1;
75     }
76
77     if (argc > 1 || fhe->Configure) {
78         if (fhe->Configure(&fhe->ctx, argc, argv)) {
79             av_log(NULL, AV_LOG_ERROR, "Failed to Configure %s\n", argv[0]);
80             return -1;
81         }
82     }
83
84     for (fhep = &first_hook; *fhep; fhep = &((*fhep)->next)) {
85     }
86
87     *fhep = fhe;
88
89     return 0;
90 #else
91     av_log(NULL, AV_LOG_ERROR, "Video hooking not compiled into this version\n");
92     return 1;
93 #endif
94 }
95
96 void frame_hook_process(AVPicture *pict, enum PixelFormat pix_fmt, int width, int height)
97 {
98     if (first_hook) {
99         FrameHookEntry *fhe;
100         int64_t pts = av_gettime();
101
102         for (fhe = first_hook; fhe; fhe = fhe->next) {
103             fhe->Process(fhe->ctx, pict, pix_fmt, width, height, pts);
104         }
105     }
106 }
107
108 void frame_hook_release(void)
109 {
110     FrameHookEntry *fhe;
111     FrameHookEntry *fhenext;
112
113     for (fhe = first_hook; fhe; fhe = fhenext) {
114         fhenext = fhe->next;
115         if (fhe->Release)
116             fhe->Release(fhe->ctx);
117         av_free(fhe);
118     }
119
120     first_hook = NULL;
121 }