1 /*
2 * PGS subtitle decoder
3 * Copyright (c) 2009 Stephen Backway
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
22 /**
23 * @file
24 * PGS subtitle decoder
25 */
26
33
34 #define RGBA(r,g,b,a) (((a) << 24) | ((r) << 16) | ((g) << 8) | (b))
35
42 };
43
50
57
65
73
75 {
77
78 return 0;
79 }
80
82 {
83 uint16_t picture;
84
86
89
90 for (picture = 0; picture < UINT16_MAX; ++picture) {
93 }
94
95 return 0;
96 }
97
98 /**
99 * Decode the RLE data.
100 *
101 * The subtitle is stored as a Run Length Encoded image.
102 *
103 * @param avctx contains the current codec context
104 * @param sub pointer to the processed subtitle data
105 * @param buf pointer to the RLE data to process
106 * @param buf_size size of the RLE data to process
107 */
110 {
112 int pixel_count, line_count;
113
114 rle_bitmap_end = buf + buf_size;
115
117
119 return -1;
120
121 pixel_count = 0;
122 line_count = 0;
123
124 while (buf < rle_bitmap_end && line_count < sub->rects[rect]->h) {
127
128 color = bytestream_get_byte(&buf);
129 run = 1;
130
131 if (color == 0x00) {
132 flags = bytestream_get_byte(&buf);
133 run = flags & 0x3f;
134 if (flags & 0x40)
135 run = (run << 8) + bytestream_get_byte(&buf);
136 color = flags & 0x80 ? bytestream_get_byte(&buf) : 0;
137 }
138
139 if (run > 0 && pixel_count + run <= sub->rects[rect]->w * sub->
rects[rect]->
h) {
140 memset(sub->
rects[rect]->
pict.
data[0] + pixel_count, color, run);
142 } else if (!run) {
143 /*
144 * New Line. Check if correct pixels decoded, if not display warning
145 * and adjust bitmap pointer to correct new line position.
146 */
147 if (pixel_count % sub->
rects[rect]->
w > 0)
149 pixel_count % sub->
rects[rect]->
w, sub->
rects[rect]->
w);
150 line_count++;
151 }
152 }
153
154 if (pixel_count < sub->rects[rect]->w * sub->
rects[rect]->
h) {
156 return -1;
157 }
158
159 av_dlog(avctx,
"Pixel Count = %d, Area = %d\n", pixel_count, sub->
rects[rect]->
w * sub->
rects[rect]->
h);
160
161 return 0;
162 }
163
164 /**
165 * Parse the picture segment packet.
166 *
167 * The picture segment contains details on the sequence id,
168 * width, height and Run Length Encoded (RLE) bitmap data.
169 *
170 * @param avctx contains the current codec context
171 * @param buf pointer to the packet to process
172 * @param buf_size size of packet to process
173 * @todo TODO: Enable support for RLE data over multiple packets
174 */
177 {
179
182 uint16_t picture_id;
183
184 if (buf_size <= 4)
185 return -1;
186 buf_size -= 4;
187
188 picture_id = bytestream_get_be16(&buf);
189
190 /* skip 1 unknown byte: Version Number */
191 buf++;
192
193 /* Read the Sequence Description to determine if start of RLE data or appended to previous RLE */
194 sequence_desc = bytestream_get_byte(&buf);
195
196 if (!(sequence_desc & 0x80)) {
197 /* Additional RLE data */
199 return -1;
200
204
205 return 0;
206 }
207
208 if (buf_size <= 7)
209 return -1;
210 buf_size -= 7;
211
212 /* Decode rle bitmap length, stored size includes width/height data */
213 rle_bitmap_len = bytestream_get_be24(&buf) - 2*2;
214
215 /* Get bitmap dimensions from data */
216 width = bytestream_get_be16(&buf);
217 height = bytestream_get_be16(&buf);
218
219 /* Make sure the bitmap is not too large */
220 if (avctx->
width < width || avctx->
height < height) {
222 return -1;
223 }
224
225 if (buf_size > rle_bitmap_len) {
228 }
229
232
234
236 return -1;
237
238 memcpy(ctx->
pictures[picture_id].
rle, buf, buf_size);
241
242 return 0;
243 }
244
245 /**
246 * Parse the palette segment packet.
247 *
248 * The palette segment contains details of the palette,
249 * a maximum of 256 colors can be defined.
250 *
251 * @param avctx contains the current codec context
252 * @param buf pointer to the packet to process
253 * @param buf_size size of packet to process
254 */
257 {
259
260 const uint8_t *buf_end = buf + buf_size;
262 int color_id;
264 int r,
g,
b, r_add, g_add, b_add;
265
266 /* Skip two null bytes */
267 buf += 2;
268
269 while (buf < buf_end) {
270 color_id = bytestream_get_byte(&buf);
271 y = bytestream_get_byte(&buf);
272 cr = bytestream_get_byte(&buf);
273 cb = bytestream_get_byte(&buf);
274 alpha = bytestream_get_byte(&buf);
275
278
279 av_dlog(avctx,
"Color %d := (%d,%d,%d,%d)\n", color_id, r, g, b, alpha);
280
281 /* Store color in palette */
282 ctx->
clut[color_id] =
RGBA(r,g,b,alpha);
283 }
284 }
285
286 /**
287 * Parse the presentation segment packet.
288 *
289 * The presentation segment contains details on the video
290 * width, video height, x & y subtitle position.
291 *
292 * @param avctx contains the current codec context
293 * @param buf pointer to the packet to process
294 * @param buf_size size of packet to process
295 * @todo TODO: Implement cropping
296 */
299 int64_t pts)
300 {
302
303 int w = bytestream_get_be16(&buf);
304 int h = bytestream_get_be16(&buf);
305
306 uint16_t object_index;
307
309
310 av_dlog(avctx,
"Video Dimensions %dx%d\n",
311 w, h);
314
315 /* Skip 1 bytes of unknown, frame rate? */
316 buf++;
317
319
320 /*
321 * Skip 3 bytes of unknown:
322 * state
323 * palette_update_flag (0x80),
324 * palette_id_to_use,
325 */
326 buf += 3;
327
330 return;
331
332 /* Verify that enough bytes are remaining for all of the objects. */
333 buf_size -= 11;
334 if (buf_size < ctx->presentation.object_count * 8) {
336 return;
337 }
338
343 return;
344 }
345
348 reference->
picture_id = bytestream_get_be16(&buf);
349
350 /* Skip window_id_ref */
351 buf++;
352 /* composition_flag (0x80 - object cropped, 0x40 - object forced) */
353 reference->
composition = bytestream_get_byte(&buf);
354
355 reference->
x = bytestream_get_be16(&buf);
356 reference->
y = bytestream_get_be16(&buf);
357
358 /* TODO If cropping, cropping_x, cropping_y, cropping_width, cropping_height (all 2 bytes).*/
359 av_dlog(avctx,
"Subtitle Placement ID=%d, x=%d, y=%d\n", reference->
picture_id, reference->
x, reference->
y);
360
361 if (reference->
x > avctx->
width || reference->
y > avctx->
height) {
362 av_log(avctx,
AV_LOG_ERROR,
"Subtitle out of video bounds. x = %d, y = %d, video width = %d, video height = %d.\n",
366 }
367 }
368 }
369
370 /**
371 * Parse the display segment packet.
372 *
373 * The display segment controls the updating of the display.
374 *
375 * @param avctx contains the current codec context
376 * @param data pointer to the data pertaining the subtitle to display
377 * @param buf pointer to the packet to process
378 * @param buf_size size of packet to process
379 * @todo TODO: Fix start time, relies on correct PTS, currently too late
380 *
381 * @todo TODO: Fix end time, normally cleared by a second display
382 * @todo segment, which is currently ignored as it clears
383 * @todo the subtitle too early.
384 */
387 {
390 int64_t pts;
391
393
394 /*
395 * The end display time is a timeout value and is only reached
396 * if the next subtitle is later than timeout or subtitle has
397 * not been cleared by a subsequent empty display command.
398 */
399
401 memset(sub, 0, sizeof(*sub));
404
405 // Blank if last object_count was 0.
407 return 1;
408
412
415
416 for (rect = 0; rect < sub->
num_rects; ++rect) {
424
425 /* Process bitmap */
432 return 0;
433 }
434
435 /* Allocate memory for colors */
438
439 /* Copy the forced flag */
441
444 }
445
446 return 1;
447 }
448
451 {
453 int buf_size = avpkt->
size;
455
458 int segment_length;
459 int i;
460
461 av_dlog(avctx,
"PGS sub packet:\n");
462
463 for (i = 0; i < buf_size; i++) {
464 av_dlog(avctx,
"%02x ", buf[i]);
465 if (i % 16 == 15)
467 }
468
469 if (i & 15)
471
472 *data_size = 0;
473
474 /* Ensure that we have received at a least a segment code and segment length */
475 if (buf_size < 3)
476 return -1;
477
478 buf_end = buf + buf_size;
479
480 /* Step through buffer to identify segments */
481 while (buf < buf_end) {
482 segment_type = bytestream_get_byte(&buf);
483 segment_length = bytestream_get_be16(&buf);
484
485 av_dlog(avctx,
"Segment Length %d, Segment Type %x\n", segment_length, segment_type);
486
488 break;
489
490 switch (segment_type) {
493 break;
496 break;
499 break;
501 /*
502 * Window Segment Structure (No new information provided):
503 * 2 bytes: Unknown,
504 * 2 bytes: X position of subtitle,
505 * 2 bytes: Y position of subtitle,
506 * 2 bytes: Width of subtitle,
507 * 2 bytes: Height of subtitle.
508 */
509 break;
512 break;
513 default:
515 segment_type, segment_length);
516 break;
517 }
518
519 buf += segment_length;
520 }
521
522 return buf_size;
523 }
524
525 #define OFFSET(x) offsetof(PGSSubContext, x)
526 #define SD AV_OPT_FLAG_SUBTITLE_PARAM | AV_OPT_FLAG_DECODING_PARAM
528 {
"forced_subs_only",
"Only show forced subtitles",
OFFSET(forced_subs_only),
AV_OPT_TYPE_INT, {.i64 = 0}, 0, 1,
SD},
529 { NULL },
530 };
531
537 };
538
548 .priv_class = &pgsdec_class,
549 };