mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2025-02-09 14:14:39 +02:00
fftools/ffmpeg: move subtitle helpers to ffmpeg_dec, their only user
This commit is contained in:
parent
826cfd9997
commit
6b6815b1c8
120
fftools/ffmpeg.c
120
fftools/ffmpeg.c
@ -640,126 +640,6 @@ static void print_report(int is_last_report, int64_t timer_start, int64_t cur_ti
|
|||||||
first_report = 0;
|
first_report = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int copy_av_subtitle(AVSubtitle *dst, const AVSubtitle *src)
|
|
||||||
{
|
|
||||||
int ret = AVERROR_BUG;
|
|
||||||
AVSubtitle tmp = {
|
|
||||||
.format = src->format,
|
|
||||||
.start_display_time = src->start_display_time,
|
|
||||||
.end_display_time = src->end_display_time,
|
|
||||||
.num_rects = 0,
|
|
||||||
.rects = NULL,
|
|
||||||
.pts = src->pts
|
|
||||||
};
|
|
||||||
|
|
||||||
if (!src->num_rects)
|
|
||||||
goto success;
|
|
||||||
|
|
||||||
if (!(tmp.rects = av_calloc(src->num_rects, sizeof(*tmp.rects))))
|
|
||||||
return AVERROR(ENOMEM);
|
|
||||||
|
|
||||||
for (int i = 0; i < src->num_rects; i++) {
|
|
||||||
AVSubtitleRect *src_rect = src->rects[i];
|
|
||||||
AVSubtitleRect *dst_rect;
|
|
||||||
|
|
||||||
if (!(dst_rect = tmp.rects[i] = av_mallocz(sizeof(*tmp.rects[0])))) {
|
|
||||||
ret = AVERROR(ENOMEM);
|
|
||||||
goto cleanup;
|
|
||||||
}
|
|
||||||
|
|
||||||
tmp.num_rects++;
|
|
||||||
|
|
||||||
dst_rect->type = src_rect->type;
|
|
||||||
dst_rect->flags = src_rect->flags;
|
|
||||||
|
|
||||||
dst_rect->x = src_rect->x;
|
|
||||||
dst_rect->y = src_rect->y;
|
|
||||||
dst_rect->w = src_rect->w;
|
|
||||||
dst_rect->h = src_rect->h;
|
|
||||||
dst_rect->nb_colors = src_rect->nb_colors;
|
|
||||||
|
|
||||||
if (src_rect->text)
|
|
||||||
if (!(dst_rect->text = av_strdup(src_rect->text))) {
|
|
||||||
ret = AVERROR(ENOMEM);
|
|
||||||
goto cleanup;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (src_rect->ass)
|
|
||||||
if (!(dst_rect->ass = av_strdup(src_rect->ass))) {
|
|
||||||
ret = AVERROR(ENOMEM);
|
|
||||||
goto cleanup;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int j = 0; j < 4; j++) {
|
|
||||||
// SUBTITLE_BITMAP images are special in the sense that they
|
|
||||||
// are like PAL8 images. first pointer to data, second to
|
|
||||||
// palette. This makes the size calculation match this.
|
|
||||||
size_t buf_size = src_rect->type == SUBTITLE_BITMAP && j == 1 ?
|
|
||||||
AVPALETTE_SIZE :
|
|
||||||
src_rect->h * src_rect->linesize[j];
|
|
||||||
|
|
||||||
if (!src_rect->data[j])
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (!(dst_rect->data[j] = av_memdup(src_rect->data[j], buf_size))) {
|
|
||||||
ret = AVERROR(ENOMEM);
|
|
||||||
goto cleanup;
|
|
||||||
}
|
|
||||||
dst_rect->linesize[j] = src_rect->linesize[j];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
success:
|
|
||||||
*dst = tmp;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
cleanup:
|
|
||||||
avsubtitle_free(&tmp);
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void subtitle_free(void *opaque, uint8_t *data)
|
|
||||||
{
|
|
||||||
AVSubtitle *sub = (AVSubtitle*)data;
|
|
||||||
avsubtitle_free(sub);
|
|
||||||
av_free(sub);
|
|
||||||
}
|
|
||||||
|
|
||||||
int subtitle_wrap_frame(AVFrame *frame, AVSubtitle *subtitle, int copy)
|
|
||||||
{
|
|
||||||
AVBufferRef *buf;
|
|
||||||
AVSubtitle *sub;
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
if (copy) {
|
|
||||||
sub = av_mallocz(sizeof(*sub));
|
|
||||||
ret = sub ? copy_av_subtitle(sub, subtitle) : AVERROR(ENOMEM);
|
|
||||||
if (ret < 0) {
|
|
||||||
av_freep(&sub);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
sub = av_memdup(subtitle, sizeof(*subtitle));
|
|
||||||
if (!sub)
|
|
||||||
return AVERROR(ENOMEM);
|
|
||||||
memset(subtitle, 0, sizeof(*subtitle));
|
|
||||||
}
|
|
||||||
|
|
||||||
buf = av_buffer_create((uint8_t*)sub, sizeof(*sub),
|
|
||||||
subtitle_free, NULL, 0);
|
|
||||||
if (!buf) {
|
|
||||||
avsubtitle_free(sub);
|
|
||||||
av_freep(&sub);
|
|
||||||
return AVERROR(ENOMEM);
|
|
||||||
}
|
|
||||||
|
|
||||||
frame->buf[0] = buf;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void print_stream_maps(void)
|
static void print_stream_maps(void)
|
||||||
{
|
{
|
||||||
av_log(NULL, AV_LOG_INFO, "Stream mapping:\n");
|
av_log(NULL, AV_LOG_INFO, "Stream mapping:\n");
|
||||||
|
@ -709,9 +709,6 @@ int init_simple_filtergraph(InputStream *ist, OutputStream *ost,
|
|||||||
Scheduler *sch, unsigned sch_idx_enc);
|
Scheduler *sch, unsigned sch_idx_enc);
|
||||||
int init_complex_filtergraph(FilterGraph *fg);
|
int init_complex_filtergraph(FilterGraph *fg);
|
||||||
|
|
||||||
int copy_av_subtitle(AVSubtitle *dst, const AVSubtitle *src);
|
|
||||||
int subtitle_wrap_frame(AVFrame *frame, AVSubtitle *subtitle, int copy);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get our axiliary frame data attached to the frame, allocating it
|
* Get our axiliary frame data attached to the frame, allocating it
|
||||||
* if needed.
|
* if needed.
|
||||||
|
@ -371,6 +371,126 @@ static int video_frame_process(DecoderPriv *dp, AVFrame *frame)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int copy_av_subtitle(AVSubtitle *dst, const AVSubtitle *src)
|
||||||
|
{
|
||||||
|
int ret = AVERROR_BUG;
|
||||||
|
AVSubtitle tmp = {
|
||||||
|
.format = src->format,
|
||||||
|
.start_display_time = src->start_display_time,
|
||||||
|
.end_display_time = src->end_display_time,
|
||||||
|
.num_rects = 0,
|
||||||
|
.rects = NULL,
|
||||||
|
.pts = src->pts
|
||||||
|
};
|
||||||
|
|
||||||
|
if (!src->num_rects)
|
||||||
|
goto success;
|
||||||
|
|
||||||
|
if (!(tmp.rects = av_calloc(src->num_rects, sizeof(*tmp.rects))))
|
||||||
|
return AVERROR(ENOMEM);
|
||||||
|
|
||||||
|
for (int i = 0; i < src->num_rects; i++) {
|
||||||
|
AVSubtitleRect *src_rect = src->rects[i];
|
||||||
|
AVSubtitleRect *dst_rect;
|
||||||
|
|
||||||
|
if (!(dst_rect = tmp.rects[i] = av_mallocz(sizeof(*tmp.rects[0])))) {
|
||||||
|
ret = AVERROR(ENOMEM);
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
tmp.num_rects++;
|
||||||
|
|
||||||
|
dst_rect->type = src_rect->type;
|
||||||
|
dst_rect->flags = src_rect->flags;
|
||||||
|
|
||||||
|
dst_rect->x = src_rect->x;
|
||||||
|
dst_rect->y = src_rect->y;
|
||||||
|
dst_rect->w = src_rect->w;
|
||||||
|
dst_rect->h = src_rect->h;
|
||||||
|
dst_rect->nb_colors = src_rect->nb_colors;
|
||||||
|
|
||||||
|
if (src_rect->text)
|
||||||
|
if (!(dst_rect->text = av_strdup(src_rect->text))) {
|
||||||
|
ret = AVERROR(ENOMEM);
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (src_rect->ass)
|
||||||
|
if (!(dst_rect->ass = av_strdup(src_rect->ass))) {
|
||||||
|
ret = AVERROR(ENOMEM);
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int j = 0; j < 4; j++) {
|
||||||
|
// SUBTITLE_BITMAP images are special in the sense that they
|
||||||
|
// are like PAL8 images. first pointer to data, second to
|
||||||
|
// palette. This makes the size calculation match this.
|
||||||
|
size_t buf_size = src_rect->type == SUBTITLE_BITMAP && j == 1 ?
|
||||||
|
AVPALETTE_SIZE :
|
||||||
|
src_rect->h * src_rect->linesize[j];
|
||||||
|
|
||||||
|
if (!src_rect->data[j])
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (!(dst_rect->data[j] = av_memdup(src_rect->data[j], buf_size))) {
|
||||||
|
ret = AVERROR(ENOMEM);
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
dst_rect->linesize[j] = src_rect->linesize[j];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
success:
|
||||||
|
*dst = tmp;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
cleanup:
|
||||||
|
avsubtitle_free(&tmp);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void subtitle_free(void *opaque, uint8_t *data)
|
||||||
|
{
|
||||||
|
AVSubtitle *sub = (AVSubtitle*)data;
|
||||||
|
avsubtitle_free(sub);
|
||||||
|
av_free(sub);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int subtitle_wrap_frame(AVFrame *frame, AVSubtitle *subtitle, int copy)
|
||||||
|
{
|
||||||
|
AVBufferRef *buf;
|
||||||
|
AVSubtitle *sub;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (copy) {
|
||||||
|
sub = av_mallocz(sizeof(*sub));
|
||||||
|
ret = sub ? copy_av_subtitle(sub, subtitle) : AVERROR(ENOMEM);
|
||||||
|
if (ret < 0) {
|
||||||
|
av_freep(&sub);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
sub = av_memdup(subtitle, sizeof(*subtitle));
|
||||||
|
if (!sub)
|
||||||
|
return AVERROR(ENOMEM);
|
||||||
|
memset(subtitle, 0, sizeof(*subtitle));
|
||||||
|
}
|
||||||
|
|
||||||
|
buf = av_buffer_create((uint8_t*)sub, sizeof(*sub),
|
||||||
|
subtitle_free, NULL, 0);
|
||||||
|
if (!buf) {
|
||||||
|
avsubtitle_free(sub);
|
||||||
|
av_freep(&sub);
|
||||||
|
return AVERROR(ENOMEM);
|
||||||
|
}
|
||||||
|
|
||||||
|
frame->buf[0] = buf;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int process_subtitle(DecoderPriv *dp, AVFrame *frame)
|
static int process_subtitle(DecoderPriv *dp, AVFrame *frame)
|
||||||
{
|
{
|
||||||
const AVSubtitle *subtitle = (AVSubtitle*)frame->buf[0]->data;
|
const AVSubtitle *subtitle = (AVSubtitle*)frame->buf[0]->data;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user