1 /*
2 * DivX (XSUB) subtitle encoder
3 * Copyright (c) 2005 DivX, Inc.
4 * Copyright (c) 2009 Bjorn Axelsson
5 *
6 * This file is part of FFmpeg.
7 *
8 * FFmpeg is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
12 *
13 * FFmpeg is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with FFmpeg; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21 */
22
26
27 /**
28 * Number of pixels to pad left and right.
29 *
30 * The official encoder pads the subtitles with two pixels on either side,
31 * but until we find out why, we won't do it (we will pad to have width
32 * divisible by 2 though).
33 */
35 #define PADDING_COLOR 0
36
37 /**
38 * Encode a single color run. At most 16 bits will be used.
39 * @param len length of the run, values > 255 mean "until end of line", may not be < 0.
40 * @param color color to encode, only the lowest two bits are used and all others must be 0.
41 */
43 {
44 if (len <= 255)
46 else
49 }
50
51 /**
52 * Encode a 4-color bitmap with XSUB rle.
53 *
54 * The encoded bitmap may be wider than the source bitmap due to padding.
55 */
57 int linesize,
int w,
int h)
58 {
60
61 for (y = 0; y <
h; y++) {
62 x0 = 0;
63 while (x0 < w) {
64 // Make sure we have enough room for at least one run and padding
66 return -1;
67
68 x1 = x0;
69 color = bitmap[x1++] & 3;
70 while (x1 < w && (bitmap[x1] & 3) == color)
71 x1++;
72 len = x1 - x0;
77 } else
79 }
80
81 // Run can't be longer than 255, unless it is the rest of a row
84 } else
85 len =
FFMIN(len, 255);
87
89 }
92
94
95 bitmap += linesize;
96 }
97
98 return 0;
99 }
100
102 {
103 static const int tc_divs[3] = { 1000, 60, 60 };
104 int i;
105 for (i=0; i<3; i++) {
106 tc[i] = ms % tc_divs[i];
107 ms /= tc_divs[i];
108 }
109 tc[3] = ms;
110 return ms > 99;
111 }
112
115 {
116 uint64_t startTime = h->
pts / 1000;
// FIXME: need better solution...
118 int start_tc[4], end_tc[4];
119 uint8_t *hdr = buf + 27;
// Point behind the timestamp
122 int i;
124
125 if (bufsize < 27 + 7*2 + 4*3) {
127 return -1;
128 }
129
130 // TODO: support multiple rects
133
134 #if FF_API_AVPICTURE
138 int j;
139 for (j = 0; j < 4; j++) {
142 }
143 }
145 #endif
146
147 // TODO: render text-based subtitles into bitmaps
150 return -1;
151 }
152
153 // TODO: color reduction, similar to dvdsub encoder
156
157 // TODO: Palette swapping if color zero is not transparent
158 if (((uint32_t *)h->
rects[0]->
data[1])[0] & 0xff000000)
159 av_log(avctx,
AV_LOG_WARNING,
"Color index 0 is not transparent. Transparency will be messed up.\n");
160
163 return -1;
164 }
165
167 "[%02d:%02d:%02d.%03d-%02d:%02d:%02d.%03d]",
168 start_tc[3], start_tc[2], start_tc[1], start_tc[0],
169 end_tc[3], end_tc[2], end_tc[1], end_tc[0]);
170
171 // Width and height must probably be multiples of 2.
172 // 2 pixels required on either side of subtitle.
173 // Possibly due to limitations of hardware renderers.
174 // TODO: check if the bitmap is already padded
177
178 bytestream_put_le16(&hdr, width);
179 bytestream_put_le16(&hdr, height);
180 bytestream_put_le16(&hdr, h->
rects[0]->
x);
181 bytestream_put_le16(&hdr, h->
rects[0]->
y);
182 bytestream_put_le16(&hdr, h->
rects[0]->
x + width -1);
183 bytestream_put_le16(&hdr, h->
rects[0]->
y + height -1);
184
185 rlelenptr = hdr; // Will store length of first field here later.
186 hdr+=2;
187
188 // Palette
189 for (i=0; i<4; i++)
190 bytestream_put_be24(&hdr, ((uint32_t *)h->
rects[0]->
data[1])[i]);
191
192 // Bitmap
193 // RLE buffer. Reserve 2 bytes for possible padding after the last row.
198 return -1;
199 bytestream_put_le16(&rlelenptr,
put_bits_count(&pb) >> 3);
// Length of first field
200
204 return -1;
205
206 // Enforce total height to be a multiple of 2
210 }
211
213
215 }
216
218 {
221
223
224 return 0;
225 }
226
234 };
#define PADDING
Number of pixels to pad left and right.
static void put_xsub_rle(PutBitContext *pb, int len, int color)
Encode a single color run.
int x
top left corner of pict, undefined when pict is not set
static void put_bits(Jpeg2000EncoderContext *s, int val, int n)
put n times val bit
#define AV_LOG_WARNING
Something somehow does not look correct.
int nb_colors
number of colors in pict, undefined when pict is not set
void avpriv_align_put_bits(PutBitContext *s)
Pad the bitstream with zeros up to the next byte boundary.
attribute_deprecated AVPicture pict
int w
width of pict, undefined when pict is not set
static int make_tc(uint64_t ms, int *tc)
attribute_deprecated int linesize[AV_NUM_DATA_POINTERS]
number of bytes per line
int h
height of pict, undefined when pict is not set
int bits_per_coded_sample
bits per sample/pixel from the demuxer (needed for huffyuv).
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
int y
top left corner of pict, undefined when pict is not set
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification. ...
static int xsub_encode(AVCodecContext *avctx, unsigned char *buf, int bufsize, const AVSubtitle *h)
const char * name
Name of the codec implementation.
static int xsub_encode_rle(PutBitContext *pb, const uint8_t *bitmap, int linesize, int w, int h)
Encode a 4-color bitmap with XSUB rle.
static int put_bits_count(PutBitContext *s)
uint32_t end_display_time
int64_t pts
Same as packet pts, in AV_TIME_BASE.
attribute_deprecated uint8_t * data[AV_NUM_DATA_POINTERS]
pointers to the image data planes
uint8_t * data[4]
data+linesize for the bitmap of this subtitle.
const uint8_t ff_log2_tab[256]
Libavcodec external API header.
main external API structure.
unsigned int codec_tag
fourcc (LSB first, so "ABCD" -> ('D'<<24) + ('C'<<16) + ('B'<<8) + 'A').
BYTE int const BYTE int int int height
static av_cold int xsub_encoder_init(AVCodecContext *avctx)
#define FF_DISABLE_DEPRECATION_WARNINGS
static void flush_put_bits(PutBitContext *s)
Pad the end of the output stream with zeros.
uint32_t start_display_time
static void init_put_bits(PutBitContext *s, uint8_t *buffer, int buffer_size)
Initialize the PutBitContext s.
#define FF_ENABLE_DEPRECATION_WARNINGS
#define MKTAG(a, b, c, d)