aboutsummaryrefslogtreecommitdiff
path: root/lib/ffmpeg
diff options
context:
space:
mode:
authorGreenOnyx <gonyx@mchsi.com>2012-12-27 00:18:40 -0600
committerGreenOnyx <gonyx@mchsi.com>2012-12-27 00:18:40 -0600
commit3b1409c1a1f0ce486f95087fa0b6ff5bfb841464 (patch)
tree6bc41e332bfb0aa65ba01358061255ec31e63340 /lib/ffmpeg
parent8158b08e0beefccb212e5c3e9eea733ec40cd04c (diff)
ffmpeg: Fixed forced subtitles display in PGS stream
Associated ffmpeg commits: https://github.com/FFmpeg/FFmpeg/commit/36436a4032b022f5439fa86a0986065d24cd51fd Add option forced_subs_only for Bluray subtitles. 2012-01-30 04:25:59 https://github.com/FFmpeg/FFmpeg/commit/1885ffb03d0af28e6bac2bcc8725fa15b93f6ac9 PGS subtitles: Expose forced flag 2012-10-20 11:56:11 https://github.com/FFmpeg/FFmpeg/commit/1c5805521c3e406886341d752ebf38f8d41e1d13 PGS subtitles: Set AVSubtitle pts value 2012-11-02 11:30:39 https://github.com/FFmpeg/FFmpeg/commit/6549a9b75333027f66cdaac450a66b6a6186fc6e pgssubdec: remove unused variable 2012-11-28 10:20:08 https://github.com/FFmpeg/FFmpeg/commit/1f46b50a9591f68b697e943f829c79a4f4829dd6 Added AVClass for AVSubtitleRect 2012-04-18 01:08:25
Diffstat (limited to 'lib/ffmpeg')
-rw-r--r--lib/ffmpeg/libavcodec/avcodec.h18
-rw-r--r--lib/ffmpeg/libavcodec/dvdsubdec.c1
-rw-r--r--lib/ffmpeg/libavcodec/options.c25
-rw-r--r--lib/ffmpeg/libavcodec/pgssubdec.c53
4 files changed, 81 insertions, 16 deletions
diff --git a/lib/ffmpeg/libavcodec/avcodec.h b/lib/ffmpeg/libavcodec/avcodec.h
index 6996c9266b..585414bf9c 100644
--- a/lib/ffmpeg/libavcodec/avcodec.h
+++ b/lib/ffmpeg/libavcodec/avcodec.h
@@ -3245,6 +3245,12 @@ typedef struct AVCodecContext {
int64_t pts_correction_num_faulty_dts; /// Number of incorrect DTS values so far
int64_t pts_correction_last_pts; /// PTS of the last frame
int64_t pts_correction_last_dts; /// DTS of the last frame
+ /**
+ * Requests that only forced subpictures be decoded.
+ * - decoding: set by user
+ * - encoding: unused
+ */
+ int forced_subs_only;
} AVCodecContext;
@@ -3488,6 +3494,8 @@ enum AVSubtitleType {
SUBTITLE_ASS,
};
+#define AV_SUBTITLE_FLAG_FORCED 0x00000001
+
typedef struct AVSubtitleRect {
int x; ///< top left corner of pict, undefined when pict is not set
int y; ///< top left corner of pict, undefined when pict is not set
@@ -3510,6 +3518,8 @@ typedef struct AVSubtitleRect {
* struct.
*/
char *ass;
+
+ int flags;
} AVSubtitleRect;
typedef struct AVSubtitle {
@@ -4895,6 +4905,14 @@ const AVClass *avcodec_get_class(void);
const AVClass *avcodec_get_frame_class(void);
/**
+ * Get the AVClass for AVSubtitleRect. It can be used in combination with
+ * AV_OPT_SEARCH_FAKE_OBJ for examining options.
+ *
+ * @see av_opt_find().
+ */
+const AVClass *avcodec_get_subtitle_rect_class(void);
+
+/**
* @return a positive value if s is open (i.e. avcodec_open2() was called on it
* with no corresponding avcodec_close()), 0 otherwise.
*/
diff --git a/lib/ffmpeg/libavcodec/dvdsubdec.c b/lib/ffmpeg/libavcodec/dvdsubdec.c
index d0d13eecec..46a0b8d384 100644
--- a/lib/ffmpeg/libavcodec/dvdsubdec.c
+++ b/lib/ffmpeg/libavcodec/dvdsubdec.c
@@ -375,6 +375,7 @@ static int decode_dvd_subtitles(DVDSubContext *ctx, AVSubtitle *sub_header,
sub_header->rects[0]->h = h;
sub_header->rects[0]->type = SUBTITLE_BITMAP;
sub_header->rects[0]->pict.linesize[0] = w;
+ sub_header->rects[0]->flags = is_menu ? AV_SUBTITLE_FLAG_FORCED : 0;
}
}
if (next_cmd_pos < cmd_pos) {
diff --git a/lib/ffmpeg/libavcodec/options.c b/lib/ffmpeg/libavcodec/options.c
index 5f940a0af6..ae62e75867 100644
--- a/lib/ffmpeg/libavcodec/options.c
+++ b/lib/ffmpeg/libavcodec/options.c
@@ -730,3 +730,28 @@ const AVClass *avcodec_get_frame_class(void)
{
return &av_frame_class;
}
+
+#define SROFFSET(x) offsetof(AVSubtitleRect,x)
+
+static const AVOption subtitle_rect_options[]={
+{"x", "", SROFFSET(x), AV_OPT_TYPE_INT, {.i64 = 0 }, 0, INT_MAX, 0},
+{"y", "", SROFFSET(y), AV_OPT_TYPE_INT, {.i64 = 0 }, 0, INT_MAX, 0},
+{"w", "", SROFFSET(w), AV_OPT_TYPE_INT, {.i64 = 0 }, 0, INT_MAX, 0},
+{"h", "", SROFFSET(h), AV_OPT_TYPE_INT, {.i64 = 0 }, 0, INT_MAX, 0},
+{"type", "", SROFFSET(type), AV_OPT_TYPE_INT, {.i64 = 0 }, 0, INT_MAX, 0},
+{"flags", "", SROFFSET(flags), AV_OPT_TYPE_FLAGS, {.i64 = 0}, 0, 1, 0, "flags"},
+{"forced", "", SROFFSET(flags), AV_OPT_TYPE_FLAGS, {.i64 = 0}, 0, 1, 0},
+{NULL},
+};
+
+static const AVClass av_subtitle_rect_class = {
+ .class_name = "AVSubtitleRect",
+ .item_name = NULL,
+ .option = subtitle_rect_options,
+ .version = LIBAVUTIL_VERSION_INT,
+};
+
+const AVClass *avcodec_get_subtitle_rect_class(void)
+{
+ return &av_subtitle_rect_class;
+} \ No newline at end of file
diff --git a/lib/ffmpeg/libavcodec/pgssubdec.c b/lib/ffmpeg/libavcodec/pgssubdec.c
index 02e650acbc..83d7f43e67 100644
--- a/lib/ffmpeg/libavcodec/pgssubdec.c
+++ b/lib/ffmpeg/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,12 +45,14 @@ typedef struct PGSSubPictureReference {
int x;
int y;
int picture_id;
+ int composition;
} PGSSubPictureReference;
typedef struct PGSSubPresentation {
int id_number;
int object_count;
PGSSubPictureReference *objects;
+ int64_t pts;
} PGSSubPresentation;
typedef struct PGSSubPicture {
@@ -61,10 +64,11 @@ typedef struct PGSSubPicture {
} PGSSubPicture;
typedef struct PGSSubContext {
+ AVClass *class;
PGSSubPresentation presentation;
uint32_t clut[256];
PGSSubPicture pictures[UINT16_MAX];
- int64_t pts;
+ int forced_subs_only;
} PGSSubContext;
static av_cold int init_decoder(AVCodecContext *avctx)
@@ -284,10 +288,10 @@ 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)
+ const uint8_t *buf, int buf_size,
+ int64_t pts)
{
PGSSubContext *ctx = avctx->priv_data;
@@ -296,6 +300,8 @@ static void parse_presentation_segment(AVCodecContext *avctx,
uint16_t object_index;
+ ctx->presentation.pts = pts;
+
av_dlog(avctx, "Video Dimensions %dx%d\n",
w, h);
if (av_image_check_size(w, h, 0, avctx) >= 0)
@@ -336,12 +342,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);
@@ -388,10 +392,10 @@ static int display_end_segment(AVCodecContext *avctx, void *data,
* not been cleared by a subsequent empty display command.
*/
- pts = ctx->pts != AV_NOPTS_VALUE ? ctx->pts : sub->pts;
+ pts = ctx->presentation.pts != AV_NOPTS_VALUE ? ctx->presentation.pts : sub->pts;
memset(sub, 0, sizeof(*sub));
sub->pts = pts;
- ctx->pts = AV_NOPTS_VALUE;
+ ctx->presentation.pts = AV_NOPTS_VALUE;
// Blank if last object_count was 0.
if (!ctx->presentation.object_count)
@@ -427,6 +431,10 @@ 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);
+ /* Copy the forced flag */
+ sub->rects[rect]->flags = (ctx->presentation.objects[rect].composition & 0x40) != 0 ? AV_SUBTITLE_FLAG_FORCED : 0;
+
+ 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));
}
@@ -436,7 +444,6 @@ static int display_end_segment(AVCodecContext *avctx, void *data,
static int decode(AVCodecContext *avctx, void *data, int *data_size,
AVPacket *avpkt)
{
- PGSSubContext *ctx = avctx->priv_data;
const uint8_t *buf = avpkt->data;
int buf_size = avpkt->size;
AVSubtitle *sub = data;
@@ -483,8 +490,7 @@ static int decode(AVCodecContext *avctx, void *data, int *data_size,
parse_picture_segment(avctx, buf, segment_length);
break;
case PRESENTATION_SEGMENT:
- parse_presentation_segment(avctx, buf, segment_length);
- ctx->pts = sub->pts;
+ parse_presentation_segment(avctx, buf, segment_length, sub->pts);
break;
case WINDOW_SEGMENT:
/*
@@ -511,6 +517,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, {.i64 = 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,
@@ -519,5 +539,6 @@ AVCodec ff_pgssub_decoder = {
.init = init_decoder,
.close = close_decoder,
.decode = decode,
- .long_name = NULL_IF_CONFIG_SMALL("HDMV Presentation Graphic Stream subtitles"),
-};
+ .long_name = NULL_IF_CONFIG_SMALL("HDMV Presentation Graphic Stream subtitles"),
+ .priv_class = &pgsdec_class,
+}; \ No newline at end of file