X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavcodec%2Fxsubdec.c;h=609f59b3510178a25fb1fc63ddd97810c5d505b6;hb=46fb896b9dde91be9646a0e7f7637487ae6236b8;hp=2a858f60b45b2031757b205d331dc06fd8bae3b0;hpb=737c5ebfc8e67cdb6bc5e6d6bb6e9af13e7989f5;p=ffmpeg diff --git a/libavcodec/xsubdec.c b/libavcodec/xsubdec.c index 2a858f60b45..609f59b3510 100644 --- a/libavcodec/xsubdec.c +++ b/libavcodec/xsubdec.c @@ -1,3 +1,23 @@ +/* + * XSUB subtitle decoder + * Copyright (c) 2007 Reimar Döffinger + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ #include "avcodec.h" #include "bitstream.h" #include "bytestream.h" @@ -10,7 +30,7 @@ static int decode_init(AVCodecContext *avctx) { static const uint8_t tc_offsets[9] = { 0, 1, 3, 4, 6, 7, 9, 10, 11 }; static const uint8_t tc_muls[9] = { 10, 6, 10, 6, 10, 6, 10, 10, 1 }; -static uint64_t parse_timecode(AVCodecContext *avctx, uint8_t *buf) { +static uint64_t parse_timecode(uint8_t *buf) { int i; int64_t ms = 0; if (buf[2] != ':' || buf[5] != ':' || buf[8] != '.') @@ -20,12 +40,9 @@ static uint64_t parse_timecode(AVCodecContext *avctx, uint8_t *buf) { if (c > 9) return AV_NOPTS_VALUE; ms = (ms + c) * tc_muls[i]; } - ms = av_rescale_q(ms, (AVRational){1, 1000}, avctx->time_base); return ms; } -static const uint8_t runbits[8] = { 14, 14, 10, 10, 6, 6, 2, 2 }; - static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, uint8_t *buf, int buf_size) { AVSubtitle *sub = data; @@ -45,8 +62,8 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, av_log(avctx, AV_LOG_ERROR, "invalid time code\n"); return -1; } - sub->start_display_time = parse_timecode(avctx, buf + 1); - sub->end_display_time = parse_timecode(avctx, buf + 14); + sub->start_display_time = parse_timecode(buf + 1); + sub->end_display_time = parse_timecode(buf + 14); buf += 27; // read header @@ -77,15 +94,20 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, // read palette for (i = 0; i < sub->rects[0].nb_colors; i++) sub->rects[0].rgba_palette[i] = bytestream_get_be24(&buf); + // make all except background (first entry) non-transparent + for (i = 1; i < sub->rects[0].nb_colors; i++) + sub->rects[0].rgba_palette[i] |= 0xff000000; // 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++) { + // interlaced: do odd lines + if (y == (h + 1) / 2) bitmap = sub->rects[0].bitmap + w; for (x = 0; x < w; ) { int log2 = ff_log2_tab[show_bits(&gb, 8)]; - int run = get_bits(&gb, runbits[log2]); + int run = get_bits(&gb, 14 - 4 * (log2 >> 1)); int colour = get_bits(&gb, 2); run = FFMIN(run, w - x); // run length 0 means till end of row @@ -94,6 +116,8 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, bitmap += run; x += run; } + // interlaced, skip every second line + bitmap += w; align_get_bits(&gb); } *data_size = 1;