Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/FFmpeg/FFmpeg.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOliver Fromme <oliver@fromme.com>2014-07-09 20:43:58 +0400
committerMichael Niedermayer <michaelni@gmx.at>2014-07-09 22:11:36 +0400
commita32dcaaaf809b63d9cffd61fa4a2d2c1976727ce (patch)
treee77f4493c8561200ccce1ff3ce50de0ec1c3f57a /libavcodec/dvdsubenc.c
parente36916a63f6fd0644461ecbd6b08eeb8dfab60ab (diff)
avcodec/dvdsubenc: Add dvdsub workaround for some players
The issue affects dvdsub subtitles (a.k.a. VOBSUB). Some players -- in particular hardware players -- cut off the lowest row of pixels if the number of rows in the subtitle is odd. The patch below implements a work-around for that. If the number of rows is odd, it is simply rounded up to an even number, adding an invisible (i.e. fully transparent) row. The work-around can be enabled or disabled with a new option -even_rows_fix. The default is disabled, so there is no change of behaviour for users who don't care about it. The overhead for the fix is low, and in many cases even zero: For subtitles with an odd number of rows (i.e. in 50% of cases on average), the size increases by two bytes because a fully transparent row is encoded as 0x00 0x00. However, in the VOBSUB standard, all data packets are padded to 2KB anyway, so in most cases the additional bytes just use some part of the padding, so there is no overhead. Only in the rare case that the 2KB boundary is hit (0.1% chance), a full 2KB block is added. Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
Diffstat (limited to 'libavcodec/dvdsubenc.c')
-rw-r--r--libavcodec/dvdsubenc.c25
1 files changed, 25 insertions, 0 deletions
diff --git a/libavcodec/dvdsubenc.c b/libavcodec/dvdsubenc.c
index d19d071bf2..ced09dd5e3 100644
--- a/libavcodec/dvdsubenc.c
+++ b/libavcodec/dvdsubenc.c
@@ -24,9 +24,12 @@
#include "libavutil/avassert.h"
#include "libavutil/bprint.h"
#include "libavutil/imgutils.h"
+#include "libavutil/opt.h"
typedef struct {
+ AVClass *class;
uint32_t global_palette[16];
+ int even_rows_fix;
} DVDSubtitleContext;
// ncnt is the nibble counter
@@ -345,6 +348,13 @@ static int encode_dvd_subtitles(AVCodecContext *avctx,
dvd_encode_rle(&q, vrect.pict.data[0] + vrect.w, vrect.w * 2,
vrect.w, vrect.h >> 1, cmap);
+ if (dvdc->even_rows_fix && (vrect.h & 1)) {
+ // Work-around for some players that want the height to be even.
+ vrect.h++;
+ *q++ = 0x00; // 0x00 0x00 == empty row, i.e. fully transparent
+ *q++ = 0x00;
+ }
+
// set data packet size
qq = outbuf + 2;
bytestream_put_be16(&qq, q - outbuf);
@@ -439,6 +449,20 @@ static int dvdsub_encode(AVCodecContext *avctx,
return ret;
}
+#define OFFSET(x) offsetof(DVDSubtitleContext, x)
+#define SE AV_OPT_FLAG_SUBTITLE_PARAM | AV_OPT_FLAG_ENCODING_PARAM
+static const AVOption options[] = {
+ {"even_rows_fix", "Make number of rows even (workaround for some players)", OFFSET(even_rows_fix), AV_OPT_TYPE_INT, {.i64 = 0}, 0, 1, SE},
+ { NULL },
+};
+
+static const AVClass dvdsubenc_class = {
+ .class_name = "VOBSUB subtitle encoder",
+ .item_name = av_default_item_name,
+ .option = options,
+ .version = LIBAVUTIL_VERSION_INT,
+};
+
AVCodec ff_dvdsub_encoder = {
.name = "dvdsub",
.long_name = NULL_IF_CONFIG_SMALL("DVD subtitles"),
@@ -446,5 +470,6 @@ AVCodec ff_dvdsub_encoder = {
.id = AV_CODEC_ID_DVD_SUBTITLE,
.init = dvdsub_init,
.encode_sub = dvdsub_encode,
+ .priv_class = &dvdsubenc_class,
.priv_data_size = sizeof(DVDSubtitleContext),
};