[FFmpeg-devel] [PATCH] ffmpeg: insert bitmap subtitles as video in filters.
Stefano Sabatini
stefasab at gmail.com
Wed Aug 1 22:30:16 CEST 2012
On date Wednesday 2012-08-01 16:06:26 +0200, Nicolas George encoded:
> With this feature, it becomes possible to perform commonly
> requested tasks, such as hardcoding bitmap subtitles.
>
> This will be reverted once libavfilter has proper support
> for subtitles. All the changes have the string "sub2video"
> in them, it makes it easy to spot the parts.
>
> Signed-off-by: Nicolas George <nicolas.george at normalesup.org>
> ---
> Changelog | 1 +
> doc/ffmpeg.texi | 16 +++++
> ffmpeg.c | 174 +++++++++++++++++++++++++++++++++++++++++++++++++++++--
> 3 files changed, 187 insertions(+), 4 deletions(-)
>
>
> Updated according to Stefano's remarks.
[...]
> +static void sub2video_heartbeat(InputStream *ist, int64_t pts)
> +{
> + InputFile *infile = input_files[ist->file_index];
> + int i, j, nb_reqs;
> + int64_t pts2;
> +
> + /* When a frame is read from a file, examine all sub2video streams in
> + the same file and send the sub2video frame again. Otherwise, decoded
> + video frames could be accumulating in the filter graph while a filter
> + (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)
> + continue;
> + /* subtitles seem to be usually muxed ahead of other streams;
> + if not, substracting a reasonable time here is necessary */
> + pts2 = av_rescale_q(pts, ist->st->time_base, ist2->st->time_base);
> + /* do not send the heartbeat frame if the subtitle is already ahead */
> + if (pts2 <= ist2->sub2video.last_pts)
> + continue;
> + for (j = 0, nb_reqs = 0; j < ist2->nb_filters; j++)
> + nb_reqs += av_buffersrc_get_nb_failed_requests(ist2->filters[j]->filter);
> + if (nb_reqs)
> + sub2video_push_ref(ist2, pts2);
I suppose that means that the frames are pushed only if thery were
previously requested on any of the buffersrc sources connected to the
stream, but could not have been provided.
> + }
[...]
> @@ -2633,13 +2794,16 @@ static int transcode_subtitles(InputStream *ist, AVPacket *pkt, int *got_output)
> AVSubtitle subtitle;
> int i, ret = avcodec_decode_subtitle2(ist->st->codec,
> &subtitle, got_output, pkt);
> - if (ret < 0)
> - return ret;
> - if (!*got_output)
> + if (ret < 0 || !*got_output) {
> + if (!pkt->size)
> + sub2video_flush(ist);
> return ret;
> + }
>
> rate_emu_sleep(ist);
>
> + sub2video_update(ist, &subtitle, pkt->pts);
> +
> for (i = 0; i < nb_output_streams; i++) {
> OutputStream *ost = output_streams[i];
>
> @@ -3844,6 +4008,8 @@ static int transcode(void)
> }
> }
>
> + sub2video_heartbeat(ist, pkt.pts);
Should we call this function only for video packets?
[...]
I couldn't spot any apparent error in the logic, so it is fine to me
if reasonably tested and works.
Thanks for the nice "hack".
--
FFmpeg = Frightening and Forgiving Muttering Practical EnGraver
More information about the ffmpeg-devel
mailing list