diff --git a/libavcodec/pgssubdec.c b/libavcodec/pgssubdec.c index 2785d25914..238dbeb00a 100644 --- a/libavcodec/pgssubdec.c +++ b/libavcodec/pgssubdec.c @@ -29,6 +29,7 @@ #include "bytestream.h" #include "libavutil/colorspace.h" #include "libavutil/imgutils.h" +#include "libavutil/opt.h" #define RGBA(r,g,b,a) (((a) << 24) | ((r) << 16) | ((g) << 8) | (b)) @@ -44,6 +45,7 @@ typedef struct PGSSubPictureReference { int x; int y; int picture_id; + int composition; } PGSSubPictureReference; typedef struct PGSSubPresentation { @@ -61,9 +63,11 @@ typedef struct PGSSubPicture { } PGSSubPicture; typedef struct PGSSubContext { + AVClass *class; PGSSubPresentation presentation; uint32_t clut[256]; PGSSubPicture pictures[UINT16_MAX]; + int forced_subs_only; } PGSSubContext; static av_cold int init_decoder(AVCodecContext *avctx) @@ -283,7 +287,6 @@ static void parse_palette_segment(AVCodecContext *avctx, * @param buf pointer to the packet to process * @param buf_size size of packet to process * @todo TODO: Implement cropping - * @todo TODO: Implement forcing of subtitles */ static void parse_presentation_segment(AVCodecContext *avctx, const uint8_t *buf, int buf_size) @@ -335,12 +338,10 @@ static void parse_presentation_segment(AVCodecContext *avctx, PGSSubPictureReference *reference = &ctx->presentation.objects[object_index]; reference->picture_id = bytestream_get_be16(&buf); - /* - * Skip 2 bytes of unknown: - * window_id_ref, - * composition_flag (0x80 - object cropped, 0x40 - object forced) - */ - buf += 2; + /* Skip window_id_ref */ + buf++; + /* composition_flag (0x80 - object cropped, 0x40 - object forced) */ + reference->composition = bytestream_get_byte(&buf); reference->x = bytestream_get_be16(&buf); reference->y = bytestream_get_be16(&buf); @@ -422,6 +423,7 @@ static int display_end_segment(AVCodecContext *avctx, void *data, sub->rects[rect]->nb_colors = 256; sub->rects[rect]->pict.data[1] = av_mallocz(AVPALETTE_SIZE); + if (!ctx->forced_subs_only || ctx->presentation.objects[rect].composition & 0x40) memcpy(sub->rects[rect]->pict.data[1], ctx->clut, sub->rects[rect]->nb_colors * sizeof(uint32_t)); } @@ -503,6 +505,20 @@ static int decode(AVCodecContext *avctx, void *data, int *data_size, return buf_size; } +#define OFFSET(x) offsetof(PGSSubContext, x) +#define SD AV_OPT_FLAG_SUBTITLE_PARAM | AV_OPT_FLAG_DECODING_PARAM +static const AVOption options[] = { + {"forced_subs_only", "Only show forced subtitles", OFFSET(forced_subs_only), AV_OPT_TYPE_INT, {.dbl = 0}, 0, 1, SD}, + { NULL }, +}; + +static const AVClass pgsdec_class = { + .class_name = "PGS subtitle decoder", + .item_name = av_default_item_name, + .option = options, + .version = LIBAVUTIL_VERSION_INT, +}; + AVCodec ff_pgssub_decoder = { .name = "pgssub", .type = AVMEDIA_TYPE_SUBTITLE, @@ -512,4 +528,5 @@ AVCodec ff_pgssub_decoder = { .close = close_decoder, .decode = decode, .long_name = NULL_IF_CONFIG_SMALL("HDMV Presentation Graphic Stream subtitles"), + .priv_class = &pgsdec_class, }; diff --git a/libavcodec/version.h b/libavcodec/version.h index 097909a548..ac28707635 100644 --- a/libavcodec/version.h +++ b/libavcodec/version.h @@ -22,7 +22,7 @@ #define LIBAVCODEC_VERSION_MAJOR 54 #define LIBAVCODEC_VERSION_MINOR 0 -#define LIBAVCODEC_VERSION_MICRO 101 +#define LIBAVCODEC_VERSION_MICRO 102 #define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \ LIBAVCODEC_VERSION_MINOR, \