FFmpeg
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
dvbsubenc.c
Go to the documentation of this file.
1 /*
2  * DVB subtitle encoding
3  * Copyright (c) 2005 Fabrice Bellard
4  *
5  * This file is part of FFmpeg.
6  *
7  * FFmpeg is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * FFmpeg is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with FFmpeg; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20  */
21 #include "avcodec.h"
22 #include "bytestream.h"
23 #include "codec_internal.h"
24 #include "libavutil/colorspace.h"
25 
26 typedef struct DVBSubtitleContext {
29 
30 #define PUTBITS2(val)\
31 {\
32  bitbuf |= (val) << bitcnt;\
33  bitcnt -= 2;\
34  if (bitcnt < 0) {\
35  bitcnt = 6;\
36  *q++ = bitbuf;\
37  bitbuf = 0;\
38  }\
39 }
40 
41 static int dvb_encode_rle2(uint8_t **pq, int buf_size,
42  const uint8_t *bitmap, int linesize,
43  int w, int h)
44 {
45  uint8_t *q, *line_begin;
46  unsigned int bitbuf;
47  int bitcnt;
48  int x, y, len, x1, v, color;
49 
50  q = *pq;
51 
52  for(y = 0; y < h; y++) {
53  // Worst case line is 3 bits per value + 4 bytes overhead
54  if (buf_size * 8 < w * 3 + 32)
56  line_begin = q;
57  *q++ = 0x10;
58  bitbuf = 0;
59  bitcnt = 6;
60 
61  x = 0;
62  while (x < w) {
63  x1 = x;
64  color = bitmap[x1++];
65  while (x1 < w && bitmap[x1] == color)
66  x1++;
67  len = x1 - x;
68  if (color == 0 && len == 2) {
69  PUTBITS2(0);
70  PUTBITS2(0);
71  PUTBITS2(1);
72  } else if (len >= 3 && len <= 10) {
73  v = len - 3;
74  PUTBITS2(0);
75  PUTBITS2((v >> 2) | 2);
76  PUTBITS2(v & 3);
77  PUTBITS2(color);
78  } else if (len >= 12 && len <= 27) {
79  v = len - 12;
80  PUTBITS2(0);
81  PUTBITS2(0);
82  PUTBITS2(2);
83  PUTBITS2(v >> 2);
84  PUTBITS2(v & 3);
85  PUTBITS2(color);
86  } else if (len >= 29) {
87  /* length = 29 ... 284 */
88  if (len > 284)
89  len = 284;
90  v = len - 29;
91  PUTBITS2(0);
92  PUTBITS2(0);
93  PUTBITS2(3);
94  PUTBITS2((v >> 6));
95  PUTBITS2((v >> 4) & 3);
96  PUTBITS2((v >> 2) & 3);
97  PUTBITS2(v & 3);
98  PUTBITS2(color);
99  } else {
100  PUTBITS2(color);
101  if (color == 0) {
102  PUTBITS2(1);
103  }
104  len = 1;
105  }
106  x += len;
107  }
108  /* end of line */
109  PUTBITS2(0);
110  PUTBITS2(0);
111  PUTBITS2(0);
112  if (bitcnt != 6) {
113  *q++ = bitbuf;
114  }
115  *q++ = 0xf0;
116  bitmap += linesize;
117  buf_size -= q - line_begin;
118  }
119  len = q - *pq;
120  *pq = q;
121  return len;
122 }
123 
124 #define PUTBITS4(val)\
125 {\
126  bitbuf |= (val) << bitcnt;\
127  bitcnt -= 4;\
128  if (bitcnt < 0) {\
129  bitcnt = 4;\
130  *q++ = bitbuf;\
131  bitbuf = 0;\
132  }\
133 }
134 
135 /* some DVB decoders only implement 4 bits/pixel */
136 static int dvb_encode_rle4(uint8_t **pq, int buf_size,
137  const uint8_t *bitmap, int linesize,
138  int w, int h)
139 {
140  uint8_t *q, *line_begin;
141  unsigned int bitbuf;
142  int bitcnt;
143  int x, y, len, x1, v, color;
144 
145  q = *pq;
146 
147  for(y = 0; y < h; y++) {
148  // Worst case line is 6 bits per value, + 4 bytes overhead
149  if (buf_size * 8 < w * 6 + 32)
151  line_begin = q;
152  *q++ = 0x11;
153  bitbuf = 0;
154  bitcnt = 4;
155 
156  x = 0;
157  while (x < w) {
158  x1 = x;
159  color = bitmap[x1++];
160  while (x1 < w && bitmap[x1] == color)
161  x1++;
162  len = x1 - x;
163  if (color == 0 && len == 2) {
164  PUTBITS4(0);
165  PUTBITS4(0xd);
166  } else if (color == 0 && (len >= 3 && len <= 9)) {
167  PUTBITS4(0);
168  PUTBITS4(len - 2);
169  } else if (len >= 4 && len <= 7) {
170  PUTBITS4(0);
171  PUTBITS4(8 + len - 4);
172  PUTBITS4(color);
173  } else if (len >= 9 && len <= 24) {
174  PUTBITS4(0);
175  PUTBITS4(0xe);
176  PUTBITS4(len - 9);
177  PUTBITS4(color);
178  } else if (len >= 25) {
179  if (len > 280)
180  len = 280;
181  v = len - 25;
182  PUTBITS4(0);
183  PUTBITS4(0xf);
184  PUTBITS4(v >> 4);
185  PUTBITS4(v & 0xf);
186  PUTBITS4(color);
187  } else {
188  PUTBITS4(color);
189  if (color == 0) {
190  PUTBITS4(0xc);
191  }
192  len = 1;
193  }
194  x += len;
195  }
196  /* end of line */
197  PUTBITS4(0);
198  PUTBITS4(0);
199  if (bitcnt != 4) {
200  *q++ = bitbuf;
201  }
202  *q++ = 0xf0;
203  bitmap += linesize;
204  buf_size -= q - line_begin;
205  }
206  len = q - *pq;
207  *pq = q;
208  return len;
209 }
210 
211 static int dvb_encode_rle8(uint8_t **pq, int buf_size,
212  const uint8_t *bitmap, int linesize,
213  int w, int h)
214 {
215  uint8_t *q, *line_begin;
216  int x, y, len, x1, color;
217 
218  q = *pq;
219 
220  for (y = 0; y < h; y++) {
221  // Worst case line is 12 bits per value, + 3 bytes overhead
222  if (buf_size * 8 < w * 12 + 24)
224  line_begin = q;
225  *q++ = 0x12;
226 
227  x = 0;
228  while (x < w) {
229  x1 = x;
230  color = bitmap[x1++];
231  while (x1 < w && bitmap[x1] == color)
232  x1++;
233  len = x1 - x;
234  if (len == 1 && color) {
235  // 00000001 to 11111111 1 pixel in colour x
236  *q++ = color;
237  } else {
238  if (color == 0x00) {
239  // 00000000 0LLLLLLL L pixels (1-127) in colour 0 (L > 0)
240  len = FFMIN(len, 127);
241  *q++ = 0x00;
242  *q++ = len;
243  } else if (len > 2) {
244  // 00000000 1LLLLLLL CCCCCCCC L pixels (3-127) in colour C (L > 2)
245  len = FFMIN(len, 127);
246  *q++ = 0x00;
247  *q++ = 0x80+len;
248  *q++ = color;
249  }
250  else if (len == 2) {
251  *q++ = color;
252  *q++ = color;
253  } else {
254  *q++ = color;
255  len = 1;
256  }
257  }
258  x += len;
259  }
260  /* end of line */
261  // 00000000 end of 8-bit/pixel_code_string
262  *q++ = 0x00;
263  *q++ = 0xf0;
264  bitmap += linesize;
265  buf_size -= q - line_begin;
266  }
267  len = q - *pq;
268  *pq = q;
269  return len;
270 }
271 
272 static int dvbsub_encode(AVCodecContext *avctx, uint8_t *outbuf, int buf_size,
273  const AVSubtitle *h)
274 {
275  DVBSubtitleContext *s = avctx->priv_data;
276  uint8_t *q, *pseg_len;
277  int page_id, region_id, clut_id, object_id, i, bpp_index, page_state;
278 
279 
280  q = outbuf;
281 
282  page_id = 1;
283 
284  if (h->num_rects && !h->rects)
285  return AVERROR(EINVAL);
286 
287  if (h->num_rects >= 256)
288  return AVERROR(EINVAL);
289 
290  if (avctx->width > 0 && avctx->height > 0) {
291  if (buf_size < 11)
293  /* display definition segment */
294  *q++ = 0x0f; /* sync_byte */
295  *q++ = 0x14; /* segment_type */
296  bytestream_put_be16(&q, page_id);
297  pseg_len = q;
298  q += 2; /* segment length */
299  *q++ = 0x00; /* dds version number & display window flag */
300  bytestream_put_be16(&q, avctx->width - 1); /* display width */
301  bytestream_put_be16(&q, avctx->height - 1); /* display height */
302  bytestream_put_be16(&pseg_len, q - pseg_len - 2);
303  buf_size -= 11;
304  }
305 
306  /* page composition segment */
307 
308  if (buf_size < 8 + h->num_rects * 6)
310  *q++ = 0x0f; /* sync_byte */
311  *q++ = 0x10; /* segment_type */
312  bytestream_put_be16(&q, page_id);
313  pseg_len = q;
314  q += 2; /* segment length */
315  *q++ = 30; /* page_timeout (seconds) */
316  page_state = 2; /* mode change */
317  /* page_version = 0 + page_state */
318  *q++ = (s->object_version << 4) | (page_state << 2) | 3;
319 
320  for (region_id = 0; region_id < h->num_rects; region_id++) {
321  *q++ = region_id;
322  *q++ = 0xff; /* reserved */
323  bytestream_put_be16(&q, h->rects[region_id]->x); /* left pos */
324  bytestream_put_be16(&q, h->rects[region_id]->y); /* top pos */
325  }
326 
327  bytestream_put_be16(&pseg_len, q - pseg_len - 2);
328  buf_size -= 8 + h->num_rects * 6;
329 
330  if (h->num_rects) {
331  for (clut_id = 0; clut_id < h->num_rects; clut_id++) {
332  /* CLUT segment */
333 
334  if (h->rects[clut_id]->nb_colors <= 4U) {
335  /* 2 bpp, some decoders do not support it correctly */
336  bpp_index = 0;
337  } else if (h->rects[clut_id]->nb_colors <= 16U) {
338  /* 4 bpp, standard encoding */
339  bpp_index = 1;
340  } else if (h->rects[clut_id]->nb_colors <= 256U) {
341  /* 8 bpp, standard encoding */
342  bpp_index = 2;
343  } else {
344  return AVERROR(EINVAL);
345  }
346 
347  if (buf_size < 6 + h->rects[clut_id]->nb_colors * 6)
349 
350  /* CLUT segment */
351  *q++ = 0x0f; /* sync byte */
352  *q++ = 0x12; /* CLUT definition segment */
353  bytestream_put_be16(&q, page_id);
354  pseg_len = q;
355  q += 2; /* segment length */
356  *q++ = clut_id;
357  *q++ = (0 << 4) | 0xf; /* version = 0 */
358 
359  for(i = 0; i < h->rects[clut_id]->nb_colors; i++) {
360  *q++ = i; /* clut_entry_id */
361  *q++ = (1 << (7 - bpp_index)) | (0xf << 1) | 1; /* 2 bits/pixel full range */
362  {
363  int a, r, g, b;
364  uint32_t x= ((uint32_t*)h->rects[clut_id]->data[1])[i];
365  a = (x >> 24) & 0xff;
366  r = (x >> 16) & 0xff;
367  g = (x >> 8) & 0xff;
368  b = (x >> 0) & 0xff;
369 
370  *q++ = RGB_TO_Y_CCIR(r, g, b);
371  *q++ = RGB_TO_V_CCIR(r, g, b, 0);
372  *q++ = RGB_TO_U_CCIR(r, g, b, 0);
373  *q++ = 255 - a;
374  }
375  }
376 
377  bytestream_put_be16(&pseg_len, q - pseg_len - 2);
378  buf_size -= 6 + h->rects[clut_id]->nb_colors * 6;
379  }
380 
381  if (buf_size < h->num_rects * 22)
383  for (region_id = 0; region_id < h->num_rects; region_id++) {
384 
385  /* region composition segment */
386 
387  if (h->rects[region_id]->nb_colors <= 4) {
388  /* 2 bpp, some decoders do not support it correctly */
389  bpp_index = 0;
390  } else if (h->rects[region_id]->nb_colors <= 16) {
391  /* 4 bpp, standard encoding */
392  bpp_index = 1;
393  } else if (h->rects[region_id]->nb_colors <= 256) {
394  /* 8 bpp, standard encoding */
395  bpp_index = 2;
396  } else {
397  return AVERROR(EINVAL);
398  }
399 
400  *q++ = 0x0f; /* sync_byte */
401  *q++ = 0x11; /* segment_type */
402  bytestream_put_be16(&q, page_id);
403  pseg_len = q;
404  q += 2; /* segment length */
405  *q++ = region_id;
406  *q++ = (s->object_version << 4) | (0 << 3) | 0x07; /* version , no fill */
407  bytestream_put_be16(&q, h->rects[region_id]->w); /* region width */
408  bytestream_put_be16(&q, h->rects[region_id]->h); /* region height */
409  *q++ = ((1 + bpp_index) << 5) | ((1 + bpp_index) << 2) | 0x03;
410  *q++ = region_id; /* clut_id == region_id */
411  *q++ = 0; /* 8 bit fill colors */
412  *q++ = 0x03; /* 4 bit and 2 bit fill colors */
413 
414  bytestream_put_be16(&q, region_id); /* object_id == region_id */
415  *q++ = (0 << 6) | (0 << 4);
416  *q++ = 0;
417  *q++ = 0xf0;
418  *q++ = 0;
419 
420  bytestream_put_be16(&pseg_len, q - pseg_len - 2);
421  }
422  buf_size -= h->num_rects * 22;
423 
424  for (object_id = 0; object_id < h->num_rects; object_id++) {
425  int (*dvb_encode_rle)(uint8_t **pq, int buf_size,
426  const uint8_t *bitmap, int linesize,
427  int w, int h);
428 
429  if (buf_size < 13)
431 
432  /* bpp_index maths */
433  if (h->rects[object_id]->nb_colors <= 4) {
434  /* 2 bpp, some decoders do not support it correctly */
435  dvb_encode_rle = dvb_encode_rle2;
436  } else if (h->rects[object_id]->nb_colors <= 16) {
437  /* 4 bpp, standard encoding */
438  dvb_encode_rle = dvb_encode_rle4;
439  } else if (h->rects[object_id]->nb_colors <= 256) {
440  /* 8 bpp, standard encoding */
441  dvb_encode_rle = dvb_encode_rle8;
442  } else {
443  return AVERROR(EINVAL);
444  }
445 
446  /* Object Data segment */
447  *q++ = 0x0f; /* sync byte */
448  *q++ = 0x13;
449  bytestream_put_be16(&q, page_id);
450  pseg_len = q;
451  q += 2; /* segment length */
452 
453  bytestream_put_be16(&q, object_id);
454  *q++ = (s->object_version << 4) | (0 << 2) | (0 << 1) | 1; /* version = 0,
455  object_coding_method,
456  non_modifying_color_flag */
457  {
458  uint8_t *ptop_field_len, *pbottom_field_len, *top_ptr, *bottom_ptr;
459  int ret;
460 
461  ptop_field_len = q;
462  q += 2;
463  pbottom_field_len = q;
464  q += 2;
465  buf_size -= 13;
466 
467  top_ptr = q;
468  ret = dvb_encode_rle(&q, buf_size,
469  h->rects[object_id]->data[0],
470  h->rects[object_id]->w * 2,
471  h->rects[object_id]->w,
472  h->rects[object_id]->h >> 1);
473  if (ret < 0)
474  return ret;
475  buf_size -= ret;
476  bottom_ptr = q;
477  ret = dvb_encode_rle(&q, buf_size,
478  h->rects[object_id]->data[0] + h->rects[object_id]->w,
479  h->rects[object_id]->w * 2,
480  h->rects[object_id]->w,
481  h->rects[object_id]->h >> 1);
482  if (ret < 0)
483  return ret;
484  buf_size -= ret;
485 
486  bytestream_put_be16(&ptop_field_len, bottom_ptr - top_ptr);
487  bytestream_put_be16(&pbottom_field_len, q - bottom_ptr);
488  }
489 
490  bytestream_put_be16(&pseg_len, q - pseg_len - 2);
491  }
492  }
493 
494  /* end of display set segment */
495 
496  if (buf_size < 6)
498  *q++ = 0x0f; /* sync_byte */
499  *q++ = 0x80; /* segment_type */
500  bytestream_put_be16(&q, page_id);
501  pseg_len = q;
502  q += 2; /* segment length */
503 
504  bytestream_put_be16(&pseg_len, q - pseg_len - 2);
505  buf_size -= 6;
506 
507  s->object_version = (s->object_version + 1) & 0xf;
508  return q - outbuf;
509 }
510 
512  .p.name = "dvbsub",
513  CODEC_LONG_NAME("DVB subtitles"),
514  .p.type = AVMEDIA_TYPE_SUBTITLE,
515  .p.id = AV_CODEC_ID_DVB_SUBTITLE,
516  .priv_data_size = sizeof(DVBSubtitleContext),
518 };
AVSubtitle
Definition: avcodec.h:2075
AVMEDIA_TYPE_SUBTITLE
@ AVMEDIA_TYPE_SUBTITLE
Definition: avutil.h:204
r
const char * r
Definition: vf_curves.c:127
AVERROR
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample they are references to shared objects When the negotiation mechanism computes the intersection of the formats supported at each end of a all references to both lists are replaced with a reference to the intersection And when a single format is eventually chosen for a link amongst the remaining all references to the list are updated That means that if a filter requires that its input and output have the same format amongst a supported all it has to do is use a reference to the same list of formats query_formats can leave some formats unset and return AVERROR(EAGAIN) to cause the negotiation mechanism toagain later. That can be used by filters with complex requirements to use the format negotiated on one link to set the formats supported on another. Frame references ownership and permissions
color
Definition: vf_paletteuse.c:513
dvb_encode_rle4
static int dvb_encode_rle4(uint8_t **pq, int buf_size, const uint8_t *bitmap, int linesize, int w, int h)
Definition: dvbsubenc.c:136
RGB_TO_U_CCIR
#define RGB_TO_U_CCIR(r1, g1, b1, shift)
Definition: colorspace.h:102
w
uint8_t w
Definition: llviddspenc.c:38
b
#define b
Definition: input.c:42
dvbsub_encode
static int dvbsub_encode(AVCodecContext *avctx, uint8_t *outbuf, int buf_size, const AVSubtitle *h)
Definition: dvbsubenc.c:272
FFCodec
Definition: codec_internal.h:127
DVBSubtitleContext::object_version
int object_version
Definition: dvbsubenc.c:27
FFCodec::p
AVCodec p
The public AVCodec.
Definition: codec_internal.h:131
AVERROR_BUFFER_TOO_SMALL
#define AVERROR_BUFFER_TOO_SMALL
Buffer too small.
Definition: error.h:53
AV_CODEC_ID_DVB_SUBTITLE
@ AV_CODEC_ID_DVB_SUBTITLE
Definition: codec_id.h:559
colorspace.h
s
#define s(width, name)
Definition: cbs_vp9.c:198
RGB_TO_Y_CCIR
#define RGB_TO_Y_CCIR(r, g, b)
Definition: colorspace.h:98
g
const char * g
Definition: vf_curves.c:128
dvb_encode_rle8
static int dvb_encode_rle8(uint8_t **pq, int buf_size, const uint8_t *bitmap, int linesize, int w, int h)
Definition: dvbsubenc.c:211
DVBSubtitleContext
Definition: dvbsubenc.c:26
CODEC_LONG_NAME
#define CODEC_LONG_NAME(str)
Definition: codec_internal.h:326
dvb_encode_rle2
static int dvb_encode_rle2(uint8_t **pq, int buf_size, const uint8_t *bitmap, int linesize, int w, int h)
Definition: dvbsubenc.c:41
RGB_TO_V_CCIR
#define RGB_TO_V_CCIR(r1, g1, b1, shift)
Definition: colorspace.h:106
FF_CODEC_ENCODE_SUB_CB
#define FF_CODEC_ENCODE_SUB_CB(func)
Definition: codec_internal.h:357
PUTBITS4
#define PUTBITS4(val)
Definition: dvbsubenc.c:124
codec_internal.h
color
static const uint32_t color[16+AV_CLASS_CATEGORY_NB]
Definition: log.c:97
a
The reader does not expect b to be semantically here and if the code is changed by maybe adding a a division or other the signedness will almost certainly be mistaken To avoid this confusion a new type was SUINT is the C unsigned type but it holds a signed int to use the same example SUINT a
Definition: undefined.txt:41
xf
#define xf(width, name, var, range_min, range_max, subs,...)
Definition: cbs_av1.c:621
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:256
FFMIN
#define FFMIN(a, b)
Definition: macros.h:49
ff_dvbsub_encoder
const FFCodec ff_dvbsub_encoder
Definition: dvbsubenc.c:511
AVCodec::name
const char * name
Name of the codec implementation.
Definition: codec.h:179
len
int len
Definition: vorbis_enc_data.h:426
AVCodecContext::height
int height
Definition: avcodec.h:592
avcodec.h
ret
ret
Definition: filter_design.txt:187
U
#define U(x)
Definition: vpx_arith.h:37
AVCodecContext
main external API structure.
Definition: avcodec.h:431
PUTBITS2
#define PUTBITS2(val)
Definition: dvbsubenc.c:30
AVCodecContext::priv_data
void * priv_data
Definition: avcodec.h:458
AVCodecContext::width
int width
picture width / height.
Definition: avcodec.h:592
bytestream.h
h
h
Definition: vp9dsp_template.c:2070