mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2024-12-23 12:43:46 +02:00
avcodec: Remove deprecated ASS with inline timing
Deprecated in 22ebbda637
.
Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@gmail.com>
Signed-off-by: James Almer <jamrial@gmail.com>
This commit is contained in:
parent
cb172ae9ab
commit
1f63665ca5
@ -27,10 +27,6 @@
|
||||
#include "libavutil/internal.h"
|
||||
#include "libavutil/mem.h"
|
||||
|
||||
typedef struct {
|
||||
int id; ///< current event id, ReadOrder field
|
||||
} ASSEncodeContext;
|
||||
|
||||
static av_cold int ass_encode_init(AVCodecContext *avctx)
|
||||
{
|
||||
avctx->extradata = av_malloc(avctx->subtitle_header_size + 1);
|
||||
@ -46,49 +42,16 @@ static int ass_encode_frame(AVCodecContext *avctx,
|
||||
unsigned char *buf, int bufsize,
|
||||
const AVSubtitle *sub)
|
||||
{
|
||||
ASSEncodeContext *s = avctx->priv_data;
|
||||
int i, len, total_len = 0;
|
||||
|
||||
for (i=0; i<sub->num_rects; i++) {
|
||||
char ass_line[2048];
|
||||
const char *ass = sub->rects[i]->ass;
|
||||
long int layer;
|
||||
char *p;
|
||||
|
||||
if (sub->rects[i]->type != SUBTITLE_ASS) {
|
||||
av_log(avctx, AV_LOG_ERROR, "Only SUBTITLE_ASS type supported.\n");
|
||||
return AVERROR(EINVAL);
|
||||
}
|
||||
|
||||
#if FF_API_ASS_TIMING
|
||||
if (!strncmp(ass, "Dialogue: ", 10)) {
|
||||
if (i > 0) {
|
||||
av_log(avctx, AV_LOG_ERROR, "ASS encoder supports only one "
|
||||
"ASS rectangle field.\n");
|
||||
return AVERROR_INVALIDDATA;
|
||||
}
|
||||
|
||||
ass += 10; // skip "Dialogue: "
|
||||
/* parse Layer field. If it's a Marked field, the content
|
||||
* will be "Marked=N" instead of the layer num, so we will
|
||||
* have layer=0, which is fine. */
|
||||
layer = strtol(ass, &p, 10);
|
||||
|
||||
#define SKIP_ENTRY(ptr) do { \
|
||||
char *sep = strchr(ptr, ','); \
|
||||
if (sep) \
|
||||
ptr = sep + 1; \
|
||||
} while (0)
|
||||
|
||||
SKIP_ENTRY(p); // skip layer or marked
|
||||
SKIP_ENTRY(p); // skip start timestamp
|
||||
SKIP_ENTRY(p); // skip end timestamp
|
||||
snprintf(ass_line, sizeof(ass_line), "%d,%ld,%s", ++s->id, layer, p);
|
||||
ass_line[strcspn(ass_line, "\r\n")] = 0;
|
||||
ass = ass_line;
|
||||
}
|
||||
#endif
|
||||
|
||||
len = av_strlcpy(buf+total_len, ass, bufsize-total_len);
|
||||
|
||||
if (len > bufsize-total_len-1) {
|
||||
@ -110,7 +73,6 @@ AVCodec ff_ssa_encoder = {
|
||||
.id = AV_CODEC_ID_ASS,
|
||||
.init = ass_encode_init,
|
||||
.encode_sub = ass_encode_frame,
|
||||
.priv_data_size = sizeof(ASSEncodeContext),
|
||||
};
|
||||
#endif
|
||||
|
||||
@ -122,6 +84,5 @@ AVCodec ff_ass_encoder = {
|
||||
.id = AV_CODEC_ID_ASS,
|
||||
.init = ass_encode_init,
|
||||
.encode_sub = ass_encode_frame,
|
||||
.priv_data_size = sizeof(ASSEncodeContext),
|
||||
};
|
||||
#endif
|
||||
|
@ -2047,9 +2047,6 @@ typedef struct AVCodecContext {
|
||||
*/
|
||||
int sub_text_format;
|
||||
#define FF_SUB_TEXT_FMT_ASS 0
|
||||
#if FF_API_ASS_TIMING
|
||||
#define FF_SUB_TEXT_FMT_ASS_WITH_TIMINGS 1
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Audio only. The amount of padding (in samples) appended by the encoder to
|
||||
|
@ -949,79 +949,6 @@ static int utf8_check(const uint8_t *str)
|
||||
return 1;
|
||||
}
|
||||
|
||||
#if FF_API_ASS_TIMING
|
||||
static void insert_ts(AVBPrint *buf, int ts)
|
||||
{
|
||||
if (ts == -1) {
|
||||
av_bprintf(buf, "9:59:59.99,");
|
||||
} else {
|
||||
int h, m, s;
|
||||
|
||||
h = ts/360000; ts -= 360000*h;
|
||||
m = ts/ 6000; ts -= 6000*m;
|
||||
s = ts/ 100; ts -= 100*s;
|
||||
av_bprintf(buf, "%d:%02d:%02d.%02d,", h, m, s, ts);
|
||||
}
|
||||
}
|
||||
|
||||
static int convert_sub_to_old_ass_form(AVSubtitle *sub, const AVPacket *pkt, AVRational tb)
|
||||
{
|
||||
int i;
|
||||
AVBPrint buf;
|
||||
|
||||
av_bprint_init(&buf, 0, AV_BPRINT_SIZE_UNLIMITED);
|
||||
|
||||
for (i = 0; i < sub->num_rects; i++) {
|
||||
char *final_dialog;
|
||||
const char *dialog;
|
||||
AVSubtitleRect *rect = sub->rects[i];
|
||||
int ts_start, ts_duration = -1;
|
||||
long int layer;
|
||||
|
||||
if (rect->type != SUBTITLE_ASS || !strncmp(rect->ass, "Dialogue: ", 10))
|
||||
continue;
|
||||
|
||||
av_bprint_clear(&buf);
|
||||
|
||||
/* skip ReadOrder */
|
||||
dialog = strchr(rect->ass, ',');
|
||||
if (!dialog)
|
||||
continue;
|
||||
dialog++;
|
||||
|
||||
/* extract Layer or Marked */
|
||||
layer = strtol(dialog, (char**)&dialog, 10);
|
||||
if (*dialog != ',')
|
||||
continue;
|
||||
dialog++;
|
||||
|
||||
/* rescale timing to ASS time base (ms) */
|
||||
ts_start = av_rescale_q(pkt->pts, tb, av_make_q(1, 100));
|
||||
if (pkt->duration != -1)
|
||||
ts_duration = av_rescale_q(pkt->duration, tb, av_make_q(1, 100));
|
||||
sub->end_display_time = FFMAX(sub->end_display_time, 10 * ts_duration);
|
||||
|
||||
/* construct ASS (standalone file form with timestamps) string */
|
||||
av_bprintf(&buf, "Dialogue: %ld,", layer);
|
||||
insert_ts(&buf, ts_start);
|
||||
insert_ts(&buf, ts_duration == -1 ? -1 : ts_start + ts_duration);
|
||||
av_bprintf(&buf, "%s\r\n", dialog);
|
||||
|
||||
final_dialog = av_strdup(buf.str);
|
||||
if (!av_bprint_is_complete(&buf) || !final_dialog) {
|
||||
av_freep(&final_dialog);
|
||||
av_bprint_finalize(&buf, NULL);
|
||||
return AVERROR(ENOMEM);
|
||||
}
|
||||
av_freep(&rect->ass);
|
||||
rect->ass = final_dialog;
|
||||
}
|
||||
|
||||
av_bprint_finalize(&buf, NULL);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
int avcodec_decode_subtitle2(AVCodecContext *avctx, AVSubtitle *sub,
|
||||
int *got_sub_ptr,
|
||||
AVPacket *avpkt)
|
||||
@ -1057,17 +984,6 @@ int avcodec_decode_subtitle2(AVCodecContext *avctx, AVSubtitle *sub,
|
||||
av_assert1((ret >= 0) >= !!*got_sub_ptr &&
|
||||
!!*got_sub_ptr >= !!sub->num_rects);
|
||||
|
||||
#if FF_API_ASS_TIMING
|
||||
if (avctx->sub_text_format == FF_SUB_TEXT_FMT_ASS_WITH_TIMINGS
|
||||
&& *got_sub_ptr && sub->num_rects) {
|
||||
const AVRational tb = avctx->pkt_timebase.num ? avctx->pkt_timebase
|
||||
: avctx->time_base;
|
||||
int err = convert_sub_to_old_ass_form(sub, avpkt, tb);
|
||||
if (err < 0)
|
||||
ret = err;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (sub->num_rects && !sub->end_display_time && avpkt->duration &&
|
||||
avctx->pkt_timebase.num) {
|
||||
AVRational ms = { 1, 1000 };
|
||||
|
@ -655,25 +655,12 @@ static int mov_text_encode_frame(AVCodecContext *avctx, unsigned char *buf,
|
||||
return AVERROR(EINVAL);
|
||||
}
|
||||
|
||||
#if FF_API_ASS_TIMING
|
||||
if (!strncmp(ass, "Dialogue: ", 10)) {
|
||||
int num;
|
||||
dialog = ff_ass_split_dialog(s->ass_ctx, ass, 0, &num);
|
||||
for (; dialog && num--; dialog++) {
|
||||
mov_text_dialog(s, dialog);
|
||||
ff_ass_split_override_codes(&mov_text_callbacks, s, dialog->text);
|
||||
}
|
||||
} else {
|
||||
#endif
|
||||
dialog = ff_ass_split_dialog2(s->ass_ctx, ass);
|
||||
if (!dialog)
|
||||
return AVERROR(ENOMEM);
|
||||
mov_text_dialog(s, dialog);
|
||||
ff_ass_split_override_codes(&mov_text_callbacks, s, dialog->text);
|
||||
ff_ass_free_dialog(&dialog);
|
||||
#if FF_API_ASS_TIMING
|
||||
}
|
||||
#endif
|
||||
|
||||
for (j = 0; j < box_count; j++) {
|
||||
box_types[j].encode(s);
|
||||
|
@ -366,15 +366,8 @@ static const AVOption avcodec_options[] = {
|
||||
{"auto", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_SUB_CHARENC_MODE_AUTOMATIC}, INT_MIN, INT_MAX, S|D, "sub_charenc_mode"},
|
||||
{"pre_decoder", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_SUB_CHARENC_MODE_PRE_DECODER}, INT_MIN, INT_MAX, S|D, "sub_charenc_mode"},
|
||||
{"ignore", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_SUB_CHARENC_MODE_IGNORE}, INT_MIN, INT_MAX, S|D, "sub_charenc_mode"},
|
||||
#if FF_API_ASS_TIMING
|
||||
{"sub_text_format", "set decoded text subtitle format", OFFSET(sub_text_format), AV_OPT_TYPE_INT, {.i64 = FF_SUB_TEXT_FMT_ASS_WITH_TIMINGS}, 0, 1, S|D, "sub_text_format"},
|
||||
#else
|
||||
{"sub_text_format", "set decoded text subtitle format", OFFSET(sub_text_format), AV_OPT_TYPE_INT, {.i64 = FF_SUB_TEXT_FMT_ASS}, 0, 1, S|D, "sub_text_format"},
|
||||
#endif
|
||||
{"ass", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_SUB_TEXT_FMT_ASS}, INT_MIN, INT_MAX, S|D, "sub_text_format"},
|
||||
#if FF_API_ASS_TIMING
|
||||
{"ass_with_timings", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_SUB_TEXT_FMT_ASS_WITH_TIMINGS}, INT_MIN, INT_MAX, S|D, "sub_text_format"},
|
||||
#endif
|
||||
#if FF_API_OLD_ENCDEC
|
||||
{"refcounted_frames", NULL, OFFSET(refcounted_frames), AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, A|V|D },
|
||||
#endif
|
||||
|
@ -244,18 +244,6 @@ static int encode_frame(AVCodecContext *avctx,
|
||||
return AVERROR(EINVAL);
|
||||
}
|
||||
|
||||
#if FF_API_ASS_TIMING
|
||||
if (!strncmp(ass, "Dialogue: ", 10)) {
|
||||
int num;
|
||||
dialog = ff_ass_split_dialog(s->ass_ctx, ass, 0, &num);
|
||||
for (; dialog && num--; dialog++) {
|
||||
s->alignment_applied = 0;
|
||||
if (avctx->codec_id == AV_CODEC_ID_SUBRIP)
|
||||
srt_style_apply(s, dialog->style);
|
||||
ff_ass_split_override_codes(cb, s, dialog->text);
|
||||
}
|
||||
} else {
|
||||
#endif
|
||||
dialog = ff_ass_split_dialog2(s->ass_ctx, ass);
|
||||
if (!dialog)
|
||||
return AVERROR(ENOMEM);
|
||||
@ -264,9 +252,6 @@ static int encode_frame(AVCodecContext *avctx,
|
||||
srt_style_apply(s, dialog->style);
|
||||
ff_ass_split_override_codes(cb, s, dialog->text);
|
||||
ff_ass_free_dialog(&dialog);
|
||||
#if FF_API_ASS_TIMING
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
if (!av_bprint_is_complete(&s->buffer))
|
||||
|
@ -94,42 +94,6 @@ static int ttml_encode_frame(AVCodecContext *avctx, uint8_t *buf,
|
||||
return AVERROR(EINVAL);
|
||||
}
|
||||
|
||||
#if FF_API_ASS_TIMING
|
||||
if (!strncmp(ass, "Dialogue: ", 10)) {
|
||||
int num;
|
||||
dialog = ff_ass_split_dialog(s->ass_ctx, ass, 0, &num);
|
||||
|
||||
for (; dialog && num--; dialog++) {
|
||||
if (dialog->style) {
|
||||
av_bprintf(&s->buffer, "<span region=\"");
|
||||
av_bprint_escape(&s->buffer, dialog->style, NULL,
|
||||
AV_ESCAPE_MODE_XML,
|
||||
AV_ESCAPE_FLAG_XML_DOUBLE_QUOTES);
|
||||
av_bprintf(&s->buffer, "\">");
|
||||
}
|
||||
|
||||
{
|
||||
int ret = ff_ass_split_override_codes(&ttml_callbacks, s,
|
||||
dialog->text);
|
||||
int log_level = (ret != AVERROR_INVALIDDATA ||
|
||||
avctx->err_recognition & AV_EF_EXPLODE) ?
|
||||
AV_LOG_ERROR : AV_LOG_WARNING;
|
||||
|
||||
if (ret < 0) {
|
||||
av_log(avctx, log_level,
|
||||
"Splitting received ASS dialog failed: %s\n",
|
||||
av_err2str(ret));
|
||||
|
||||
if (log_level == AV_LOG_ERROR)
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
if (dialog->style)
|
||||
av_bprintf(&s->buffer, "</span>");
|
||||
}
|
||||
} else {
|
||||
#endif
|
||||
dialog = ff_ass_split_dialog2(s->ass_ctx, ass);
|
||||
if (!dialog)
|
||||
return AVERROR(ENOMEM);
|
||||
@ -166,9 +130,6 @@ static int ttml_encode_frame(AVCodecContext *avctx, uint8_t *buf,
|
||||
|
||||
ff_ass_free_dialog(&dialog);
|
||||
}
|
||||
#if FF_API_ASS_TIMING
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
if (!av_bprint_is_complete(&s->buffer))
|
||||
|
@ -63,9 +63,6 @@
|
||||
#ifndef FF_API_VBV_DELAY
|
||||
#define FF_API_VBV_DELAY (LIBAVCODEC_VERSION_MAJOR < 59)
|
||||
#endif
|
||||
#ifndef FF_API_ASS_TIMING
|
||||
#define FF_API_ASS_TIMING (LIBAVCODEC_VERSION_MAJOR < 59)
|
||||
#endif
|
||||
#ifndef FF_API_COPY_CONTEXT
|
||||
#define FF_API_COPY_CONTEXT (LIBAVCODEC_VERSION_MAJOR < 59)
|
||||
#endif
|
||||
|
@ -171,26 +171,12 @@ static int webvtt_encode_frame(AVCodecContext *avctx,
|
||||
return AVERROR(EINVAL);
|
||||
}
|
||||
|
||||
#if FF_API_ASS_TIMING
|
||||
if (!strncmp(ass, "Dialogue: ", 10)) {
|
||||
int num;
|
||||
dialog = ff_ass_split_dialog(s->ass_ctx, ass, 0, &num);
|
||||
// TODO reindent
|
||||
for (; dialog && num--; dialog++) {
|
||||
webvtt_style_apply(s, dialog->style);
|
||||
ff_ass_split_override_codes(&webvtt_callbacks, s, dialog->text);
|
||||
}
|
||||
} else {
|
||||
#endif
|
||||
dialog = ff_ass_split_dialog2(s->ass_ctx, ass);
|
||||
if (!dialog)
|
||||
return AVERROR(ENOMEM);
|
||||
webvtt_style_apply(s, dialog->style);
|
||||
ff_ass_split_override_codes(&webvtt_callbacks, s, dialog->text);
|
||||
ff_ass_free_dialog(&dialog);
|
||||
#if FF_API_ASS_TIMING
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
if (!av_bprint_is_complete(&s->buffer))
|
||||
|
Loading…
Reference in New Issue
Block a user