[FFmpeg-devel] [PATCH] ffmpeg: port sub2video to AVFrame.
Nicolas George
nicolas.george at normalesup.org
Sun Mar 10 11:54:07 CET 2013
And re-enable the FATE test.
Signed-off-by: Nicolas George <nicolas.george at normalesup.org>
---
ffmpeg.c | 41 ++++++++++++++++++++++++++---------------
ffmpeg.h | 2 +-
ffmpeg_filter.c | 16 +++-------------
tests/fate/ffmpeg.mak | 2 +-
4 files changed, 31 insertions(+), 30 deletions(-)
Note: I intend to push this one at the same time:
http://ffmpeg.org/pipermail/ffmpeg-devel/2013-February/139782.html
if nobody objects.
Note 2: all the AV_BUFFERSRC_FLAG_ need to be repared: I am on it now.
diff --git a/ffmpeg.c b/ffmpeg.c
index 33d5783..039f957 100644
--- a/ffmpeg.c
+++ b/ffmpeg.c
@@ -168,7 +168,20 @@ static int restore_tty;
This is a temporary solution until libavfilter gets real subtitles support.
*/
+static int sub2video_get_blank_frame(InputStream *ist)
+{
+ int ret;
+ AVFrame *frame = ist->sub2video.frame;
+ av_frame_unref(frame);
+ ist->sub2video.frame->width = ist->sub2video.w;
+ ist->sub2video.frame->height = ist->sub2video.h;
+ ist->sub2video.frame->format = AV_PIX_FMT_RGB32;
+ if ((ret = av_frame_get_buffer(frame, 32)) < 0)
+ return ret;
+ memset(frame->data[0], 0, frame->height * frame->linesize[0]);
+ return 0;
+}
static void sub2video_copy_rect(uint8_t *dst, int dst_linesize, int w, int h,
AVSubtitleRect *r)
@@ -201,28 +214,25 @@ static void sub2video_copy_rect(uint8_t *dst, int dst_linesize, int w, int h,
static void sub2video_push_ref(InputStream *ist, int64_t pts)
{
- AVFilterBufferRef *ref = ist->sub2video.ref;
+ AVFrame *frame = ist->sub2video.frame;
int i;
- ist->sub2video.last_pts = ref->pts = pts;
+ av_assert1(frame->data[0]);
+ ist->sub2video.last_pts = frame->pts = pts;
for (i = 0; i < ist->nb_filters; i++)
- av_buffersrc_add_ref(ist->filters[i]->filter,
- avfilter_ref_buffer(ref, ~0),
- AV_BUFFERSRC_FLAG_NO_CHECK_FORMAT |
- AV_BUFFERSRC_FLAG_NO_COPY |
- AV_BUFFERSRC_FLAG_PUSH);
+ av_buffersrc_write_frame(ist->filters[i]->filter, frame);
}
static void sub2video_update(InputStream *ist, AVSubtitle *sub)
{
int w = ist->sub2video.w, h = ist->sub2video.h;
- AVFilterBufferRef *ref = ist->sub2video.ref;
+ AVFrame *frame = ist->sub2video.frame;
int8_t *dst;
int dst_linesize;
int num_rects, i;
int64_t pts, end_pts;
- if (!ref)
+ if (!frame)
return;
if (sub) {
pts = av_rescale_q(sub->pts + sub->start_display_time * 1000,
@@ -235,9 +245,10 @@ static void sub2video_update(InputStream *ist, AVSubtitle *sub)
end_pts = INT64_MAX;
num_rects = 0;
}
- dst = ref->data [0];
- dst_linesize = ref->linesize[0];
- memset(dst, 0, h * dst_linesize);
+ if (sub2video_get_blank_frame(ist) < 0)
+ return;
+ dst = frame->data [0];
+ dst_linesize = frame->linesize[0];
for (i = 0; i < num_rects; i++)
sub2video_copy_rect(dst, dst_linesize, w, h, sub->rects[i]);
sub2video_push_ref(ist, pts);
@@ -256,7 +267,7 @@ static void sub2video_heartbeat(InputStream *ist, int64_t pts)
(possibly overlay) is desperately waiting for a subtitle frame. */
for (i = 0; i < infile->nb_streams; i++) {
InputStream *ist2 = input_streams[infile->ist_index + i];
- if (!ist2->sub2video.ref)
+ if (!ist2->sub2video.frame)
continue;
/* subtitles seem to be usually muxed ahead of other streams;
if not, substracting a larger time here is necessary */
@@ -264,7 +275,7 @@ static void sub2video_heartbeat(InputStream *ist, int64_t pts)
/* do not send the heartbeat frame if the subtitle is already ahead */
if (pts2 <= ist2->sub2video.last_pts)
continue;
- if (pts2 >= ist2->sub2video.end_pts)
+ if (pts2 >= ist2->sub2video.end_pts || !ist2->sub2video.frame->data[0])
sub2video_update(ist2, NULL);
for (j = 0, nb_reqs = 0; j < ist2->nb_filters; j++)
nb_reqs += av_buffersrc_get_nb_failed_requests(ist2->filters[j]->filter);
@@ -466,7 +477,7 @@ static void exit_program(void)
av_dict_free(&input_streams[i]->opts);
free_buffer_pool(&input_streams[i]->buffer_pool);
avsubtitle_free(&input_streams[i]->prev_sub.subtitle);
- avfilter_unref_bufferp(&input_streams[i]->sub2video.ref);
+ avcodec_free_frame(&input_streams[i]->sub2video.frame);
av_freep(&input_streams[i]->filters);
av_freep(&input_streams[i]);
}
diff --git a/ffmpeg.h b/ffmpeg.h
index d7046fd..a04913e 100644
--- a/ffmpeg.h
+++ b/ffmpeg.h
@@ -255,7 +255,7 @@ typedef struct InputStream {
struct sub2video {
int64_t last_pts;
int64_t end_pts;
- AVFilterBufferRef *ref;
+ AVFrame *frame;
int w, h;
} sub2video;
diff --git a/ffmpeg_filter.c b/ffmpeg_filter.c
index bdf4363..1c30961 100644
--- a/ffmpeg_filter.c
+++ b/ffmpeg_filter.c
@@ -501,9 +501,7 @@ int configure_output_filter(FilterGraph *fg, OutputFilter *ofilter, AVFilterInOu
static int sub2video_prepare(InputStream *ist)
{
AVFormatContext *avf = input_files[ist->file_index]->ctx;
- int i, ret, w, h;
- uint8_t *image[4];
- int linesize[4];
+ int i, w, h;
/* Compute the size of the canvas for the subtitles stream.
If the subtitles codec has set a size, use it. Otherwise use the
@@ -530,17 +528,9 @@ static int sub2video_prepare(InputStream *ist)
palettes for all rectangles are identical or compatible */
ist->resample_pix_fmt = ist->st->codec->pix_fmt = AV_PIX_FMT_RGB32;
- ret = av_image_alloc(image, linesize, w, h, AV_PIX_FMT_RGB32, 32);
- if (ret < 0)
- return ret;
- memset(image[0], 0, h * linesize[0]);
- ist->sub2video.ref = avfilter_get_video_buffer_ref_from_arrays(
- image, linesize, AV_PERM_READ | AV_PERM_PRESERVE,
- w, h, AV_PIX_FMT_RGB32);
- if (!ist->sub2video.ref) {
- av_free(image[0]);
+ ist->sub2video.frame = av_frame_alloc();
+ if (!ist->sub2video.frame)
return AVERROR(ENOMEM);
- }
return 0;
}
diff --git a/tests/fate/ffmpeg.mak b/tests/fate/ffmpeg.mak
index a39b013..cc0e22a 100644
--- a/tests/fate/ffmpeg.mak
+++ b/tests/fate/ffmpeg.mak
@@ -22,7 +22,7 @@ fate-force_key_frames: CMD = enc_dec \
avi "-c mpeg4 -g 240 -qscale 10 -force_key_frames 0.5,0:00:01.5" \
framecrc "" "" "-skip_frame nokey"
-#FATE_SAMPLES_FFMPEG-$(call ALLYES, VOBSUB_DEMUXER DVDSUB_DECODER AVFILTER OVERLAY_FILTER DVDSUB_ENCODER) += fate-sub2video
+FATE_SAMPLES_FFMPEG-$(call ALLYES, VOBSUB_DEMUXER DVDSUB_DECODER AVFILTER OVERLAY_FILTER DVDSUB_ENCODER) += fate-sub2video
fate-sub2video: tests/data/vsynth2.yuv
fate-sub2video: CMD = framecrc \
-f rawvideo -r 5 -s 352x288 -pix_fmt yuv420p -i tests/data/vsynth2.yuv \
--
1.7.10.4
More information about the ffmpeg-devel
mailing list