Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
M
mpd
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Иван Мажукин
mpd
Commits
0c2d767f
Commit
0c2d767f
authored
Aug 26, 2014
by
Max Kellermann
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
DecoderAPI: use std::chrono::duration for decoder_seek*()
For type safety and code readability.
parent
02e69703
Hide whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
110 additions
and
61 deletions
+110
-61
Makefile.am
Makefile.am
+1
-0
Chrono.hxx
src/Chrono.hxx
+66
-0
DecoderAPI.cxx
src/decoder/DecoderAPI.cxx
+4
-20
DecoderAPI.hxx
src/decoder/DecoderAPI.hxx
+3
-12
FfmpegDecoderPlugin.cxx
src/decoder/plugins/FfmpegDecoderPlugin.cxx
+11
-3
GmeDecoderPlugin.cxx
src/decoder/plugins/GmeDecoderPlugin.cxx
+1
-1
MadDecoderPlugin.cxx
src/decoder/plugins/MadDecoderPlugin.cxx
+16
-10
ModplugDecoderPlugin.cxx
src/decoder/plugins/ModplugDecoderPlugin.cxx
+1
-1
Mp4v2DecoderPlugin.cxx
src/decoder/plugins/Mp4v2DecoderPlugin.cxx
+2
-3
SidplayDecoderPlugin.cxx
src/decoder/plugins/SidplayDecoderPlugin.cxx
+2
-2
FakeDecoderAPI.cxx
test/FakeDecoderAPI.cxx
+3
-9
No files found.
Makefile.am
View file @
0c2d767f
...
...
@@ -178,6 +178,7 @@ libmpd_a_SOURCES = \
src/TagStream.cxx src/TagStream.hxx
\
src/TimePrint.cxx src/TimePrint.hxx
\
src/mixer/Volume.cxx src/mixer/Volume.hxx
\
src/Chrono.hxx
\
src/SongFilter.cxx src/SongFilter.hxx
\
src/PlaylistFile.cxx src/PlaylistFile.hxx
...
...
src/Chrono.hxx
0 → 100644
View file @
0c2d767f
/*
* Copyright (C) 2003-2014 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef MPD_CHRONO_HXX
#define MPD_CHRONO_HXX
#include <chrono>
#include <cstdint>
/**
* A time stamp within a song. Granularity is 1 millisecond and the
* maximum value is about 49 days.
*/
class
SongTime
:
public
std
::
chrono
::
duration
<
std
::
uint32_t
,
std
::
milli
>
{
typedef
std
::
chrono
::
duration
<
std
::
uint32_t
,
std
::
milli
>
Base
;
typedef
Base
::
rep
rep
;
public
:
SongTime
()
=
default
;
template
<
typename
T
>
explicit
constexpr
SongTime
(
T
t
)
:
Base
(
t
)
{}
static
constexpr
SongTime
FromS
(
unsigned
s
)
{
return
SongTime
(
rep
(
s
)
*
1000
);
}
static
constexpr
SongTime
FromS
(
float
s
)
{
return
SongTime
(
rep
(
s
*
1000
));
}
static
constexpr
SongTime
FromS
(
double
s
)
{
return
SongTime
(
rep
(
s
*
1000
));
}
static
constexpr
SongTime
FromMS
(
rep
ms
)
{
return
SongTime
(
ms
);
}
constexpr
rep
ToMS
()
const
{
return
count
();
}
constexpr
unsigned
ToScale
(
unsigned
base
)
const
{
// TODO: case to 64 bit to avoid integer overflow?
return
count
()
*
base
/
1000
;
}
};
#endif
src/decoder/DecoderAPI.cxx
View file @
0c2d767f
...
...
@@ -204,37 +204,21 @@ decoder_command_finished(Decoder &decoder)
dc
.
Unlock
();
}
double
decoder_seek_where
(
gcc_unused
Decoder
&
decoder
)
SongTime
decoder_seek_time
(
Decoder
&
decoder
)
{
const
DecoderControl
&
dc
=
decoder
.
dc
;
assert
(
dc
.
pipe
!=
nullptr
);
if
(
decoder
.
initial_seek_running
)
return
dc
.
start_ms
/
1000.
;
return
SongTime
(
dc
.
start_ms
)
;
assert
(
dc
.
command
==
DecoderCommand
::
SEEK
);
decoder
.
seeking
=
true
;
return
dc
.
seek_where
;
}
unsigned
decoder_seek_where_ms
(
Decoder
&
decoder
)
{
const
DecoderControl
&
dc
=
decoder
.
dc
;
assert
(
dc
.
pipe
!=
nullptr
);
if
(
decoder
.
initial_seek_running
)
return
dc
.
start_ms
;
assert
(
dc
.
command
==
DecoderCommand
::
SEEK
);
decoder
.
seeking
=
true
;
return
unsigned
(
dc
.
seek_where
*
1000
);
return
SongTime
::
FromS
(
dc
.
seek_where
);
}
uint64_t
...
...
src/decoder/DecoderAPI.hxx
View file @
0c2d767f
...
...
@@ -37,6 +37,7 @@
#include "AudioFormat.hxx"
#include "MixRampInfo.hxx"
#include "config/ConfigData.hxx"
#include "Chrono.hxx"
// IWYU pragma: end_exports
...
...
@@ -84,21 +85,11 @@ decoder_command_finished(Decoder &decoder);
* Call this when you have received the DecoderCommand::SEEK command.
*
* @param decoder the decoder object
* @return the destination position for the week
*/
gcc_pure
double
decoder_seek_where
(
Decoder
&
decoder
);
/**
* Call this when you have received the DecoderCommand::SEEK command.
*
* @param decoder the decoder object
* @return the destination position for the seek in milliseconds
*/
gcc_pure
unsigned
decoder_seek_
where_ms
(
Decoder
&
decoder
);
SongTime
decoder_seek_
time
(
Decoder
&
decoder
);
/**
* Call this when you have received the DecoderCommand::SEEK command.
...
...
src/decoder/plugins/FfmpegDecoderPlugin.cxx
View file @
0c2d767f
...
...
@@ -210,11 +210,19 @@ time_from_ffmpeg(int64_t t, const AVRational time_base)
/
(
double
)
1024
;
}
template
<
typename
Ratio
>
static
constexpr
AVRational
RatioToAVRational
()
{
return
{
Ratio
::
num
,
Ratio
::
den
};
}
gcc_const
static
int64_t
time_to_ffmpeg
(
double
t_ms
,
const
AVRational
time_base
)
time_to_ffmpeg
(
SongTime
t
,
const
AVRational
time_base
)
{
return
av_rescale_q
(
t_ms
,
(
AVRational
){
1
,
1000
},
return
av_rescale_q
(
t
.
count
(),
RatioToAVRational
<
SongTime
::
period
>
(),
time_base
);
}
...
...
@@ -547,7 +555,7 @@ ffmpeg_decode(Decoder &decoder, InputStream &input)
if
(
cmd
==
DecoderCommand
::
SEEK
)
{
int64_t
where
=
time_to_ffmpeg
(
decoder_seek_
where_ms
(
decoder
),
time_to_ffmpeg
(
decoder_seek_
time
(
decoder
),
av_stream
->
time_base
)
+
start_time_fallback
(
*
av_stream
);
...
...
src/decoder/plugins/GmeDecoderPlugin.cxx
View file @
0c2d767f
...
...
@@ -194,7 +194,7 @@ gme_file_decode(Decoder &decoder, Path path_fs)
cmd
=
decoder_data
(
decoder
,
nullptr
,
buf
,
sizeof
(
buf
),
0
);
if
(
cmd
==
DecoderCommand
::
SEEK
)
{
unsigned
where
=
decoder_seek_
where_ms
(
decoder
);
unsigned
where
=
decoder_seek_
time
(
decoder
).
ToMS
(
);
gme_err
=
gme_seek
(
emu
,
where
);
if
(
gme_err
!=
nullptr
)
LogWarning
(
gme_domain
,
gme_err
);
...
...
src/decoder/plugins/MadDecoderPlugin.cxx
View file @
0c2d767f
...
...
@@ -67,6 +67,13 @@ static constexpr Domain mad_domain("mad");
static
bool
gapless_playback
;
gcc_const
static
SongTime
ToSongTime
(
mad_timer_t
t
)
{
return
SongTime
::
FromMS
(
mad_timer_count
(
t
,
MAD_UNITS_MILLISECONDS
));
}
static
inline
int32_t
mad_fixed_to_24_sample
(
mad_fixed_t
sample
)
{
...
...
@@ -116,8 +123,8 @@ struct MadDecoder {
unsigned
char
input_buffer
[
READ_BUFFER_SIZE
];
int32_t
output_buffer
[
MP3_DATA_OUTPUT_BUFFER_SIZE
];
float
total_time
;
unsigned
elapsed_time
;
unsigned
seek_wher
e
;
SongTime
elapsed_time
;
SongTime
seek_tim
e
;
enum
muteframe
mute_frame
;
long
*
frame_offsets
;
mad_timer_t
*
times
;
...
...
@@ -159,7 +166,7 @@ struct MadDecoder {
bool
DecodeFirstFrame
(
Tag
**
tag
);
gcc_pure
long
TimeToFrame
(
unsigned
t
)
const
;
long
TimeToFrame
(
SongTime
t
)
const
;
void
UpdateTimerNextFrame
();
...
...
@@ -847,13 +854,12 @@ mad_decoder_total_file_time(InputStream &is)
}
long
MadDecoder
::
TimeToFrame
(
unsigned
t
)
const
MadDecoder
::
TimeToFrame
(
SongTime
t
)
const
{
unsigned
long
i
;
for
(
i
=
0
;
i
<
highest_frame
;
++
i
)
{
unsigned
frame_time
=
mad_timer_count
(
times
[
i
],
MAD_UNITS_MILLISECONDS
);
auto
frame_time
=
ToSongTime
(
times
[
i
]);
if
(
frame_time
>=
t
)
break
;
}
...
...
@@ -884,7 +890,7 @@ MadDecoder::UpdateTimerNextFrame()
timer
=
times
[
current_frame
];
current_frame
++
;
elapsed_time
=
mad_timer_count
(
timer
,
MAD_UNITS_MILLISECONDS
);
elapsed_time
=
ToSongTime
(
timer
);
}
DecoderCommand
...
...
@@ -980,7 +986,7 @@ MadDecoder::Read()
mute_frame
=
MUTEFRAME_NONE
;
break
;
case
MUTEFRAME_SEEK
:
if
(
elapsed_time
>=
seek_
wher
e
)
if
(
elapsed_time
>=
seek_
tim
e
)
mute_frame
=
MUTEFRAME_NONE
;
break
;
case
MUTEFRAME_NONE
:
...
...
@@ -989,7 +995,7 @@ MadDecoder::Read()
assert
(
input_stream
.
IsSeekable
());
unsigned
long
j
=
TimeToFrame
(
decoder_seek_
where_ms
(
*
decoder
));
TimeToFrame
(
decoder_seek_
time
(
*
decoder
));
if
(
j
<
highest_frame
)
{
if
(
Seek
(
frame_offsets
[
j
]))
{
current_frame
=
j
;
...
...
@@ -997,7 +1003,7 @@ MadDecoder::Read()
}
else
decoder_seek_error
(
*
decoder
);
}
else
{
seek_
where
=
decoder_seek_where_ms
(
*
decoder
);
seek_
time
=
decoder_seek_time
(
*
decoder
);
mute_frame
=
MUTEFRAME_SEEK
;
decoder_command_finished
(
*
decoder
);
}
...
...
src/decoder/plugins/ModplugDecoderPlugin.cxx
View file @
0c2d767f
...
...
@@ -166,7 +166,7 @@ mod_decode(Decoder &decoder, InputStream &is)
0
);
if
(
cmd
==
DecoderCommand
::
SEEK
)
{
ModPlug_Seek
(
f
,
decoder_seek_
where_ms
(
decoder
));
ModPlug_Seek
(
f
,
decoder_seek_
time
(
decoder
).
ToMS
(
));
decoder_command_finished
(
decoder
);
}
...
...
src/decoder/plugins/Mp4v2DecoderPlugin.cxx
View file @
0c2d767f
...
...
@@ -165,9 +165,8 @@ mp4_file_decode(Decoder &mpd_decoder, Path path_fs)
unsigned
int
data_length
=
0
;
if
(
cmd
==
DecoderCommand
::
SEEK
)
{
const
unsigned
offset_ms
=
decoder_seek_where_ms
(
mpd_decoder
);
const
MP4Timestamp
offset
=
(
offset_ms
*
scale
)
/
1000
;
const
MP4Timestamp
offset
=
decoder_seek_time
(
mpd_decoder
).
ToScale
(
scale
);
sample
=
MP4GetSampleIdFromTime
(
handle
,
track
,
offset
,
false
);
...
...
src/decoder/plugins/SidplayDecoderPlugin.cxx
View file @
0c2d767f
...
...
@@ -314,8 +314,8 @@ sidplay_file_decode(Decoder &decoder, Path path_fs)
if
(
cmd
==
DecoderCommand
::
SEEK
)
{
unsigned
data_time
=
player
.
time
();
unsigned
target_time
=
(
unsigned
)
(
decoder_seek_where
(
decoder
)
*
timebase
);
unsigned
target_time
=
decoder_seek_time
(
decoder
).
ToScale
(
timebase
);
/* can't rewind so return to zero and seek forward */
if
(
target_time
<
data_time
)
{
...
...
test/FakeDecoderAPI.cxx
View file @
0c2d767f
...
...
@@ -55,16 +55,10 @@ decoder_command_finished(gcc_unused Decoder &decoder)
{
}
doubl
e
decoder_seek_
wher
e
(
gcc_unused
Decoder
&
decoder
)
SongTim
e
decoder_seek_
tim
e
(
gcc_unused
Decoder
&
decoder
)
{
return
1.0
;
}
unsigned
decoder_seek_where_ms
(
gcc_unused
Decoder
&
decoder
)
{
return
1
;
return
SongTime
();
}
uint64_t
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment