[FFmpeg-devel] [PATCH v5 02/12] global: Merge AVSubtitle into AVFrame
Soft Works
softworkz at hotmail.com
Sun Sep 12 06:21:37 EEST 2021
Signed-off-by: softworkz <softworkz at hotmail.com>
---
libavcodec/ass.c | 16 ++--
libavcodec/ass.h | 8 +-
libavcodec/assdec.c | 18 ++---
libavcodec/assenc.c | 10 +--
libavcodec/avcodec.c | 19 -----
libavcodec/avcodec.h | 81 ++++----------------
libavcodec/ccaption_dec.c | 28 +++----
libavcodec/codec.h | 4 +-
libavcodec/codec_desc.h | 4 +-
libavcodec/decode.c | 23 +++---
libavcodec/dvbsubdec.c | 48 ++++++------
libavcodec/dvbsubenc.c | 72 +++++++++---------
libavcodec/dvdsubdec.c | 122 +++++++++++++++----------------
libavcodec/dvdsubenc.c | 40 +++++-----
libavcodec/encode.c | 6 +-
libavcodec/jacosubdec.c | 4 +-
libavcodec/libzvbi-teletextdec.c | 16 ++--
libavcodec/microdvddec.c | 4 +-
libavcodec/movtextdec.c | 4 +-
libavcodec/movtextenc.c | 10 +--
libavcodec/mpl2dec.c | 4 +-
libavcodec/pgssubdec.c | 68 ++++++++---------
libavcodec/realtextdec.c | 4 +-
libavcodec/samidec.c | 4 +-
libavcodec/srtdec.c | 4 +-
libavcodec/srtenc.c | 14 ++--
libavcodec/subviewerdec.c | 4 +-
libavcodec/textdec.c | 4 +-
libavcodec/ttmlenc.c | 10 +--
libavcodec/utils.c | 11 +++
libavcodec/webvttdec.c | 4 +-
libavcodec/webvttenc.c | 10 +--
libavcodec/xsubdec.c | 58 +++++++--------
libavcodec/xsubenc.c | 48 ++++++------
libavfilter/vf_subtitles.c | 28 +++----
libavformat/utils.c | 5 +-
libavutil/Makefile | 2 +
libavutil/frame.c | 41 ++++++++++-
libavutil/frame.h | 12 +++
libavutil/subfmt.c | 52 +++++++++++++
libavutil/subfmt.h | 94 ++++++++++++++++++++++++
41 files changed, 576 insertions(+), 442 deletions(-)
create mode 100644 libavutil/subfmt.c
create mode 100644 libavutil/subfmt.h
diff --git a/libavcodec/ass.c b/libavcodec/ass.c
index 907e2d7b88..415ef12911 100644
--- a/libavcodec/ass.c
+++ b/libavcodec/ass.c
@@ -114,26 +114,26 @@ char *ff_ass_get_dialog(int readorder, int layer, const char *style,
speaker ? speaker : "", text);
}
-int ff_ass_add_rect(AVSubtitle *sub, const char *dialog,
+int ff_ass_add_rect(AVFrame *sub, const char *dialog,
int readorder, int layer, const char *style,
const char *speaker)
{
char *ass_str;
AVSubtitleRect **rects;
- rects = av_realloc_array(sub->rects, sub->num_rects+1, sizeof(*sub->rects));
+ rects = av_realloc_array(sub->subtitle_rects, sub->num_subtitle_rects+1, sizeof(*sub->subtitle_rects));
if (!rects)
return AVERROR(ENOMEM);
- sub->rects = rects;
- rects[sub->num_rects] = av_mallocz(sizeof(*rects[0]));
- if (!rects[sub->num_rects])
+ sub->subtitle_rects = rects;
+ rects[sub->num_subtitle_rects] = av_mallocz(sizeof(*rects[0]));
+ if (!rects[sub->num_subtitle_rects])
return AVERROR(ENOMEM);
- rects[sub->num_rects]->type = SUBTITLE_ASS;
+ rects[sub->num_subtitle_rects]->type = AV_SUBTITLE_FMT_ASS;
ass_str = ff_ass_get_dialog(readorder, layer, style, speaker, dialog);
if (!ass_str)
return AVERROR(ENOMEM);
- rects[sub->num_rects]->ass = ass_str;
- sub->num_rects++;
+ rects[sub->num_subtitle_rects]->ass = ass_str;
+ sub->num_subtitle_rects++;
return 0;
}
diff --git a/libavcodec/ass.h b/libavcodec/ass.h
index 2c260e4e78..de31f35c8a 100644
--- a/libavcodec/ass.h
+++ b/libavcodec/ass.h
@@ -48,7 +48,7 @@ typedef struct FFASSDecoderContext {
} FFASSDecoderContext;
/**
- * Generate a suitable AVCodecContext.subtitle_header for SUBTITLE_ASS.
+ * Generate a suitable AVCodecContext.subtitle_header for AV_SUBTITLE_FMT_ASS.
* Can specify all fields explicitly
*
* @param avctx pointer to the AVCodecContext
@@ -76,7 +76,7 @@ int ff_ass_subtitle_header_full(AVCodecContext *avctx,
int bold, int italic, int underline,
int border_style, int alignment);
/**
- * Generate a suitable AVCodecContext.subtitle_header for SUBTITLE_ASS.
+ * Generate a suitable AVCodecContext.subtitle_header for AV_SUBTITLE_FMT_ASS.
*
* @param avctx pointer to the AVCodecContext
* @param font name of the default font face to use
@@ -97,7 +97,7 @@ int ff_ass_subtitle_header(AVCodecContext *avctx,
int border_style, int alignment);
/**
- * Generate a suitable AVCodecContext.subtitle_header for SUBTITLE_ASS
+ * Generate a suitable AVCodecContext.subtitle_header for AV_SUBTITLE_FMT_ASS
* with default style.
*
* @param avctx pointer to the AVCodecContext
@@ -114,7 +114,7 @@ char *ff_ass_get_dialog(int readorder, int layer, const char *style,
/**
* Add an ASS dialog to a subtitle.
*/
-int ff_ass_add_rect(AVSubtitle *sub, const char *dialog,
+int ff_ass_add_rect(AVFrame *sub, const char *dialog,
int readorder, int layer, const char *style,
const char *speaker);
diff --git a/libavcodec/assdec.c b/libavcodec/assdec.c
index 319279490c..0df08ba756 100644
--- a/libavcodec/assdec.c
+++ b/libavcodec/assdec.c
@@ -42,21 +42,21 @@ static av_cold int ass_decode_init(AVCodecContext *avctx)
static int ass_decode_frame(AVCodecContext *avctx, void *data, int *got_sub_ptr,
AVPacket *avpkt)
{
- AVSubtitle *sub = data;
+ AVFrame *sub = data;
if (avpkt->size <= 0)
return avpkt->size;
- sub->rects = av_malloc(sizeof(*sub->rects));
- if (!sub->rects)
+ sub->subtitle_rects = av_malloc(sizeof(*sub->subtitle_rects));
+ if (!sub->subtitle_rects)
return AVERROR(ENOMEM);
- sub->rects[0] = av_mallocz(sizeof(*sub->rects[0]));
- if (!sub->rects[0])
+ sub->subtitle_rects[0] = av_mallocz(sizeof(*sub->subtitle_rects[0]));
+ if (!sub->subtitle_rects[0])
return AVERROR(ENOMEM);
- sub->num_rects = 1;
- sub->rects[0]->type = SUBTITLE_ASS;
- sub->rects[0]->ass = av_strdup(avpkt->data);
- if (!sub->rects[0]->ass)
+ sub->num_subtitle_rects = 1;
+ sub->subtitle_rects[0]->type = AV_SUBTITLE_FMT_ASS;
+ sub->subtitle_rects[0]->ass = av_strdup(avpkt->data);
+ if (!sub->subtitle_rects[0]->ass)
return AVERROR(ENOMEM);
*got_sub_ptr = 1;
return avpkt->size;
diff --git a/libavcodec/assenc.c b/libavcodec/assenc.c
index a6d107ded2..84745a4487 100644
--- a/libavcodec/assenc.c
+++ b/libavcodec/assenc.c
@@ -41,15 +41,15 @@ static av_cold int ass_encode_init(AVCodecContext *avctx)
static int ass_encode_frame(AVCodecContext *avctx,
unsigned char *buf, int bufsize,
- const AVSubtitle *sub)
+ const AVFrame *sub)
{
int i, len, total_len = 0;
- for (i=0; i<sub->num_rects; i++) {
- const char *ass = sub->rects[i]->ass;
+ for (i=0; i<sub->num_subtitle_rects; i++) {
+ const char *ass = sub->subtitle_rects[i]->ass;
- if (sub->rects[i]->type != SUBTITLE_ASS) {
- av_log(avctx, AV_LOG_ERROR, "Only SUBTITLE_ASS type supported.\n");
+ if (sub->subtitle_rects[i]->type != AV_SUBTITLE_FMT_ASS) {
+ av_log(avctx, AV_LOG_ERROR, "Only AV_SUBTITLE_FMT_ASS type supported.\n");
return AVERROR(EINVAL);
}
diff --git a/libavcodec/avcodec.c b/libavcodec/avcodec.c
index 2dd7dd84e0..963f52c4bd 100644
--- a/libavcodec/avcodec.c
+++ b/libavcodec/avcodec.c
@@ -426,25 +426,6 @@ void avcodec_flush_buffers(AVCodecContext *avctx)
av_bsf_flush(avci->bsf);
}
-void avsubtitle_free(AVSubtitle *sub)
-{
- int i;
-
- for (i = 0; i < sub->num_rects; i++) {
- av_freep(&sub->rects[i]->data[0]);
- av_freep(&sub->rects[i]->data[1]);
- av_freep(&sub->rects[i]->data[2]);
- av_freep(&sub->rects[i]->data[3]);
- av_freep(&sub->rects[i]->text);
- av_freep(&sub->rects[i]->ass);
- av_freep(&sub->rects[i]);
- }
-
- av_freep(&sub->rects);
-
- memset(sub, 0, sizeof(*sub));
-}
-
av_cold int avcodec_close(AVCodecContext *avctx)
{
int i;
diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h
index ffd58c333f..a7a2df8cf4 100644
--- a/libavcodec/avcodec.h
+++ b/libavcodec/avcodec.h
@@ -35,6 +35,7 @@
#include "libavutil/frame.h"
#include "libavutil/log.h"
#include "libavutil/pixfmt.h"
+#include "libavutil/subfmt.h"
#include "libavutil/rational.h"
#include "codec.h"
@@ -1670,7 +1671,7 @@ typedef struct AVCodecContext {
/**
* Header containing style information for text subtitles.
- * For SUBTITLE_ASS subtitle type, it should contain the whole ASS
+ * For AV_SUBTITLE_FMT_ASS subtitle type, it should contain the whole ASS
* [Script Info] and [V4+ Styles] section, plus the [Events] line and
* the Format line following. It shouldn't include any Dialogue line.
* - encoding: Set/allocated/freed by user (before avcodec_open2())
@@ -2233,63 +2234,8 @@ typedef struct AVHWAccel {
* @}
*/
-enum AVSubtitleType {
- SUBTITLE_NONE,
-
- SUBTITLE_BITMAP, ///< A bitmap, pict will be set
-
- /**
- * Plain text, the text field must be set by the decoder and is
- * authoritative. ass and pict fields may contain approximations.
- */
- SUBTITLE_TEXT,
-
- /**
- * Formatted text, the ass field must be set by the decoder and is
- * authoritative. pict and text fields may contain approximations.
- */
- SUBTITLE_ASS,
-};
-
#define AV_SUBTITLE_FLAG_FORCED 0x00000001
-typedef struct AVSubtitleRect {
- int x; ///< top left corner of pict, undefined when pict is not set
- int y; ///< top left corner of pict, undefined when pict is not set
- int w; ///< width of pict, undefined when pict is not set
- int h; ///< height of pict, undefined when pict is not set
- int nb_colors; ///< number of colors in pict, undefined when pict is not set
-
- /**
- * data+linesize for the bitmap of this subtitle.
- * Can be set for text/ass as well once they are rendered.
- */
- uint8_t *data[4];
- int linesize[4];
-
- enum AVSubtitleType type;
-
- char *text; ///< 0 terminated plain UTF-8 text
-
- /**
- * 0 terminated ASS/SSA compatible event line.
- * The presentation of this is unaffected by the other values in this
- * struct.
- */
- char *ass;
-
- int flags;
-} AVSubtitleRect;
-
-typedef struct AVSubtitle {
- uint16_t format; /* 0 = graphics */
- uint32_t start_display_time; /* relative to packet pts, in ms */
- uint32_t end_display_time; /* relative to packet pts, in ms */
- unsigned num_rects;
- AVSubtitleRect **rects;
- int64_t pts; ///< Same as packet pts, in AV_TIME_BASE
-} AVSubtitle;
-
/**
* Return the LIBAVCODEC_VERSION_INT constant.
*/
@@ -2425,13 +2371,6 @@ int avcodec_open2(AVCodecContext *avctx, const AVCodec *codec, AVDictionary **op
*/
int avcodec_close(AVCodecContext *avctx);
-/**
- * Free all allocated data in the given subtitle struct.
- *
- * @param sub AVSubtitle to free.
- */
-void avsubtitle_free(AVSubtitle *sub);
-
/**
* @}
*/
@@ -2518,12 +2457,12 @@ enum AVChromaLocation avcodec_chroma_pos_to_enum(int xpos, int ypos);
* before packets may be fed to the decoder.
*
* @param avctx the codec context
- * @param[out] sub The preallocated AVSubtitle in which the decoded subtitle will be stored,
- * must be freed with avsubtitle_free if *got_sub_ptr is set.
+ * @param[out] sub The preallocated AVFrame in which the decoded subtitle will be stored,
+ * must be freed with av_frame_free if *got_sub_ptr is set.
* @param[in,out] got_sub_ptr Zero if no subtitle could be decompressed, otherwise, it is nonzero.
* @param[in] avpkt The input AVPacket containing the input buffer.
*/
-int avcodec_decode_subtitle2(AVCodecContext *avctx, AVSubtitle *sub,
+int avcodec_decode_subtitle2(AVCodecContext *avctx, AVFrame *sub,
int *got_sub_ptr,
AVPacket *avpkt);
@@ -3004,7 +2943,7 @@ void av_parser_close(AVCodecParserContext *s);
*/
int avcodec_encode_subtitle(AVCodecContext *avctx, uint8_t *buf, int buf_size,
- const AVSubtitle *sub);
+ const AVFrame *sub);
/**
@@ -3120,6 +3059,14 @@ void avcodec_flush_buffers(AVCodecContext *avctx);
*/
int av_get_audio_frame_duration(AVCodecContext *avctx, int frame_bytes);
+/**
+ * Return subtitle format from a codec descriptor
+ *
+ * @param codec_descriptor codec descriptor
+ * @return the subtitle type (e.g. bitmap, text)
+ */
+enum AVSubtitleType av_get_subtitle_format_from_codecdesc(const AVCodecDescriptor *codec_descriptor);
+
/* memory */
/**
diff --git a/libavcodec/ccaption_dec.c b/libavcodec/ccaption_dec.c
index 27c61527f6..33cc88f705 100644
--- a/libavcodec/ccaption_dec.c
+++ b/libavcodec/ccaption_dec.c
@@ -841,8 +841,8 @@ static int process_cc608(CCaptionSubContext *ctx, uint8_t hi, uint8_t lo)
static int decode(AVCodecContext *avctx, void *data, int *got_sub, AVPacket *avpkt)
{
CCaptionSubContext *ctx = avctx->priv_data;
- AVSubtitle *sub = data;
- int64_t in_time = sub->pts;
+ AVFrame *sub = data;
+ int64_t in_time = sub->subtitle_pts;
int64_t start_time;
int64_t end_time;
int bidx = ctx->buffer_index;
@@ -879,17 +879,17 @@ static int decode(AVCodecContext *avctx, void *data, int *got_sub, AVPacket *avp
if (ctx->buffer[bidx].str[0] || ctx->real_time) {
ff_dlog(ctx, "cdp writing data (%s)\n", ctx->buffer[bidx].str);
start_time = ctx->buffer_time[0];
- sub->pts = start_time;
+ sub->subtitle_pts = start_time;
end_time = ctx->buffer_time[1];
if (!ctx->real_time)
- sub->end_display_time = av_rescale_q(end_time - start_time,
+ sub->subtitle_end_time = av_rescale_q(end_time - start_time,
AV_TIME_BASE_Q, ms_tb);
else
- sub->end_display_time = -1;
+ sub->subtitle_end_time = -1;
ret = ff_ass_add_rect(sub, ctx->buffer[bidx].str, ctx->readorder++, 0, NULL, NULL);
if (ret < 0)
return ret;
- ctx->last_real_time = sub->pts;
+ ctx->last_real_time = sub->subtitle_pts;
ctx->screen_touched = 0;
}
}
@@ -899,16 +899,16 @@ static int decode(AVCodecContext *avctx, void *data, int *got_sub, AVPacket *avp
ret = ff_ass_add_rect(sub, ctx->buffer[bidx].str, ctx->readorder++, 0, NULL, NULL);
if (ret < 0)
return ret;
- sub->pts = ctx->buffer_time[1];
- sub->end_display_time = av_rescale_q(ctx->buffer_time[1] - ctx->buffer_time[0],
+ sub->subtitle_pts = ctx->buffer_time[1];
+ sub->subtitle_end_time = av_rescale_q(ctx->buffer_time[1] - ctx->buffer_time[0],
AV_TIME_BASE_Q, ms_tb);
- if (sub->end_display_time == 0)
- sub->end_display_time = ctx->buffer[bidx].len * 20;
+ if (sub->subtitle_end_time == 0)
+ sub->subtitle_end_time = ctx->buffer[bidx].len * 20;
}
if (ctx->real_time && ctx->screen_touched &&
- sub->pts >= ctx->last_real_time + av_rescale_q(ctx->real_time_latency_msec, ms_tb, AV_TIME_BASE_Q)) {
- ctx->last_real_time = sub->pts;
+ sub->subtitle_pts >= ctx->last_real_time + av_rescale_q(ctx->real_time_latency_msec, ms_tb, AV_TIME_BASE_Q)) {
+ ctx->last_real_time = sub->subtitle_pts;
ctx->screen_touched = 0;
capture_screen(ctx);
@@ -917,10 +917,10 @@ static int decode(AVCodecContext *avctx, void *data, int *got_sub, AVPacket *avp
ret = ff_ass_add_rect(sub, ctx->buffer[bidx].str, ctx->readorder++, 0, NULL, NULL);
if (ret < 0)
return ret;
- sub->end_display_time = -1;
+ sub->subtitle_end_time = -1;
}
- *got_sub = sub->num_rects > 0;
+ *got_sub = sub->num_subtitle_rects > 0;
return ret;
}
diff --git a/libavcodec/codec.h b/libavcodec/codec.h
index 8f12705066..785a6bf27e 100644
--- a/libavcodec/codec.h
+++ b/libavcodec/codec.h
@@ -188,7 +188,7 @@ typedef struct AVProfile {
typedef struct AVCodecDefault AVCodecDefault;
struct AVCodecContext;
-struct AVSubtitle;
+struct AVFrame;
struct AVPacket;
/**
@@ -283,7 +283,7 @@ typedef struct AVCodec {
int (*init)(struct AVCodecContext *);
int (*encode_sub)(struct AVCodecContext *, uint8_t *buf, int buf_size,
- const struct AVSubtitle *sub);
+ const struct AVFrame *sub);
/**
* Encode data to an AVPacket.
*
diff --git a/libavcodec/codec_desc.h b/libavcodec/codec_desc.h
index 126b52df47..387863a041 100644
--- a/libavcodec/codec_desc.h
+++ b/libavcodec/codec_desc.h
@@ -92,12 +92,12 @@ typedef struct AVCodecDescriptor {
#define AV_CODEC_PROP_REORDER (1 << 3)
/**
* Subtitle codec is bitmap based
- * Decoded AVSubtitle data can be read from the AVSubtitleRect->pict field.
+ * Decoded AVFrame data can be read from the AVSubtitleRect->pict field.
*/
#define AV_CODEC_PROP_BITMAP_SUB (1 << 16)
/**
* Subtitle codec is text based.
- * Decoded AVSubtitle data can be read from the AVSubtitleRect->ass field.
+ * Decoded AVFrame data can be read from the AVSubtitleRect->ass field.
*/
#define AV_CODEC_PROP_TEXT_SUB (1 << 17)
diff --git a/libavcodec/decode.c b/libavcodec/decode.c
index 643f9d6a30..37dd69070e 100644
--- a/libavcodec/decode.c
+++ b/libavcodec/decode.c
@@ -712,10 +712,10 @@ int attribute_align_arg avcodec_receive_frame(AVCodecContext *avctx, AVFrame *fr
return 0;
}
-static void get_subtitle_defaults(AVSubtitle *sub)
+static void get_subtitle_defaults(AVFrame *sub)
{
memset(sub, 0, sizeof(*sub));
- sub->pts = AV_NOPTS_VALUE;
+ sub->subtitle_pts = AV_NOPTS_VALUE;
}
#define UTF8_MAX_BYTES 4 /* 5 and 6 bytes sequences should not be used */
@@ -799,7 +799,7 @@ static int utf8_check(const uint8_t *str)
return 1;
}
-int avcodec_decode_subtitle2(AVCodecContext *avctx, AVSubtitle *sub,
+int avcodec_decode_subtitle2(AVCodecContext *avctx, AVFrame *sub,
int *got_sub_ptr,
AVPacket *avpkt)
{
@@ -828,31 +828,28 @@ int avcodec_decode_subtitle2(AVCodecContext *avctx, AVSubtitle *sub,
return ret;
if (avctx->pkt_timebase.num && avpkt->pts != AV_NOPTS_VALUE)
- sub->pts = av_rescale_q(avpkt->pts,
+ sub->subtitle_pts = av_rescale_q(avpkt->pts,
avctx->pkt_timebase, AV_TIME_BASE_Q);
ret = avctx->codec->decode(avctx, sub, got_sub_ptr, pkt);
av_assert1((ret >= 0) >= !!*got_sub_ptr &&
!!*got_sub_ptr >= !!sub->num_rects);
- if (sub->num_rects && !sub->end_display_time && avpkt->duration &&
+ if (sub->num_subtitle_rects && !sub->subtitle_end_time && avpkt->duration &&
avctx->pkt_timebase.num) {
AVRational ms = { 1, 1000 };
- sub->end_display_time = av_rescale_q(avpkt->duration,
+ sub->subtitle_end_time = av_rescale_q(avpkt->duration,
avctx->pkt_timebase, ms);
}
- if (avctx->codec_descriptor->props & AV_CODEC_PROP_BITMAP_SUB)
- sub->format = 0;
- else if (avctx->codec_descriptor->props & AV_CODEC_PROP_TEXT_SUB)
- sub->format = 1;
+ sub->format = av_get_subtitle_format_from_codecdesc(avctx->codec_descriptor);
- for (unsigned i = 0; i < sub->num_rects; i++) {
+ for (unsigned i = 0; i < sub->num_subtitle_rects; i++) {
if (avctx->sub_charenc_mode != FF_SUB_CHARENC_MODE_IGNORE &&
- sub->rects[i]->ass && !utf8_check(sub->rects[i]->ass)) {
+ sub->subtitle_rects[i]->ass && !utf8_check(sub->subtitle_rects[i]->ass)) {
av_log(avctx, AV_LOG_ERROR,
"Invalid UTF-8 in decoded subtitles text; "
"maybe missing -sub_charenc option\n");
- avsubtitle_free(sub);
+ av_frame_free(&sub);
ret = AVERROR_INVALIDDATA;
break;
}
diff --git a/libavcodec/dvbsubdec.c b/libavcodec/dvbsubdec.c
index e45c14e878..aeb88df06f 100644
--- a/libavcodec/dvbsubdec.c
+++ b/libavcodec/dvbsubdec.c
@@ -725,7 +725,7 @@ static void compute_default_clut(DVBSubContext *ctx, uint8_t *clut, AVSubtitleRe
}
-static int save_subtitle_set(AVCodecContext *avctx, AVSubtitle *sub, int *got_output)
+static int save_subtitle_set(AVCodecContext *avctx, AVFrame *sub, int *got_output)
{
DVBSubContext *ctx = avctx->priv_data;
DVBSubRegionDisplay *display;
@@ -745,34 +745,34 @@ static int save_subtitle_set(AVCodecContext *avctx, AVSubtitle *sub, int *got_ou
}
/* Not touching AVSubtitles again*/
- if (sub->num_rects) {
+ if (sub->num_subtitle_rects) {
avpriv_request_sample(ctx, "Different Version of Segment asked Twice");
return AVERROR_PATCHWELCOME;
}
for (display = ctx->display_list; display; display = display->next) {
region = get_region(ctx, display->region_id);
if (region && region->dirty)
- sub->num_rects++;
+ sub->num_subtitle_rects++;
}
if (ctx->compute_edt == 0) {
- sub->end_display_time = ctx->time_out * 1000;
+ sub->subtitle_end_time = ctx->time_out * 1000;
*got_output = 1;
} else if (ctx->prev_start != AV_NOPTS_VALUE) {
- sub->end_display_time = av_rescale_q((sub->pts - ctx->prev_start ), AV_TIME_BASE_Q, (AVRational){ 1, 1000 }) - 1;
+ sub->subtitle_end_time = av_rescale_q((sub->subtitle_pts - ctx->prev_start ), AV_TIME_BASE_Q, (AVRational){ 1, 1000 }) - 1;
*got_output = 1;
}
- if (sub->num_rects > 0) {
+ if (sub->num_subtitle_rects > 0) {
- sub->rects = av_mallocz_array(sizeof(*sub->rects), sub->num_rects);
- if (!sub->rects) {
+ sub->subtitle_rects = av_mallocz_array(sizeof(*sub->subtitle_rects), sub->num_subtitle_rects);
+ if (!sub->subtitle_rects) {
ret = AVERROR(ENOMEM);
goto fail;
}
- for (i = 0; i < sub->num_rects; i++) {
- sub->rects[i] = av_mallocz(sizeof(*sub->rects[i]));
- if (!sub->rects[i]) {
+ for (i = 0; i < sub->num_subtitle_rects; i++) {
+ sub->subtitle_rects[i] = av_mallocz(sizeof(*sub->subtitle_rects[i]));
+ if (!sub->subtitle_rects[i]) {
ret = AVERROR(ENOMEM);
goto fail;
}
@@ -789,13 +789,13 @@ static int save_subtitle_set(AVCodecContext *avctx, AVSubtitle *sub, int *got_ou
if (!region->dirty)
continue;
- rect = sub->rects[i];
+ rect = sub->subtitle_rects[i];
rect->x = display->x_pos + offset_x;
rect->y = display->y_pos + offset_y;
rect->w = region->width;
rect->h = region->height;
rect->nb_colors = (1 << region->depth);
- rect->type = SUBTITLE_BITMAP;
+ rect->type = AV_SUBTITLE_FMT_BITMAP;
rect->linesize[0] = region->width;
clut = get_clut(ctx, region->clut);
@@ -846,18 +846,18 @@ static int save_subtitle_set(AVCodecContext *avctx, AVSubtitle *sub, int *got_ou
return 0;
fail:
- if (sub->rects) {
- for (i=0; i < sub->num_rects; i++) {
- rect = sub->rects[i];
+ if (sub->subtitle_rects) {
+ for (i=0; i < sub->num_subtitle_rects; i++) {
+ rect = sub->subtitle_rects[i];
if (rect) {
av_freep(&rect->data[0]);
av_freep(&rect->data[1]);
}
- av_freep(&sub->rects[i]);
+ av_freep(&sub->subtitle_rects[i]);
}
- av_freep(&sub->rects);
+ av_freep(&sub->subtitle_rects);
}
- sub->num_rects = 0;
+ sub->num_subtitle_rects = 0;
return ret;
}
@@ -1291,7 +1291,7 @@ static int dvbsub_parse_region_segment(AVCodecContext *avctx,
}
static int dvbsub_parse_page_segment(AVCodecContext *avctx,
- const uint8_t *buf, int buf_size, AVSubtitle *sub, int *got_output)
+ const uint8_t *buf, int buf_size, AVFrame *sub, int *got_output)
{
DVBSubContext *ctx = avctx->priv_data;
DVBSubRegionDisplay *display;
@@ -1598,7 +1598,7 @@ static int dvbsub_parse_display_definition_segment(AVCodecContext *avctx,
}
static int dvbsub_display_end_segment(AVCodecContext *avctx, const uint8_t *buf,
- int buf_size, AVSubtitle *sub,int *got_output)
+ int buf_size, AVFrame *sub,int *got_output)
{
DVBSubContext *ctx = avctx->priv_data;
@@ -1617,7 +1617,7 @@ static int dvbsub_decode(AVCodecContext *avctx,
const uint8_t *buf = avpkt->data;
int buf_size = avpkt->size;
DVBSubContext *ctx = avctx->priv_data;
- AVSubtitle *sub = data;
+ AVFrame *sub = data;
const uint8_t *p, *p_end;
int segment_type;
int page_id;
@@ -1720,11 +1720,11 @@ static int dvbsub_decode(AVCodecContext *avctx,
end:
if (ret < 0) {
*got_sub_ptr = 0;
- avsubtitle_free(sub);
+ av_frame_free(&sub);
return ret;
} else {
if (ctx->compute_edt == 1)
- FFSWAP(int64_t, ctx->prev_start, sub->pts);
+ FFSWAP(int64_t, ctx->prev_start, sub->subtitle_pts);
}
return p - buf;
diff --git a/libavcodec/dvbsubenc.c b/libavcodec/dvbsubenc.c
index 322fc27cb4..480092867e 100644
--- a/libavcodec/dvbsubenc.c
+++ b/libavcodec/dvbsubenc.c
@@ -269,7 +269,7 @@ static int dvb_encode_rle8(uint8_t **pq, int buf_size,
}
static int dvbsub_encode(AVCodecContext *avctx, uint8_t *outbuf, int buf_size,
- const AVSubtitle *h)
+ const AVFrame *h)
{
DVBSubtitleContext *s = avctx->priv_data;
uint8_t *q, *pseg_len;
@@ -280,7 +280,7 @@ static int dvbsub_encode(AVCodecContext *avctx, uint8_t *outbuf, int buf_size,
page_id = 1;
- if (h->num_rects && !h->rects)
+ if (h->num_subtitle_rects && !h->subtitle_rects)
return AVERROR(EINVAL);
if (avctx->width > 0 && avctx->height > 0) {
@@ -301,7 +301,7 @@ static int dvbsub_encode(AVCodecContext *avctx, uint8_t *outbuf, int buf_size,
/* page composition segment */
- if (buf_size < 8 + h->num_rects * 6)
+ if (buf_size < 8 + h->num_subtitle_rects * 6)
return AVERROR_BUFFER_TOO_SMALL;
*q++ = 0x0f; /* sync_byte */
*q++ = 0x10; /* segment_type */
@@ -313,30 +313,30 @@ static int dvbsub_encode(AVCodecContext *avctx, uint8_t *outbuf, int buf_size,
/* page_version = 0 + page_state */
*q++ = (s->object_version << 4) | (page_state << 2) | 3;
- for (region_id = 0; region_id < h->num_rects; region_id++) {
+ for (region_id = 0; region_id < h->num_subtitle_rects; region_id++) {
*q++ = region_id;
*q++ = 0xff; /* reserved */
- bytestream_put_be16(&q, h->rects[region_id]->x); /* left pos */
- bytestream_put_be16(&q, h->rects[region_id]->y); /* top pos */
+ bytestream_put_be16(&q, h->subtitle_rects[region_id]->x); /* left pos */
+ bytestream_put_be16(&q, h->subtitle_rects[region_id]->y); /* top pos */
}
bytestream_put_be16(&pseg_len, q - pseg_len - 2);
- buf_size -= 8 + h->num_rects * 6;
+ buf_size -= 8 + h->num_subtitle_rects * 6;
- if (h->num_rects) {
- for (clut_id = 0; clut_id < h->num_rects; clut_id++) {
- if (buf_size < 6 + h->rects[clut_id]->nb_colors * 6)
+ if (h->num_subtitle_rects) {
+ for (clut_id = 0; clut_id < h->num_subtitle_rects; clut_id++) {
+ if (buf_size < 6 + h->subtitle_rects[clut_id]->nb_colors * 6)
return AVERROR_BUFFER_TOO_SMALL;
/* CLUT segment */
- if (h->rects[clut_id]->nb_colors <= 4) {
+ if (h->subtitle_rects[clut_id]->nb_colors <= 4) {
/* 2 bpp, some decoders do not support it correctly */
bpp_index = 0;
- } else if (h->rects[clut_id]->nb_colors <= 16) {
+ } else if (h->subtitle_rects[clut_id]->nb_colors <= 16) {
/* 4 bpp, standard encoding */
bpp_index = 1;
- } else if (h->rects[clut_id]->nb_colors <= 256) {
+ } else if (h->subtitle_rects[clut_id]->nb_colors <= 256) {
/* 8 bpp, standard encoding */
bpp_index = 2;
} else {
@@ -353,12 +353,12 @@ static int dvbsub_encode(AVCodecContext *avctx, uint8_t *outbuf, int buf_size,
*q++ = clut_id;
*q++ = (0 << 4) | 0xf; /* version = 0 */
- for(i = 0; i < h->rects[clut_id]->nb_colors; i++) {
+ for(i = 0; i < h->subtitle_rects[clut_id]->nb_colors; i++) {
*q++ = i; /* clut_entry_id */
*q++ = (1 << (7 - bpp_index)) | (0xf << 1) | 1; /* 2 bits/pixel full range */
{
int a, r, g, b;
- uint32_t x= ((uint32_t*)h->rects[clut_id]->data[1])[i];
+ uint32_t x= ((uint32_t*)h->subtitle_rects[clut_id]->data[1])[i];
a = (x >> 24) & 0xff;
r = (x >> 16) & 0xff;
g = (x >> 8) & 0xff;
@@ -372,22 +372,22 @@ static int dvbsub_encode(AVCodecContext *avctx, uint8_t *outbuf, int buf_size,
}
bytestream_put_be16(&pseg_len, q - pseg_len - 2);
- buf_size -= 6 + h->rects[clut_id]->nb_colors * 6;
+ buf_size -= 6 + h->subtitle_rects[clut_id]->nb_colors * 6;
}
- if (buf_size < h->num_rects * 22)
+ if (buf_size < h->num_subtitle_rects * 22)
return AVERROR_BUFFER_TOO_SMALL;
- for (region_id = 0; region_id < h->num_rects; region_id++) {
+ for (region_id = 0; region_id < h->num_subtitle_rects; region_id++) {
/* region composition segment */
- if (h->rects[region_id]->nb_colors <= 4) {
+ if (h->subtitle_rects[region_id]->nb_colors <= 4) {
/* 2 bpp, some decoders do not support it correctly */
bpp_index = 0;
- } else if (h->rects[region_id]->nb_colors <= 16) {
+ } else if (h->subtitle_rects[region_id]->nb_colors <= 16) {
/* 4 bpp, standard encoding */
bpp_index = 1;
- } else if (h->rects[region_id]->nb_colors <= 256) {
+ } else if (h->subtitle_rects[region_id]->nb_colors <= 256) {
/* 8 bpp, standard encoding */
bpp_index = 2;
} else {
@@ -401,8 +401,8 @@ static int dvbsub_encode(AVCodecContext *avctx, uint8_t *outbuf, int buf_size,
q += 2; /* segment length */
*q++ = region_id;
*q++ = (s->object_version << 4) | (0 << 3) | 0x07; /* version , no fill */
- bytestream_put_be16(&q, h->rects[region_id]->w); /* region width */
- bytestream_put_be16(&q, h->rects[region_id]->h); /* region height */
+ bytestream_put_be16(&q, h->subtitle_rects[region_id]->w); /* region width */
+ bytestream_put_be16(&q, h->subtitle_rects[region_id]->h); /* region height */
*q++ = ((1 + bpp_index) << 5) | ((1 + bpp_index) << 2) | 0x03;
*q++ = region_id; /* clut_id == region_id */
*q++ = 0; /* 8 bit fill colors */
@@ -416,9 +416,9 @@ static int dvbsub_encode(AVCodecContext *avctx, uint8_t *outbuf, int buf_size,
bytestream_put_be16(&pseg_len, q - pseg_len - 2);
}
- buf_size -= h->num_rects * 22;
+ buf_size -= h->num_subtitle_rects * 22;
- for (object_id = 0; object_id < h->num_rects; object_id++) {
+ for (object_id = 0; object_id < h->num_subtitle_rects; object_id++) {
int (*dvb_encode_rle)(uint8_t **pq, int buf_size,
const uint8_t *bitmap, int linesize,
int w, int h);
@@ -427,13 +427,13 @@ static int dvbsub_encode(AVCodecContext *avctx, uint8_t *outbuf, int buf_size,
return AVERROR_BUFFER_TOO_SMALL;
/* bpp_index maths */
- if (h->rects[object_id]->nb_colors <= 4) {
+ if (h->subtitle_rects[object_id]->nb_colors <= 4) {
/* 2 bpp, some decoders do not support it correctly */
dvb_encode_rle = dvb_encode_rle2;
- } else if (h->rects[object_id]->nb_colors <= 16) {
+ } else if (h->subtitle_rects[object_id]->nb_colors <= 16) {
/* 4 bpp, standard encoding */
dvb_encode_rle = dvb_encode_rle4;
- } else if (h->rects[object_id]->nb_colors <= 256) {
+ } else if (h->subtitle_rects[object_id]->nb_colors <= 256) {
/* 8 bpp, standard encoding */
dvb_encode_rle = dvb_encode_rle8;
} else {
@@ -463,19 +463,19 @@ static int dvbsub_encode(AVCodecContext *avctx, uint8_t *outbuf, int buf_size,
top_ptr = q;
ret = dvb_encode_rle(&q, buf_size,
- h->rects[object_id]->data[0],
- h->rects[object_id]->w * 2,
- h->rects[object_id]->w,
- h->rects[object_id]->h >> 1);
+ h->subtitle_rects[object_id]->data[0],
+ h->subtitle_rects[object_id]->w * 2,
+ h->subtitle_rects[object_id]->w,
+ h->subtitle_rects[object_id]->h >> 1);
if (ret < 0)
return ret;
buf_size -= ret;
bottom_ptr = q;
ret = dvb_encode_rle(&q, buf_size,
- h->rects[object_id]->data[0] + h->rects[object_id]->w,
- h->rects[object_id]->w * 2,
- h->rects[object_id]->w,
- h->rects[object_id]->h >> 1);
+ h->subtitle_rects[object_id]->data[0] + h->subtitle_rects[object_id]->w,
+ h->subtitle_rects[object_id]->w * 2,
+ h->subtitle_rects[object_id]->w,
+ h->subtitle_rects[object_id]->h >> 1);
if (ret < 0)
return ret;
buf_size -= ret;
diff --git a/libavcodec/dvdsubdec.c b/libavcodec/dvdsubdec.c
index 52259f0730..6c7b315026 100644
--- a/libavcodec/dvdsubdec.c
+++ b/libavcodec/dvdsubdec.c
@@ -200,24 +200,24 @@ static void guess_palette(DVDSubContext* ctx,
}
}
-static void reset_rects(AVSubtitle *sub_header)
+static void reset_rects(AVFrame *sub_header)
{
int i;
- if (sub_header->rects) {
- for (i = 0; i < sub_header->num_rects; i++) {
- av_freep(&sub_header->rects[i]->data[0]);
- av_freep(&sub_header->rects[i]->data[1]);
- av_freep(&sub_header->rects[i]);
+ if (sub_header->subtitle_rects) {
+ for (i = 0; i < sub_header->num_subtitle_rects; i++) {
+ av_freep(&sub_header->subtitle_rects[i]->data[0]);
+ av_freep(&sub_header->subtitle_rects[i]->data[1]);
+ av_freep(&sub_header->subtitle_rects[i]);
}
- av_freep(&sub_header->rects);
- sub_header->num_rects = 0;
+ av_freep(&sub_header->subtitle_rects);
+ sub_header->num_subtitle_rects = 0;
}
}
#define READ_OFFSET(a) (big_offsets ? AV_RB32(a) : AV_RB16(a))
-static int decode_dvd_subtitles(DVDSubContext *ctx, AVSubtitle *sub_header,
+static int decode_dvd_subtitles(DVDSubContext *ctx, AVFrame *sub_header,
const uint8_t *buf, int buf_size)
{
int cmd_pos, pos, cmd, x1, y1, x2, y2, next_cmd_pos;
@@ -273,11 +273,11 @@ static int decode_dvd_subtitles(DVDSubContext *ctx, AVSubtitle *sub_header,
break;
case 0x01:
/* set start date */
- sub_header->start_display_time = (date << 10) / 90;
+ sub_header->subtitle_start_time = (date << 10) / 90;
break;
case 0x02:
/* set end date */
- sub_header->end_display_time = (date << 10) / 90;
+ sub_header->subtitle_end_time = (date << 10) / 90;
break;
case 0x03:
/* set colormap */
@@ -371,14 +371,14 @@ static int decode_dvd_subtitles(DVDSubContext *ctx, AVSubtitle *sub_header,
if (w > 0 && h > 1) {
reset_rects(sub_header);
memset(ctx->used_color, 0, sizeof(ctx->used_color));
- sub_header->rects = av_mallocz(sizeof(*sub_header->rects));
- if (!sub_header->rects)
+ sub_header->subtitle_rects = av_mallocz(sizeof(*sub_header->subtitle_rects));
+ if (!sub_header->subtitle_rects)
goto fail;
- sub_header->rects[0] = av_mallocz(sizeof(AVSubtitleRect));
- if (!sub_header->rects[0])
+ sub_header->subtitle_rects[0] = av_mallocz(sizeof(AVSubtitleRect));
+ if (!sub_header->subtitle_rects[0])
goto fail;
- sub_header->num_rects = 1;
- bitmap = sub_header->rects[0]->data[0] = av_malloc(w * h);
+ sub_header->num_subtitle_rects = 1;
+ bitmap = sub_header->subtitle_rects[0]->data[0] = av_malloc(w * h);
if (!bitmap)
goto fail;
if (decode_rle(bitmap, w * 2, w, (h + 1) / 2, ctx->used_color,
@@ -387,28 +387,28 @@ static int decode_dvd_subtitles(DVDSubContext *ctx, AVSubtitle *sub_header,
if (decode_rle(bitmap + w, w * 2, w, h / 2, ctx->used_color,
buf, offset2, buf_size, is_8bit) < 0)
goto fail;
- sub_header->rects[0]->data[1] = av_mallocz(AVPALETTE_SIZE);
- if (!sub_header->rects[0]->data[1])
+ sub_header->subtitle_rects[0]->data[1] = av_mallocz(AVPALETTE_SIZE);
+ if (!sub_header->subtitle_rects[0]->data[1])
goto fail;
if (is_8bit) {
if (!yuv_palette)
goto fail;
- sub_header->rects[0]->nb_colors = 256;
+ sub_header->subtitle_rects[0]->nb_colors = 256;
yuv_a_to_rgba(yuv_palette, alpha,
- (uint32_t *)sub_header->rects[0]->data[1],
+ (uint32_t *)sub_header->subtitle_rects[0]->data[1],
256);
} else {
- sub_header->rects[0]->nb_colors = 4;
- guess_palette(ctx, (uint32_t*)sub_header->rects[0]->data[1],
+ sub_header->subtitle_rects[0]->nb_colors = 4;
+ guess_palette(ctx, (uint32_t*)sub_header->subtitle_rects[0]->data[1],
0xffff00);
}
- sub_header->rects[0]->x = x1;
- sub_header->rects[0]->y = y1;
- sub_header->rects[0]->w = w;
- sub_header->rects[0]->h = h;
- sub_header->rects[0]->type = SUBTITLE_BITMAP;
- sub_header->rects[0]->linesize[0] = w;
- sub_header->rects[0]->flags = is_menu ? AV_SUBTITLE_FLAG_FORCED : 0;
+ sub_header->subtitle_rects[0]->x = x1;
+ sub_header->subtitle_rects[0]->y = y1;
+ sub_header->subtitle_rects[0]->w = w;
+ sub_header->subtitle_rects[0]->h = h;
+ sub_header->subtitle_rects[0]->type = AV_SUBTITLE_FMT_BITMAP;
+ sub_header->subtitle_rects[0]->linesize[0] = w;
+ sub_header->subtitle_rects[0]->flags = is_menu ? AV_SUBTITLE_FLAG_FORCED : 0;
}
}
if (next_cmd_pos < cmd_pos) {
@@ -419,7 +419,7 @@ static int decode_dvd_subtitles(DVDSubContext *ctx, AVSubtitle *sub_header,
break;
cmd_pos = next_cmd_pos;
}
- if (sub_header->num_rects > 0)
+ if (sub_header->num_subtitle_rects > 0)
return is_menu;
fail:
reset_rects(sub_header);
@@ -439,18 +439,18 @@ static int is_transp(const uint8_t *buf, int pitch, int n,
}
/* return 0 if empty rectangle, 1 if non empty */
-static int find_smallest_bounding_rectangle(DVDSubContext *ctx, AVSubtitle *s)
+static int find_smallest_bounding_rectangle(DVDSubContext *ctx, AVFrame *s)
{
uint8_t transp_color[256] = { 0 };
int y1, y2, x1, x2, y, w, h, i;
uint8_t *bitmap;
int transparent = 1;
- if (s->num_rects == 0 || !s->rects || s->rects[0]->w <= 0 || s->rects[0]->h <= 0)
+ if (s->num_subtitle_rects == 0 || !s->subtitle_rects || s->subtitle_rects[0]->w <= 0 || s->subtitle_rects[0]->h <= 0)
return 0;
- for(i = 0; i < s->rects[0]->nb_colors; i++) {
- if ((((uint32_t *)s->rects[0]->data[1])[i] >> 24) == 0) {
+ for(i = 0; i < s->subtitle_rects[0]->nb_colors; i++) {
+ if ((((uint32_t *)s->subtitle_rects[0]->data[1])[i] >> 24) == 0) {
transp_color[i] = 1;
} else if (ctx->used_color[i])
transparent = 0;
@@ -458,25 +458,25 @@ static int find_smallest_bounding_rectangle(DVDSubContext *ctx, AVSubtitle *s)
if (transparent)
return 0;
y1 = 0;
- while (y1 < s->rects[0]->h && is_transp(s->rects[0]->data[0] + y1 * s->rects[0]->linesize[0],
- 1, s->rects[0]->w, transp_color))
+ while (y1 < s->subtitle_rects[0]->h && is_transp(s->subtitle_rects[0]->data[0] + y1 * s->subtitle_rects[0]->linesize[0],
+ 1, s->subtitle_rects[0]->w, transp_color))
y1++;
- if (y1 == s->rects[0]->h) {
- av_freep(&s->rects[0]->data[0]);
- s->rects[0]->w = s->rects[0]->h = 0;
+ if (y1 == s->subtitle_rects[0]->h) {
+ av_freep(&s->subtitle_rects[0]->data[0]);
+ s->subtitle_rects[0]->w = s->subtitle_rects[0]->h = 0;
return 0;
}
- y2 = s->rects[0]->h - 1;
- while (y2 > 0 && is_transp(s->rects[0]->data[0] + y2 * s->rects[0]->linesize[0], 1,
- s->rects[0]->w, transp_color))
+ y2 = s->subtitle_rects[0]->h - 1;
+ while (y2 > 0 && is_transp(s->subtitle_rects[0]->data[0] + y2 * s->subtitle_rects[0]->linesize[0], 1,
+ s->subtitle_rects[0]->w, transp_color))
y2--;
x1 = 0;
- while (x1 < (s->rects[0]->w - 1) && is_transp(s->rects[0]->data[0] + x1, s->rects[0]->linesize[0],
- s->rects[0]->h, transp_color))
+ while (x1 < (s->subtitle_rects[0]->w - 1) && is_transp(s->subtitle_rects[0]->data[0] + x1, s->subtitle_rects[0]->linesize[0],
+ s->subtitle_rects[0]->h, transp_color))
x1++;
- x2 = s->rects[0]->w - 1;
- while (x2 > 0 && is_transp(s->rects[0]->data[0] + x2, s->rects[0]->linesize[0], s->rects[0]->h,
+ x2 = s->subtitle_rects[0]->w - 1;
+ while (x2 > 0 && is_transp(s->subtitle_rects[0]->data[0] + x2, s->subtitle_rects[0]->linesize[0], s->subtitle_rects[0]->h,
transp_color))
x2--;
w = x2 - x1 + 1;
@@ -485,15 +485,15 @@ static int find_smallest_bounding_rectangle(DVDSubContext *ctx, AVSubtitle *s)
if (!bitmap)
return 1;
for(y = 0; y < h; y++) {
- memcpy(bitmap + w * y, s->rects[0]->data[0] + x1 + (y1 + y) * s->rects[0]->linesize[0], w);
+ memcpy(bitmap + w * y, s->subtitle_rects[0]->data[0] + x1 + (y1 + y) * s->subtitle_rects[0]->linesize[0], w);
}
- av_freep(&s->rects[0]->data[0]);
- s->rects[0]->data[0] = bitmap;
- s->rects[0]->linesize[0] = w;
- s->rects[0]->w = w;
- s->rects[0]->h = h;
- s->rects[0]->x += x1;
- s->rects[0]->y += y1;
+ av_freep(&s->subtitle_rects[0]->data[0]);
+ s->subtitle_rects[0]->data[0] = bitmap;
+ s->subtitle_rects[0]->linesize[0] = w;
+ s->subtitle_rects[0]->w = w;
+ s->subtitle_rects[0]->h = h;
+ s->subtitle_rects[0]->x += x1;
+ s->subtitle_rects[0]->y += y1;
return 1;
}
@@ -554,7 +554,7 @@ static int dvdsub_decode(AVCodecContext *avctx,
DVDSubContext *ctx = avctx->priv_data;
const uint8_t *buf = avpkt->data;
int buf_size = avpkt->size;
- AVSubtitle *sub = data;
+ AVFrame *sub = data;
int appended = 0;
int is_menu;
@@ -586,7 +586,7 @@ static int dvdsub_decode(AVCodecContext *avctx,
if (!is_menu && find_smallest_bounding_rectangle(ctx, sub) == 0)
goto no_subtitle;
- if (ctx->forced_subs_only && !(sub->rects[0]->flags & AV_SUBTITLE_FLAG_FORCED))
+ if (ctx->forced_subs_only && !(sub->subtitle_rects[0]->flags & AV_SUBTITLE_FLAG_FORCED))
goto no_subtitle;
#if defined(DEBUG)
@@ -595,10 +595,10 @@ static int dvdsub_decode(AVCodecContext *avctx,
snprintf(ppm_name, sizeof(ppm_name), "/tmp/%05d.ppm", ctx->sub_id++);
ff_dlog(NULL, "start=%d ms end =%d ms\n",
- sub->start_display_time,
- sub->end_display_time);
- ppm_save(ppm_name, sub->rects[0]->data[0],
- sub->rects[0]->w, sub->rects[0]->h, (uint32_t*) sub->rects[0]->data[1]);
+ sub->subtitle_start_time,
+ sub->subtitle_end_time);
+ ppm_save(ppm_name, sub->subtitle_rects[0]->data[0],
+ sub->subtitle_rects[0]->w, sub->subtitle_rects[0]->h, (uint32_t*) sub->subtitle_rects[0]->data[1]);
}
#endif
diff --git a/libavcodec/dvdsubenc.c b/libavcodec/dvdsubenc.c
index ff4fbed39d..53df1251ed 100644
--- a/libavcodec/dvdsubenc.c
+++ b/libavcodec/dvdsubenc.c
@@ -250,12 +250,12 @@ static void copy_rectangle(AVSubtitleRect *dst, AVSubtitleRect *src, int cmap[])
static int encode_dvd_subtitles(AVCodecContext *avctx,
uint8_t *outbuf, int outbuf_size,
- const AVSubtitle *h)
+ const AVFrame *h)
{
DVDSubtitleContext *dvdc = avctx->priv_data;
uint8_t *q, *qq;
int offset1, offset2;
- int i, rects = h->num_rects, ret;
+ int i, rects = h->num_subtitle_rects, ret;
unsigned global_palette_hits[33] = { 0 };
int cmap[256];
int out_palette[4];
@@ -265,34 +265,34 @@ static int encode_dvd_subtitles(AVCodecContext *avctx,
int x2, y2;
int forced = 0;
- if (rects == 0 || !h->rects)
+ if (rects == 0 || !h->subtitle_rects)
return AVERROR(EINVAL);
for (i = 0; i < rects; i++)
- if (h->rects[i]->type != SUBTITLE_BITMAP) {
+ if (h->subtitle_rects[i]->type != AV_SUBTITLE_FMT_BITMAP) {
av_log(avctx, AV_LOG_ERROR, "Bitmap subtitle required\n");
return AVERROR(EINVAL);
}
/* Mark this subtitle forced if any of the rectangles is forced. */
for (i = 0; i < rects; i++)
- if ((h->rects[i]->flags & AV_SUBTITLE_FLAG_FORCED) != 0) {
+ if ((h->subtitle_rects[i]->flags & AV_SUBTITLE_FLAG_FORCED) != 0) {
forced = 1;
break;
}
- vrect = *h->rects[0];
+ vrect = *h->subtitle_rects[0];
if (rects > 1) {
/* DVD subtitles can have only one rectangle: build a virtual
rectangle containing all actual rectangles.
The data of the rectangles will be copied later, when the palette
is decided, because the rectangles may have different palettes. */
- int xmin = h->rects[0]->x, xmax = xmin + h->rects[0]->w;
- int ymin = h->rects[0]->y, ymax = ymin + h->rects[0]->h;
+ int xmin = h->subtitle_rects[0]->x, xmax = xmin + h->subtitle_rects[0]->w;
+ int ymin = h->subtitle_rects[0]->y, ymax = ymin + h->subtitle_rects[0]->h;
for (i = 1; i < rects; i++) {
- xmin = FFMIN(xmin, h->rects[i]->x);
- ymin = FFMIN(ymin, h->rects[i]->y);
- xmax = FFMAX(xmax, h->rects[i]->x + h->rects[i]->w);
- ymax = FFMAX(ymax, h->rects[i]->y + h->rects[i]->h);
+ xmin = FFMIN(xmin, h->subtitle_rects[i]->x);
+ ymin = FFMIN(ymin, h->subtitle_rects[i]->y);
+ xmax = FFMAX(xmax, h->subtitle_rects[i]->x + h->subtitle_rects[i]->w);
+ ymax = FFMAX(ymax, h->subtitle_rects[i]->y + h->subtitle_rects[i]->h);
}
vrect.x = xmin;
vrect.y = ymin;
@@ -304,11 +304,11 @@ static int encode_dvd_subtitles(AVCodecContext *avctx,
/* Count pixels outside the virtual rectangle as transparent */
global_palette_hits[0] = vrect.w * vrect.h;
for (i = 0; i < rects; i++)
- global_palette_hits[0] -= h->rects[i]->w * h->rects[i]->h;
+ global_palette_hits[0] -= h->subtitle_rects[i]->w * h->subtitle_rects[i]->h;
}
for (i = 0; i < rects; i++)
- count_colors(avctx, global_palette_hits, h->rects[i]);
+ count_colors(avctx, global_palette_hits, h->subtitle_rects[i]);
select_palette(avctx, out_palette, out_alpha, global_palette_hits);
if (rects > 1) {
@@ -317,14 +317,14 @@ static int encode_dvd_subtitles(AVCodecContext *avctx,
vrect.data [0] = vrect_data;
vrect.linesize[0] = vrect.w;
for (i = 0; i < rects; i++) {
- build_color_map(avctx, cmap, (uint32_t *)h->rects[i]->data[1],
+ build_color_map(avctx, cmap, (uint32_t *)h->subtitle_rects[i]->data[1],
out_palette, out_alpha);
- copy_rectangle(&vrect, h->rects[i], cmap);
+ copy_rectangle(&vrect, h->subtitle_rects[i], cmap);
}
for (i = 0; i < 4; i++)
cmap[i] = i;
} else {
- build_color_map(avctx, cmap, (uint32_t *)h->rects[0]->data[1],
+ build_color_map(avctx, cmap, (uint32_t *)h->subtitle_rects[0]->data[1],
out_palette, out_alpha);
}
@@ -362,7 +362,7 @@ static int encode_dvd_subtitles(AVCodecContext *avctx,
bytestream_put_be16(&qq, q - outbuf);
// send start display command
- bytestream_put_be16(&q, (h->start_display_time*90) >> 10);
+ bytestream_put_be16(&q, (h->subtitle_start_time*90) >> 10);
bytestream_put_be16(&q, (q - outbuf) /*- 2 */ + 8 + 12 + 2);
*q++ = 0x03; // palette - 4 nibbles
*q++ = (out_palette[3] << 4) | out_palette[2];
@@ -394,7 +394,7 @@ static int encode_dvd_subtitles(AVCodecContext *avctx,
*q++ = 0xff; // terminating command
// send stop display command last
- bytestream_put_be16(&q, (h->end_display_time*90) >> 10);
+ bytestream_put_be16(&q, (h->subtitle_end_time*90) >> 10);
bytestream_put_be16(&q, (q - outbuf) - 2 /*+ 4*/);
*q++ = 0x02; // set end
*q++ = 0xff; // terminating command
@@ -469,7 +469,7 @@ static int dvdsub_init(AVCodecContext *avctx)
static int dvdsub_encode(AVCodecContext *avctx,
unsigned char *buf, int buf_size,
- const AVSubtitle *sub)
+ const AVFrame *sub)
{
//DVDSubtitleContext *s = avctx->priv_data;
int ret;
diff --git a/libavcodec/encode.c b/libavcodec/encode.c
index 98dfbfdff3..289f6e88f1 100644
--- a/libavcodec/encode.c
+++ b/libavcodec/encode.c
@@ -141,11 +141,11 @@ fail:
}
int avcodec_encode_subtitle(AVCodecContext *avctx, uint8_t *buf, int buf_size,
- const AVSubtitle *sub)
+ const AVFrame *sub)
{
int ret;
- if (sub->start_display_time) {
- av_log(avctx, AV_LOG_ERROR, "start_display_time must be 0.\n");
+ if (sub->subtitle_start_time) {
+ av_log(avctx, AV_LOG_ERROR, "subtitle_start_time must be 0.\n");
return -1;
}
diff --git a/libavcodec/jacosubdec.c b/libavcodec/jacosubdec.c
index 698895a86b..4c87d0f06d 100644
--- a/libavcodec/jacosubdec.c
+++ b/libavcodec/jacosubdec.c
@@ -166,7 +166,7 @@ static int jacosub_decode_frame(AVCodecContext *avctx,
void *data, int *got_sub_ptr, AVPacket *avpkt)
{
int ret;
- AVSubtitle *sub = data;
+ AVFrame *sub = data;
const char *ptr = avpkt->data;
FFASSDecoderContext *s = avctx->priv_data;
@@ -190,7 +190,7 @@ static int jacosub_decode_frame(AVCodecContext *avctx,
}
end:
- *got_sub_ptr = sub->num_rects > 0;
+ *got_sub_ptr = sub->num_subtitle_rects > 0;
return avpkt->size;
}
diff --git a/libavcodec/libzvbi-teletextdec.c b/libavcodec/libzvbi-teletextdec.c
index 1073d6a0bd..b597042c52 100644
--- a/libavcodec/libzvbi-teletextdec.c
+++ b/libavcodec/libzvbi-teletextdec.c
@@ -215,7 +215,7 @@ static int gen_sub_text(TeletextContext *ctx, AVSubtitleRect *sub_rect, vbi_page
}
if (buf.len) {
- sub_rect->type = SUBTITLE_ASS;
+ sub_rect->type = AV_SUBTITLE_FMT_ASS;
sub_rect->ass = create_ass_text(ctx, buf.str);
if (!sub_rect->ass) {
@@ -224,7 +224,7 @@ static int gen_sub_text(TeletextContext *ctx, AVSubtitleRect *sub_rect, vbi_page
}
av_log(ctx, AV_LOG_DEBUG, "subtext:%s:txetbus\n", sub_rect->ass);
} else {
- sub_rect->type = SUBTITLE_NONE;
+ sub_rect->type = AV_SUBTITLE_FMT_NONE;
}
av_bprint_finalize(&buf, NULL);
return 0;
@@ -393,7 +393,7 @@ static int gen_sub_ass(TeletextContext *ctx, AVSubtitleRect *sub_rect, vbi_page
}
if (buf.len) {
- sub_rect->type = SUBTITLE_ASS;
+ sub_rect->type = AV_SUBTITLE_FMT_ASS;
sub_rect->ass = ff_ass_get_dialog(ctx->readorder++, 0, is_subtitle_page ? "Subtitle" : "Teletext", NULL, buf.str);
if (!sub_rect->ass) {
@@ -402,7 +402,7 @@ static int gen_sub_ass(TeletextContext *ctx, AVSubtitleRect *sub_rect, vbi_page
}
av_log(ctx, AV_LOG_DEBUG, "subtext:%s:txetbus\n", sub_rect->ass);
} else {
- sub_rect->type = SUBTITLE_NONE;
+ sub_rect->type = AV_SUBTITLE_FMT_NONE;
}
av_bprint_finalize(&buf, NULL);
return 0;
@@ -462,7 +462,7 @@ static int gen_sub_bitmap(TeletextContext *ctx, AVSubtitleRect *sub_rect, vbi_pa
if (vc >= vcend) {
av_log(ctx, AV_LOG_DEBUG, "dropping empty page %3x\n", page->pgno);
- sub_rect->type = SUBTITLE_NONE;
+ sub_rect->type = AV_SUBTITLE_FMT_NONE;
return 0;
}
@@ -500,7 +500,7 @@ static int gen_sub_bitmap(TeletextContext *ctx, AVSubtitleRect *sub_rect, vbi_pa
}
((uint32_t *)sub_rect->data[1])[VBI_TRANSPARENT_BLACK] = RGBA(0, 0, 0, 0);
((uint32_t *)sub_rect->data[1])[VBI_TRANSPARENT_BLACK + VBI_NB_COLORS] = RGBA(0, 0, 0, 0);
- sub_rect->type = SUBTITLE_BITMAP;
+ sub_rect->type = AV_SUBTITLE_FMT_BITMAP;
return 0;
}
@@ -639,7 +639,7 @@ static int slice_to_vbi_lines(TeletextContext *ctx, uint8_t* buf, int size)
static int teletext_decode_frame(AVCodecContext *avctx, void *data, int *got_sub_ptr, AVPacket *pkt)
{
TeletextContext *ctx = avctx->priv_data;
- AVSubtitle *sub = data;
+ AVFrame *sub = data;
int ret = 0;
if (!ctx->vbi) {
@@ -695,7 +695,7 @@ static int teletext_decode_frame(AVCodecContext *avctx, void *data, int *got_sub
sub->num_rects = 0;
sub->pts = ctx->pages->pts;
- if (ctx->pages->sub_rect->type != SUBTITLE_NONE) {
+ if (ctx->pages->sub_rect->type != AV_SUBTITLE_FMT_NONE) {
sub->rects = av_malloc(sizeof(*sub->rects));
if (sub->rects) {
sub->num_rects = 1;
diff --git a/libavcodec/microdvddec.c b/libavcodec/microdvddec.c
index c45fe043bf..8618c94bf2 100644
--- a/libavcodec/microdvddec.c
+++ b/libavcodec/microdvddec.c
@@ -277,7 +277,7 @@ static void microdvd_close_no_persistent_tags(AVBPrint *new_line,
static int microdvd_decode_frame(AVCodecContext *avctx,
void *data, int *got_sub_ptr, AVPacket *avpkt)
{
- AVSubtitle *sub = data;
+ AVFrame *sub = data;
AVBPrint new_line;
char *line = avpkt->data;
char *end = avpkt->data + avpkt->size;
@@ -316,7 +316,7 @@ static int microdvd_decode_frame(AVCodecContext *avctx,
return ret;
}
- *got_sub_ptr = sub->num_rects > 0;
+ *got_sub_ptr = sub->num_subtitle_rects > 0;
return avpkt->size;
}
diff --git a/libavcodec/movtextdec.c b/libavcodec/movtextdec.c
index 4e14ae5900..55fc1db69d 100644
--- a/libavcodec/movtextdec.c
+++ b/libavcodec/movtextdec.c
@@ -461,7 +461,7 @@ static int mov_text_init(AVCodecContext *avctx) {
static int mov_text_decode_frame(AVCodecContext *avctx,
void *data, int *got_sub_ptr, AVPacket *avpkt)
{
- AVSubtitle *sub = data;
+ AVFrame *sub = data;
MovTextContext *m = avctx->priv_data;
int ret;
AVBPrint buf;
@@ -549,7 +549,7 @@ static int mov_text_decode_frame(AVCodecContext *avctx,
av_bprint_finalize(&buf, NULL);
if (ret < 0)
return ret;
- *got_sub_ptr = sub->num_rects > 0;
+ *got_sub_ptr = sub->num_subtitle_rects > 0;
return avpkt->size;
}
diff --git a/libavcodec/movtextenc.c b/libavcodec/movtextenc.c
index 2ae5a9bf0b..315fb9732a 100644
--- a/libavcodec/movtextenc.c
+++ b/libavcodec/movtextenc.c
@@ -635,7 +635,7 @@ static const ASSCodesCallbacks mov_text_callbacks = {
};
static int mov_text_encode_frame(AVCodecContext *avctx, unsigned char *buf,
- int bufsize, const AVSubtitle *sub)
+ int bufsize, const AVFrame *sub)
{
MovTextContext *s = avctx->priv_data;
ASSDialog *dialog;
@@ -646,11 +646,11 @@ static int mov_text_encode_frame(AVCodecContext *avctx, unsigned char *buf,
s->text_pos = 0;
s->count = 0;
s->box_flags = 0;
- for (i = 0; i < sub->num_rects; i++) {
- const char *ass = sub->rects[i]->ass;
+ for (i = 0; i < sub->num_subtitle_rects; i++) {
+ const char *ass = sub->subtitle_rects[i]->ass;
- if (sub->rects[i]->type != SUBTITLE_ASS) {
- av_log(avctx, AV_LOG_ERROR, "Only SUBTITLE_ASS type supported.\n");
+ if (sub->subtitle_rects[i]->type != AV_SUBTITLE_FMT_ASS) {
+ av_log(avctx, AV_LOG_ERROR, "Only AV_SUBTITLE_FMT_ASS type supported.\n");
return AVERROR(EINVAL);
}
diff --git a/libavcodec/mpl2dec.c b/libavcodec/mpl2dec.c
index 61e47050ec..76efc0ce4f 100644
--- a/libavcodec/mpl2dec.c
+++ b/libavcodec/mpl2dec.c
@@ -68,7 +68,7 @@ static int mpl2_decode_frame(AVCodecContext *avctx, void *data,
{
int ret = 0;
AVBPrint buf;
- AVSubtitle *sub = data;
+ AVFrame *sub = data;
const char *ptr = avpkt->data;
FFASSDecoderContext *s = avctx->priv_data;
@@ -78,7 +78,7 @@ static int mpl2_decode_frame(AVCodecContext *avctx, void *data,
av_bprint_finalize(&buf, NULL);
if (ret < 0)
return ret;
- *got_sub_ptr = sub->num_rects > 0;
+ *got_sub_ptr = sub->num_subtitle_rects > 0;
return avpkt->size;
}
diff --git a/libavcodec/pgssubdec.c b/libavcodec/pgssubdec.c
index 55eda4c2a9..1e4557ed42 100644
--- a/libavcodec/pgssubdec.c
+++ b/libavcodec/pgssubdec.c
@@ -498,28 +498,28 @@ static int parse_presentation_segment(AVCodecContext *avctx,
static int display_end_segment(AVCodecContext *avctx, void *data,
const uint8_t *buf, int buf_size)
{
- AVSubtitle *sub = data;
+ AVFrame *sub = data;
PGSSubContext *ctx = avctx->priv_data;
int64_t pts;
PGSSubPalette *palette;
int i, ret;
- pts = ctx->presentation.pts != AV_NOPTS_VALUE ? ctx->presentation.pts : sub->pts;
+ pts = ctx->presentation.pts != AV_NOPTS_VALUE ? ctx->presentation.pts : sub->subtitle_pts;
memset(sub, 0, sizeof(*sub));
- sub->pts = pts;
+ sub->subtitle_pts = pts;
ctx->presentation.pts = AV_NOPTS_VALUE;
- sub->start_display_time = 0;
+ sub->subtitle_start_time = 0;
// There is no explicit end time for PGS subtitles. The end time
// is defined by the start of the next sub which may contain no
// objects (i.e. clears the previous sub)
- sub->end_display_time = UINT32_MAX;
- sub->format = 0;
+ sub->subtitle_end_time = UINT32_MAX;
+ sub->format = AV_SUBTITLE_FMT_BITMAP;
// Blank if last object_count was 0.
if (!ctx->presentation.object_count)
return 1;
- sub->rects = av_mallocz_array(ctx->presentation.object_count, sizeof(*sub->rects));
- if (!sub->rects) {
+ sub->subtitle_rects = av_mallocz_array(ctx->presentation.object_count, sizeof(*sub->subtitle_rects));
+ if (!sub->subtitle_rects) {
return AVERROR(ENOMEM);
}
palette = find_palette(ctx->presentation.palette_id, &ctx->palettes);
@@ -527,19 +527,19 @@ static int display_end_segment(AVCodecContext *avctx, void *data,
// Missing palette. Should only happen with damaged streams.
av_log(avctx, AV_LOG_ERROR, "Invalid palette id %d\n",
ctx->presentation.palette_id);
- avsubtitle_free(sub);
+ av_frame_free(&sub);
return AVERROR_INVALIDDATA;
}
for (i = 0; i < ctx->presentation.object_count; i++) {
PGSSubObject *object;
- sub->rects[i] = av_mallocz(sizeof(*sub->rects[0]));
- if (!sub->rects[i]) {
- avsubtitle_free(sub);
+ sub->subtitle_rects[i] = av_mallocz(sizeof(*sub->subtitle_rects[0]));
+ if (!sub->subtitle_rects[i]) {
+ av_frame_free(&sub);
return AVERROR(ENOMEM);
}
- sub->num_rects++;
- sub->rects[i]->type = SUBTITLE_BITMAP;
+ sub->num_subtitle_rects++;
+ sub->subtitle_rects[i]->type = AV_SUBTITLE_FMT_BITMAP;
/* Process bitmap */
object = find_object(ctx->presentation.objects[i].id, &ctx->objects);
@@ -548,54 +548,54 @@ static int display_end_segment(AVCodecContext *avctx, void *data,
av_log(avctx, AV_LOG_ERROR, "Invalid object id %d\n",
ctx->presentation.objects[i].id);
if (avctx->err_recognition & AV_EF_EXPLODE) {
- avsubtitle_free(sub);
+ av_frame_free(&sub);
return AVERROR_INVALIDDATA;
}
// Leaves rect empty with 0 width and height.
continue;
}
if (ctx->presentation.objects[i].composition_flag & 0x40)
- sub->rects[i]->flags |= AV_SUBTITLE_FLAG_FORCED;
+ sub->subtitle_rects[i]->flags |= AV_SUBTITLE_FLAG_FORCED;
- sub->rects[i]->x = ctx->presentation.objects[i].x;
- sub->rects[i]->y = ctx->presentation.objects[i].y;
+ sub->subtitle_rects[i]->x = ctx->presentation.objects[i].x;
+ sub->subtitle_rects[i]->y = ctx->presentation.objects[i].y;
if (object->rle) {
- sub->rects[i]->w = object->w;
- sub->rects[i]->h = object->h;
+ sub->subtitle_rects[i]->w = object->w;
+ sub->subtitle_rects[i]->h = object->h;
- sub->rects[i]->linesize[0] = object->w;
+ sub->subtitle_rects[i]->linesize[0] = object->w;
if (object->rle_remaining_len) {
av_log(avctx, AV_LOG_ERROR, "RLE data length %u is %u bytes shorter than expected\n",
object->rle_data_len, object->rle_remaining_len);
if (avctx->err_recognition & AV_EF_EXPLODE) {
- avsubtitle_free(sub);
+ av_frame_free(&sub);
return AVERROR_INVALIDDATA;
}
}
- ret = decode_rle(avctx, sub->rects[i], object->rle, object->rle_data_len);
+ ret = decode_rle(avctx, sub->subtitle_rects[i], object->rle, object->rle_data_len);
if (ret < 0) {
if ((avctx->err_recognition & AV_EF_EXPLODE) ||
ret == AVERROR(ENOMEM)) {
- avsubtitle_free(sub);
+ av_frame_free(&sub);
return ret;
}
- sub->rects[i]->w = 0;
- sub->rects[i]->h = 0;
+ sub->subtitle_rects[i]->w = 0;
+ sub->subtitle_rects[i]->h = 0;
continue;
}
}
/* Allocate memory for colors */
- sub->rects[i]->nb_colors = 256;
- sub->rects[i]->data[1] = av_mallocz(AVPALETTE_SIZE);
- if (!sub->rects[i]->data[1]) {
- avsubtitle_free(sub);
+ sub->subtitle_rects[i]->nb_colors = 256;
+ sub->subtitle_rects[i]->data[1] = av_mallocz(AVPALETTE_SIZE);
+ if (!sub->subtitle_rects[i]->data[1]) {
+ av_frame_free(&sub);
return AVERROR(ENOMEM);
}
if (!ctx->forced_subs_only || ctx->presentation.objects[i].composition_flag & 0x40)
- memcpy(sub->rects[i]->data[1], palette->clut, sub->rects[i]->nb_colors * sizeof(uint32_t));
+ memcpy(sub->subtitle_rects[i]->data[1], palette->clut, sub->subtitle_rects[i]->nb_colors * sizeof(uint32_t));
}
return 1;
}
@@ -605,7 +605,7 @@ static int decode(AVCodecContext *avctx, void *data, int *got_sub_ptr,
{
const uint8_t *buf = avpkt->data;
int buf_size = avpkt->size;
-
+ AVFrame *sub = data;
const uint8_t *buf_end;
uint8_t segment_type;
int segment_length;
@@ -649,7 +649,7 @@ static int decode(AVCodecContext *avctx, void *data, int *got_sub_ptr,
ret = parse_object_segment(avctx, buf, segment_length);
break;
case PRESENTATION_SEGMENT:
- ret = parse_presentation_segment(avctx, buf, segment_length, ((AVSubtitle*)(data))->pts);
+ ret = parse_presentation_segment(avctx, buf, segment_length, sub->subtitle_pts);
break;
case WINDOW_SEGMENT:
/*
@@ -678,7 +678,7 @@ static int decode(AVCodecContext *avctx, void *data, int *got_sub_ptr,
break;
}
if (ret < 0 && (avctx->err_recognition & AV_EF_EXPLODE)) {
- avsubtitle_free(data);
+ av_frame_free(&sub);
*got_sub_ptr = 0;
return ret;
}
diff --git a/libavcodec/realtextdec.c b/libavcodec/realtextdec.c
index 11b586d493..8ce24e0bcc 100644
--- a/libavcodec/realtextdec.c
+++ b/libavcodec/realtextdec.c
@@ -60,7 +60,7 @@ static int realtext_decode_frame(AVCodecContext *avctx,
void *data, int *got_sub_ptr, AVPacket *avpkt)
{
int ret = 0;
- AVSubtitle *sub = data;
+ AVFrame *sub = data;
const char *ptr = avpkt->data;
FFASSDecoderContext *s = avctx->priv_data;
AVBPrint buf;
@@ -71,7 +71,7 @@ static int realtext_decode_frame(AVCodecContext *avctx,
av_bprint_finalize(&buf, NULL);
if (ret < 0)
return ret;
- *got_sub_ptr = sub->num_rects > 0;
+ *got_sub_ptr = sub->num_subtitle_rects > 0;
return avpkt->size;
}
diff --git a/libavcodec/samidec.c b/libavcodec/samidec.c
index 32d07447b4..2c25edefea 100644
--- a/libavcodec/samidec.c
+++ b/libavcodec/samidec.c
@@ -135,7 +135,7 @@ end:
static int sami_decode_frame(AVCodecContext *avctx,
void *data, int *got_sub_ptr, AVPacket *avpkt)
{
- AVSubtitle *sub = data;
+ AVFrame *sub = data;
const char *ptr = avpkt->data;
SAMIContext *sami = avctx->priv_data;
@@ -148,7 +148,7 @@ static int sami_decode_frame(AVCodecContext *avctx,
if (ret < 0)
return ret;
}
- *got_sub_ptr = sub->num_rects > 0;
+ *got_sub_ptr = sub->num_subtitle_rects > 0;
return avpkt->size;
}
diff --git a/libavcodec/srtdec.c b/libavcodec/srtdec.c
index 4f16226b83..557ffab45e 100644
--- a/libavcodec/srtdec.c
+++ b/libavcodec/srtdec.c
@@ -56,7 +56,7 @@ static int srt_to_ass(AVCodecContext *avctx, AVBPrint *dst,
static int srt_decode_frame(AVCodecContext *avctx,
void *data, int *got_sub_ptr, AVPacket *avpkt)
{
- AVSubtitle *sub = data;
+ AVFrame *sub = data;
AVBPrint buffer;
int x1 = -1, y1 = -1, x2 = -1, y2 = -1;
int ret;
@@ -83,7 +83,7 @@ static int srt_decode_frame(AVCodecContext *avctx,
if (ret < 0)
return ret;
- *got_sub_ptr = sub->num_rects > 0;
+ *got_sub_ptr = sub->num_subtitle_rects > 0;
return avpkt->size;
}
diff --git a/libavcodec/srtenc.c b/libavcodec/srtenc.c
index 2e3ac55770..f4a9de1e70 100644
--- a/libavcodec/srtenc.c
+++ b/libavcodec/srtenc.c
@@ -228,7 +228,7 @@ static const ASSCodesCallbacks text_callbacks = {
};
static int encode_frame(AVCodecContext *avctx,
- unsigned char *buf, int bufsize, const AVSubtitle *sub,
+ unsigned char *buf, int bufsize, const AVFrame *sub,
const ASSCodesCallbacks *cb)
{
SRTContext *s = avctx->priv_data;
@@ -237,11 +237,11 @@ static int encode_frame(AVCodecContext *avctx,
av_bprint_clear(&s->buffer);
- for (i=0; i<sub->num_rects; i++) {
- const char *ass = sub->rects[i]->ass;
+ for (i=0; i<sub->num_subtitle_rects; i++) {
+ const char *ass = sub->subtitle_rects[i]->ass;
- if (sub->rects[i]->type != SUBTITLE_ASS) {
- av_log(avctx, AV_LOG_ERROR, "Only SUBTITLE_ASS type supported.\n");
+ if (sub->subtitle_rects[i]->type != AV_SUBTITLE_FMT_ASS) {
+ av_log(avctx, AV_LOG_ERROR, "Only AV_SUBTITLE_FMT_ASS type supported.\n");
return AVERROR(EINVAL);
}
@@ -270,13 +270,13 @@ static int encode_frame(AVCodecContext *avctx,
}
static int srt_encode_frame(AVCodecContext *avctx,
- unsigned char *buf, int bufsize, const AVSubtitle *sub)
+ unsigned char *buf, int bufsize, const AVFrame *sub)
{
return encode_frame(avctx, buf, bufsize, sub, &srt_callbacks);
}
static int text_encode_frame(AVCodecContext *avctx,
- unsigned char *buf, int bufsize, const AVSubtitle *sub)
+ unsigned char *buf, int bufsize, const AVFrame *sub)
{
return encode_frame(avctx, buf, bufsize, sub, &text_callbacks);
}
diff --git a/libavcodec/subviewerdec.c b/libavcodec/subviewerdec.c
index 5c650d0cde..e4eff51d33 100644
--- a/libavcodec/subviewerdec.c
+++ b/libavcodec/subviewerdec.c
@@ -51,7 +51,7 @@ static int subviewer_decode_frame(AVCodecContext *avctx,
void *data, int *got_sub_ptr, AVPacket *avpkt)
{
int ret = 0;
- AVSubtitle *sub = data;
+ AVFrame *sub = data;
const char *ptr = avpkt->data;
FFASSDecoderContext *s = avctx->priv_data;
AVBPrint buf;
@@ -62,7 +62,7 @@ static int subviewer_decode_frame(AVCodecContext *avctx,
av_bprint_finalize(&buf, NULL);
if (ret < 0)
return ret;
- *got_sub_ptr = sub->num_rects > 0;
+ *got_sub_ptr = sub->num_subtitle_rects > 0;
return avpkt->size;
}
diff --git a/libavcodec/textdec.c b/libavcodec/textdec.c
index 308553660a..274b53f74d 100644
--- a/libavcodec/textdec.c
+++ b/libavcodec/textdec.c
@@ -48,7 +48,7 @@ static int text_decode_frame(AVCodecContext *avctx, void *data,
{
int ret = 0;
AVBPrint buf;
- AVSubtitle *sub = data;
+ AVFrame *sub = data;
const char *ptr = avpkt->data;
TextContext *text = avctx->priv_data;
@@ -60,7 +60,7 @@ static int text_decode_frame(AVCodecContext *avctx, void *data,
av_bprint_finalize(&buf, NULL);
if (ret < 0)
return ret;
- *got_sub_ptr = sub->num_rects > 0;
+ *got_sub_ptr = sub->num_subtitle_rects > 0;
return avpkt->size;
}
diff --git a/libavcodec/ttmlenc.c b/libavcodec/ttmlenc.c
index ad2eddfdd5..3a439db98e 100644
--- a/libavcodec/ttmlenc.c
+++ b/libavcodec/ttmlenc.c
@@ -78,7 +78,7 @@ static const ASSCodesCallbacks ttml_callbacks = {
};
static int ttml_encode_frame(AVCodecContext *avctx, uint8_t *buf,
- int bufsize, const AVSubtitle *sub)
+ int bufsize, const AVFrame *sub)
{
TTMLContext *s = avctx->priv_data;
ASSDialog *dialog;
@@ -86,12 +86,12 @@ static int ttml_encode_frame(AVCodecContext *avctx, uint8_t *buf,
av_bprint_clear(&s->buffer);
- for (i=0; i<sub->num_rects; i++) {
- const char *ass = sub->rects[i]->ass;
+ for (i=0; i<sub->num_subtitle_rects; i++) {
+ const char *ass = sub->subtitle_rects[i]->ass;
int ret;
- if (sub->rects[i]->type != SUBTITLE_ASS) {
- av_log(avctx, AV_LOG_ERROR, "Only SUBTITLE_ASS type supported.\n");
+ if (sub->subtitle_rects[i]->type != AV_SUBTITLE_FMT_ASS) {
+ av_log(avctx, AV_LOG_ERROR, "Only AV_SUBTITLE_FMT_ASS type supported.\n");
return AVERROR(EINVAL);
}
diff --git a/libavcodec/utils.c b/libavcodec/utils.c
index cfc07cbcb8..767dfabd1e 100644
--- a/libavcodec/utils.c
+++ b/libavcodec/utils.c
@@ -818,6 +818,17 @@ int av_get_audio_frame_duration(AVCodecContext *avctx, int frame_bytes)
return FFMAX(0, duration);
}
+enum AVSubtitleType av_get_subtitle_format_from_codecdesc(const AVCodecDescriptor *codec_descriptor)
+{
+ if(codec_descriptor->props & AV_CODEC_PROP_BITMAP_SUB)
+ return AV_SUBTITLE_FMT_BITMAP;
+
+ if(codec_descriptor->props & AV_CODEC_PROP_TEXT_SUB)
+ return AV_SUBTITLE_FMT_ASS;
+
+ return AV_SUBTITLE_FMT_UNKNOWN;
+}
+
int av_get_audio_frame_duration2(AVCodecParameters *par, int frame_bytes)
{
int duration = get_audio_frame_duration(par->codec_id, par->sample_rate,
diff --git a/libavcodec/webvttdec.c b/libavcodec/webvttdec.c
index 0093f328fa..23b0c5245c 100644
--- a/libavcodec/webvttdec.c
+++ b/libavcodec/webvttdec.c
@@ -84,7 +84,7 @@ static int webvtt_decode_frame(AVCodecContext *avctx,
void *data, int *got_sub_ptr, AVPacket *avpkt)
{
int ret = 0;
- AVSubtitle *sub = data;
+ AVFrame *sub = data;
const char *ptr = avpkt->data;
FFASSDecoderContext *s = avctx->priv_data;
AVBPrint buf;
@@ -95,7 +95,7 @@ static int webvtt_decode_frame(AVCodecContext *avctx,
av_bprint_finalize(&buf, NULL);
if (ret < 0)
return ret;
- *got_sub_ptr = sub->num_rects > 0;
+ *got_sub_ptr = sub->num_subtitle_rects > 0;
return avpkt->size;
}
diff --git a/libavcodec/webvttenc.c b/libavcodec/webvttenc.c
index 89b49e42bf..287a246156 100644
--- a/libavcodec/webvttenc.c
+++ b/libavcodec/webvttenc.c
@@ -156,7 +156,7 @@ static const ASSCodesCallbacks webvtt_callbacks = {
};
static int webvtt_encode_frame(AVCodecContext *avctx,
- unsigned char *buf, int bufsize, const AVSubtitle *sub)
+ unsigned char *buf, int bufsize, const AVFrame *sub)
{
WebVTTContext *s = avctx->priv_data;
ASSDialog *dialog;
@@ -164,11 +164,11 @@ static int webvtt_encode_frame(AVCodecContext *avctx,
av_bprint_clear(&s->buffer);
- for (i=0; i<sub->num_rects; i++) {
- const char *ass = sub->rects[i]->ass;
+ for (i=0; i<sub->num_subtitle_rects; i++) {
+ const char *ass = sub->subtitle_rects[i]->ass;
- if (sub->rects[i]->type != SUBTITLE_ASS) {
- av_log(avctx, AV_LOG_ERROR, "Only SUBTITLE_ASS type supported.\n");
+ if (sub->subtitle_rects[i]->type != AV_SUBTITLE_FMT_ASS) {
+ av_log(avctx, AV_LOG_ERROR, "Only AV_SUBTITLE_FMT_ASS type supported.\n");
return AVERROR(EINVAL);
}
diff --git a/libavcodec/xsubdec.c b/libavcodec/xsubdec.c
index 979399bae6..f45edcc0ca 100644
--- a/libavcodec/xsubdec.c
+++ b/libavcodec/xsubdec.c
@@ -51,7 +51,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_sub_ptr,
AVPacket *avpkt) {
const uint8_t *buf = avpkt->data;
int buf_size = avpkt->size;
- AVSubtitle *sub = data;
+ AVFrame *sub = data;
const uint8_t *buf_end = buf + buf_size;
uint8_t *bitmap;
int w, h, x, y, i, ret;
@@ -72,8 +72,8 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_sub_ptr,
}
if (avpkt->pts != AV_NOPTS_VALUE)
packet_time = av_rescale_q(avpkt->pts, AV_TIME_BASE_Q, (AVRational){1, 1000});
- sub->start_display_time = parse_timecode(buf + 1, packet_time);
- sub->end_display_time = parse_timecode(buf + 14, packet_time);
+ sub->subtitle_start_time = parse_timecode(buf + 1, packet_time);
+ sub->subtitle_end_time = parse_timecode(buf + 14, packet_time);
buf += 27;
// read header
@@ -96,51 +96,51 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_sub_ptr,
return AVERROR_INVALIDDATA;
// allocate sub and set values
- sub->rects = av_mallocz(sizeof(*sub->rects));
- if (!sub->rects)
+ sub->subtitle_rects = av_mallocz(sizeof(*sub->subtitle_rects));
+ if (!sub->subtitle_rects)
return AVERROR(ENOMEM);
- sub->rects[0] = av_mallocz(sizeof(*sub->rects[0]));
- if (!sub->rects[0]) {
- av_freep(&sub->rects);
+ sub->subtitle_rects[0] = av_mallocz(sizeof(*sub->subtitle_rects[0]));
+ if (!sub->subtitle_rects[0]) {
+ av_freep(&sub->subtitle_rects);
return AVERROR(ENOMEM);
}
- sub->rects[0]->x = x; sub->rects[0]->y = y;
- sub->rects[0]->w = w; sub->rects[0]->h = h;
- sub->rects[0]->type = SUBTITLE_BITMAP;
- sub->rects[0]->linesize[0] = w;
- sub->rects[0]->data[0] = av_malloc(w * h);
- sub->rects[0]->nb_colors = 4;
- sub->rects[0]->data[1] = av_mallocz(AVPALETTE_SIZE);
- if (!sub->rects[0]->data[0] || !sub->rects[0]->data[1]) {
- av_freep(&sub->rects[0]->data[1]);
- av_freep(&sub->rects[0]->data[0]);
- av_freep(&sub->rects[0]);
- av_freep(&sub->rects);
+ sub->subtitle_rects[0]->x = x; sub->subtitle_rects[0]->y = y;
+ sub->subtitle_rects[0]->w = w; sub->subtitle_rects[0]->h = h;
+ sub->subtitle_rects[0]->type = AV_SUBTITLE_FMT_BITMAP;
+ sub->subtitle_rects[0]->linesize[0] = w;
+ sub->subtitle_rects[0]->data[0] = av_malloc(w * h);
+ sub->subtitle_rects[0]->nb_colors = 4;
+ sub->subtitle_rects[0]->data[1] = av_mallocz(AVPALETTE_SIZE);
+ if (!sub->subtitle_rects[0]->data[0] || !sub->subtitle_rects[0]->data[1]) {
+ av_freep(&sub->subtitle_rects[0]->data[1]);
+ av_freep(&sub->subtitle_rects[0]->data[0]);
+ av_freep(&sub->subtitle_rects[0]);
+ av_freep(&sub->subtitle_rects);
return AVERROR(ENOMEM);
}
- sub->num_rects = 1;
+ sub->num_subtitle_rects = 1;
// read palette
- for (i = 0; i < sub->rects[0]->nb_colors; i++)
- ((uint32_t*)sub->rects[0]->data[1])[i] = bytestream_get_be24(&buf);
+ for (i = 0; i < sub->subtitle_rects[0]->nb_colors; i++)
+ ((uint32_t*)sub->subtitle_rects[0]->data[1])[i] = bytestream_get_be24(&buf);
if (!has_alpha) {
// make all except background (first entry) non-transparent
- for (i = 1; i < sub->rects[0]->nb_colors; i++)
- ((uint32_t *)sub->rects[0]->data[1])[i] |= 0xff000000;
+ for (i = 1; i < sub->subtitle_rects[0]->nb_colors; i++)
+ ((uint32_t *)sub->subtitle_rects[0]->data[1])[i] |= 0xff000000;
} else {
- for (i = 0; i < sub->rects[0]->nb_colors; i++)
- ((uint32_t *)sub->rects[0]->data[1])[i] |= (unsigned)*buf++ << 24;
+ for (i = 0; i < sub->subtitle_rects[0]->nb_colors; i++)
+ ((uint32_t *)sub->subtitle_rects[0]->data[1])[i] |= (unsigned)*buf++ << 24;
}
// process RLE-compressed data
if ((ret = init_get_bits8(&gb, buf, buf_end - buf)) < 0)
return ret;
- bitmap = sub->rects[0]->data[0];
+ bitmap = sub->subtitle_rects[0]->data[0];
for (y = 0; y < h; y++) {
// interlaced: do odd lines
- if (y == (h + 1) / 2) bitmap = sub->rects[0]->data[0] + w;
+ if (y == (h + 1) / 2) bitmap = sub->subtitle_rects[0]->data[0] + w;
for (x = 0; x < w; ) {
int log2 = ff_log2_tab[show_bits(&gb, 8)];
int run = get_bits(&gb, 14 - 4 * (log2 >> 1));
diff --git a/libavcodec/xsubenc.c b/libavcodec/xsubenc.c
index 03d0dc2d86..6508af9a73 100644
--- a/libavcodec/xsubenc.c
+++ b/libavcodec/xsubenc.c
@@ -112,10 +112,10 @@ static int make_tc(uint64_t ms, int *tc)
}
static int xsub_encode(AVCodecContext *avctx, unsigned char *buf,
- int bufsize, const AVSubtitle *h)
+ int bufsize, const AVFrame *h)
{
- uint64_t startTime = h->pts / 1000; // FIXME: need better solution...
- uint64_t endTime = startTime + h->end_display_time - h->start_display_time;
+ uint64_t startTime = h->subtitle_pts / 1000; // FIXME: need better solution...
+ uint64_t endTime = startTime + h->subtitle_end_time - h->subtitle_start_time;
int start_tc[4], end_tc[4];
uint8_t *hdr = buf + 27; // Point behind the timestamp
uint8_t *rlelenptr;
@@ -129,21 +129,21 @@ static int xsub_encode(AVCodecContext *avctx, unsigned char *buf,
}
// TODO: support multiple rects
- if (h->num_rects != 1)
- av_log(avctx, AV_LOG_WARNING, "Only single rects supported (%d in subtitle.)\n", h->num_rects);
+ if (h->num_subtitle_rects != 1)
+ av_log(avctx, AV_LOG_WARNING, "Only single rects supported (%d in subtitle.)\n", h->num_subtitle_rects);
// TODO: render text-based subtitles into bitmaps
- if (!h->rects[0]->data[0] || !h->rects[0]->data[1]) {
+ if (!h->subtitle_rects[0]->data[0] || !h->subtitle_rects[0]->data[1]) {
av_log(avctx, AV_LOG_WARNING, "No subtitle bitmap available.\n");
return AVERROR(EINVAL);
}
// TODO: color reduction, similar to dvdsub encoder
- if (h->rects[0]->nb_colors > 4)
- av_log(avctx, AV_LOG_WARNING, "No more than 4 subtitle colors supported (%d found.)\n", h->rects[0]->nb_colors);
+ if (h->subtitle_rects[0]->nb_colors > 4)
+ av_log(avctx, AV_LOG_WARNING, "No more than 4 subtitle colors supported (%d found.)\n", h->subtitle_rects[0]->nb_colors);
// TODO: Palette swapping if color zero is not transparent
- if (((uint32_t *)h->rects[0]->data[1])[0] & 0xff000000)
+ if (((uint32_t *)h->subtitle_rects[0]->data[1])[0] & 0xff000000)
av_log(avctx, AV_LOG_WARNING, "Color index 0 is not transparent. Transparency will be messed up.\n");
if (make_tc(startTime, start_tc) || make_tc(endTime, end_tc)) {
@@ -160,40 +160,40 @@ static int xsub_encode(AVCodecContext *avctx, unsigned char *buf,
// 2 pixels required on either side of subtitle.
// Possibly due to limitations of hardware renderers.
// TODO: check if the bitmap is already padded
- width = FFALIGN(h->rects[0]->w, 2) + PADDING * 2;
- height = FFALIGN(h->rects[0]->h, 2);
+ width = FFALIGN(h->subtitle_rects[0]->w, 2) + PADDING * 2;
+ height = FFALIGN(h->subtitle_rects[0]->h, 2);
bytestream_put_le16(&hdr, width);
bytestream_put_le16(&hdr, height);
- bytestream_put_le16(&hdr, h->rects[0]->x);
- bytestream_put_le16(&hdr, h->rects[0]->y);
- bytestream_put_le16(&hdr, h->rects[0]->x + width -1);
- bytestream_put_le16(&hdr, h->rects[0]->y + height -1);
+ bytestream_put_le16(&hdr, h->subtitle_rects[0]->x);
+ bytestream_put_le16(&hdr, h->subtitle_rects[0]->y);
+ bytestream_put_le16(&hdr, h->subtitle_rects[0]->x + width -1);
+ bytestream_put_le16(&hdr, h->subtitle_rects[0]->y + height -1);
rlelenptr = hdr; // Will store length of first field here later.
hdr+=2;
// Palette
for (i=0; i<4; i++)
- bytestream_put_be24(&hdr, ((uint32_t *)h->rects[0]->data[1])[i]);
+ bytestream_put_be24(&hdr, ((uint32_t *)h->subtitle_rects[0]->data[1])[i]);
// Bitmap
// RLE buffer. Reserve 2 bytes for possible padding after the last row.
init_put_bits(&pb, hdr, bufsize - (hdr - buf) - 2);
- if (xsub_encode_rle(&pb, h->rects[0]->data[0],
- h->rects[0]->linesize[0] * 2,
- h->rects[0]->w, (h->rects[0]->h + 1) >> 1))
+ if (xsub_encode_rle(&pb, h->subtitle_rects[0]->data[0],
+ h->subtitle_rects[0]->linesize[0] * 2,
+ h->subtitle_rects[0]->w, (h->subtitle_rects[0]->h + 1) >> 1))
return AVERROR_BUFFER_TOO_SMALL;
bytestream_put_le16(&rlelenptr, put_bytes_count(&pb, 0)); // Length of first field
- if (xsub_encode_rle(&pb, h->rects[0]->data[0] + h->rects[0]->linesize[0],
- h->rects[0]->linesize[0] * 2,
- h->rects[0]->w, h->rects[0]->h >> 1))
+ if (xsub_encode_rle(&pb, h->subtitle_rects[0]->data[0] + h->subtitle_rects[0]->linesize[0],
+ h->subtitle_rects[0]->linesize[0] * 2,
+ h->subtitle_rects[0]->w, h->subtitle_rects[0]->h >> 1))
return AVERROR_BUFFER_TOO_SMALL;
// Enforce total height to be a multiple of 2
- if (h->rects[0]->h & 1) {
- put_xsub_rle(&pb, h->rects[0]->w, PADDING_COLOR);
+ if (h->subtitle_rects[0]->h & 1) {
+ put_xsub_rle(&pb, h->subtitle_rects[0]->w, PADDING_COLOR);
}
flush_put_bits(&pb);
diff --git a/libavfilter/vf_subtitles.c b/libavfilter/vf_subtitles.c
index d0bafcd3cf..c536854c45 100644
--- a/libavfilter/vf_subtitles.c
+++ b/libavfilter/vf_subtitles.c
@@ -35,14 +35,12 @@
# include "libavformat/avformat.h"
#endif
#include "libavutil/avstring.h"
-#include "libavutil/imgutils.h"
#include "libavutil/opt.h"
#include "libavutil/parseutils.h"
#include "drawutils.h"
#include "avfilter.h"
#include "internal.h"
#include "formats.h"
-#include "video.h"
typedef struct AssContext {
const AVClass *class;
@@ -306,6 +304,7 @@ static av_cold int init_subtitles(AVFilterContext *ctx)
AVStream *st;
AVPacket pkt;
AssContext *ass = ctx->priv;
+ enum AVSubtitleType subtitle_format;
/* Init libass */
ret = init(ctx);
@@ -386,16 +385,19 @@ static av_cold int init_subtitles(AVFilterContext *ctx)
ret = AVERROR_DECODER_NOT_FOUND;
goto end;
}
+
dec_desc = avcodec_descriptor_get(st->codecpar->codec_id);
- if (dec_desc && !(dec_desc->props & AV_CODEC_PROP_TEXT_SUB)) {
+ subtitle_format = av_get_subtitle_format_from_codecdesc(dec_desc);
+
+ if (subtitle_format != AV_SUBTITLE_FMT_ASS) {
av_log(ctx, AV_LOG_ERROR,
- "Only text based subtitles are currently supported\n");
- ret = AVERROR_PATCHWELCOME;
+ "Only text based subtitles are supported by this filter\n");
+ ret = AVERROR_INVALIDDATA;
goto end;
}
+
if (ass->charenc)
av_dict_set(&codec_opts, "sub_charenc", ass->charenc, 0);
- av_dict_set(&codec_opts, "sub_text_format", "ass", 0);
dec_ctx = avcodec_alloc_context3(dec);
if (!dec_ctx) {
@@ -449,18 +451,18 @@ static av_cold int init_subtitles(AVFilterContext *ctx)
dec_ctx->subtitle_header_size);
while (av_read_frame(fmt, &pkt) >= 0) {
int i, got_subtitle;
- AVSubtitle sub = {0};
+ AVFrame *sub = av_frame_alloc();
if (pkt.stream_index == sid) {
- ret = avcodec_decode_subtitle2(dec_ctx, &sub, &got_subtitle, &pkt);
+ ret = avcodec_decode_subtitle2(dec_ctx, sub, &got_subtitle, &pkt);
if (ret < 0) {
av_log(ctx, AV_LOG_WARNING, "Error decoding: %s (ignored)\n",
av_err2str(ret));
} else if (got_subtitle) {
- const int64_t start_time = av_rescale_q(sub.pts, AV_TIME_BASE_Q, av_make_q(1, 1000));
- const int64_t duration = sub.end_display_time;
- for (i = 0; i < sub.num_rects; i++) {
- char *ass_line = sub.rects[i]->ass;
+ const int64_t start_time = av_rescale_q(sub->subtitle_pts, AV_TIME_BASE_Q, av_make_q(1, 1000));
+ const int64_t duration = sub->subtitle_end_time;
+ for (i = 0; i < sub->num_subtitle_rects; i++) {
+ char *ass_line = sub->subtitle_rects[i]->ass;
if (!ass_line)
break;
ass_process_chunk(ass->track, ass_line, strlen(ass_line),
@@ -469,7 +471,7 @@ static av_cold int init_subtitles(AVFilterContext *ctx)
}
}
av_packet_unref(&pkt);
- avsubtitle_free(&sub);
+ av_frame_free(&sub);
}
end:
diff --git a/libavformat/utils.c b/libavformat/utils.c
index b56190d2da..f83dadd477 100644
--- a/libavformat/utils.c
+++ b/libavformat/utils.c
@@ -2949,7 +2949,6 @@ static int try_decode_frame(AVFormatContext *s, AVStream *st,
const AVCodec *codec;
int got_picture = 1, ret = 0;
AVFrame *frame = av_frame_alloc();
- AVSubtitle subtitle;
AVPacket pkt = *avpkt;
int do_skip_frame = 0;
enum AVDiscard skip_frame;
@@ -3020,10 +3019,8 @@ static int try_decode_frame(AVFormatContext *s, AVStream *st,
if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF)
ret = 0;
} else if (avctx->codec_type == AVMEDIA_TYPE_SUBTITLE) {
- ret = avcodec_decode_subtitle2(avctx, &subtitle,
+ ret = avcodec_decode_subtitle2(avctx, frame,
&got_picture, &pkt);
- if (got_picture)
- avsubtitle_free(&subtitle);
if (ret >= 0)
pkt.size = 0;
}
diff --git a/libavutil/Makefile b/libavutil/Makefile
index 410ac636f7..04e1101bf3 100644
--- a/libavutil/Makefile
+++ b/libavutil/Makefile
@@ -74,6 +74,7 @@ HEADERS = adler32.h \
sha512.h \
spherical.h \
stereo3d.h \
+ subfmt.h \
threadmessage.h \
time.h \
timecode.h \
@@ -159,6 +160,7 @@ OBJS = adler32.o \
slicethread.o \
spherical.o \
stereo3d.o \
+ subfmt.o \
threadmessage.o \
time.o \
timecode.o \
diff --git a/libavutil/frame.c b/libavutil/frame.c
index ef2867d318..1855de9b3d 100644
--- a/libavutil/frame.c
+++ b/libavutil/frame.c
@@ -72,7 +72,12 @@ static void get_frame_defaults(AVFrame *frame)
frame->colorspace = AVCOL_SPC_UNSPECIFIED;
frame->color_range = AVCOL_RANGE_UNSPECIFIED;
frame->chroma_location = AVCHROMA_LOC_UNSPECIFIED;
- frame->flags = 0;
+ frame->subtitle_start_time = 0;
+ frame->subtitle_end_time = 0;
+ frame->num_subtitle_rects = 0;
+ frame->subtitle_rects = NULL;
+ frame->subtitle_pts = 0;
+ frame->subtitle_header = NULL;
}
static void free_side_data(AVFrameSideData **ptr_sd)
@@ -306,6 +311,9 @@ static int frame_copy_props(AVFrame *dst, const AVFrame *src, int force_copy)
dst->colorspace = src->colorspace;
dst->color_range = src->color_range;
dst->chroma_location = src->chroma_location;
+ dst->subtitle_start_time = src->subtitle_start_time;
+ dst->subtitle_end_time = src->subtitle_end_time;
+ dst->subtitle_pts = src->subtitle_pts;
av_dict_copy(&dst->metadata, src->metadata, 0);
@@ -359,6 +367,19 @@ int av_frame_ref(AVFrame *dst, const AVFrame *src)
if (ret < 0)
goto fail;
+ /* duplicate subtitle rects */
+ dst->num_subtitle_rects = src->num_subtitle_rects;
+
+ if (src->num_subtitle_rects) {
+ dst->subtitle_rects = av_malloc_array(src->num_subtitle_rects, sizeof(AVSubtitleRect *));
+
+ for (i = 0; i < src->num_subtitle_rects; i++) {
+ AVSubtitleRect *rect = src->subtitle_rects[i];
+ rect->nb_refs++;
+ dst->subtitle_rects[i] = rect;
+ }
+ }
+
/* duplicate the frame data if it's not refcounted */
if (!src->buf[0]) {
ret = av_frame_get_buffer2(dst, 0);
@@ -472,6 +493,24 @@ void av_frame_unref(AVFrame *frame)
av_buffer_unref(&frame->opaque_ref);
av_buffer_unref(&frame->private_ref);
+ for (i = 0; i < frame->num_subtitle_rects; i++) {
+ AVSubtitleRect *rect = frame->subtitle_rects[i];
+
+ if (rect && rect->nb_refs > 0)
+ rect->nb_refs--;
+ else {
+ av_freep(&rect->data[0]);
+ av_freep(&rect->data[1]);
+ av_freep(&rect->data[2]);
+ av_freep(&rect->data[3]);
+ av_freep(&rect->text);
+ av_freep(&rect->ass);
+ av_freep(&rect);
+ }
+ }
+
+ av_freep(&frame->subtitle_rects);
+
get_frame_defaults(frame);
}
diff --git a/libavutil/frame.h b/libavutil/frame.h
index 005eed9d18..4e2cfe19b3 100644
--- a/libavutil/frame.h
+++ b/libavutil/frame.h
@@ -34,6 +34,7 @@
#include "rational.h"
#include "samplefmt.h"
#include "pixfmt.h"
+#include "subfmt.h"
#include "version.h"
@@ -469,6 +470,17 @@ typedef struct AVFrame {
*/
uint64_t channel_layout;
+ uint32_t subtitle_start_time; /* display start time, relative to packet pts, in ms */
+ uint32_t subtitle_end_time; /* display end time, relative to packet pts, in ms */
+ unsigned num_subtitle_rects;
+ AVSubtitleRect **subtitle_rects;
+ int64_t subtitle_pts; ///< Same as packet pts, in AV_TIME_BASE
+
+ /**
+ * Header containing style information for text subtitles.
+ */
+ char *subtitle_header;
+
/**
* AVBuffer references backing the data for this frame. If all elements of
* this array are NULL, then this frame is not reference counted. This array
diff --git a/libavutil/subfmt.c b/libavutil/subfmt.c
new file mode 100644
index 0000000000..9a19d01aa3
--- /dev/null
+++ b/libavutil/subfmt.c
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2021 softworkz
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg 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,
+ * 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
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <string.h>
+#include "common.h"
+#include "subfmt.h"
+
+typedef struct SubtitleFmtInfo {
+ enum AVSubtitleType fmt;
+ char* name;
+} SubtitleFmtInfo;
+
+static SubtitleFmtInfo sub_fmt_info[AV_SUBTITLE_FMT_NB] = {
+ {.fmt = AV_SUBTITLE_FMT_UNKNOWN, .name = "Unknown subtitle format", },
+ {.fmt = AV_SUBTITLE_FMT_BITMAP, .name = "Graphical subtitles", },
+ {.fmt = AV_SUBTITLE_FMT_TEXT, .name = "Text subtitles (plain)", },
+ {.fmt = AV_SUBTITLE_FMT_ASS, .name = "Text subtitles (ass)", },
+};
+
+const char *av_get_subtitle_fmt_name(enum AVSubtitleType sub_fmt)
+{
+ if (sub_fmt < 0 || sub_fmt >= AV_SUBTITLE_FMT_NB)
+ return NULL;
+ return sub_fmt_info[sub_fmt].name;
+}
+
+enum AVSubtitleType av_get_subtitle_fmt(const char *name)
+{
+ int i;
+
+ for (i = 0; i < AV_SUBTITLE_FMT_NB; i++)
+ if (!strcmp(sub_fmt_info[i].name, name))
+ return i;
+ return AV_SUBTITLE_FMT_NONE;
+}
diff --git a/libavutil/subfmt.h b/libavutil/subfmt.h
new file mode 100644
index 0000000000..31dabc957c
--- /dev/null
+++ b/libavutil/subfmt.h
@@ -0,0 +1,94 @@
+/*
+ * Copyright (c) 2021 softworkz
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg 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,
+ * 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
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef AVUTIL_SUBFMT_H
+#define AVUTIL_SUBFMT_H
+
+#include <inttypes.h>
+
+enum AVSubtitleType {
+
+ /**
+ * Subtitle format unknown.
+ */
+ AV_SUBTITLE_FMT_NONE = -1,
+
+ /**
+ * Subtitle format unknown.
+ */
+ AV_SUBTITLE_FMT_UNKNOWN = 0,
+
+ /**
+ * Bitmap area in AVSubtitleRect.data, pixfmt AV_PIX_FMT_PAL8.
+ */
+ AV_SUBTITLE_FMT_BITMAP = 1,
+
+ /**
+ * Plain text in AVSubtitleRect.text.
+ */
+ AV_SUBTITLE_FMT_TEXT = 2,
+
+ /**
+ * Text Formatted as per ASS specification, contained AVSubtitleRect.ass.
+ */
+ AV_SUBTITLE_FMT_ASS = 3,
+
+ AV_SUBTITLE_FMT_NB,
+};
+
+typedef struct AVSubtitleRect {
+ unsigned nb_refs;
+ int x; ///< top left corner of pict, undefined when pict is not set
+ int y; ///< top left corner of pict, undefined when pict is not set
+ int w; ///< width of pict, undefined when pict is not set
+ int h; ///< height of pict, undefined when pict is not set
+ int nb_colors; ///< number of colors in pict, undefined when pict is not set
+
+ /**
+ * data+linesize for the bitmap of this subtitle.
+ */
+ uint8_t *data[4];
+ int linesize[4];
+
+ enum AVSubtitleType type;
+
+ char *text; ///< 0 terminated plain UTF-8 text
+
+ /**
+ * 0-terminated ASS/SSA compatible event line.
+ */
+ char *ass;
+
+ int flags;
+} AVSubtitleRect;
+
+/**
+ * Return the name of sub_fmt, or NULL if sub_fmt is not
+ * recognized.
+ */
+const char *av_get_subtitle_fmt_name(enum AVSubtitleType sub_fmt);
+
+/**
+ * Return a subtitle format corresponding to name, or AV_SUBTITLE_FMT_NONE
+ * on error.
+ */
+enum AVSubtitleType av_get_subtitle_fmt(const char *name);
+
+#endif /* AVUTIL_SUBFMT_H */
--
2.30.2.windows.1
More information about the ffmpeg-devel
mailing list