Skip to content
Snippets Groups Projects
Commit 7e2643ae authored by Reimar Döffinger's avatar Reimar Döffinger
Browse files

First version of xsub decoder, not yet tested

Originally committed as revision 9933 to svn://svn.ffmpeg.org/ffmpeg/trunk
parent 6b05eb31
No related branches found
No related tags found
No related merge requests found
......@@ -210,6 +210,7 @@ OBJS-$(CONFIG_XAN_DPCM_DECODER) += dpcm.o
OBJS-$(CONFIG_XAN_WC3_DECODER) += xan.o
OBJS-$(CONFIG_XAN_WC4_DECODER) += xan.o
OBJS-$(CONFIG_XL_DECODER) += xl.o
OBJS-$(CONFIG_XSUB_DECODER) += xsubdec.o
OBJS-$(CONFIG_ZLIB_DECODER) += lcldec.o
OBJS-$(CONFIG_ZLIB_ENCODER) += lclenc.o
OBJS-$(CONFIG_ZMBV_DECODER) += zmbv.o
......
......@@ -160,6 +160,7 @@ void avcodec_register_all(void)
REGISTER_DECODER(WNV1, wnv1);
REGISTER_DECODER(XAN_WC3, xan_wc3);
REGISTER_DECODER(XL, xl);
REGISTER_DECODER(XSUB, xsub);
REGISTER_ENCDEC (ZLIB, zlib);
REGISTER_ENCDEC (ZMBV, zmbv);
......
......@@ -204,6 +204,7 @@ extern AVCodec ws_snd1_decoder;
extern AVCodec xan_dpcm_decoder;
extern AVCodec xan_wc3_decoder;
extern AVCodec xl_decoder;
extern AVCodec xsub_decoder;
extern AVCodec zmbv_decoder;
/* PCM codecs */
......
......@@ -265,6 +265,7 @@ enum CodecID {
CODEC_ID_DVD_SUBTITLE= 0x17000,
CODEC_ID_DVB_SUBTITLE,
CODEC_ID_TEXT, /* raw UTF-8 text */
CODEC_ID_XSUB,
CODEC_ID_MPEG2TS= 0x20000, /* _FAKE_ codec to indicate a raw MPEG-2 TS
* stream (only used by libavformat) */
......
#include "avcodec.h"
#include "bitstream.h"
#include "bytestream.h"
static int decode_init(AVCodecContext *avctx) {
avctx->pix_fmt = PIX_FMT_PAL8;
return 0;
}
static const uint8_t runbits[8] = { 2, 2, 6, 6, 10, 10, 14, 14 };
static int decode_frame(AVCodecContext *avctx, void *data, int *data_size,
uint8_t *buf, int buf_size) {
AVSubtitle *sub = data;
uint8_t *buf_end = buf + buf_size;
uint8_t *bitmap;
int w, h, x, y, rlelen, i;
GetBitContext gb;
// check that at least header fits
if (buf_size < 27 + 7 * 2 + 4 * 3) {
av_log(avctx, AV_LOG_ERROR, "coded frame too small\n");
return -1;
}
// read header
w = bytestream_get_le16(&buf);
h = bytestream_get_le16(&buf);
if (avcodec_check_dimensions(avctx, w, h) < 0)
return -1;
x = bytestream_get_le16(&buf);
y = bytestream_get_le16(&buf);
// skip bottom right position, it gives no new information
bytestream_get_le16(&buf);
bytestream_get_le16(&buf);
rlelen = bytestream_get_le16(&buf);
// allocate sub and set values
if (!sub->rects) {
sub->rects = av_mallocz(sizeof(AVSubtitleRect));
sub->num_rects = 1;
}
av_freep(sub->rects[0].bitmap);
sub->rects[0].x = x; sub->rects[0].y = y;
sub->rects[0].w = w; sub->rects[0].h = h;
sub->rects[0].linesize = w;
sub->rects[0].bitmap = av_malloc(w * h);
sub->rects[0].nb_colors = 4;
sub->rects[0].rgba_palette = av_malloc(sub->rects[0].nb_colors * 4);
// read palette
for (i = 0; i < sub->rects[0].nb_colors; i++)
sub->rects[0].rgba_palette[i] = bytestream_get_be24(&buf);
// process RLE-compressed data
rlelen = FFMIN(rlelen, buf_end - buf);
init_get_bits(&gb, buf, rlelen * 8);
bitmap = sub->rects[0].bitmap;
for (y = 0; y < h; y++) {
for (x = 0; x < w; ) {
int log2 = ff_log2_tab[show_bits(&gb, 8)];
int run = get_bits(&gb, runbits[log2]);
int colour = get_bits(&gb, 2);
run = FFMIN(run, w - x);
// run length 0 means till end of row
if (!run) run = w - x;
memset(bitmap, colour, run);
bitmap += run;
x += run;
}
align_get_bits(&gb);
}
*data_size = 1;
return buf_size;
}
AVCodec xsub_decoder = {
"xsub",
CODEC_TYPE_SUBTITLE,
CODEC_ID_XSUB,
0,
decode_init,
NULL,
NULL,
decode_frame,
};
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment