| OLD | NEW |
| 1 /* | 1 /* |
| 2 * PGS subtitle decoder | 2 * PGS subtitle decoder |
| 3 * Copyright (c) 2009 Stephen Backway | 3 * Copyright (c) 2009 Stephen Backway |
| 4 * | 4 * |
| 5 * This file is part of FFmpeg. | 5 * This file is part of FFmpeg. |
| 6 * | 6 * |
| 7 * FFmpeg is free software; you can redistribute it and/or | 7 * FFmpeg is free software; you can redistribute it and/or |
| 8 * modify it under the terms of the GNU Lesser General Public | 8 * modify it under the terms of the GNU Lesser General Public |
| 9 * License as published by the Free Software Foundation; either | 9 * License as published by the Free Software Foundation; either |
| 10 * version 2.1 of the License, or (at your option) any later version. | 10 * version 2.1 of the License, or (at your option) any later version. |
| (...skipping 10 matching lines...) Expand all Loading... |
| 21 | 21 |
| 22 /** | 22 /** |
| 23 * @file | 23 * @file |
| 24 * PGS subtitle decoder | 24 * PGS subtitle decoder |
| 25 */ | 25 */ |
| 26 | 26 |
| 27 #include "avcodec.h" | 27 #include "avcodec.h" |
| 28 #include "dsputil.h" | 28 #include "dsputil.h" |
| 29 #include "bytestream.h" | 29 #include "bytestream.h" |
| 30 #include "libavutil/colorspace.h" | 30 #include "libavutil/colorspace.h" |
| 31 #include "libavcore/imgutils.h" |
| 31 | 32 |
| 32 //#define DEBUG_PACKET_CONTENTS | 33 //#define DEBUG_PACKET_CONTENTS |
| 33 | 34 |
| 34 #define RGBA(r,g,b,a) (((a) << 24) | ((r) << 16) | ((g) << 8) | (b)) | 35 #define RGBA(r,g,b,a) (((a) << 24) | ((r) << 16) | ((g) << 8) | (b)) |
| 35 | 36 |
| 36 enum SegmentType { | 37 enum SegmentType { |
| 37 PALETTE_SEGMENT = 0x14, | 38 PALETTE_SEGMENT = 0x14, |
| 38 PICTURE_SEGMENT = 0x15, | 39 PICTURE_SEGMENT = 0x15, |
| 39 PRESENTATION_SEGMENT = 0x16, | 40 PRESENTATION_SEGMENT = 0x16, |
| 40 WINDOW_SEGMENT = 0x17, | 41 WINDOW_SEGMENT = 0x17, |
| 41 DISPLAY_SEGMENT = 0x80, | 42 DISPLAY_SEGMENT = 0x80, |
| 42 }; | 43 }; |
| 43 | 44 |
| 44 typedef struct PGSSubPresentation { | 45 typedef struct PGSSubPresentation { |
| 45 int x; | 46 int x; |
| 46 int y; | 47 int y; |
| 47 int video_w; | |
| 48 int video_h; | |
| 49 int id_number; | 48 int id_number; |
| 50 } PGSSubPresentation; | 49 } PGSSubPresentation; |
| 51 | 50 |
| 52 typedef struct PGSSubPicture { | 51 typedef struct PGSSubPicture { |
| 53 int w; | 52 int w; |
| 54 int h; | 53 int h; |
| 55 uint8_t *rle; | 54 uint8_t *rle; |
| 56 unsigned int rle_buffer_size, rle_data_len; | 55 unsigned int rle_buffer_size, rle_data_len; |
| 57 } PGSSubPicture; | 56 } PGSSubPicture; |
| 58 | 57 |
| (...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 179 return -1; | 178 return -1; |
| 180 } | 179 } |
| 181 | 180 |
| 182 ctx->picture.rle_data_len = rle_bitmap_len; | 181 ctx->picture.rle_data_len = rle_bitmap_len; |
| 183 | 182 |
| 184 /* Get bitmap dimensions from data */ | 183 /* Get bitmap dimensions from data */ |
| 185 width = bytestream_get_be16(&buf); | 184 width = bytestream_get_be16(&buf); |
| 186 height = bytestream_get_be16(&buf); | 185 height = bytestream_get_be16(&buf); |
| 187 | 186 |
| 188 /* Make sure the bitmap is not too large */ | 187 /* Make sure the bitmap is not too large */ |
| 189 if (ctx->presentation.video_w < width || ctx->presentation.video_h < height)
{ | 188 if (avctx->width < width || avctx->height < height) { |
| 190 av_log(avctx, AV_LOG_ERROR, "Bitmap dimensions larger then video.\n"); | 189 av_log(avctx, AV_LOG_ERROR, "Bitmap dimensions larger then video.\n"); |
| 191 return -1; | 190 return -1; |
| 192 } | 191 } |
| 193 | 192 |
| 194 ctx->picture.w = width; | 193 ctx->picture.w = width; |
| 195 ctx->picture.h = height; | 194 ctx->picture.h = height; |
| 196 | 195 |
| 197 av_fast_malloc(&ctx->picture.rle, &ctx->picture.rle_buffer_size, rle_bitmap_
len); | 196 av_fast_malloc(&ctx->picture.rle, &ctx->picture.rle_buffer_size, rle_bitmap_
len); |
| 198 | 197 |
| 199 if (!ctx->picture.rle) | 198 if (!ctx->picture.rle) |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 259 * @todo TODO: Blanking of subtitle | 258 * @todo TODO: Blanking of subtitle |
| 260 */ | 259 */ |
| 261 static void parse_presentation_segment(AVCodecContext *avctx, | 260 static void parse_presentation_segment(AVCodecContext *avctx, |
| 262 const uint8_t *buf, int buf_size) | 261 const uint8_t *buf, int buf_size) |
| 263 { | 262 { |
| 264 PGSSubContext *ctx = avctx->priv_data; | 263 PGSSubContext *ctx = avctx->priv_data; |
| 265 | 264 |
| 266 int x, y; | 265 int x, y; |
| 267 uint8_t block; | 266 uint8_t block; |
| 268 | 267 |
| 269 ctx->presentation.video_w = bytestream_get_be16(&buf); | 268 int w = bytestream_get_be16(&buf); |
| 270 ctx->presentation.video_h = bytestream_get_be16(&buf); | 269 int h = bytestream_get_be16(&buf); |
| 271 | 270 |
| 272 dprintf(avctx, "Video Dimensions %dx%d\n", | 271 dprintf(avctx, "Video Dimensions %dx%d\n", |
| 273 ctx->presentation.video_w, ctx->presentation.video_h); | 272 w, h); |
| 273 if (av_image_check_size(w, h, 0, avctx) >= 0) |
| 274 avcodec_set_dimensions(avctx, w, h); |
| 274 | 275 |
| 275 /* Skip 1 bytes of unknown, frame rate? */ | 276 /* Skip 1 bytes of unknown, frame rate? */ |
| 276 buf++; | 277 buf++; |
| 277 | 278 |
| 278 ctx->presentation.id_number = bytestream_get_be16(&buf); | 279 ctx->presentation.id_number = bytestream_get_be16(&buf); |
| 279 | 280 |
| 280 /* Next byte is the state. */ | 281 /* Next byte is the state. */ |
| 281 block = bytestream_get_byte(&buf);; | 282 block = bytestream_get_byte(&buf);; |
| 282 if (block == 0x80) { | 283 if (block == 0x80) { |
| 283 /* | 284 /* |
| 284 * Skip 7 bytes of unknown: | 285 * Skip 7 bytes of unknown: |
| 285 * palette_update_flag (0x80), | 286 * palette_update_flag (0x80), |
| 286 * palette_id_to_use, | 287 * palette_id_to_use, |
| 287 * Object Number (if > 0 determines if more data to process), | 288 * Object Number (if > 0 determines if more data to process), |
| 288 * object_id_ref (2 bytes), | 289 * object_id_ref (2 bytes), |
| 289 * window_id_ref, | 290 * window_id_ref, |
| 290 * composition_flag (0x80 - object cropped, 0x40 - object forced) | 291 * composition_flag (0x80 - object cropped, 0x40 - object forced) |
| 291 */ | 292 */ |
| 292 buf += 7; | 293 buf += 7; |
| 293 | 294 |
| 294 x = bytestream_get_be16(&buf); | 295 x = bytestream_get_be16(&buf); |
| 295 y = bytestream_get_be16(&buf); | 296 y = bytestream_get_be16(&buf); |
| 296 | 297 |
| 297 /* TODO If cropping, cropping_x, cropping_y, cropping_width, cropping_he
ight (all 2 bytes).*/ | 298 /* TODO If cropping, cropping_x, cropping_y, cropping_width, cropping_he
ight (all 2 bytes).*/ |
| 298 | 299 |
| 299 dprintf(avctx, "Subtitle Placement x=%d, y=%d\n", x, y); | 300 dprintf(avctx, "Subtitle Placement x=%d, y=%d\n", x, y); |
| 300 | 301 |
| 301 if (x > ctx->presentation.video_w || y > ctx->presentation.video_h) { | 302 if (x > avctx->width || y > avctx->height) { |
| 302 av_log(avctx, AV_LOG_ERROR, "Subtitle out of video bounds. x = %d, y
= %d, video width = %d, video height = %d.\n", | 303 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); | 304 x, y, avctx->width, avctx->height); |
| 304 x = 0; y = 0; | 305 x = 0; y = 0; |
| 305 } | 306 } |
| 306 | 307 |
| 307 /* Fill in dimensions */ | 308 /* Fill in dimensions */ |
| 308 ctx->presentation.x = x; | 309 ctx->presentation.x = x; |
| 309 ctx->presentation.y = y; | 310 ctx->presentation.y = y; |
| 310 } else if (block == 0x00) { | 311 } else if (block == 0x00) { |
| 311 /* TODO: Blank context as subtitle should not be displayed. | 312 /* TODO: Blank context as subtitle should not be displayed. |
| 312 * If the subtitle is blanked now the subtitle is not | 313 * If the subtitle is blanked now the subtitle is not |
| 313 * on screen long enough to read, due to a delay in | 314 * on screen long enough to read, due to a delay in |
| (...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 456 "pgssub", | 457 "pgssub", |
| 457 AVMEDIA_TYPE_SUBTITLE, | 458 AVMEDIA_TYPE_SUBTITLE, |
| 458 CODEC_ID_HDMV_PGS_SUBTITLE, | 459 CODEC_ID_HDMV_PGS_SUBTITLE, |
| 459 sizeof(PGSSubContext), | 460 sizeof(PGSSubContext), |
| 460 init_decoder, | 461 init_decoder, |
| 461 NULL, | 462 NULL, |
| 462 close_decoder, | 463 close_decoder, |
| 463 decode, | 464 decode, |
| 464 .long_name = NULL_IF_CONFIG_SMALL("HDMV Presentation Graphic Stream subtitle
s"), | 465 .long_name = NULL_IF_CONFIG_SMALL("HDMV Presentation Graphic Stream subtitle
s"), |
| 465 }; | 466 }; |
| OLD | NEW |