diff mbox series

[FFmpeg-devel] avformat/dvdvideodec: Fix duration logic with 1 chapter and validate chapter range

Message ID 20240627030546.143368-1-marth64@proxyid.net
State New
Headers show
Series [FFmpeg-devel] avformat/dvdvideodec: Fix duration logic with 1 chapter and validate chapter range | expand

Checks

Context Check Description
yinshiyou/make_loongarch64 success Make finished
yinshiyou/make_fate_loongarch64 success Make fate finished
andriy/make_x86 success Make finished
andriy/make_fate_x86 success Make fate finished

Commit Message

Marth64 June 27, 2024, 3:05 a.m. UTC
Chapters and duration are calculated together in dvdvideo demuxer.
Previous chapter calculation logic treated extraction of 1 chapter
using chapter_start and chapter_end switches incorrectly, returning
the duration of the entire title instead of just the segment.

Fix the logic so that it calculates and returns the duration of the
chapter segment instead. Additionally, validate that chapter_end
exceeds chapter_start (except in the special case of 0).

Signed-off-by: Marth64 <marth64@proxyid.net>
---
 libavformat/dvdvideodec.c | 15 ++++++++++++---
 1 file changed, 12 insertions(+), 3 deletions(-)
diff mbox series

Patch

diff --git a/libavformat/dvdvideodec.c b/libavformat/dvdvideodec.c
index 8326595e1b..e7132725b7 100644
--- a/libavformat/dvdvideodec.c
+++ b/libavformat/dvdvideodec.c
@@ -865,8 +865,7 @@  static int dvdvideo_chapters_setup_simple(AVFormatContext *s)
     int chapter_end = c->opt_chapter_end > 0 ? c->opt_chapter_end : c->play_state.pgc_nb_pg_est - 1;
 
     /* dvdnav_describe_title_chapters() describes PGs rather than PTTs, so validate our range */
-    if (chapter_start == chapter_end                ||
-        c->play_state.pgc_nb_pg_est == 1            ||
+    if (c->play_state.pgc_nb_pg_est == 1            ||
         chapter_start > c->play_state.pgc_nb_pg_est ||
         chapter_end > c->play_state.pgc_nb_pg_est) {
 
@@ -878,8 +877,11 @@  static int dvdvideo_chapters_setup_simple(AVFormatContext *s)
     for (int i = chapter_start - 1; i < chapter_end; i++) {
         uint64_t time_effective = c->play_state.pgc_pg_times_est[i] - c->play_state.nav_pts;
 
-        if (!avpriv_new_chapter(s, i, DVDVIDEO_TIME_BASE_Q, time_prev, time_effective, NULL))
+        if (chapter_start != chapter_end &&
+            !avpriv_new_chapter(s, i, DVDVIDEO_TIME_BASE_Q, time_prev, time_effective, NULL)) {
+
             return AVERROR(ENOMEM);
+        }
 
         time_prev = time_effective;
         total_duration = time_effective;
@@ -1548,6 +1550,13 @@  static int dvdvideo_read_header(AVFormatContext *s)
         return 0;
     }
 
+    if (c->opt_chapter_end != 0 && c->opt_chapter_start > c->opt_chapter_end) {
+        av_log(s, AV_LOG_ERROR, "Chapter (PTT) range [%d, %d] is invalid\n",
+                                c->opt_chapter_start, c->opt_chapter_end);
+
+        return AVERROR(EINVAL);
+    }
+
     if (c->opt_title == 0) {
         av_log(s, AV_LOG_INFO, "Defaulting to title #1. "
                                "This is not always the main feature, validation suggested.\n");