📄 imlib2.c
字号:
/*
* imlib2 based hook
* Copyright (c) 2002 Philip Gladstone
*
* This module is very much intended as an example of what could be done.
*
* One caution is that this is an expensive process -- in particular the
* conversion of the image into RGB and back is time consuming. For some
* special cases -- e.g. painting black text -- it would be faster to paint
* the text into a bitmap and then combine it directly into the YUV
* image. However, this code is fast enough to handle 10 fps of 320x240 on a
* 900MHz Duron in maybe 15% of the CPU.
* See further statistics on Pentium4, 3GHz, FFMpeg is SVN-r6798
* Input movie is 20.2 seconds of PAL DV on AVI
* Output movie is DVD compliant VOB.
*
ffmpeg -i input.avi -target pal-dvd out.vob
# 13.516s just transcode
ffmpeg -i input.avi -vhook /usr/local/bin/vhook/null.dll -target pal-dvd out.vob
# 23.546s transcode and img_convert
ffmpeg -i input.avi -vhook \
'vhook/imlib2.dll -c red -F Vera/20 -x 150-0.5*N -y 70+0.25*N -t Hello_person' \
-target pal-dvd out.vob
# 21.454s transcode, img_convert and move text around
ffmpeg -i input.avi -vhook \
'vhook/imlib2.dll -x 150-0.5*N -y 70+0.25*N -i /usr/share/imlib2/data/images/bulb.png' \
-target pal-dvd out.vob
# 20.828s transcode, img_convert and move image around
*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "framehook.h"
#include "swscale.h"
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <stdarg.h>
#include <string.h>
#include <unistd.h>
#undef time
#include <sys/time.h>
#include <time.h>
#include <Imlib2.h>
#include "eval.h"
const char *const_names[]={
"PI",
"E",
"N", // frame number (starting at zero)
"H", // frame height
"W", // frame width
"h", // image height
"w", // image width
"X", // previous x
"Y", // previous y
NULL
};
static int sws_flags = SWS_BICUBIC;
typedef struct {
int dummy;
Imlib_Font fn;
char *text;
char *file;
int r, g, b, a;
AVEvalExpr *eval_r, *eval_g, *eval_b, *eval_a;
char *expr_R, *expr_G, *expr_B, *expr_A;
int eval_colors;
double x, y;
char *fileImage;
struct _CachedImage *cache;
Imlib_Image imageOverlaid;
AVEvalExpr *eval_x, *eval_y;
char *expr_x, *expr_y;
int frame_number;
int imageOverlaid_width, imageOverlaid_height;
// This vhook first converts frame to RGB ...
struct SwsContext *toRGB_convert_ctx;
// ... and then converts back frame from RGB to initial format
struct SwsContext *fromRGB_convert_ctx;
} ContextInfo;
typedef struct _CachedImage {
struct _CachedImage *next;
Imlib_Image image;
int width;
int height;
} CachedImage;
void Release(void *ctx)
{
ContextInfo *ci;
ci = (ContextInfo *) ctx;
if (ci->cache) {
imlib_context_set_image(ci->cache->image);
imlib_free_image();
av_free(ci->cache);
}
if (ctx) {
if (ci->imageOverlaid) {
imlib_context_set_image(ci->imageOverlaid);
imlib_free_image();
}
ff_eval_free(ci->eval_x);
ff_eval_free(ci->eval_y);
ff_eval_free(ci->eval_r);
ff_eval_free(ci->eval_g);
ff_eval_free(ci->eval_b);
ff_eval_free(ci->eval_a);
av_free(ci->expr_x);
av_free(ci->expr_y);
av_free(ci->expr_R);
av_free(ci->expr_G);
av_free(ci->expr_B);
av_free(ci->expr_A);
sws_freeContext(ci->toRGB_convert_ctx);
sws_freeContext(ci->fromRGB_convert_ctx);
av_free(ctx);
}
}
int Configure(void **ctxp, int argc, char *argv[])
{
int c;
ContextInfo *ci;
char *rgbtxt = 0;
char *font = "LucidaSansDemiBold/16";
char *fp = getenv("FONTPATH");
char *color = 0;
FILE *f;
char *p;
char *error;
*ctxp = av_mallocz(sizeof(ContextInfo));
ci = (ContextInfo *) *ctxp;
ci->x = 0.0;
ci->y = 0.0;
ci->expr_x = "0.0";
ci->expr_y = "0.0";
optind = 0;
/* Use ':' to split FONTPATH */
if (fp)
while (p = strchr(fp, ':')) {
*p = 0;
imlib_add_path_to_font_path(fp);
fp = p + 1;
}
if ((fp) && (*fp))
imlib_add_path_to_font_path(fp);
while ((c = getopt(argc, argv, "R:G:B:A:C:c:f:F:t:x:y:i:")) > 0) {
switch (c) {
case 'R':
ci->expr_R = av_strdup(optarg);
ci->eval_colors = 1;
break;
case 'G':
ci->expr_G = av_strdup(optarg);
ci->eval_colors = 1;
break;
case 'B':
ci->expr_B = av_strdup(optarg);
ci->eval_colors = 1;
break;
case 'A':
ci->expr_A = av_strdup(optarg);
break;
case 'C':
rgbtxt = optarg;
break;
case 'c':
color = optarg;
break;
case 'F':
font = optarg;
break;
case 't':
ci->text = av_strdup(optarg);
break;
case 'f':
ci->file = av_strdup(optarg);
break;
case 'x':
ci->expr_x = av_strdup(optarg);
break;
case 'y':
ci->expr_y = av_strdup(optarg);
break;
case 'i':
ci->fileImage = av_strdup(optarg);
break;
case '?':
fprintf(stderr, "Unrecognized argument '%s'\n", argv[optind]);
return -1;
}
}
if (ci->eval_colors && !(ci->expr_R && ci->expr_G && ci->expr_B))
{
fprintf(stderr, "You must specify expressions for all or no colors.\n");
return -1;
}
if (ci->text || ci->file) {
ci->fn = imlib_load_font(font);
if (!ci->fn) {
fprintf(stderr, "Failed to load font '%s'\n", font);
return -1;
}
imlib_context_set_font(ci->fn);
imlib_context_set_direction(IMLIB_TEXT_TO_RIGHT);
}
if (color) {
char buff[256];
int done = 0;
if (ci->eval_colors)
{
fprintf(stderr, "You must not specify both a color name and expressions for the colors.\n");
return -1;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -