Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100644 191 lines (188 sloc) 6.927 kb
be869b24 »
2009-09-12 added patch
1 --- watermark-old.c 2009-09-12 10:53:42.000000000 +0100
2 +++ watermark.c 2009-09-06 22:51:51.000000000 +0100
3 @@ -3,7 +3,7 @@
4 * Copyright (c) 2005 Marcus Engene myfirstname(at)mylastname.se
5 *
6 * parameters for watermark:
7 - * -m nbr = nbr is 0..1. 0 is the default mode, see below.
8 + * -m nbr = nbr is 0..2. 0 is the default mode, see below.
9 * -t nbr = nbr is six digit hex. Threshold.
10 * -f file = file is the watermark image filename. You must specify this!
11 *
12 @@ -29,13 +29,25 @@
13 * Per color do this:
14 * If mask color > threshold color then the watermark pixel is used.
15 *
16 + * MODE 2:
17 + * Paste the watermark image onto the video image respecting alpha channels.
18 + *
19 + * Alpha channels are regularly found in PNG images and affect the tranparency
20 + * of the image. If the pixel has 0x00 alpha value it is entirely transparent
21 + * and the original video pixel is unchanged. If the alpha value is 0xff
22 + * (100%) the watermark pixel is used entirely. Otherwise, the following
23 + * formula is used:
24 + *
25 + * video_pixel = (1 - alpha) * video_pixel + alpha * watermark_pixel
26 + *
27 * Example usage:
28 * ffmpeg -i infile -vhook '/path/watermark.so -f wm.gif' -an out.mov
29 * ffmpeg -i infile -vhook '/path/watermark.so -f wm.gif -m 1 -t 222222' -an out.mov
30 + * ffmpeg -i infile -vhook '/path/watermark.so -f wm.png -m 2' -an out.mov
31 *
32 * Note that the entire vhook argument is encapsulated in ''. This
33 * way, arguments to the vhook won't be mixed up with those for ffmpeg.
34 - *
35 + *
36 * This file is part of FFmpeg.
37 *
38 * FFmpeg is free software; you can redistribute it and/or
39 @@ -309,6 +321,140 @@
40 av_free(buf);
41 }
42
43 +/****************************************************************************
44 + * For mode 2 - alpha blending
45 + ****************************************************************************/
46 +static void AlphaBlendingProcess(void *ctx,
47 + AVPicture *picture,
48 + enum PixelFormat pix_fmt,
49 + int src_width,
50 + int src_height,
51 + int64_t pts)
52 +{
53 + ContextInfo *ci = (ContextInfo *) ctx;
54 + char *buf = 0;
55 + AVPicture picture1;
56 + AVPicture *pict = picture;
57 +
58 + AVFrame *pFrameRGB;
59 + int xm_size;
60 + int ym_size;
61 +
62 + int x;
63 + int y;
64 + int offs, offsm;
65 + int mpoffs;
66 + uint32_t *p_pixel = 0;
67 + uint32_t pixel_meck;
68 + uint32_t pixel;
69 + uint32_t pixelm;
70 + uint32_t tmp;
71 + uint32_t alpha, src_colour, dest_colour, inverse_alpha;
72 +
73 + if (pix_fmt != PIX_FMT_RGB32) {
74 + int size;
75 +
76 + size = avpicture_get_size(PIX_FMT_RGB32, src_width, src_height);
77 + buf = av_malloc(size);
78 +
79 + avpicture_fill(&picture1, buf, PIX_FMT_RGB32, src_width, src_height);
80 +
81 + // if we already got a SWS context, let's realloc if is not re-useable
82 + ci->toRGB_convert_ctx = sws_getCachedContext(ci->toRGB_convert_ctx,
83 + src_width, src_height, pix_fmt,
84 + src_width, src_height, PIX_FMT_RGB32,
85 + sws_flags, NULL, NULL, NULL);
86 + if (ci->toRGB_convert_ctx == NULL) {
87 + av_log(NULL, AV_LOG_ERROR,
88 + "Cannot initialize the toRGB conversion context\n");
89 + return;
90 + }
91 +
92 +// img_convert parameters are 2 first destination, then 4 source
93 +// sws_scale parameters are context, 4 first source, then 2 destination
94 + sws_scale(ci->toRGB_convert_ctx,
95 + picture->data, picture->linesize, 0, src_height,
96 + picture1.data, picture1.linesize);
97 +
98 + pict = &picture1;
99 + }
100 +
101 + /* Insert filter code here */ /* ok */
102 +
103 + // Get me next frame
104 + if (0 > get_watermark_picture(ci, 0)) {
105 + return;
106 + }
107 + // These are the three original static variables in the ffmpeg hack.
108 + pFrameRGB = ci->pFrameRGB;
109 + xm_size = ci->x_size;
110 + ym_size = ci->y_size;
111 +
112 + // I'll do the *4 => <<2 crap later. Most compilers understand that anyway.
113 + // According to avcodec.h PIX_FMT_RGB32 is handled in endian specific manner.
114 + for (y=0; y<src_height; y++) {
115 + offs = y * (src_width * 4);
116 + offsm = (((y * ym_size) / src_height) * 4) * xm_size; // offsm first in maskline. byteoffs!
117 + for (x=0; x<src_width; x++) {
118 + mpoffs = offsm + (((x * xm_size) / src_width) * 4);
119 + p_pixel = (uint32_t *)&((pFrameRGB->data[0])[mpoffs]);
120 + pixelm = *p_pixel;
121 + p_pixel = (uint32_t *)&((pict->data[0])[offs]);
122 + pixel = *p_pixel;
123 + pixel_meck = pixel & 0xff000000;
124 +
125 + alpha = (uint32_t)((pixelm >> 24) & 0xff);
126 +
127 + if (alpha) {
128 + alpha++;
129 + inverse_alpha = 0x100 - alpha;
130 +
131 + // R
132 + dest_colour = (int)((pixel >> 16) & 0xff);
133 + src_colour = (int)((pixelm >> 16) & 0xff);
134 + tmp = ((dest_colour * inverse_alpha) >> 8) + ((src_colour * alpha) >> 8);
135 + pixel_meck |= (tmp << 16) & 0xff0000;
136 + // G
137 + dest_colour = (int)((pixel >> 8) & 0xff);
138 + src_colour = (int)((pixelm >> 8) & 0xff);
139 + tmp = ((dest_colour * inverse_alpha) >> 8) + ((src_colour * alpha) >> 8);
140 + pixel_meck |= (tmp << 8) & 0xff00;
141 + // B
142 + dest_colour = (int)(pixel & 0xff);
143 + src_colour = (int)(pixelm & 0xff);
144 + tmp = ((dest_colour * inverse_alpha) >> 8) + ((src_colour * alpha) >> 8);
145 + pixel_meck |= (tmp << 0) & 0xff;
146 +
147 + *p_pixel = pixel_meck;
148 + }
149 +
150 + offs += 4;
151 + } // foreach X
152 + } // foreach Y
153 +
154 +
155 +
156 +
157 + if (pix_fmt != PIX_FMT_RGB32) {
158 + ci->fromRGB_convert_ctx = sws_getCachedContext(ci->fromRGB_convert_ctx,
159 + src_width, src_height, PIX_FMT_RGB32,
160 + src_width, src_height, pix_fmt,
161 + sws_flags, NULL, NULL, NULL);
162 + if (ci->fromRGB_convert_ctx == NULL) {
163 + av_log(NULL, AV_LOG_ERROR,
164 + "Cannot initialize the fromRGB conversion context\n");
165 + return;
166 + }
167 +// img_convert parameters are 2 first destination, then 4 source
168 +// sws_scale parameters are context, 4 first source, then 2 destination
169 + sws_scale(ci->fromRGB_convert_ctx,
170 + picture1.data, picture1.linesize, 0, src_height,
171 + picture->data, picture->linesize);
172 + }
173 +
174 + av_free(buf);
175 +}
176 +
177
178 /****************************************************************************
179 * For mode 1 (the original one)
180 @@ -432,7 +578,9 @@
181 int64_t pts)
182 {
183 ContextInfo *ci = (ContextInfo *) ctx;
184 - if (1 == ci->mode) {
185 + if (2 == ci->mode) {
186 + AlphaBlendingProcess(ctx, picture, pix_fmt, src_width, src_height, pts);
187 + } else if (1 == ci->mode) {
188 Process1(ctx, picture, pix_fmt, src_width, src_height, pts);
189 } else {
190 Process0(ctx, picture, pix_fmt, src_width, src_height, pts);
Something went wrong with that request. Please try again.