stream-deploy/ZLM/3rdpart/media-server/librtsp/test/media/vod-file-source.cpp

118 lines
2.2 KiB
C++

#include "vod-file-source.h"
#include "sys/system.h"
#include <stdlib.h>
#include <string.h>
#include <assert.h>
VodFileSource::VodFileSource(std::shared_ptr<IFileReader> reader, std::shared_ptr<IListener> listener)
:m_status(STOP), m_running(true), m_speed(128), m_clock(0), m_timestamp(0), m_reader(reader), m_listener(listener)
{
thread_create(&m_thread, Worker, this);
}
VodFileSource::~VodFileSource()
{
m_running = false;
m_event.Signal();
thread_destroy(m_thread);
}
int VodFileSource::Worker(void* param)
{
VodFileSource* s = (VodFileSource*)param;
return s->Worker();
}
int VodFileSource::Worker()
{
int r = 0;
struct avpacket_t* pkt = NULL;
if (!m_reader)
return -1;
do
{
while ((m_status == STOP || m_status == PAUSE) && m_running)
m_event.Wait();
while (m_status == PLAY && 0 == r && m_running)
{
if (!pkt)
{
AutoThreadLocker locker(m_locker);
r = m_reader->Read(&pkt);
if (r <= 0)
break; // all done
r = 0; // 1 -> 0
}
uint64_t now = system_time();
uint64_t timestamp = pkt ? (0 == pkt->dts || -1 == pkt->dts ? pkt->pts : pkt->dts) : m_timestamp;
if (0 == m_clock || now < m_clock || timestamp < m_timestamp)
{
m_clock = now;
m_timestamp = timestamp;
}
int64_t diff = (int64_t)((timestamp - m_timestamp) - ((now - m_clock) * m_speed / 128));
if (diff <= 0 || m_event.TimeWait((int)(diff * 128 / m_speed)))
{
if (m_listener)
r = m_listener->OnPacket(pkt);
avpacket_release(pkt);
pkt = NULL; // reset
}
}
} while (0 == r && m_running);
avpacket_release(pkt);
return 0;
}
int VodFileSource::Play()
{
if (PLAY != m_status)
{
m_clock = 0;
m_timestamp = 0;
m_status = PLAY;
m_event.Signal();
}
return 0;
}
int VodFileSource::Pause()
{
m_status = PAUSE;
m_event.Signal();
return 0;
}
int VodFileSource::Seek(uint64_t* pos, int strategy)
{
AutoThreadLocker locker(m_locker);
return m_reader->Seek(pos, strategy);
}
int VodFileSource::GetSpeed() const
{
return m_speed;
}
int VodFileSource::SetSpeed(int speed)
{
m_speed = speed;
return 0;
}
uint64_t VodFileSource::GetPosition() const
{
return m_reader->GetPosotion();
}
uint64_t VodFileSource::GetDuration() const
{
return m_reader->GetDuration();
}