diff mbox series

[FFmpeg-devel,1/1] Output .lrc with correct end time

Message ID CAEb_=DHXL8OWD8j3_BzoDJPGiL_iGYQox209GGG-TpLJt=N-gQ@mail.gmail.com
State New
Headers show
Series Output .lrc with correct end time | expand

Checks

Context Check Description
yinshiyou/configure_loongarch64 warning Failed to apply patch

Commit Message

Gu Song Oct. 23, 2024, 7:50 a.m. UTC
When input .sbv or .srt and output .lrc, line end time is incorrect as
condition below:
$ cat > input.sbv << EOF
0:00:00.000,0:00:03.000
Title

0:00:10.000,0:00:15.000
Line 1
EOF

$ ffmpeg -i input.sbv out.lrc

$ cat out.lrc
[re:Lavf61.7.100]
[ve:61.7.100]

[00:00.00]Title
[00:10.00]Line 1

'Title' should show only 3 seconds, not 10 seconds
Expected out.lrc should be:
========
[00:00.00]Title
[00:03.00]
[00:10.00]Line 1
========
Fix "Generate .lrc from .sbv or .srt have end time error on some lines"
https://trac.ffmpeg.org/ticket/11253
---
 libavformat/lrcenc.c | 22 +++++++++++++++++++++-
 1 file changed, 21 insertions(+), 1 deletion(-)

                 size = next_line - line;
@@ -103,6 +115,14 @@ static int lrc_write_packet(AVFormatContext *s,
AVPacket *pkt)
                        "Subtitle starts with '[', may cause problems
with LRC format.\n");
             }

+            /* Verify whether a blank line is required between the two lines */
+            if (te < pkt->pts && pkt->pts - te >= 10) {
+                avio_printf(s->pb, "[%02"PRIu64":%02"PRIu64".%02"PRIu64"]\n",
+                        (FFABS64U(te) / 6000),
+                        ((FFABS64U(te) / 100) % 60),
+                        (FFABS64U(te) % 100));
+            }
+
             /* Offset feature of LRC can easily make pts negative,
              * we just output it directly and let the player drop it. */
             avio_write(s->pb, "[-", 1 + (pkt->pts < 0));
@@ -129,7 +149,7 @@ const FFOutputFormat ff_lrc_muxer = {
     .p.audio_codec    = AV_CODEC_ID_NONE,
     .p.subtitle_codec = AV_CODEC_ID_SUBRIP,
     .flags_internal   = FF_OFMT_FLAG_MAX_ONE_OF_EACH,
-    .priv_data_size = 0,
+    .priv_data_size = sizeof(LrcContext),
     .write_header   = lrc_write_header,
     .write_packet   = lrc_write_packet,
 };
--
2.47.0

Comments

Michael Niedermayer Oct. 23, 2024, 11:23 a.m. UTC | #1
On Wed, Oct 23, 2024 at 03:50:54PM +0800, Lu Renjia wrote:
[...]
> @@ -91,6 +101,8 @@ static int lrc_write_packet(AVFormatContext *s,
> AVPacket *pkt)
>          while(line) {

patch corrupted by a linebreak:

Applying: Output .lrc with correct end time
error: corrupt patch at line 38
error: could not build fake ancestor
Patch failed at 0001 Output .lrc with correct end time

thx

[...]
Gu Song Oct. 23, 2024, 12:13 p.m. UTC | #2
I put the patch in the attachment of the email, please get it out of
the attachment and try again.

Michael Niedermayer <michael@niedermayer.cc> 于2024年10月23日周三 19:24写道:
>
> On Wed, Oct 23, 2024 at 03:50:54PM +0800, Lu Renjia wrote:
> [...]
> > @@ -91,6 +101,8 @@ static int lrc_write_packet(AVFormatContext *s,
> > AVPacket *pkt)
> >          while(line) {
>
> patch corrupted by a linebreak:
>
> Applying: Output .lrc with correct end time
> error: corrupt patch at line 38
> error: could not build fake ancestor
> Patch failed at 0001 Output .lrc with correct end time
>
> thx
>
> [...]
>
> --
> Michael     GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB
>
> No human being will ever know the Truth, for even if they happen to say it
> by chance, they would not even known they had done so. -- Xenophanes
> _______________________________________________
> ffmpeg-devel mailing list
> ffmpeg-devel@ffmpeg.org
> https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
>
> To unsubscribe, visit link above, or email
> ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
diff mbox series

Patch

diff --git a/libavformat/lrcenc.c b/libavformat/lrcenc.c
index 7570529..37380cf 100644
--- a/libavformat/lrcenc.c
+++ b/libavformat/lrcenc.c
@@ -33,10 +33,19 @@ 
 #include "libavutil/log.h"
 #include "libavutil/macros.h"

+typedef struct LrcContext {
+    /**
+     * Look ahead timestamp pts + duration
+     */
+    int64_t lookahead_te;
+} LrcContext;
+
 static int lrc_write_header(AVFormatContext *s)
 {
     const AVDictionaryEntry *metadata_item;
+    LrcContext *lc = s->priv_data;

+    lc->lookahead_te = 0;
     if(s->streams[0]->codecpar->codec_id != AV_CODEC_ID_SUBRIP &&
        s->streams[0]->codecpar->codec_id != AV_CODEC_ID_TEXT) {
         av_log(s, AV_LOG_ERROR, "Unsupported subtitle codec: %s\n",
@@ -77,6 +86,7 @@  static int lrc_write_header(AVFormatContext *s)

 static int lrc_write_packet(AVFormatContext *s, AVPacket *pkt)
 {
+    LrcContext *lc = s->priv_data;
     if(pkt->pts != AV_NOPTS_VALUE) {
         const uint8_t *line = pkt->data;
         const uint8_t *end  = pkt->data + pkt->size;
@@ -91,6 +101,8 @@  static int lrc_write_packet(AVFormatContext *s,
AVPacket *pkt)
         while(line) {
             const uint8_t *next_line = memchr(line, '\n', end - line);
             size_t size = end - line;
+            const int64_t te = lc->lookahead_te;
+            lc->lookahead_te = pkt->pts + pkt->duration;

             if (next_line) {