demux: add moving average helper

This commit is contained in:
Francois Cartegnie 2018-08-01 11:44:38 +02:00
parent 033710cec3
commit 4f8d222038
1 changed files with 100 additions and 0 deletions

100
modules/demux/moving_avg.h Normal file
View File

@ -0,0 +1,100 @@
/*****************************************************************************
* moving_avg.h: Moving average helper
*****************************************************************************
* Copyright © 2018 VideoLabs, VideoLAN, VLC authors
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser 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 VLC_MOVING_AVG_H
#define VLC_MOVING_AVG_H
#ifndef MVA_PACKETS
#define MVA_PACKETS 6
#endif
struct mva_packet_s
{
vlc_tick_t duration;
vlc_tick_t dts;
vlc_tick_t diff;
};
struct moving_average_s
{
struct mva_packet_s packets[MVA_PACKETS];
unsigned i_packet;
};
static void mva_init(struct moving_average_s *m)
{
m->i_packet = 0;
}
static vlc_tick_t mva_get(const struct moving_average_s *m);
static void mva_add(struct moving_average_s *m,
vlc_tick_t dts, vlc_tick_t duration)
{
m->packets[m->i_packet % MVA_PACKETS].dts = dts;
m->packets[m->i_packet % MVA_PACKETS].duration = duration;
m->packets[m->i_packet % MVA_PACKETS].diff = duration; /* will erase, last one */
m->i_packet++;
}
static vlc_tick_t mva_get(const struct moving_average_s *m)
{
unsigned start;
const struct mva_packet_s *min = NULL, *max = NULL;
if(likely(m->i_packet >= MVA_PACKETS))
{
start = m->i_packet - MVA_PACKETS;
for(unsigned i = start; i < m->i_packet; i++)
{
if(!min || m->packets[i % MVA_PACKETS].diff < min->diff)
min = &m->packets[i % MVA_PACKETS];
if(!max || m->packets[i % MVA_PACKETS].diff > max->diff)
max = &m->packets[i % MVA_PACKETS];
}
}
else start = 0;
unsigned count = 0;
vlc_tick_t avgdiff = 0;
for(unsigned i = start; i < m->i_packet; i++)
{
if(&m->packets[i % MVA_PACKETS] == min ||
&m->packets[i % MVA_PACKETS] == max)
continue;
avgdiff += m->packets[i % MVA_PACKETS].diff;
count++;
}
return count ? avgdiff / count : 0;
}
static struct mva_packet_s * mva_getLastPacket(struct moving_average_s *m)
{
return m->i_packet > 0 ? &m->packets[(m->i_packet - 1) % MVA_PACKETS] : NULL;
}
static vlc_tick_t mva_getLastDTS(struct moving_average_s *m)
{
struct mva_packet_s *p = mva_getLastPacket(m);
return p ? p->dts : 0;
}
#endif