ffmpeg: port sub2video to AVFrame.

And re-enable the FATE test.
This commit is contained in:
Nicolas George
2013-03-10 11:51:02 +01:00
parent f185a040b0
commit f9b34b8bf9
4 changed files with 34 additions and 30 deletions

View File

@@ -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,13 @@ 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) {
av_log(ist->st->codec, AV_LOG_ERROR,
"Impossible to get a blank canvas.\n");
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 +270,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 +278,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 +480,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]);
}