[vlc-devel] [PATCH 2/2] demux: mock: audio and video sample lengths can be different

Thomas Guillem thomas at gllm.fr
Wed Aug 28 14:42:58 CEST 2019


The video sample length (calculated from the FPS) can be now different than the
audio sample length. This will be used by player timer tests/
---
 modules/demux/mock.c | 154 +++++++++++++++++++++++++++++++------------
 1 file changed, 112 insertions(+), 42 deletions(-)

diff --git a/modules/demux/mock.c b/modules/demux/mock.c
index 50fa6e79e8..c071026cdc 100644
--- a/modules/demux/mock.c
+++ b/modules/demux/mock.c
@@ -89,7 +89,7 @@ var_InheritFourcc(vlc_object_t *obj, const char *name)
     X(audio_format, vlc_fourcc_t, add_string, var_InheritFourcc, "u8") \
     X(audio_rate, unsigned, add_integer, var_InheritUnsigned, 44100) \
     X(audio_packetized, bool, add_bool, var_InheritBool, true) \
-    X(audio_sample_length, vlc_tick_t, add_integer, var_InheritInteger, VLC_TICK_FROM_MS(100) ) \
+    X(audio_sample_length, vlc_tick_t, add_integer, var_InheritInteger, VLC_TICK_FROM_MS(40) ) \
     X(video_track_count, ssize_t, add_integer, var_InheritSsize, 0) \
     X(video_chroma, vlc_fourcc_t, add_string, var_InheritFourcc, "I420") \
     X(video_width, unsigned, add_integer, var_InheritUnsigned, 640) \
@@ -117,7 +117,10 @@ struct demux_sys
 {
     mock_track_vector tracks;
     vlc_tick_t pts;
-    vlc_tick_t step_length;
+    vlc_tick_t audio_pts;
+    vlc_tick_t video_pts;
+    vlc_tick_t video_step_length;
+    vlc_tick_t audio_step_length;
 
     int current_title;
     size_t chapter_gap;
@@ -205,7 +208,7 @@ Control(demux_t *demux, int query, va_list args)
                 if (new_title >= sys->title_count)
                     return VLC_EGENERIC;
                 sys->current_title = new_title;
-                sys->pts = VLC_TICK_0;
+                sys->pts = sys->audio_pts = sys->video_pts = VLC_TICK_0;
                 return VLC_SUCCESS;
             }
             return VLC_EGENERIC;
@@ -215,7 +218,8 @@ Control(demux_t *demux, int query, va_list args)
                 const int seekpoint_idx = va_arg(args, int);
                 if (seekpoint_idx < sys->chapter_count)
                 {
-                    sys->pts = seekpoint_idx * sys->chapter_gap;
+                    sys->pts = sys->audio_pts = sys->video_pts =
+                        seekpoint_idx * sys->chapter_gap;
                     return VLC_SUCCESS;
                 }
             }
@@ -242,7 +246,7 @@ Control(demux_t *demux, int query, va_list args)
         case DEMUX_SET_POSITION:
             if (!sys->can_seek)
                 return VLC_EGENERIC;
-            sys->pts = va_arg(args, double) * sys->length;
+            sys->pts = sys->video_pts = sys->audio_pts = va_arg(args, double) * sys->length;
             return VLC_SUCCESS;
         case DEMUX_GET_LENGTH:
             *va_arg(args, vlc_tick_t *) = sys->length;
@@ -253,7 +257,7 @@ Control(demux_t *demux, int query, va_list args)
         case DEMUX_SET_TIME:
             if (!sys->can_seek)
                 return VLC_EGENERIC;
-            sys->pts = va_arg(args, vlc_tick_t);
+            sys->pts = sys->video_pts = sys->audio_pts = va_arg(args, vlc_tick_t);
             return VLC_SUCCESS;
         case DEMUX_GET_TITLE_INFO:
             if (sys->title_count > 0)
