Go to the documentation of this file.
49 static void yuv_a_to_rgba(
const uint8_t *ycbcr,
const uint8_t *
alpha, uint32_t *rgba,
int num_values)
54 int r_add, g_add, b_add;
56 for (
i = num_values;
i > 0;
i--) {
62 *rgba++ = ((unsigned)*
alpha++ << 24) | (
r << 16) | (
g << 8) |
b;
71 for (t = 1; v < t && t <= 0x40; t <<= 2)
99 static int decode_rle(uint8_t *bitmap,
int linesize,
int w,
int h, uint8_t used_color[256],
100 const uint8_t *buf,
int start,
int buf_size,
int is_8bit)
107 if (start >= buf_size)
110 if (
w <= 0 ||
h <= 0)
113 bit_len = (buf_size - start) * 8;
126 if (
len != INT_MAX &&
len >
w - x)
130 used_color[
color] = 1;
146 uint32_t *rgba_palette,
147 uint32_t subtitle_color)
149 static const uint8_t level_map[4][4] = {
155 {0x00, 0x55, 0xaa, 0xff},
157 uint8_t color_used[16] = { 0 };
158 int nb_opaque_colors,
i,
level, j,
r,
g,
b;
159 uint8_t *colormap =
ctx->colormap, *
alpha =
ctx->alpha;
161 if(
ctx->has_palette) {
162 for(
i = 0;
i < 4;
i++)
163 rgba_palette[
i] = (
ctx->palette[colormap[
i]] & 0x00ffffff)
168 for(
i = 0;
i < 4;
i++)
171 nb_opaque_colors = 0;
172 for(
i = 0;
i < 4;
i++) {
173 if (
alpha[
i] != 0 && !color_used[colormap[
i]]) {
174 color_used[colormap[
i]] = 1;
179 if (nb_opaque_colors == 0)
183 memset(color_used, 0, 16);
184 for(
i = 0;
i < 4;
i++) {
186 if (!color_used[colormap[
i]]) {
187 level = level_map[nb_opaque_colors - 1][j];
188 r = (((subtitle_color >> 16) & 0xff) *
level) >> 8;
189 g = (((subtitle_color >> 8) & 0xff) *
level) >> 8;
190 b = (((subtitle_color >> 0) & 0xff) *
level) >> 8;
191 rgba_palette[
i] =
b | (
g << 8) | (
r << 16) | ((
alpha[
i] * 17
U) << 24);
192 color_used[colormap[
i]] = (
i + 1);
195 rgba_palette[
i] = (rgba_palette[color_used[colormap[
i]] - 1] & 0x00ffffff) |
206 if (sub_header->
rects) {
217 #define READ_OFFSET(a) (big_offsets ? AV_RB32(a) : AV_RB16(a))
220 const uint8_t *buf,
int buf_size)
222 int cmd_pos,
pos, cmd, x1, y1, x2, y2, next_cmd_pos;
223 int big_offsets, offset_size, is_8bit = 0;
224 const uint8_t *yuv_palette =
NULL;
225 uint8_t *colormap =
ctx->colormap, *
alpha =
ctx->alpha;
230 int64_t offset1, offset2;
248 if (cmd_pos < 0 || cmd_pos > buf_size - 2 - offset_size) {
249 if (cmd_pos >
size) {
256 while (cmd_pos > 0 && cmd_pos < buf_size - 2 - offset_size) {
259 ff_dlog(
NULL,
"cmd_pos=0x%04x next=0x%04x date=%d\n",
260 cmd_pos, next_cmd_pos, date);
261 pos = cmd_pos + 2 + offset_size;
264 x1 = y1 = x2 = y2 = 0;
265 while (
pos < buf_size) {
283 if ((buf_size -
pos) < 2)
285 colormap[3] = buf[
pos] >> 4;
286 colormap[2] = buf[
pos] & 0x0f;
287 colormap[1] = buf[
pos + 1] >> 4;
288 colormap[0] = buf[
pos + 1] & 0x0f;
293 if ((buf_size -
pos) < 2)
304 if ((buf_size -
pos) < 6)
306 x1 = (buf[
pos] << 4) | (buf[
pos + 1] >> 4);
307 x2 = ((buf[
pos + 1] & 0x0f) << 8) | buf[
pos + 2];
308 y1 = (buf[
pos + 3] << 4) | (buf[
pos + 4] >> 4);
309 y2 = ((buf[
pos + 4] & 0x0f) << 8) | buf[
pos + 5];
312 ff_dlog(
NULL,
"x1=%d x2=%d y1=%d y2=%d\n", x1, x2, y1, y2);
316 if ((buf_size -
pos) < 4)
320 ff_dlog(
NULL,
"offset1=0x%04"PRIx64
" offset2=0x%04"PRIx64
"\n", offset1, offset2);
324 if ((buf_size -
pos) < 8)
328 ff_dlog(
NULL,
"offset1=0x%04"PRIx64
" offset2=0x%04"PRIx64
"\n", offset1, offset2);
334 if ((buf_size -
pos) < 768)
336 yuv_palette = buf +
pos;
341 if ((buf_size -
pos) < 256)
343 for (
i = 0;
i < 256;
i++)
351 ff_dlog(
NULL,
"unrecognised subpicture command 0x%x\n", cmd);
356 if (offset1 >= buf_size || offset2 >= buf_size)
359 if (offset1 >= 0 && offset2 >= 0) {
370 if (
w > 0 &&
h > 1) {
372 memset(
ctx->used_color, 0,
sizeof(
ctx->used_color));
374 if (!sub_header->
rects)
377 if (!sub_header->
rects[0])
384 buf, offset1, buf_size, is_8bit) < 0)
387 buf, offset2, buf_size, is_8bit) < 0)
397 (uint32_t *)sub_header->
rects[0]->
data[1],
404 sub_header->
rects[0]->
x = x1;
405 sub_header->
rects[0]->
y = y1;
413 if (next_cmd_pos < cmd_pos) {
417 if (next_cmd_pos == cmd_pos)
419 cmd_pos = next_cmd_pos;
428 static int is_transp(
const uint8_t *buf,
int pitch,
int n,
429 const uint8_t *transp_color)
432 for(
i = 0;
i < n;
i++) {
433 if (!transp_color[*buf])
443 uint8_t transp_color[256] = { 0 };
444 int y1, y2, x1, x2, y,
w,
h,
i;
448 if (
s->num_rects == 0 || !
s->rects ||
s->rects[0]->w <= 0 ||
s->rects[0]->h <= 0)
451 for(
i = 0;
i <
s->rects[0]->nb_colors;
i++) {
452 if ((((uint32_t *)
s->rects[0]->data[1])[
i] >> 24) == 0) {
454 }
else if (
ctx->used_color[
i])
460 while (y1 < s->rects[0]->
h &&
is_transp(
s->rects[0]->data[0] + y1 *
s->rects[0]->linesize[0],
461 1,
s->rects[0]->w, transp_color))
463 if (y1 ==
s->rects[0]->h) {
465 s->rects[0]->w =
s->rects[0]->h = 0;
469 y2 =
s->rects[0]->h - 1;
470 while (y2 > 0 &&
is_transp(
s->rects[0]->data[0] + y2 *
s->rects[0]->linesize[0], 1,
471 s->rects[0]->w, transp_color))
474 while (x1 < (
s->rects[0]->w - 1) &&
is_transp(
s->rects[0]->data[0] + x1,
s->rects[0]->linesize[0],
475 s->rects[0]->h, transp_color))
477 x2 =
s->rects[0]->w - 1;
478 while (x2 > 0 &&
is_transp(
s->rects[0]->data[0] + x2,
s->rects[0]->linesize[0],
s->rects[0]->h,
486 for(y = 0; y <
h; y++) {
487 memcpy(bitmap +
w * y,
s->rects[0]->data[0] + x1 + (y1 + y) *
s->rects[0]->linesize[0],
w);
490 s->rects[0]->data[0] = bitmap;
491 s->rects[0]->linesize[0] =
w;
494 s->rects[0]->x += x1;
495 s->rects[0]->y += y1;
501 const uint8_t *buf,
int buf_size)
506 if (buf_size >=
sizeof(
ctx->buf) -
ctx->buf_size) {
508 "too large SPU packets aborted.\n");
512 memcpy(
ctx->buf +
ctx->buf_size, buf, buf_size);
513 ctx->buf_size += buf_size;
518 int *data_size,
const AVPacket *avpkt)
521 const uint8_t *buf = avpkt->
data;
522 int buf_size = avpkt->
size;
533 buf_size =
ctx->buf_size;
538 if (is_menu ==
AVERROR(EAGAIN)) {
566 uint32_t sp_pgci, pgci, off_pgc, pgc;
567 uint8_t
r,
g,
b, yuv[65], *buf;
568 int i, y,
cb,
cr, r_add, g_add, b_add;
572 ctx->has_palette = 0;
577 if (fread(ifostr, 12, 1, ifo) != 1 || memcmp(ifostr,
"DVDVIDEO-VTS", 12)) {
582 if (fseek(ifo, 0xCC, SEEK_SET) == -1) {
586 if (fread(&sp_pgci, 4, 1, ifo) == 1) {
588 if (fseek(ifo, pgci + 0x0C, SEEK_SET) == -1) {
592 if (fread(&off_pgc, 4, 1, ifo) == 1) {
594 if (fseek(ifo, pgc + 0xA4, SEEK_SET) == -1) {
598 if (fread(yuv, 64, 1, ifo) == 1) {
600 for(
i=0;
i<16;
i++) {
606 ctx->palette[
i] = (
r << 16) + (
g << 8) +
b;
609 ctx->has_palette = 1;
613 if (
ctx->has_palette == 0) {
625 char *dataorig, *
data;
638 int pos = strcspn(
data,
"\n\r");
642 if (strncmp(
"palette:",
data, 8) == 0) {
643 ctx->has_palette = 1;
645 }
else if (strncmp(
"size:",
data, 5) == 0) {
647 if (sscanf(
data + 5,
"%dx%d", &
w, &
h) == 2) {
673 if (
ctx->palette_str) {
674 ctx->has_palette = 1;
677 if (
ctx->has_palette) {
694 #define OFFSET(field) offsetof(DVDSubContext, field)
695 #define SD AV_OPT_FLAG_SUBTITLE_PARAM | AV_OPT_FLAG_DECODING_PARAM
699 {
"forced_subs_only",
"Only show forced subtitles",
OFFSET(forced_subs_only),
AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1,
SD},
static const AVOption options[]
#define AV_LOG_WARNING
Something somehow does not look correct.
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample they are references to shared objects When the negotiation mechanism computes the intersection of the formats supported at each end of a all references to both lists are replaced with a reference to the intersection And when a single format is eventually chosen for a link amongst the remaining all references to the list are updated That means that if a filter requires that its input and output have the same format amongst a supported all it has to do is use a reference to the same list of formats query_formats can leave some formats unset and return AVERROR(EAGAIN) to cause the negotiation mechanism toagain later. That can be used by filters with complex requirements to use the format negotiated on one link to set the formats supported on another. Frame references ownership and permissions
static double cb(void *priv, double x, double y)
#define AVERROR_EOF
End of file.
static av_cold int dvdsub_init(AVCodecContext *avctx)
static void reset_rects(AVSubtitle *sub_header)
void ff_dvdsub_parse_palette(uint32_t *palette, const char *p)
static void dvdsub_flush(AVCodecContext *avctx)
static int get_bits_count(const GetBitContext *s)
#define YUV_TO_RGB1_CCIR(cb1, cr1)
int ff_set_dimensions(AVCodecContext *s, int width, int height)
Check that the provided frame dimensions are valid and set them on the codec context.
static int init_get_bits(GetBitContext *s, const uint8_t *buffer, int bit_size)
Initialize GetBitContext.
static unsigned int get_bits(GetBitContext *s, int n)
Read 1-25 bits.
static int dvdsub_parse_extradata(AVCodecContext *avctx)
AVCodec p
The public AVCodec.
static int dvdsub_decode(AVCodecContext *avctx, AVSubtitle *sub, int *data_size, const AVPacket *avpkt)
int x
top left corner of pict, undefined when pict is not set
static int find_smallest_bounding_rectangle(DVDSubContext *ctx, AVSubtitle *s)
static int append_to_cached_buf(AVCodecContext *avctx, const uint8_t *buf, int buf_size)
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
int y
top left corner of pict, undefined when pict is not set
int(* init)(AVBSFContext *ctx)
#define av_assert0(cond)
assert() equivalent, that is always enabled.
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
#define CODEC_LONG_NAME(str)
int w
width of pict, undefined when pict is not set
#define LIBAVUTIL_VERSION_INT
Describe the class of an AVClass context structure.
@ AV_CODEC_ID_DVD_SUBTITLE
const char * av_default_item_name(void *ptr)
Return the context name.
static unsigned int get_bits1(GetBitContext *s)
uint8_t * data[4]
data+linesize for the bitmap of this subtitle.
#define YUV_TO_RGB2_CCIR(r, g, b, y1)
static int decode_run_2bit(GetBitContext *gb, int *color)
#define av_err2str(errnum)
Convenience macro, the return value should be used only directly in function arguments but never stan...
static const uint32_t color[16+AV_CLASS_CATEGORY_NB]
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_WL32 unsigned int_TMPL AV_WL24 unsigned int_TMPL AV_WL16 uint64_t_TMPL AV_WB64 unsigned int_TMPL AV_RB32
uint32_t end_display_time
static const AVClass dvdsub_class
static int decode_rle(uint8_t *bitmap, int linesize, int w, int h, uint8_t used_color[256], const uint8_t *buf, int start, int buf_size, int is_8bit)
#define AV_SUBTITLE_FLAG_FORCED
@ SUBTITLE_BITMAP
A bitmap, pict will be set.
static int decode_dvd_subtitles(DVDSubContext *ctx, AVSubtitle *sub_header, const uint8_t *buf, int buf_size)
#define i(width, name, range_min, range_max)
uint8_t * extradata
some codecs need / can use extradata like Huffman tables.
int nb_colors
number of colors in pict, undefined when pict is not set
static int parse_ifo_palette(DVDSubContext *ctx, char *p)
void * av_mallocz(size_t size)
Allocate a memory block with alignment suitable for all memory accesses (including vectors if availab...
const char * name
Name of the codec implementation.
const FFCodec ff_dvdsub_decoder
FILE * avpriv_fopen_utf8(const char *path, const char *mode)
Open a file using a UTF-8 filename.
int h
height of pict, undefined when pict is not set
const char * class_name
The name of the class; usually it is the same name as the context structure type to which the AVClass...
static int is_transp(const uint8_t *buf, int pitch, int n, const uint8_t *transp_color)
static const uint8_t * align_get_bits(GetBitContext *s)
main external API structure.
#define FF_CODEC_DECODE_SUB_CB(func)
static const int16_t alpha[]
This structure stores compressed data.
static double cr(void *priv, double x, double y)
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
static void yuv_a_to_rgba(const uint8_t *ycbcr, const uint8_t *alpha, uint32_t *rgba, int num_values)
uint32_t start_display_time
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_WL32 unsigned int_TMPL AV_WL24 unsigned int_TMPL AV_WL16 uint64_t_TMPL AV_WB64 unsigned int_TMPL AV_WB32 unsigned int_TMPL AV_WB24 unsigned int_TMPL AV_RB16
static void guess_palette(DVDSubContext *ctx, uint32_t *rgba_palette, uint32_t subtitle_color)
static int decode_run_8bit(GetBitContext *gb, int *color)