Permalink
Browse files

added patch

  • Loading branch information...
1 parent 618a57f commit be869b242b4cdff9125ed634a39939ee55211598 @refractalize committed Sep 12, 2009
Showing with 190 additions and 0 deletions.
  1. +190 −0 ffmpeg/vhook/watermark.patch
@@ -0,0 +1,190 @@
+--- watermark-old.c 2009-09-12 10:53:42.000000000 +0100
++++ watermark.c 2009-09-06 22:51:51.000000000 +0100
+@@ -3,7 +3,7 @@
+ * Copyright (c) 2005 Marcus Engene myfirstname(at)mylastname.se
+ *
+ * parameters for watermark:
+- * -m nbr = nbr is 0..1. 0 is the default mode, see below.
++ * -m nbr = nbr is 0..2. 0 is the default mode, see below.
+ * -t nbr = nbr is six digit hex. Threshold.
+ * -f file = file is the watermark image filename. You must specify this!
+ *
+@@ -29,13 +29,25 @@
+ * Per color do this:
+ * If mask color > threshold color then the watermark pixel is used.
+ *
++ * MODE 2:
++ * Paste the watermark image onto the video image respecting alpha channels.
++ *
++ * Alpha channels are regularly found in PNG images and affect the tranparency
++ * of the image. If the pixel has 0x00 alpha value it is entirely transparent
++ * and the original video pixel is unchanged. If the alpha value is 0xff
++ * (100%) the watermark pixel is used entirely. Otherwise, the following
++ * formula is used:
++ *
++ * video_pixel = (1 - alpha) * video_pixel + alpha * watermark_pixel
++ *
+ * Example usage:
+ * ffmpeg -i infile -vhook '/path/watermark.so -f wm.gif' -an out.mov
+ * ffmpeg -i infile -vhook '/path/watermark.so -f wm.gif -m 1 -t 222222' -an out.mov
++ * ffmpeg -i infile -vhook '/path/watermark.so -f wm.png -m 2' -an out.mov
+ *
+ * Note that the entire vhook argument is encapsulated in ''. This
+ * way, arguments to the vhook won't be mixed up with those for ffmpeg.
+- *
++ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+@@ -309,6 +321,140 @@
+ av_free(buf);
+ }
+
++/****************************************************************************
++ * For mode 2 - alpha blending
++ ****************************************************************************/
++static void AlphaBlendingProcess(void *ctx,
++ AVPicture *picture,
++ enum PixelFormat pix_fmt,
++ int src_width,
++ int src_height,
++ int64_t pts)
++{
++ ContextInfo *ci = (ContextInfo *) ctx;
++ char *buf = 0;
++ AVPicture picture1;
++ AVPicture *pict = picture;
++
++ AVFrame *pFrameRGB;
++ int xm_size;
++ int ym_size;
++
++ int x;
++ int y;
++ int offs, offsm;
++ int mpoffs;
++ uint32_t *p_pixel = 0;
++ uint32_t pixel_meck;
++ uint32_t pixel;
++ uint32_t pixelm;
++ uint32_t tmp;
++ uint32_t alpha, src_colour, dest_colour, inverse_alpha;
++
++ if (pix_fmt != PIX_FMT_RGB32) {
++ int size;
++
++ size = avpicture_get_size(PIX_FMT_RGB32, src_width, src_height);
++ buf = av_malloc(size);
++
++ avpicture_fill(&picture1, buf, PIX_FMT_RGB32, src_width, src_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,
++ src_width, src_height, pix_fmt,
++ src_width, src_height, PIX_FMT_RGB32,
++ sws_flags, NULL, NULL, NULL);
++ if (ci->toRGB_convert_ctx == NULL) {
++ av_log(NULL, AV_LOG_ERROR,
++ "Cannot initialize the toRGB conversion context\n");
++ return;
++ }
++
++// img_convert parameters are 2 first destination, then 4 source
++// sws_scale parameters are context, 4 first source, then 2 destination
++ sws_scale(ci->toRGB_convert_ctx,
++ picture->data, picture->linesize, 0, src_height,
++ picture1.data, picture1.linesize);
++
++ pict = &picture1;
++ }
++
++ /* Insert filter code here */ /* ok */
++
++ // Get me next frame
++ if (0 > get_watermark_picture(ci, 0)) {
++ return;
++ }
++ // These are the three original static variables in the ffmpeg hack.
++ pFrameRGB = ci->pFrameRGB;
++ xm_size = ci->x_size;
++ ym_size = ci->y_size;
++
++ // I'll do the *4 => <<2 crap later. Most compilers understand that anyway.
++ // According to avcodec.h PIX_FMT_RGB32 is handled in endian specific manner.
++ for (y=0; y<src_height; y++) {
++ offs = y * (src_width * 4);
++ offsm = (((y * ym_size) / src_height) * 4) * xm_size; // offsm first in maskline. byteoffs!
++ for (x=0; x<src_width; x++) {
++ mpoffs = offsm + (((x * xm_size) / src_width) * 4);
++ p_pixel = (uint32_t *)&((pFrameRGB->data[0])[mpoffs]);
++ pixelm = *p_pixel;
++ p_pixel = (uint32_t *)&((pict->data[0])[offs]);
++ pixel = *p_pixel;
++ pixel_meck = pixel & 0xff000000;
++
++ alpha = (uint32_t)((pixelm >> 24) & 0xff);
++
++ if (alpha) {
++ alpha++;
++ inverse_alpha = 0x100 - alpha;
++
++ // R
++ dest_colour = (int)((pixel >> 16) & 0xff);
++ src_colour = (int)((pixelm >> 16) & 0xff);
++ tmp = ((dest_colour * inverse_alpha) >> 8) + ((src_colour * alpha) >> 8);
++ pixel_meck |= (tmp << 16) & 0xff0000;
++ // G
++ dest_colour = (int)((pixel >> 8) & 0xff);
++ src_colour = (int)((pixelm >> 8) & 0xff);
++ tmp = ((dest_colour * inverse_alpha) >> 8) + ((src_colour * alpha) >> 8);
++ pixel_meck |= (tmp << 8) & 0xff00;
++ // B
++ dest_colour = (int)(pixel & 0xff);
++ src_colour = (int)(pixelm & 0xff);
++ tmp = ((dest_colour * inverse_alpha) >> 8) + ((src_colour * alpha) >> 8);
++ pixel_meck |= (tmp << 0) & 0xff;
++
++ *p_pixel = pixel_meck;
++ }
++
++ offs += 4;
++ } // foreach X
++ } // foreach Y
++
++
++
++
++ if (pix_fmt != PIX_FMT_RGB32) {
++ ci->fromRGB_convert_ctx = sws_getCachedContext(ci->fromRGB_convert_ctx,
++ src_width, src_height, PIX_FMT_RGB32,
++ src_width, src_height, pix_fmt,
++ sws_flags, NULL, NULL, NULL);
++ if (ci->fromRGB_convert_ctx == NULL) {
++ av_log(NULL, AV_LOG_ERROR,
++ "Cannot initialize the fromRGB conversion context\n");
++ return;
++ }
++// img_convert parameters are 2 first destination, then 4 source
++// sws_scale parameters are context, 4 first source, then 2 destination
++ sws_scale(ci->fromRGB_convert_ctx,
++ picture1.data, picture1.linesize, 0, src_height,
++ picture->data, picture->linesize);
++ }
++
++ av_free(buf);
++}
++
+
+ /****************************************************************************
+ * For mode 1 (the original one)
+@@ -432,7 +578,9 @@
+ int64_t pts)
+ {
+ ContextInfo *ci = (ContextInfo *) ctx;
+- if (1 == ci->mode) {
++ if (2 == ci->mode) {
++ AlphaBlendingProcess(ctx, picture, pix_fmt, src_width, src_height, pts);
++ } else if (1 == ci->mode) {
+ Process1(ctx, picture, pix_fmt, src_width, src_height, pts);
+ } else {
+ Process0(ctx, picture, pix_fmt, src_width, src_height, pts);

0 comments on commit be869b2

Please sign in to comment.