3 * Copyright (c) 2009 Stephen Backway
5 * This file is part of FFmpeg.
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.
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.
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
23 * @file libavcodec/pgssubdec.c
24 * PGS subtitle decoder
29 #include "colorspace.h"
30 #include "bytestream.h"
32 //#define DEBUG_PACKET_CONTENTS
34 #define RGBA(r,g,b,a) (((a) << 24) | ((r) << 16) | ((g) << 8) | (b))
37 PALETTE_SEGMENT
= 0x14,
38 PICTURE_SEGMENT
= 0x15,
39 PRESENTATION_SEGMENT
= 0x16,
40 WINDOW_SEGMENT
= 0x17,
41 DISPLAY_SEGMENT
= 0x80,
44 typedef struct PGSSubPresentation
{
52 typedef struct PGSSubPicture
{
56 unsigned int rle_buffer_size
, rle_data_len
;
59 typedef struct PGSSubContext
{
60 PGSSubPresentation presentation
;
62 PGSSubPicture picture
;
65 static av_cold
int init_decoder(AVCodecContext
*avctx
)
67 avctx
->pix_fmt
= PIX_FMT_RGB32
;
72 static av_cold
int close_decoder(AVCodecContext
*avctx
)
74 PGSSubContext
*ctx
= avctx
->priv_data
;
76 av_freep(&ctx
->picture
.rle
);
77 ctx
->picture
.rle_buffer_size
= 0;
83 * Decodes the RLE data.
85 * The subtitle is stored as an Run Length Encoded image.
87 * @param avctx contains the current codec context
88 * @param sub pointer to the processed subtitle data
89 * @param buf pointer to the RLE data to process
90 * @param buf_size size of the RLE data to process
92 static int decode_rle(AVCodecContext
*avctx
, AVSubtitle
*sub
,
93 const uint8_t *buf
, unsigned int buf_size
)
95 const uint8_t *rle_bitmap_end
;
96 int pixel_count
, line_count
;
98 rle_bitmap_end
= buf
+ buf_size
;
100 sub
->rects
[0]->pict
.data
[0] = av_malloc(sub
->rects
[0]->w
* sub
->rects
[0]->h
);
102 if (!sub
->rects
[0]->pict
.data
[0])
108 while (buf
< rle_bitmap_end
&& line_count
< sub
->rects
[0]->h
) {
109 uint8_t flags
, color
;
112 color
= bytestream_get_byte(&buf
);
116 flags
= bytestream_get_byte(&buf
);
119 run
= (run
<< 8) + bytestream_get_byte(&buf
);
120 color
= flags
& 0x80 ? bytestream_get_byte(&buf
) : 0;
123 if (run
> 0 && pixel_count
+ run
<= sub
->rects
[0]->w
* sub
->rects
[0]->h
) {
124 memset(sub
->rects
[0]->pict
.data
[0] + pixel_count
, color
, run
);
128 * New Line. Check if correct pixels decoded, if not display warning
129 * and adjust bitmap pointer to correct new line position.
131 if (pixel_count
% sub
->rects
[0]->w
> 0)
132 av_log(avctx
, AV_LOG_ERROR
, "Decoded %d pixels, when line should be %d pixels\n",
133 pixel_count
% sub
->rects
[0]->w
, sub
->rects
[0]->w
);
138 dprintf(avctx
, "Pixel Count = %d, Area = %d\n", pixel_count
, sub
->rects
[0]->w
* sub
->rects
[0]->h
);
144 * Parses the picture segment packet.
146 * The picture segment contains details on the sequence id,
147 * width, height and Run Length Encoded (RLE) bitmap data.
149 * @param avctx contains the current codec context
150 * @param buf pointer to the packet to process
151 * @param buf_size size of packet to process
152 * @todo TODO: Enable support for RLE data over multiple packets
154 static int parse_picture_segment(AVCodecContext
*avctx
,
155 const uint8_t *buf
, int buf_size
)
157 PGSSubContext
*ctx
= avctx
->priv_data
;
159 uint8_t sequence_desc
;
160 unsigned int rle_bitmap_len
, width
, height
;
162 /* skip 3 unknown bytes: Object ID (2 bytes), Version Number */
165 /* Read the Sequence Description to determine if start of RLE data or appended to previous RLE */
166 sequence_desc
= bytestream_get_byte(&buf
);
168 if (!(sequence_desc
& 0x80)) {
169 av_log(avctx
, AV_LOG_ERROR
, "Decoder does not support object data over multiple packets.\n");
173 /* Decode rle bitmap length */
174 rle_bitmap_len
= bytestream_get_be24(&buf
);
176 /* Check to ensure we have enough data for rle_bitmap_length if just a single packet */
177 if (rle_bitmap_len
> buf_size
- 7) {
178 av_log(avctx
, AV_LOG_ERROR
, "Not enough RLE data for specified length of %d.\n", rle_bitmap_len
);
182 ctx
->picture
.rle_data_len
= rle_bitmap_len
;
184 /* Get bitmap dimensions from data */
185 width
= bytestream_get_be16(&buf
);
186 height
= bytestream_get_be16(&buf
);
188 /* Make sure the bitmap is not too large */
189 if (ctx
->presentation
.video_w
< width
|| ctx
->presentation
.video_h
< height
) {
190 av_log(avctx
, AV_LOG_ERROR
, "Bitmap dimensions larger then video.\n");
194 ctx
->picture
.w
= width
;
195 ctx
->picture
.h
= height
;
197 av_fast_malloc(&ctx
->picture
.rle
, &ctx
->picture
.rle_buffer_size
, rle_bitmap_len
);
199 if (!ctx
->picture
.rle
)
202 memcpy(ctx
->picture
.rle
, buf
, rle_bitmap_len
);
208 * Parses the palette segment packet.
210 * The palette segment contains details of the palette,
211 * a maximum of 256 colors can be defined.
213 * @param avctx contains the current codec context
214 * @param buf pointer to the packet to process
215 * @param buf_size size of packet to process
217 static void parse_palette_segment(AVCodecContext
*avctx
,
218 const uint8_t *buf
, int buf_size
)
220 PGSSubContext
*ctx
= avctx
->priv_data
;
222 const uint8_t *buf_end
= buf
+ buf_size
;
223 const uint8_t *cm
= ff_cropTbl
+ MAX_NEG_CROP
;
225 int y
, cb
, cr
, alpha
;
226 int r
, g
, b
, r_add
, g_add
, b_add
;
228 /* Skip two null bytes */
231 while (buf
< buf_end
) {
232 color_id
= bytestream_get_byte(&buf
);
233 y
= bytestream_get_byte(&buf
);
234 cb
= bytestream_get_byte(&buf
);
235 cr
= bytestream_get_byte(&buf
);
236 alpha
= bytestream_get_byte(&buf
);
239 YUV_TO_RGB2(r
, g
, b
, y
);
241 dprintf(avctx
, "Color %d := (%d,%d,%d,%d)\n", color_id
, r
, g
, b
, alpha
);
243 /* Store color in palette */
244 ctx
->clut
[color_id
] = RGBA(r
,g
,b
,alpha
);
249 * Parses the presentation segment packet.
251 * The presentation segment contains details on the video
252 * width, video height, x & y subtitle position.
254 * @param avctx contains the current codec context
255 * @param buf pointer to the packet to process
256 * @param buf_size size of packet to process
257 * @todo TODO: Implement cropping
258 * @todo TODO: Implement forcing of subtitles
259 * @todo TODO: Blanking of subtitle
261 static void parse_presentation_segment(AVCodecContext
*avctx
,
262 const uint8_t *buf
, int buf_size
)
264 PGSSubContext
*ctx
= avctx
->priv_data
;
269 ctx
->presentation
.video_w
= bytestream_get_be16(&buf
);
270 ctx
->presentation
.video_h
= bytestream_get_be16(&buf
);
272 dprintf(avctx
, "Video Dimensions %dx%d\n",
273 ctx
->presentation
.video_w
, ctx
->presentation
.video_h
);
275 /* Skip 1 bytes of unknown, frame rate? */
278 ctx
->presentation
.id_number
= bytestream_get_be16(&buf
);
280 /* Next byte is the state. */
281 block
= bytestream_get_byte(&buf
);;
284 * Skip 7 bytes of unknown:
285 * palette_update_flag (0x80),
287 * Object Number (if > 0 determines if more data to process),
288 * object_id_ref (2 bytes),
290 * composition_flag (0x80 - object cropped, 0x40 - object forced)
294 x
= bytestream_get_be16(&buf
);
295 y
= bytestream_get_be16(&buf
);
297 /* TODO If cropping, cropping_x, cropping_y, cropping_width, cropping_height (all 2 bytes).*/
299 dprintf(avctx
, "Subtitle Placement x=%d, y=%d\n", x
, y
);
301 if (x
> ctx
->presentation
.video_w
|| y
> ctx
->presentation
.video_h
) {
302 av_log(avctx
, AV_LOG_ERROR
, "Subtitle out of video bounds. x = %d, y = %d, video width = %d, video height = %d.\n",
303 x
, y
, ctx
->presentation
.video_w
, ctx
->presentation
.video_h
);
307 /* Fill in dimensions */
308 ctx
->presentation
.x
= x
;
309 ctx
->presentation
.y
= y
;
310 } else if (block
== 0x00) {
311 /* TODO: Blank context as subtitle should not be displayed.
312 * If the subtitle is blanked now the subtitle is not
313 * on screen long enough to read, due to a delay in
314 * initial display timing.
320 * Parses the display segment packet.
322 * The display segment controls the updating of the display.
324 * @param avctx contains the current codec context
325 * @param data pointer to the data pertaining the subtitle to display
326 * @param buf pointer to the packet to process
327 * @param buf_size size of packet to process
328 * @todo TODO: Fix start time, relies on correct PTS, currently too late
330 * @todo TODO: Fix end time, normally cleared by a second display
331 * @todo segment, which is currently ignored as it clears
332 * @todo the subtitle too early.
334 static int display_end_segment(AVCodecContext
*avctx
, void *data
,
335 const uint8_t *buf
, int buf_size
)
337 AVSubtitle
*sub
= data
;
338 PGSSubContext
*ctx
= avctx
->priv_data
;
341 * The end display time is a timeout value and is only reached
342 * if the next subtitle is later then timeout or subtitle has
343 * not been cleared by a subsequent empty display command.
346 memset(sub
, 0, sizeof(*sub
));
347 sub
->start_display_time
= 0;
348 sub
->end_display_time
= 20000;
351 sub
->rects
= av_mallocz(sizeof(*sub
->rects
));
352 sub
->rects
[0] = av_mallocz(sizeof(*sub
->rects
[0]));
355 sub
->rects
[0]->x
= ctx
->presentation
.x
;
356 sub
->rects
[0]->y
= ctx
->presentation
.y
;
357 sub
->rects
[0]->w
= ctx
->picture
.w
;
358 sub
->rects
[0]->h
= ctx
->picture
.h
;
359 sub
->rects
[0]->type
= SUBTITLE_BITMAP
;
362 sub
->rects
[0]->pict
.linesize
[0] = ctx
->picture
.w
;
364 if (ctx
->picture
.rle
)
365 if(decode_rle(avctx
, sub
, ctx
->picture
.rle
, ctx
->picture
.rle_data_len
) < 0)
368 /* Allocate memory for colors */
369 sub
->rects
[0]->nb_colors
= 256;
370 sub
->rects
[0]->pict
.data
[1] = av_mallocz(AVPALETTE_SIZE
);
372 memcpy(sub
->rects
[0]->pict
.data
[1], ctx
->clut
, sub
->rects
[0]->nb_colors
* sizeof(uint32_t));
377 static int decode(AVCodecContext
*avctx
, void *data
, int *data_size
,
380 const uint8_t *buf
= avpkt
->data
;
381 int buf_size
= avpkt
->size
;
383 const uint8_t *buf_end
;
384 uint8_t segment_type
;
387 #ifdef DEBUG_PACKET_CONTENTS
390 av_log(avctx
, AV_LOG_INFO
, "PGS sub packet:\n");
392 for (i
= 0; i
< buf_size
; i
++) {
393 av_log(avctx
, AV_LOG_INFO
, "%02x ", buf
[i
]);
395 av_log(avctx
, AV_LOG_INFO
, "\n");
399 av_log(avctx
, AV_LOG_INFO
, "\n");
404 /* Ensure that we have received at a least a segment code and segment length */
408 buf_end
= buf
+ buf_size
;
410 /* Step through buffer to identify segments */
411 while (buf
< buf_end
) {
412 segment_type
= bytestream_get_byte(&buf
);
413 segment_length
= bytestream_get_be16(&buf
);
415 dprintf(avctx
, "Segment Length %d, Segment Type %x\n", segment_length
, segment_type
);
417 if (segment_type
!= DISPLAY_SEGMENT
&& segment_length
> buf_end
- buf
)
420 switch (segment_type
) {
421 case PALETTE_SEGMENT
:
422 parse_palette_segment(avctx
, buf
, segment_length
);
424 case PICTURE_SEGMENT
:
425 parse_picture_segment(avctx
, buf
, segment_length
);
427 case PRESENTATION_SEGMENT
:
428 parse_presentation_segment(avctx
, buf
, segment_length
);
432 * Window Segment Structure (No new information provided):
434 * 2 bytes: X position of subtitle,
435 * 2 bytes: Y position of subtitle,
436 * 2 bytes: Width of subtitle,
437 * 2 bytes: Height of subtitle.
440 case DISPLAY_SEGMENT
:
441 *data_size
= display_end_segment(avctx
, data
, buf
, segment_length
);
444 av_log(avctx
, AV_LOG_ERROR
, "Unknown subtitle segment type 0x%x, length %d\n",
445 segment_type
, segment_length
);
449 buf
+= segment_length
;
455 AVCodec pgssub_decoder
= {
458 CODEC_ID_HDMV_PGS_SUBTITLE
,
459 sizeof(PGSSubContext
),
464 .long_name
= NULL_IF_CONFIG_SMALL("HDMV Presentation Graphic Stream subtitles"),