118 lines
2.2 KiB
C++
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();
|
|
}
|