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#if HAVE_DLFCN_H 27#include <dlfcn.h> 28#endif 29 30 31typedef struct FrameHookEntry { 32 struct FrameHookEntry *next; 33 FrameHookConfigureFn Configure; 34 FrameHookProcessFn Process; 35 FrameHookReleaseFn Release; 36 void *ctx; 37} FrameHookEntry; 38 39static FrameHookEntry *first_hook; 40 41/* Returns 0 on OK */ 42int frame_hook_add(int argc, char *argv[]) 43{ 44 void *loaded; 45 FrameHookEntry *fhe, **fhep; 46 47 if (argc < 1) { 48 return ENOENT; 49 } 50 51 loaded = dlopen(argv[0], RTLD_NOW); 52 if (!loaded) { 53 av_log(NULL, AV_LOG_ERROR, "%s\n", dlerror()); 54 return -1; 55 } 56 57 fhe = av_mallocz(sizeof(*fhe)); 58 if (!fhe) { 59 return AVERROR(ENOMEM); 60 } 61 62 fhe->Configure = dlsym(loaded, "Configure"); 63 fhe->Process = dlsym(loaded, "Process"); 64 fhe->Release = dlsym(loaded, "Release"); /* Optional */ 65 66 if (!fhe->Process) { 67 av_log(NULL, AV_LOG_ERROR, "Failed to find Process entrypoint in %s\n", argv[0]); 68 return AVERROR(ENOENT); 69 } 70 71 if (!fhe->Configure && argc > 1) { 72 av_log(NULL, AV_LOG_ERROR, "Failed to find Configure entrypoint in %s\n", argv[0]); 73 return AVERROR(ENOENT); 74 } 75 76 if (argc > 1 || fhe->Configure) { 77 if (fhe->Configure(&fhe->ctx, argc, argv)) { 78 av_log(NULL, AV_LOG_ERROR, "Failed to Configure %s\n", argv[0]); 79 return AVERROR(EINVAL); 80 } 81 } 82 83 for (fhep = &first_hook; *fhep; fhep = &((*fhep)->next)) { 84 } 85 86 *fhep = fhe; 87 88 return 0; 89} 90 91void frame_hook_process(AVPicture *pict, enum PixelFormat pix_fmt, int width, int height, int64_t pts) 92{ 93 if (first_hook) { 94 FrameHookEntry *fhe; 95 96 for (fhe = first_hook; fhe; fhe = fhe->next) { 97 fhe->Process(fhe->ctx, pict, pix_fmt, width, height, pts); 98 } 99 } 100} 101 102void frame_hook_release(void) 103{ 104 FrameHookEntry *fhe; 105 FrameHookEntry *fhenext; 106 107 for (fhe = first_hook; fhe; fhe = fhenext) { 108 fhenext = fhe->next; 109 if (fhe->Release) 110 fhe->Release(fhe->ctx); 111 av_free(fhe); 112 } 113 114 first_hook = NULL; 115} 116