}
count = FFMAX(i - 1, 1);
- for (i--; i>=0; i--) {
- int v = i*255/count;
+ for (i--; i >= 0; i--) {
+ int v = i * 255 / count;
AV_WN32(clut + 4*list_inv[i], RGBA(v/2,v,v/2,v));
}
}
}
/* Not touching AVSubtitles again*/
- if(sub->num_rects) {
+ if (sub->num_rects) {
avpriv_request_sample(ctx, "Different Version of Segment asked Twice");
return AVERROR_PATCHWELCOME;
}
sub->num_rects++;
}
- if(ctx->compute_edt == 0) {
+ if (ctx->compute_edt == 0) {
sub->end_display_time = ctx->time_out * 1000;
*got_output = 1;
} else if (ctx->prev_start != AV_NOPTS_VALUE) {
ret = AVERROR(ENOMEM);
goto fail;
}
- memcpy(rect->data[1], clut_table, (1 << region->depth) * sizeof(uint32_t));
+ memcpy(rect->data[1], clut_table, (1 << region->depth) * sizeof(*clut_table));
rect->data[0] = av_malloc(region->buf_size);
if (!rect->data[0]) {
memcpy(rect->data[0], region->pbuf, region->buf_size);
- if ((clut == &default_clut && ctx->compute_clut == -1) || ctx->compute_clut == 1) {
+ if ((clut == &default_clut && ctx->compute_clut < 0) || ctx->compute_clut == 1) {
if (!region->has_computed_clut) {
compute_default_clut(ctx, region->computed_clut, rect, rect->w, rect->h);
region->has_computed_clut = 1;
memcpy(rect->data[1], region->computed_clut, sizeof(region->computed_clut));
}
-#if FF_API_AVPICTURE
-FF_DISABLE_DEPRECATION_WARNINGS
-{
- int j;
- for (j = 0; j < 4; j++) {
- rect->pict.data[j] = rect->data[j];
- rect->pict.linesize[j] = rect->linesize[j];
- }
-}
-FF_ENABLE_DEPRECATION_WARNINGS
-#endif
-
i++;
}
}
return 0;
fail:
if (sub->rects) {
- for(i=0; i<sub->num_rects; i++) {
+ for (i=0; i < sub->num_rects; i++) {
rect = sub->rects[i];
if (rect) {
av_freep(&rect->data[0]);
}
}
- region->has_computed_clut = 0;
+ if (ctx->compute_clut != -2)
+ region->has_computed_clut = 0;
}
static int dvbsub_parse_object_segment(AVCodecContext *avctx,
dvbsub_parse_pixel_data_block(avctx, display, block, bfl, 1,
non_modifying_color);
}
-
-/* } else if (coding_method == 1) {*/
-
+ } else if (coding_method == 1) {
+ avpriv_report_missing_feature(avctx, "coded as a string of characters");
+ return AVERROR_PATCHWELCOME;
+ } else if (coding_method == 2) {
+ avpriv_report_missing_feature(avctx, "progressive coding of pixels");
+ return AVERROR_PATCHWELCOME;
} else {
av_log(avctx, AV_LOG_ERROR, "Unknown object coding %d\n", coding_method);
+ return AVERROR_INVALIDDATA;
}
return 0;
clut = get_clut(ctx, clut_id);
if (!clut) {
- clut = av_malloc(sizeof(DVBSubCLUT));
+ clut = av_malloc(sizeof(*clut));
if (!clut)
return AVERROR(ENOMEM);
- memcpy(clut, &default_clut, sizeof(DVBSubCLUT));
+ memcpy(clut, &default_clut, sizeof(*clut));
clut->id = clut_id;
clut->version = -1;
if (clut->version != version) {
- clut->version = version;
+ clut->version = version;
- while (buf + 4 < buf_end) {
- entry_id = *buf++;
+ while (buf + 4 < buf_end) {
+ entry_id = *buf++;
- depth = (*buf) & 0xe0;
+ depth = (*buf) & 0xe0;
- if (depth == 0) {
- av_log(avctx, AV_LOG_ERROR, "Invalid clut depth 0x%x!\n", *buf);
- }
+ if (depth == 0) {
+ av_log(avctx, AV_LOG_ERROR, "Invalid clut depth 0x%x!\n", *buf);
+ }
- full_range = (*buf++) & 1;
+ full_range = (*buf++) & 1;
- if (full_range) {
- y = *buf++;
- cr = *buf++;
- cb = *buf++;
- alpha = *buf++;
- } else {
- y = buf[0] & 0xfc;
- cr = (((buf[0] & 3) << 2) | ((buf[1] >> 6) & 3)) << 4;
- cb = (buf[1] << 2) & 0xf0;
- alpha = (buf[1] << 6) & 0xc0;
+ if (full_range) {
+ y = *buf++;
+ cr = *buf++;
+ cb = *buf++;
+ alpha = *buf++;
+ } else {
+ y = buf[0] & 0xfc;
+ cr = (((buf[0] & 3) << 2) | ((buf[1] >> 6) & 3)) << 4;
+ cb = (buf[1] << 2) & 0xf0;
+ alpha = (buf[1] << 6) & 0xc0;
- buf += 2;
- }
+ buf += 2;
+ }
- if (y == 0)
- alpha = 0xff;
+ if (y == 0)
+ alpha = 0xff;
- YUV_TO_RGB1_CCIR(cb, cr);
- YUV_TO_RGB2_CCIR(r, g, b, y);
+ YUV_TO_RGB1_CCIR(cb, cr);
+ YUV_TO_RGB2_CCIR(r, g, b, y);
- ff_dlog(avctx, "clut %d := (%d,%d,%d,%d)\n", entry_id, r, g, b, alpha);
- if (!!(depth & 0x80) + !!(depth & 0x40) + !!(depth & 0x20) > 1) {
- ff_dlog(avctx, "More than one bit level marked: %x\n", depth);
- if (avctx->strict_std_compliance > FF_COMPLIANCE_NORMAL)
- return AVERROR_INVALIDDATA;
- }
+ ff_dlog(avctx, "clut %d := (%d,%d,%d,%d)\n", entry_id, r, g, b, alpha);
+ if (!!(depth & 0x80) + !!(depth & 0x40) + !!(depth & 0x20) > 1) {
+ ff_dlog(avctx, "More than one bit level marked: %x\n", depth);
+ if (avctx->strict_std_compliance > FF_COMPLIANCE_NORMAL)
+ return AVERROR_INVALIDDATA;
+ }
- if (depth & 0x80 && entry_id < 4)
- clut->clut4[entry_id] = RGBA(r,g,b,255 - alpha);
- else if (depth & 0x40 && entry_id < 16)
- clut->clut16[entry_id] = RGBA(r,g,b,255 - alpha);
- else if (depth & 0x20)
- clut->clut256[entry_id] = RGBA(r,g,b,255 - alpha);
- }
+ if (depth & 0x80 && entry_id < 4)
+ clut->clut4[entry_id] = RGBA(r,g,b,255 - alpha);
+ else if (depth & 0x40 && entry_id < 16)
+ clut->clut16[entry_id] = RGBA(r,g,b,255 - alpha);
+ else if (depth & 0x20)
+ clut->clut256[entry_id] = RGBA(r,g,b,255 - alpha);
+ }
}
return 0;
region = get_region(ctx, region_id);
if (!region) {
- region = av_mallocz(sizeof(DVBSubRegion));
+ region = av_mallocz(sizeof(*region));
if (!region)
return AVERROR(ENOMEM);
}
region->depth = 1 << (((*buf++) >> 2) & 7);
- if(region->depth<2 || region->depth>8){
+ if (region->depth < 2 || region->depth > 8) {
av_log(avctx, AV_LOG_ERROR, "region depth %d is invalid\n", region->depth);
region->depth= 4;
}
object = get_object(ctx, object_id);
if (!object) {
- object = av_mallocz(sizeof(DVBSubObject));
+ object = av_mallocz(sizeof(*object));
if (!object)
return AVERROR(ENOMEM);
object->type = (*buf) >> 6;
- display = av_mallocz(sizeof(DVBSubObjectDisplay));
+ display = av_mallocz(sizeof(*display));
if (!display)
return AVERROR(ENOMEM);
display->y_pos = AV_RB16(buf) & 0xfff;
buf += 2;
+ if (display->x_pos >= region->width ||
+ display->y_pos >= region->height) {
+ av_log(avctx, AV_LOG_ERROR, "Object outside region\n");
+ av_free(display);
+ return AVERROR_INVALIDDATA;
+ }
+
if ((object->type == 1 || object->type == 2) && buf+1 < buf_end) {
display->fgcolor = *buf++;
display->bgcolor = *buf++;
ff_dlog(avctx, "Page time out %ds, state %d\n", ctx->time_out, page_state);
- if(ctx->compute_edt == 1)
+ if (ctx->compute_edt == 1)
save_subtitle_set(avctx, sub, got_output);
if (page_state == 1 || page_state == 2) {
}
if (!display) {
- display = av_mallocz(sizeof(DVBSubRegionDisplay));
+ display = av_mallocz(sizeof(*display));
if (!display)
return AVERROR(ENOMEM);
}
display_def->width = bytestream_get_be16(&buf) + 1;
display_def->height = bytestream_get_be16(&buf) + 1;
if (!avctx->width || !avctx->height) {
- avctx->width = display_def->width;
- avctx->height = display_def->height;
+ int ret = ff_set_dimensions(avctx, display_def->width, display_def->height);
+ if (ret < 0)
+ return ret;
}
if (info_byte & 1<<3) { // display_window_flag
{
DVBSubContext *ctx = avctx->priv_data;
- if(ctx->compute_edt == 0)
+ if (ctx->compute_edt == 0)
save_subtitle_set(avctx, sub, got_output);
#ifdef DEBUG
save_display_set(ctx);
}
static int dvbsub_decode(AVCodecContext *avctx,
- void *data, int *data_size,
+ void *data, int *got_sub_ptr,
AVPacket *avpkt)
{
const uint8_t *buf = avpkt->data;
int ret = 0;
switch (segment_type) {
case DVBSUB_PAGE_SEGMENT:
- ret = dvbsub_parse_page_segment(avctx, p, segment_length, sub, data_size);
+ ret = dvbsub_parse_page_segment(avctx, p, segment_length, sub, got_sub_ptr);
got_segment |= 1;
break;
case DVBSUB_REGION_SEGMENT:
got_dds = 1;
break;
case DVBSUB_DISPLAY_SEGMENT:
- ret = dvbsub_display_end_segment(avctx, p, segment_length, sub, data_size);
+ ret = dvbsub_display_end_segment(avctx, p, segment_length, sub, got_sub_ptr);
if (got_segment == 15 && !got_dds && !avctx->width && !avctx->height) {
// Default from ETSI EN 300 743 V1.3.1 (7.2.1)
avctx->width = 720;
// segments then we need no further data.
if (got_segment == 15) {
av_log(avctx, AV_LOG_DEBUG, "Missing display_end_segment, emulating\n");
- dvbsub_display_end_segment(avctx, p, 0, sub, data_size);
+ dvbsub_display_end_segment(avctx, p, 0, sub, got_sub_ptr);
}
end:
- if(ret < 0) {
- *data_size = 0;
+ if (ret < 0) {
+ *got_sub_ptr = 0;
avsubtitle_free(sub);
return ret;
} else {
- if(ctx->compute_edt == 1 )
+ if (ctx->compute_edt == 1)
FFSWAP(int64_t, ctx->prev_start, sub->pts);
}
}
#define DS AV_OPT_FLAG_DECODING_PARAM | AV_OPT_FLAG_SUBTITLE_PARAM
+#define OFFSET(x) offsetof(DVBSubContext, x)
static const AVOption options[] = {
- {"compute_edt", "compute end of time using pts or timeout", offsetof(DVBSubContext, compute_edt), AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, DS},
- {"compute_clut", "compute clut when not available(-1) or always(1) or never(0)", offsetof(DVBSubContext, compute_clut), AV_OPT_TYPE_BOOL, {.i64 = -1}, -1, 1, DS},
- {"dvb_substream", "", offsetof(DVBSubContext, substream), AV_OPT_TYPE_INT, {.i64 = -1}, -1, 63, DS},
+ {"compute_edt", "compute end of time using pts or timeout", OFFSET(compute_edt), AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, DS},
+ {"compute_clut", "compute clut when not available(-1) or only once (-2) or always(1) or never(0)", OFFSET(compute_clut), AV_OPT_TYPE_BOOL, {.i64 = -1}, -2, 1, DS},
+ {"dvb_substream", "", OFFSET(substream), AV_OPT_TYPE_INT, {.i64 = -1}, -1, 63, DS},
{NULL}
};
static const AVClass dvbsubdec_class = {
.version = LIBAVUTIL_VERSION_INT,
};
-AVCodec ff_dvbsub_decoder = {
+const AVCodec ff_dvbsub_decoder = {
.name = "dvbsub",
.long_name = NULL_IF_CONFIG_SMALL("DVB subtitles"),
.type = AVMEDIA_TYPE_SUBTITLE,