[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