@@ -334,7 +338,7 @@ CreateAudioBlock(demux_t *demux, struct mock_track *track)
 {
     struct demux_sys *sys = demux->p_sys;
     const int64_t samples =
-        samples_from_vlc_tick(sys->step_length, track->fmt.audio.i_rate);
+        samples_from_vlc_tick(sys->audio_step_length, track->fmt.audio.i_rate);
     const int64_t bytes = samples / track->fmt.audio.i_frame_length
                         * track->fmt.audio.i_bytes_per_frame;
     block_t *b = block_Alloc(bytes);
@@ -382,7 +386,7 @@ CreateVideoBlock(demux_t *demux, struct mock_track *track)
     size_t block_len = 0;
     for (int i = 0; i < pic->i_planes; ++i)
         block_len += pic->p[i].i_lines * pic->p[i].i_pitch;
-    memset(pic->p[0].p_pixels, (sys->pts / VLC_TICK_FROM_MS(10)) % 255,
+    memset(pic->p[0].p_pixels, (sys->video_pts / VLC_TICK_FROM_MS(10)) % 255,
            block_len);
     return block_Init(&video->b, &cbs, pic->p[0].p_pixels, block_len);
     (void) demux;
@@ -393,7 +397,7 @@ CreateSubBlock(demux_t *demux, struct mock_track *track)
 {
     struct demux_sys *sys = demux->p_sys;
     char *text;
-    if (asprintf(&text, "subtitle @ %"PRId64, sys->pts) == -1)
+    if (asprintf(&text, "subtitle @ %"PRId64, sys->video_pts) == -1)
         return NULL;
     size_t len = strlen(text) + 1;
 
@@ -559,43 +563,108 @@ InitSubTracks(demux_t *demux, int group, size_t count)
 }
 
 static int
-Demux(demux_t *demux)
+DemuxAudio(demux_t *demux, vlc_tick_t end_pts)
 {
     struct demux_sys *sys = demux->p_sys;
 
-    if (sys->error)
-        return VLC_DEMUXER_EGENERIC;
+    while (sys->audio_pts < end_pts)
+    {
+        struct mock_track *track;
+        vlc_vector_foreach(track, &sys->tracks)
+        {
+            block_t *block;
+            switch (track->fmt.i_cat)
+            {
+                case AUDIO_ES:
+                    block = CreateAudioBlock(demux, track);
+                    break;
+                default:
+                    continue;
+            }
+            if (!block)
+                return VLC_DEMUXER_EGENERIC;
 
-    struct mock_track *track;
-    vlc_vector_foreach(track, &sys->tracks)
+            block->i_length = sys->audio_step_length;
+            block->i_pts = block->i_dts = sys->audio_pts;
+
+            int ret = es_out_Send(demux->out, track->id, block);
+            if (ret != VLC_SUCCESS)
+                return VLC_DEMUXER_EGENERIC;
+        }
+        sys->audio_pts += sys->audio_step_length; 
+    }
+    return VLC_DEMUXER_SUCCESS;
+}
+
+static int
+DemuxVideo(demux_t *demux, vlc_tick_t end_pts)
+{
+    struct demux_sys *sys = demux->p_sys;
+
+    while (sys->video_pts < end_pts)
     {
-        block_t *block;
-        switch (track->fmt.i_cat)
+        struct mock_track *track;
+        vlc_vector_foreach(track, &sys->tracks)
         {
-            case AUDIO_ES:
-                block = CreateAudioBlock(demux, track);
-                break;
-            case VIDEO_ES:
-                block = CreateVideoBlock(demux, track);
-                break;
-            case SPU_ES:
-                block = CreateSubBlock(demux, track);
-                break;
-            default:
-                vlc_assert_unreachable();
+            block_t *block;
+            switch (track->fmt.i_cat)
+            {
+                case VIDEO_ES:
+                    block = CreateVideoBlock(demux, track);
+                    break;
+                case SPU_ES:
+                    block = CreateSubBlock(demux, track);
+                    break;
+                default:
+                    continue;
+            }
+            if (!block)
+                return VLC_DEMUXER_EGENERIC;
+
+            block->i_length = sys->video_step_length;
+            block->i_pts = block->i_dts = sys->video_pts;
+
+            int ret = es_out_Send(demux->out, track->id, block);
+            if (ret != VLC_SUCCESS)
+                return VLC_DEMUXER_EGENERIC;
         }
-        if (!block)
-            return VLC_DEMUXER_EGENERIC;
-        block->i_length = sys->step_length;
-        block->i_pts = block->i_dts = sys->pts;
-        int ret = es_out_Send(demux->out, track->id, block);
-        if (ret != VLC_SUCCESS)
-            return VLC_DEMUXER_EGENERIC;
+        sys->video_pts += sys->video_step_length;
     }
-    es_out_SetPCR(demux->out, sys->pts);
-    sys->pts += sys->step_length;
+    return VLC_DEMUXER_SUCCESS;
+}
+
+static int
+Demux(demux_t *demux)
+{
+    struct demux_sys *sys = demux->p_sys;
+
+    if (sys->error)
+        return VLC_DEMUXER_EGENERIC;
+
+    if (sys->audio_track_count > 0
+     && (sys->video_track_count > 0 || sys->sub_track_count > 0))
+        sys->pts = __MIN(sys->audio_pts, sys->video_pts);
+    else if (sys->audio_track_count > 0)
+        sys->pts = sys->audio_pts;
+    else
+        sys->pts = sys->video_pts;
+
     if (sys->pts > sys->length)
         sys->pts = sys->length;
+    es_out_SetPCR(demux->out, sys->pts);
+
+    vlc_tick_t step_length = __MAX(sys->audio_step_length, sys->video_step_length);
+
+    int ret = VLC_DEMUXER_SUCCESS;
+    if (sys->audio_track_count > 0)
+        ret = DemuxAudio(demux, step_length + sys->audio_pts);
+
+    if (ret == VLC_DEMUXER_SUCCESS
+     && (sys->video_track_count > 0 || sys->sub_track_count > 0))
+        ret = DemuxVideo(demux, step_length + sys->video_pts);
+
+    if (ret != VLC_DEMUXER_SUCCESS)
+        return ret;
 
     if (sys->add_video_track_at != VLC_TICK_INVALID &&
         sys->add_video_track_at <= sys->pts)
@@ -709,13 +778,14 @@ Open(vlc_object_t *obj)
             goto error;
     }
 
-    if (sys->video_track_count > 0)
-        sys->step_length = VLC_TICK_FROM_SEC(1) * sys->video_frame_rate_base
-                         / sys->video_frame_rate;
-    else
-        sys->step_length = sys->audio_sample_length;
+    sys->video_step_length = sys->video_track_count > 0 ?
+                             VLC_TICK_FROM_SEC(1) * sys->video_frame_rate_base
+                             / sys->video_frame_rate : 0;
+
+    sys->audio_step_length = sys->audio_track_count > 0 ?
+                             sys->audio_sample_length : 0;
 
-    sys->pts = VLC_TICK_0;
+    sys->pts = sys->audio_pts = sys->video_pts = VLC_TICK_0;
     sys->current_title = 0;
     sys->chapter_gap = sys->chapter_count > 0 ?
                        (sys->length / sys->chapter_count) : 0;
-- 
2.20.1



More information about the vlc-devel mailing list