diff options
author | Diego 'Flameeyes' Pettenò <flameeyes@gmail.com> | 2008-03-01 03:05:13 +0100 |
---|---|---|
committer | Diego 'Flameeyes' Pettenò <flameeyes@gmail.com> | 2008-03-01 03:05:13 +0100 |
commit | 1d0b3b20c34517b9d1ddf3ea347776304b0c4b44 (patch) | |
tree | 89f4fc640c2becc6f00ae08996754952ecf149c1 /contrib/ffmpeg/vhook/imlib2.c | |
parent | 09496ad3469a0ade8dbd9a351e639b78f20b7942 (diff) | |
download | xine-lib-1d0b3b20c34517b9d1ddf3ea347776304b0c4b44.tar.gz xine-lib-1d0b3b20c34517b9d1ddf3ea347776304b0c4b44.tar.bz2 |
Update internal FFmpeg copy.
Diffstat (limited to 'contrib/ffmpeg/vhook/imlib2.c')
-rw-r--r-- | contrib/ffmpeg/vhook/imlib2.c | 183 |
1 files changed, 113 insertions, 70 deletions
diff --git a/contrib/ffmpeg/vhook/imlib2.c b/contrib/ffmpeg/vhook/imlib2.c index 4e6ffb67c..7df4c0aca 100644 --- a/contrib/ffmpeg/vhook/imlib2.c +++ b/contrib/ffmpeg/vhook/imlib2.c @@ -2,52 +2,6 @@ * imlib2 based hook * Copyright (c) 2002 Philip Gladstone * - * This module implements a text overlay for a video image. Currently it - * supports a fixed overlay or reading the text from a file. The string - * is passed through strftime so that it is easy to imprint the date and - * time onto the image. - * - * You may also overlay an image (even semi-transparent) like TV stations do. - * You may move either the text or the image around your video to create - * scrolling credits, for example. - * - * Text fonts are being looked for in FONTPATH - * - * Options: - * - * -c <color> The color of the text - * -F <fontname> The font face and size - * -t <text> The text - * -f <filename> The filename to read text from - * -x <expresion> X coordinate of text or image - * -y <expresion> Y coordinate of text or image - * -i <filename> The filename to read a image from - * - * Expresions are functions of: - * N // frame number (starting at zero) - * H // frame height - * W // frame width - * h // image height - * w // image width - * X // previous x - * Y // previous y - * - - Examples: - - FONTPATH="/cygdrive/c/WINDOWS/Fonts/" - FONTPATH="$FONTPATH:/usr/share/imlib2/data/fonts/" - FONTPATH="$FONTPATH:/usr/X11R6/lib/X11/fonts/TTF/" - export FONTPATH - - ffmpeg -i input.avi -vhook \ - 'vhook/imlib2.dll -x W*(0.5+0.25*sin(N/47*PI))-w/2 -y H*(0.5+0.50*cos(N/97*PI))-h/2 -i /usr/share/imlib2/data/images/bulb.png' - -acodec copy -sameq output.avi - - ffmpeg -i input.avi -vhook \ - 'vhook/imlib2.dll -c red -F Vera.ttf/20 -x 150+0.5*N -y 70+0.25*N -t Hello' - -acodec copy -sameq output.avi - * 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 @@ -126,10 +80,13 @@ typedef struct { Imlib_Font fn; char *text; char *file; - int r, g, b; + 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; + struct CachedImage *cache; Imlib_Image imageOverlaid; AVEvalExpr *eval_x, *eval_y; char *expr_x, *expr_y; @@ -142,8 +99,8 @@ typedef struct { struct SwsContext *fromRGB_convert_ctx; } ContextInfo; -typedef struct _CachedImage { - struct _CachedImage *next; +typedef struct CachedImage { + struct CachedImage *next; Imlib_Image image; int width; int height; @@ -164,8 +121,19 @@ void Release(void *ctx) imlib_context_set_image(ci->imageOverlaid); imlib_free_image(); } - ff_eval_free(ci->expr_x); - ff_eval_free(ci->expr_y); + 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); @@ -176,11 +144,13 @@ 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; @@ -190,7 +160,7 @@ int Configure(void **ctxp, int argc, char *argv[]) ci->expr_x = "0.0"; ci->expr_y = "0.0"; - optind = 0; + optind = 1; /* Use ':' to split FONTPATH */ if (fp) @@ -203,8 +173,26 @@ int Configure(void **ctxp, int argc, char *argv[]) imlib_add_path_to_font_path(fp); - while ((c = getopt(argc, argv, "c:f:F:t:x:y:i:")) > 0) { + 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; @@ -232,25 +220,42 @@ int Configure(void **ctxp, int argc, char *argv[]) } } - if (ci->text || ci->file) { - ci->fn = imlib_load_font(font); - if (!ci->fn) { - fprintf(stderr, "Failed to load font '%s'\n", font); + 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; } - imlib_context_set_font(ci->fn); - imlib_context_set_direction(IMLIB_TEXT_TO_RIGHT); + + 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; - f = fopen("/usr/share/X11/rgb.txt", "r"); - if (!f) - f = fopen("/usr/lib/X11/rgb.txt", "r"); + if (ci->eval_colors) + { + fprintf(stderr, "You must not specify both a color name and expressions for the colors.\n"); + return -1; + } + + if (rgbtxt) + f = fopen(rgbtxt, "r"); + else + { + f = fopen("/usr/share/X11/rgb.txt", "r"); + if (!f) + f = fopen("/usr/lib/X11/rgb.txt", "r"); + } if (!f) { - fprintf(stderr, "Failed to find rgb.txt\n"); + fprintf(stderr, "Failed to find RGB color names file\n"); return -1; } while (fgets(buff, sizeof(buff), f)) { @@ -272,8 +277,32 @@ int Configure(void **ctxp, int argc, char *argv[]) fprintf(stderr, "Unable to find color '%s' in rgb.txt\n", color); return -1; } + } else if (ci->eval_colors) { + if (!(ci->eval_r = ff_parse(ci->expr_R, const_names, NULL, NULL, NULL, NULL, &error))){ + av_log(NULL, AV_LOG_ERROR, "Couldn't parse R expression '%s': %s\n", ci->expr_R, error); + return -1; + } + if (!(ci->eval_g = ff_parse(ci->expr_G, const_names, NULL, NULL, NULL, NULL, &error))){ + av_log(NULL, AV_LOG_ERROR, "Couldn't parse G expression '%s': %s\n", ci->expr_G, error); + return -1; + } + if (!(ci->eval_b = ff_parse(ci->expr_B, const_names, NULL, NULL, NULL, NULL, &error))){ + av_log(NULL, AV_LOG_ERROR, "Couldn't parse B expression '%s': %s\n", ci->expr_B, error); + return -1; + } } - imlib_context_set_color(ci->r, ci->g, ci->b, 255); + + if (ci->expr_A) { + if (!(ci->eval_a = ff_parse(ci->expr_A, const_names, NULL, NULL, NULL, NULL, &error))){ + av_log(NULL, AV_LOG_ERROR, "Couldn't parse A expression '%s': %s\n", ci->expr_A, error); + return -1; + } + } else { + ci->a = 255; + } + + if (!(ci->eval_colors || ci->eval_a)) + imlib_context_set_color(ci->r, ci->g, ci->b, ci->a); /* load the image (for example, credits for a movie) */ if (ci->fileImage) { @@ -287,13 +316,13 @@ int Configure(void **ctxp, int argc, char *argv[]) ci->imageOverlaid_height = imlib_image_get_height(); } - if (!(ci->eval_x = ff_parse(ci->expr_x, const_names, NULL, NULL, NULL, NULL, NULL))){ - av_log(NULL, AV_LOG_ERROR, "Couldn't parse x expression '%s'\n", ci->expr_x); + if (!(ci->eval_x = ff_parse(ci->expr_x, const_names, NULL, NULL, NULL, NULL, &error))){ + av_log(NULL, AV_LOG_ERROR, "Couldn't parse x expression '%s': %s\n", ci->expr_x, error); return -1; } - if (!(ci->eval_y = ff_parse(ci->expr_y, const_names, NULL, NULL, NULL, NULL, NULL))){ - av_log(NULL, AV_LOG_ERROR, "Couldn't parse y expression '%s'\n", ci->expr_y); + if (!(ci->eval_y = ff_parse(ci->expr_y, const_names, NULL, NULL, NULL, NULL, &error))){ + av_log(NULL, AV_LOG_ERROR, "Couldn't parse y expression '%s': %s\n", ci->expr_y, error); return -1; } @@ -340,7 +369,7 @@ void Process(void *ctx, AVPicture *picture, enum PixelFormat pix_fmt, int width, imlib_context_set_image(image); data = imlib_image_get_data(); - avpicture_fill(&picture1, (uint8_t *) data, PIX_FMT_RGB32, width, height); + avpicture_fill(&picture1, (uint8_t *) data, PIX_FMT_RGB32, width, height); // if we already got a SWS context, let's realloc if is not re-useable ci->toRGB_convert_ctx = sws_getCachedContext(ci->toRGB_convert_ctx, @@ -410,6 +439,20 @@ void Process(void *ctx, AVPicture *picture, enum PixelFormat pix_fmt, int width, ci->y = ff_parse_eval(ci->eval_y, const_values, ci); y = ci->y; + if (ci->eval_a) { + ci->a = ff_parse_eval(ci->eval_a, const_values, ci); + } + + if (ci->eval_colors) { + ci->r = ff_parse_eval(ci->eval_r, const_values, ci); + ci->g = ff_parse_eval(ci->eval_g, const_values, ci); + ci->b = ff_parse_eval(ci->eval_b, const_values, ci); + } + + if (ci->eval_colors || ci->eval_a) { + imlib_context_set_color(ci->r, ci->g, ci->b, ci->a); + } + if (!(ci->imageOverlaid)) for (p = buff; p; p = q) { q = strchr(p, '\n'); |