[FFmpeg-devel] [PATCH 3/3] ffmpeg: respect AV_CODEC_CAP_SINGLE_SUB_RECT
Ridley Combs
rcombs at rcombs.me
Tue Feb 21 10:09:12 EET 2023
> On Feb 21, 2023, at 01:45, Nicolas George <george at nsup.org> wrote:
>
> rcombs (12023-02-20):
>> Fixes ASS output when multiple rects are present.
>> ---
>> fftools/ffmpeg.c | 28 ++++++++++++++++++----------
>> 1 file changed, 18 insertions(+), 10 deletions(-)
>
> Does this not belong to the framework?
I don't see a way it could be? avcodec_encode_subtitle takes an AVSubtitle and writes to a single caller-provided buffer; there's no way for it to generate multiple outputs for a single input.
>
>>
>> diff --git a/fftools/ffmpeg.c b/fftools/ffmpeg.c
>> index 9884e0c6c6..23eac52438 100644
>> --- a/fftools/ffmpeg.c
>> +++ b/fftools/ffmpeg.c
>> @@ -1021,6 +1021,7 @@ static void do_subtitle_out(OutputFile *of,
>> AVCodecContext *enc;
>> AVPacket *pkt = ost->pkt;
>> int64_t pts;
>> + int single_rect;
>>
>> if (sub->pts == AV_NOPTS_VALUE) {
>> av_log(ost, AV_LOG_ERROR, "Subtitle packets must have a pts\n");
>> @@ -1031,11 +1032,15 @@ static void do_subtitle_out(OutputFile *of,
>>
>> enc = ost->enc_ctx;
>>
>> + single_rect = !!(enc->codec->capabilities & AV_CODEC_CAP_SINGLE_SUB_RECT);
>> +
>> /* Note: DVB subtitle need one packet to draw them and one other
>> packet to clear them */
>> /* XXX: signal it in the codec context ? */
>> if (enc->codec_id == AV_CODEC_ID_DVB_SUBTITLE)
>> nb = 2;
>> + else if (single_rect)
>> + nb = FFMAX(sub->num_rects, 1);
>> else
>> nb = 1;
>>
>> @@ -1044,7 +1049,7 @@ static void do_subtitle_out(OutputFile *of,
>> if (output_files[ost->file_index]->start_time != AV_NOPTS_VALUE)
>> pts -= output_files[ost->file_index]->start_time;
>> for (i = 0; i < nb; i++) {
>> - unsigned save_num_rects = sub->num_rects;
>> + AVSubtitle local_sub = *sub;
>>
>> if (!check_recording_time(ost, pts, AV_TIME_BASE_Q))
>> return;
>> @@ -1053,19 +1058,22 @@ static void do_subtitle_out(OutputFile *of,
>> if (ret < 0)
>> report_and_exit(AVERROR(ENOMEM));
>>
>> - sub->pts = pts;
>> + local_sub.pts = pts;
>> // start_display_time is required to be 0
>> - sub->pts += av_rescale_q(sub->start_display_time, (AVRational){ 1, 1000 }, AV_TIME_BASE_Q);
>> - sub->end_display_time -= sub->start_display_time;
>> - sub->start_display_time = 0;
>> - if (i == 1)
>> - sub->num_rects = 0;
>> + local_sub.pts += av_rescale_q(sub->start_display_time, (AVRational){ 1, 1000 }, AV_TIME_BASE_Q);
>> + local_sub.end_display_time -= sub->start_display_time;
>> + local_sub.start_display_time = 0;
>> +
>> + if (enc->codec_id == AV_CODEC_ID_DVB_SUBTITLE && i == 1)
>> + local_sub.num_rects = 0;
>> + else if (single_rect && sub->num_rects > 0) {
>> + local_sub.num_rects = 1;
>> + local_sub.rects += i;
>> + }
>>
>> ost->frames_encoded++;
>>
>> - subtitle_out_size = avcodec_encode_subtitle(enc, pkt->data, pkt->size, sub);
>> - if (i == 1)
>> - sub->num_rects = save_num_rects;
>> + subtitle_out_size = avcodec_encode_subtitle(enc, pkt->data, pkt->size, &local_sub);
>> if (subtitle_out_size < 0) {
>> av_log(ost, AV_LOG_FATAL, "Subtitle encoding failed\n");
>> exit_program(1);
>
> Regards,
>
> --
> Nicolas George
> _______________________________________________
> ffmpeg-devel mailing list
> ffmpeg-devel at ffmpeg.org <mailto:ffmpeg-devel at ffmpeg.org>
> https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
>
> To unsubscribe, visit link above, or email
> ffmpeg-devel-request at ffmpeg.org <mailto:ffmpeg-devel-request at ffmpeg.org> with subject "unsubscribe".
More information about the ffmpeg-devel
mailing list