3 * Copyright (c) 2002 Philip Gladstone
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21 #include "framehook.h"
24 static int sws_flags = SWS_BICUBIC;
29 // This vhook first converts frame to RGB ...
30 struct SwsContext *toRGB_convert_ctx;
32 // ... and later converts back frame from RGB to initial format
33 struct SwsContext *fromRGB_convert_ctx;
35 enum PixelFormat sws_pix_fmt; // Sws_Context is opaque, we need to save
36 int sws_width, sws_height; // this to check if we can re-use contexts
37 // Contexts will be re-used 99% of time,
38 // I know of width/height changes only in DVB broadcasts
42 void Release(void *ctx)
45 ci = (ContextInfo *) ctx;
48 sws_freeContext(ci->toRGB_convert_ctx);
49 sws_freeContext(ci->fromRGB_convert_ctx);
54 int Configure(void **ctxp, int argc, char *argv[])
56 fprintf(stderr, "Called with argc=%d\n", argc);
58 *ctxp = av_mallocz(sizeof(ContextInfo));
62 void Process(void *ctx, AVPicture *picture, enum PixelFormat pix_fmt, int width, int height, int64_t pts)
64 ContextInfo *ci = (ContextInfo *) ctx;
67 AVPicture *pict = picture;
71 if (pix_fmt != PIX_FMT_RGB24) {
74 size = avpicture_get_size(PIX_FMT_RGB24, width, height);
75 buf = av_malloc(size);
77 avpicture_fill(&picture1, buf, PIX_FMT_RGB24, width, height);
79 // if we already got a SWS context, let's realloc if is not re-useable
80 if (ci->toRGB_convert_ctx != NULL) {
81 if ((ci->sws_pix_fmt != pix_fmt) ||
82 (ci->sws_width != width) || (ci->sws_height != height)) {
83 sws_freeContext(ci->toRGB_convert_ctx);
84 ci->toRGB_convert_ctx = NULL;
85 sws_freeContext(ci->fromRGB_convert_ctx);
86 ci->fromRGB_convert_ctx = NULL;
89 if (ci->toRGB_convert_ctx == NULL) {
90 ci->sws_pix_fmt = pix_fmt;
91 ci->sws_width = width;
92 ci->sws_height = height;
93 ci->toRGB_convert_ctx = sws_getContext(
94 ci->sws_width, ci->sws_height,
96 ci->sws_width, ci->sws_height,
98 sws_flags, NULL, NULL, NULL);
99 if (ci->toRGB_convert_ctx == NULL) {
100 av_log(NULL, AV_LOG_ERROR,
101 "Cannot initialize the toRGB conversion context\n");
104 ci->fromRGB_convert_ctx = sws_getContext(
105 ci->sws_width, ci->sws_height,
107 ci->sws_width, ci->sws_height,
109 sws_flags, NULL, NULL, NULL);
110 if (ci->fromRGB_convert_ctx == NULL) {
111 av_log(NULL, AV_LOG_ERROR,
112 "Cannot initialize the fromRGB conversion context\n");
116 // img_convert parameters are 2 first destination, then 4 source
117 // sws_scale parameters are context, 4 first source, then 2 destination
118 sws_scale(ci->toRGB_convert_ctx,
119 picture->data, picture->linesize, 0, ci->sws_height,
120 picture1.data, picture1.linesize);
125 /* Insert filter code here */
127 if (pix_fmt != PIX_FMT_RGB24) {
128 sws_scale(ci->fromRGB_convert_ctx,
129 picture1.data, picture1.linesize, 0, ci->sws_height,
130 picture->data, picture->linesize);