X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavcodec%2Fdvbsubdec.c;h=f33744df0fa1c177c103e8967ac650d7278c22a9;hb=a247ac640df3da573cd661065bf53f37863e2b46;hp=bc4a17bde0ffa726a9828310446fcf881c98b3c0;hpb=29929fc8e2449d2db8bd144b2badc8d1e6347412;p=ffmpeg diff --git a/libavcodec/dvbsubdec.c b/libavcodec/dvbsubdec.c index bc4a17bde0f..f33744df0fa 100644 --- a/libavcodec/dvbsubdec.c +++ b/libavcodec/dvbsubdec.c @@ -710,8 +710,8 @@ static void compute_default_clut(DVBSubContext *ctx, uint8_t *clut, AVSubtitleRe } 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)); } } @@ -737,7 +737,7 @@ static int save_subtitle_set(AVCodecContext *avctx, AVSubtitle *sub, int *got_ou } /* 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; } @@ -747,7 +747,7 @@ static int save_subtitle_set(AVCodecContext *avctx, AVSubtitle *sub, int *got_ou 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) { @@ -813,7 +813,7 @@ static int save_subtitle_set(AVCodecContext *avctx, AVSubtitle *sub, int *got_ou 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]) { @@ -823,7 +823,7 @@ static int save_subtitle_set(AVCodecContext *avctx, AVSubtitle *sub, int *got_ou 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; @@ -832,18 +832,6 @@ static int save_subtitle_set(AVCodecContext *avctx, AVSubtitle *sub, int *got_ou 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++; } } @@ -851,7 +839,7 @@ FF_ENABLE_DEPRECATION_WARNINGS return 0; fail: if (sub->rects) { - for(i=0; inum_rects; i++) { + for (i=0; i < sub->num_rects; i++) { rect = sub->rects[i]; if (rect) { av_freep(&rect->data[0]); @@ -979,7 +967,8 @@ static void dvbsub_parse_pixel_data_block(AVCodecContext *avctx, DVBSubObjectDis } } - region->has_computed_clut = 0; + if (ctx->compute_clut != -2) + region->has_computed_clut = 0; } static int dvbsub_parse_object_segment(AVCodecContext *avctx, @@ -1032,11 +1021,15 @@ 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; @@ -1073,11 +1066,11 @@ static int dvbsub_parse_clut_segment(AVCodecContext *avctx, 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; @@ -1088,53 +1081,53 @@ static int dvbsub_parse_clut_segment(AVCodecContext *avctx, 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; @@ -1163,7 +1156,7 @@ static int dvbsub_parse_region_segment(AVCodecContext *avctx, region = get_region(ctx, region_id); if (!region) { - region = av_mallocz(sizeof(DVBSubRegion)); + region = av_mallocz(sizeof(*region)); if (!region) return AVERROR(ENOMEM); @@ -1210,7 +1203,7 @@ static int dvbsub_parse_region_segment(AVCodecContext *avctx, } 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; } @@ -1244,7 +1237,7 @@ static int dvbsub_parse_region_segment(AVCodecContext *avctx, object = get_object(ctx, object_id); if (!object) { - object = av_mallocz(sizeof(DVBSubObject)); + object = av_mallocz(sizeof(*object)); if (!object) return AVERROR(ENOMEM); @@ -1255,7 +1248,7 @@ static int dvbsub_parse_region_segment(AVCodecContext *avctx, object->type = (*buf) >> 6; - display = av_mallocz(sizeof(DVBSubObjectDisplay)); + display = av_mallocz(sizeof(*display)); if (!display) return AVERROR(ENOMEM); @@ -1318,7 +1311,7 @@ static int dvbsub_parse_page_segment(AVCodecContext *avctx, 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) { @@ -1352,7 +1345,7 @@ static int dvbsub_parse_page_segment(AVCodecContext *avctx, } if (!display) { - display = av_mallocz(sizeof(DVBSubRegionDisplay)); + display = av_mallocz(sizeof(*display)); if (!display) return AVERROR(ENOMEM); } @@ -1578,8 +1571,9 @@ static int dvbsub_parse_display_definition_segment(AVCodecContext *avctx, 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 @@ -1600,7 +1594,7 @@ static int dvbsub_display_end_segment(AVCodecContext *avctx, const uint8_t *buf, { 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); @@ -1609,7 +1603,7 @@ static int dvbsub_display_end_segment(AVCodecContext *avctx, const uint8_t *buf, } 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; @@ -1667,7 +1661,7 @@ static int dvbsub_decode(AVCodecContext *avctx, 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: @@ -1689,7 +1683,7 @@ static int dvbsub_decode(AVCodecContext *avctx, 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; @@ -1712,16 +1706,16 @@ static int dvbsub_decode(AVCodecContext *avctx, // 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); } @@ -1729,10 +1723,11 @@ end: } #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 = { @@ -1742,7 +1737,7 @@ 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,