Go to the documentation of this file.
56 int r_add, g_add, b_add;
58 for (
i = num_values;
i > 0;
i--) {
64 *rgba++ = ((unsigned)*
alpha++ << 24) | (
r << 16) | (
g << 8) |
b;
73 for (t = 1; v < t && t <= 0x40; t <<= 2)
109 if (
start >= buf_size)
112 if (
w <= 0 ||
h <= 0)
115 bit_len = (buf_size -
start) * 8;
128 if (
len != INT_MAX &&
len >
w - x)
132 used_color[
color] = 1;
148 uint32_t *rgba_palette,
149 uint32_t subtitle_color)
151 static const uint8_t level_map[4][4] = {
157 {0x00, 0x55, 0xaa, 0xff},
159 uint8_t color_used[16] = { 0 };
160 int nb_opaque_colors,
i,
level, j,
r,
g,
b;
163 if(
ctx->has_palette) {
164 for(
i = 0;
i < 4;
i++)
165 rgba_palette[
i] = (
ctx->palette[colormap[
i]] & 0x00ffffff)
170 for(
i = 0;
i < 4;
i++)
173 nb_opaque_colors = 0;
174 for(
i = 0;
i < 4;
i++) {
175 if (
alpha[
i] != 0 && !color_used[colormap[
i]]) {
176 color_used[colormap[
i]] = 1;
181 if (nb_opaque_colors == 0)
185 memset(color_used, 0, 16);
186 for(
i = 0;
i < 4;
i++) {
188 if (!color_used[colormap[
i]]) {
189 level = level_map[nb_opaque_colors - 1][j];
190 r = (((subtitle_color >> 16) & 0xff) *
level) >> 8;
191 g = (((subtitle_color >> 8) & 0xff) *
level) >> 8;
192 b = (((subtitle_color >> 0) & 0xff) *
level) >> 8;
193 rgba_palette[
i] =
b | (
g << 8) | (
r << 16) | ((
alpha[
i] * 17
U) << 24);
194 color_used[colormap[
i]] = (
i + 1);
197 rgba_palette[
i] = (rgba_palette[color_used[colormap[
i]] - 1] & 0x00ffffff) |
208 if (sub_header->
rects) {
219 #define READ_OFFSET(a) (big_offsets ? AV_RB32(a) : AV_RB16(a))
224 int cmd_pos, pos, cmd, x1, y1, x2, y2, next_cmd_pos;
225 int big_offsets, offset_size, is_8bit = 0;
232 int64_t offset1, offset2;
250 if (cmd_pos < 0 || cmd_pos > buf_size - 2 - offset_size) {
251 if (cmd_pos >
size) {
258 while (cmd_pos > 0 && cmd_pos < buf_size - 2 - offset_size) {
261 ff_dlog(
NULL,
"cmd_pos=0x%04x next=0x%04x date=%d\n",
262 cmd_pos, next_cmd_pos, date);
263 pos = cmd_pos + 2 + offset_size;
266 x1 = y1 = x2 = y2 = 0;
267 while (pos < buf_size) {
285 if ((buf_size - pos) < 2)
287 colormap[3] =
buf[pos] >> 4;
288 colormap[2] =
buf[pos] & 0x0f;
289 colormap[1] =
buf[pos + 1] >> 4;
290 colormap[0] =
buf[pos + 1] & 0x0f;
295 if ((buf_size - pos) < 2)
306 if ((buf_size - pos) < 6)
308 x1 = (
buf[pos] << 4) | (
buf[pos + 1] >> 4);
309 x2 = ((
buf[pos + 1] & 0x0f) << 8) |
buf[pos + 2];
310 y1 = (
buf[pos + 3] << 4) | (
buf[pos + 4] >> 4);
311 y2 = ((
buf[pos + 4] & 0x0f) << 8) |
buf[pos + 5];
314 ff_dlog(
NULL,
"x1=%d x2=%d y1=%d y2=%d\n", x1, x2, y1, y2);
318 if ((buf_size - pos) < 4)
322 ff_dlog(
NULL,
"offset1=0x%04"PRIx64
" offset2=0x%04"PRIx64
"\n", offset1, offset2);
326 if ((buf_size - pos) < 8)
330 ff_dlog(
NULL,
"offset1=0x%04"PRIx64
" offset2=0x%04"PRIx64
"\n", offset1, offset2);
336 if ((buf_size - pos) < 768)
338 yuv_palette =
buf + pos;
343 if ((buf_size - pos) < 256)
345 for (
i = 0;
i < 256;
i++)
353 ff_dlog(
NULL,
"unrecognised subpicture command 0x%x\n", cmd);
358 if (offset1 >= buf_size || offset2 >= buf_size)
361 if (offset1 >= 0 && offset2 >= 0) {
372 if (
w > 0 &&
h > 1) {
374 memset(
ctx->used_color, 0,
sizeof(
ctx->used_color));
376 if (!sub_header->
rects)
379 if (!sub_header->
rects[0])
386 buf, offset1, buf_size, is_8bit) < 0)
389 buf, offset2, buf_size, is_8bit) < 0)
399 (uint32_t *)sub_header->
rects[0]->
data[1],
406 sub_header->
rects[0]->
x = x1;
407 sub_header->
rects[0]->
y = y1;
416 for (
i = 0;
i < 4;
i++) {
424 if (next_cmd_pos < cmd_pos) {
428 if (next_cmd_pos == cmd_pos)
430 cmd_pos = next_cmd_pos;
443 for(
i = 0;
i <
n;
i++) {
444 if (!transp_color[*
buf])
454 uint8_t transp_color[256] = { 0 };
455 int y1, y2, x1, x2, y,
w,
h,
i;
459 if (
s->num_rects == 0 || !
s->rects ||
s->rects[0]->w <= 0 ||
s->rects[0]->h <= 0)
462 for(
i = 0;
i <
s->rects[0]->nb_colors;
i++) {
463 if ((((uint32_t *)
s->rects[0]->data[1])[
i] >> 24) == 0) {
465 }
else if (
ctx->used_color[
i])
471 while (y1 < s->rects[0]->
h &&
is_transp(
s->rects[0]->data[0] + y1 *
s->rects[0]->linesize[0],
472 1,
s->rects[0]->w, transp_color))
474 if (y1 ==
s->rects[0]->h) {
476 s->rects[0]->w =
s->rects[0]->h = 0;
480 y2 =
s->rects[0]->h - 1;
481 while (y2 > 0 &&
is_transp(
s->rects[0]->data[0] + y2 *
s->rects[0]->linesize[0], 1,
482 s->rects[0]->w, transp_color))
485 while (x1 < (
s->rects[0]->w - 1) &&
is_transp(
s->rects[0]->data[0] + x1,
s->rects[0]->linesize[0],
486 s->rects[0]->h, transp_color))
488 x2 =
s->rects[0]->w - 1;
489 while (x2 > 0 &&
is_transp(
s->rects[0]->data[0] + x2,
s->rects[0]->linesize[0],
s->rects[0]->h,
497 for(y = 0; y <
h; y++) {
498 memcpy(bitmap +
w * y,
s->rects[0]->data[0] + x1 + (y1 + y) *
s->rects[0]->linesize[0],
w);
501 s->rects[0]->data[0] = bitmap;
502 s->rects[0]->linesize[0] =
w;
505 s->rects[0]->x += x1;
506 s->rects[0]->y += y1;
510 for (
i = 0;
i < 4;
i++) {
511 s->rects[0]->pict.data[
i] =
s->rects[0]->data[
i];
512 s->rects[0]->pict.linesize[
i] =
s->rects[0]->linesize[
i];
521 #define ALPHA_MIX(A,BACK,FORE) (((255-(A)) * (BACK) + (A) * (FORE)) / 255)
522 static void ppm_save(
const char *filename,
uint8_t *bitmap,
int w,
int h,
523 uint32_t *rgba_palette)
527 int back[3] = {0, 255, 0};
530 f = fopen(filename,
"w");
539 for(y = 0; y <
h; y++) {
540 for(x = 0; x <
w; x++) {
541 v = rgba_palette[bitmap[y *
w + x]];
543 putc(ALPHA_MIX(
alpha, back[0], (v >> 16) & 0xff),
f);
544 putc(ALPHA_MIX(
alpha, back[1], (v >> 8) & 0xff),
f);
545 putc(ALPHA_MIX(
alpha, back[2], (v >> 0) & 0xff),
f);
558 if (buf_size >=
sizeof(
ctx->buf) -
ctx->buf_size) {
560 "too large SPU packets aborted.\n");
564 memcpy(
ctx->buf +
ctx->buf_size,
buf, buf_size);
565 ctx->buf_size += buf_size;
570 void *
data,
int *data_size,
575 int buf_size = avpkt->
size;
587 buf_size =
ctx->buf_size;
592 if (is_menu ==
AVERROR(EAGAIN)) {
615 snprintf(ppm_name,
sizeof(ppm_name),
"/tmp/%05d.ppm",
ctx->sub_id++);
619 ppm_save(ppm_name, sub->
rects[0]->
data[0],
633 ctx->has_palette = 1;
635 ctx->palette[
i] = strtoul(p, &p, 16);
645 uint32_t sp_pgci, pgci, off_pgc, pgc;
647 int i, y,
cb,
cr, r_add, g_add, b_add;
651 ctx->has_palette = 0;
652 if ((ifo = fopen(p,
"r")) ==
NULL) {
656 if (fread(ifostr, 12, 1, ifo) != 1 || memcmp(ifostr,
"DVDVIDEO-VTS", 12)) {
661 if (fseek(ifo, 0xCC, SEEK_SET) == -1) {
665 if (fread(&sp_pgci, 4, 1, ifo) == 1) {
667 if (fseek(ifo, pgci + 0x0C, SEEK_SET) == -1) {
671 if (fread(&off_pgc, 4, 1, ifo) == 1) {
673 if (fseek(ifo, pgc + 0xA4, SEEK_SET) == -1) {
677 if (fread(yuv, 64, 1, ifo) == 1) {
679 for(
i=0;
i<16;
i++) {
685 ctx->palette[
i] = (
r << 16) + (
g << 8) +
b;
688 ctx->has_palette = 1;
692 if (
ctx->has_palette == 0) {
704 char *dataorig, *
data;
717 int pos = strcspn(
data,
"\n\r");
718 if (pos==0 && *
data==0)
721 if (strncmp(
"palette:",
data, 8) == 0) {
723 }
else if (strncmp(
"size:",
data, 5) == 0) {
725 if (sscanf(
data + 5,
"%dx%d", &
w, &
h) == 2) {
751 if (
ctx->palette_str)
753 if (
ctx->has_palette) {
776 #define OFFSET(field) offsetof(DVDSubContext, field)
777 #define SD AV_OPT_FLAG_SUBTITLE_PARAM | AV_OPT_FLAG_DECODING_PARAM
781 {
"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 FF_ENABLE_DEPRECATION_WARNINGS
#define AV_LOG_WARNING
Something somehow does not look correct.
static av_cold int init(AVCodecContext *avctx)
AVCodec ff_dvdsub_decoder
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 void parse_palette(DVDSubContext *ctx, char *p)
static double cb(void *priv, double x, double y)
static av_cold int dvdsub_close(AVCodecContext *avctx)
#define AVERROR_EOF
End of file.
static av_cold int dvdsub_init(AVCodecContext *avctx)
static void reset_rects(AVSubtitle *sub_header)
static void dvdsub_flush(AVCodecContext *avctx)
static int get_bits_count(const GetBitContext *s)
static av_const int av_isspace(int c)
Locale-independent conversion of ASCII isspace.
static av_cold int end(AVCodecContext *avctx)
#define YUV_TO_RGB1_CCIR(cb1, cr1)
static int init_get_bits(GetBitContext *s, const uint8_t *buffer, int bit_size)
Initialize GetBitContext.
attribute_deprecated uint8_t * data[AV_NUM_DATA_POINTERS]
pointers to the image data planes
static unsigned int get_bits(GetBitContext *s, int n)
Read 1-25 bits.
static int dvdsub_parse_extradata(AVCodecContext *avctx)
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.
static void decode(AVCodecContext *dec_ctx, AVPacket *pkt, AVFrame *frame, FILE *outfile)
int y
top left corner of pict, undefined when pict is not set
#define av_assert0(cond)
assert() equivalent, that is always enabled.
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
int w
width of pict, undefined when pict is not set
#define LIBAVUTIL_VERSION_INT
Describe the class of an AVClass context structure.
static void flush(AVCodecContext *avctx)
@ 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 NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification.
#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)
attribute_deprecated AVPicture pict
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.
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_DISABLE_DEPRECATION_WARNINGS
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 const int16_t alpha[]
This structure stores compressed data.
static double cr(void *priv, double x, double y)
attribute_deprecated int linesize[AV_NUM_DATA_POINTERS]
number of bytes per line
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
static int dvdsub_decode(AVCodecContext *avctx, void *data, int *data_size, AVPacket *avpkt)
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)