/*
- * DVB subtitle decoding for ffmpeg
+ * DVB subtitle decoding
* Copyright (c) 2005 Ian Caulfield
*
- * This file is part of FFmpeg.
+ * This file is part of Libav.
*
- * FFmpeg is free software; you can redistribute it and/or
+ * Libav 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,
+ * Libav 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
+ * License along with Libav; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
+
#include "avcodec.h"
-#include "dsputil.h"
#include "get_bits.h"
#include "bytestream.h"
#include "libavutil/colorspace.h"
-//#define DEBUG
-//#define DEBUG_PACKET_CONTENTS
-//#define DEBUG_SAVE_IMAGES
-
#define DVBSUB_PAGE_SEGMENT 0x10
#define DVBSUB_REGION_SEGMENT 0x11
#define DVBSUB_CLUT_SEGMENT 0x12
#define DVBSUB_DISPLAYDEFINITION_SEGMENT 0x14
#define DVBSUB_DISPLAY_SEGMENT 0x80
-#define cm (ff_cropTbl + MAX_NEG_CROP)
+#define cm (ff_crop_tab + MAX_NEG_CROP)
-#ifdef DEBUG_SAVE_IMAGES
-#undef fprintf
+#ifdef DEBUG
#if 0
static void png_save(const char *filename, uint8_t *bitmap, int w, int h,
uint32_t *rgba_palette)
f = fopen(fname, "w");
if (!f) {
perror(fname);
- exit(1);
+ return;
}
fprintf(f, "P6\n"
"%d %d\n"
f = fopen(fname2, "w");
if (!f) {
perror(fname2);
- exit(1);
+ return;
}
fprintf(f, "P5\n"
"%d %d\n"
f = fopen(fname, "w");
if (!f) {
perror(fname);
- exit(1);
+ return;
}
fprintf(f, "P6\n"
"%d %d\n"
f = fopen(fname2, "w");
if (!f) {
perror(fname2);
- exit(1);
+ return;
}
fprintf(f, "P5\n"
"%d %d\n"
}
#endif
-#define RGBA(r,g,b,a) (((a) << 24) | ((r) << 16) | ((g) << 8) | (b))
+#define RGBA(r,g,b,a) (((unsigned)(a) << 24) | ((r) << 16) | ((g) << 8) | (b))
typedef struct DVBSubCLUT {
int id;
av_dlog(avctx, "DVB pixel block size %d, %s field:\n", buf_size,
top_bottom ? "bottom" : "top");
-#ifdef DEBUG_PACKET_CONTENTS
for (i = 0; i < buf_size; i++) {
if (i % 16 == 0)
- av_log(avctx, AV_LOG_INFO, "0x%08p: ", buf+i);
+ av_dlog(avctx, "0x%8p: ", buf+i);
- av_log(avctx, AV_LOG_INFO, "%02x ", buf[i]);
+ av_dlog(avctx, "%02x ", buf[i]);
if (i % 16 == 15)
- av_log(avctx, AV_LOG_INFO, "\n");
+ av_dlog(avctx, "\n");
}
if (i % 16)
- av_log(avctx, AV_LOG_INFO, "\n");
-
-#endif
+ av_dlog(avctx, "\n");
if (region == 0)
return;
DVBSubContext *ctx = avctx->priv_data;
const uint8_t *buf_end = buf + buf_size;
- int clut_id;
+ int i, clut_id;
DVBSubCLUT *clut;
int entry_id, depth , full_range;
int y, cr, cb, alpha;
int r, g, b, r_add, g_add, b_add;
-#ifdef DEBUG_PACKET_CONTENTS
- int i;
-
- av_log(avctx, AV_LOG_INFO, "DVB clut packet:\n");
+ av_dlog(avctx, "DVB clut packet:\n");
for (i=0; i < buf_size; i++) {
- av_log(avctx, AV_LOG_INFO, "%02x ", buf[i]);
+ av_dlog(avctx, "%02x ", buf[i]);
if (i % 16 == 15)
- av_log(avctx, AV_LOG_INFO, "\n");
+ av_dlog(avctx, "\n");
}
if (i % 16)
- av_log(avctx, AV_LOG_INFO, "\n");
-
-#endif
+ av_dlog(avctx, "\n");
clut_id = *buf++;
buf += 1;
}
-#ifdef DEBUG_SAVE_IMAGES
+#ifdef DEBUG
static void save_display_set(DVBSubContext *ctx)
{
DVBSubRegion *region;
sub->num_rects = i;
-#ifdef DEBUG_SAVE_IMAGES
+#ifdef DEBUG
save_display_set(ctx);
#endif
int segment_type;
int page_id;
int segment_length;
-
-#ifdef DEBUG_PACKET_CONTENTS
int i;
- av_log(avctx, AV_LOG_INFO, "DVB sub packet:\n");
+ av_dlog(avctx, "DVB sub packet:\n");
for (i=0; i < buf_size; i++) {
- av_log(avctx, AV_LOG_INFO, "%02x ", buf[i]);
+ av_dlog(avctx, "%02x ", buf[i]);
if (i % 16 == 15)
- av_log(avctx, AV_LOG_INFO, "\n");
+ av_dlog(avctx, "\n");
}
if (i % 16)
- av_log(avctx, AV_LOG_INFO, "\n");
+ av_dlog(avctx, "\n");
-#endif
-
- if (buf_size <= 2)
+ if (buf_size <= 6 || *buf != 0x0f) {
+ av_dlog(avctx, "incomplete or broken packet");
return -1;
+ }
p = buf;
p_end = buf + buf_size;
- while (p < p_end && *p == 0x0f) {
+ while (p_end - p >= 6 && *p == 0x0f) {
p += 1;
segment_type = *p++;
page_id = AV_RB16(p);
segment_length = AV_RB16(p);
p += 2;
+ if (p_end - p < segment_length) {
+ av_dlog(avctx, "incomplete or broken packet");
+ return -1;
+ }
+
if (page_id == ctx->composition_id || page_id == ctx->ancillary_id ||
ctx->composition_id == -1 || ctx->ancillary_id == -1) {
switch (segment_type) {
p += segment_length;
}
- if (p != p_end) {
- av_dlog(avctx, "Junk at end of packet\n");
- return -1;
- }
-
- return buf_size;
+ return p - buf;
}
AVCodec ff_dvbsub_decoder = {
- "dvbsub",
- AVMEDIA_TYPE_SUBTITLE,
- CODEC_ID_DVB_SUBTITLE,
- sizeof(DVBSubContext),
- dvbsub_init_decoder,
- NULL,
- dvbsub_close_decoder,
- dvbsub_decode,
- .long_name = NULL_IF_CONFIG_SMALL("DVB subtitles"),
+ .name = "dvbsub",
+ .long_name = NULL_IF_CONFIG_SMALL("DVB subtitles"),
+ .type = AVMEDIA_TYPE_SUBTITLE,
+ .id = AV_CODEC_ID_DVB_SUBTITLE,
+ .priv_data_size = sizeof(DVBSubContext),
+ .init = dvbsub_init_decoder,
+ .close = dvbsub_close_decoder,
+ .decode = dvbsub_decode,
};