fix: avpacket queue iterator invalid

This commit is contained in:
ireader
2024-11-02 11:45:41 +08:00
parent 27ff66fdee
commit 53254e9750
5 changed files with 422 additions and 472 deletions

View File

@@ -93,6 +93,7 @@ enum EPSI_STREAM_TYPE
PSI_STREAM_AUDIO_DTS = 0x8a, // ffmpeg/libavformat/mpegts.h
PSI_STREAM_VIDEO_DIRAC = 0xd1, // ffmpeg/libavformat/mpegts.h
PSI_STREAM_VIDEO_AVS3 = 0xd4, // ffmpeg/libavformat/mpegts.h
PSI_STREAM_AUDIO_AVS3 = 0xd5, // avs3-p6
PSI_STREAM_VIDEO_VC1 = 0xea, // ffmpeg/libavformat/mpegts.h
PSI_STREAM_VIDEO_SVAC = 0x80, // GBT 25724-2010 SVAC(2014)
PSI_STREAM_AUDIO_SVAC = 0x9B, // GBT 25724-2010 SVAC(2014)

View File

@@ -1,163 +1,128 @@
#include "avpacket-queue.h"
#include "sys/sync.hpp"
#include <deque>
struct avpacket_queue_t
{
std::deque<avpacket_t*>::size_type maxsize;
std::deque<avpacket_t*> q;
std::deque<avpacket_t*>::iterator it;
ThreadLocker locker;
ThreadEvent event;
};
struct avpacket_queue_t* avpacket_queue_create(int size)
{
struct avpacket_queue_t* q = new struct avpacket_queue_t;
q->maxsize = size;
q->it = q->q.begin();
return q;
}
void avpacket_queue_destroy(struct avpacket_queue_t* q)
{
avpacket_queue_clear(q);
delete q;
}
void avpacket_queue_clear(struct avpacket_queue_t* q)
{
AutoThreadLocker locker(q->locker);
while (!q->q.empty())
{
struct avpacket_t* pkt = q->q.front();
avpacket_release(pkt);
q->q.pop_front();
}
q->it = q->q.begin();
}
int avpacket_queue_count(struct avpacket_queue_t* q)
{
AutoThreadLocker locker(q->locker);
return (int)q->q.size();
}
int avpacket_queue_pop(struct avpacket_queue_t* q)
{
struct avpacket_t* pkt;
{
AutoThreadLocker locker(q->locker);
if (q->q.empty())
return -1;
pkt = q->q.front();
q->q.pop_front();
q->event.Signal();
}
if (*q->it == pkt)
q->it++;
avpacket_release(pkt);
return 0;
}
struct avpacket_t* avpacket_queue_front(struct avpacket_queue_t* q)
{
struct avpacket_t* pkt;
AutoThreadLocker locker(q->locker);
if (q->q.empty())
return NULL;
pkt = q->q.front();
avpacket_addref(pkt);
return pkt;
}
int avpacket_queue_push(struct avpacket_queue_t* q, struct avpacket_t* pkt)
{
AutoThreadLocker locker(q->locker);
if (q->maxsize > 0 && q->q.size() >= q->maxsize)
return -1;
avpacket_addref(pkt);
q->q.push_back(pkt);
q->event.Signal();
return 0;
}
struct avpacket_t* avpacket_queue_front_wait(struct avpacket_queue_t* q, int ms)
{
q->locker.Lock();
if (q->q.empty())
{
q->locker.Unlock();
if (0 != q->event.TimeWait(ms))
return NULL;
q->locker.Lock();
}
if (q->q.empty())
{
q->locker.Unlock();
return NULL;
}
struct avpacket_t* pkt = q->q.front();
avpacket_addref(pkt);
q->locker.Unlock();
return pkt;
}
int avpacket_queue_push_wait(struct avpacket_queue_t* q, struct avpacket_t* pkt, int ms)
{
q->locker.Lock();
if (q->maxsize > 0 && q->q.size() >= q->maxsize)
{
q->locker.Unlock();
if (0 != q->event.TimeWait(ms))
return -1;
q->locker.Lock();
}
if (q->maxsize > 0 && q->q.size() >= q->maxsize)
{
q->locker.Unlock();
return -1;
}
avpacket_addref(pkt);
q->q.push_back(pkt);
q->locker.Unlock();
return 0;
}
struct avpacket_t* avpacket_queue_cur(struct avpacket_queue_t* q)
{
struct avpacket_t* pkt;
AutoThreadLocker locker(q->locker);
if (q->q.empty())
return NULL;
if (q->it == q->q.end())
return NULL;
pkt = *q->it++;
avpacket_addref(pkt);
return pkt;
}
bool avpacket_queue_end(struct avpacket_queue_t* q)
{
AutoThreadLocker locker(q->locker);
return q->it == q->q.end();
}
void avpacket_queue_reset(struct avpacket_queue_t* q)
{
AutoThreadLocker locker(q->locker);
q->it = q->q.begin();
}
#include "avpacket-queue.h"
#include "sys/sync.hpp"
#include <queue>
struct avpacket_queue_t
{
std::queue<avpacket_t*>::size_type maxsize;
std::queue<avpacket_t*> q;
ThreadLocker locker;
ThreadEvent event;
};
struct avpacket_queue_t* avpacket_queue_create(int size)
{
struct avpacket_queue_t* q = new struct avpacket_queue_t;
q->maxsize = size;
return q;
}
void avpacket_queue_destroy(struct avpacket_queue_t* q)
{
avpacket_queue_clear(q);
delete q;
}
void avpacket_queue_clear(struct avpacket_queue_t* q)
{
AutoThreadLocker locker(q->locker);
while (!q->q.empty())
{
struct avpacket_t* pkt = q->q.front();
avpacket_release(pkt);
q->q.pop();
}
}
int avpacket_queue_count(struct avpacket_queue_t* q)
{
AutoThreadLocker locker(q->locker);
return (int)q->q.size();
}
int avpacket_queue_pop(struct avpacket_queue_t* q)
{
struct avpacket_t* pkt;
{
AutoThreadLocker locker(q->locker);
if (q->q.empty())
return -1;
pkt = q->q.front();
q->q.pop();
q->event.Signal();
}
avpacket_release(pkt);
return 0;
}
struct avpacket_t* avpacket_queue_front(struct avpacket_queue_t* q)
{
struct avpacket_t* pkt;
AutoThreadLocker locker(q->locker);
if (q->q.empty())
return NULL;
pkt = q->q.front();
avpacket_addref(pkt);
return pkt;
}
int avpacket_queue_push(struct avpacket_queue_t* q, struct avpacket_t* pkt)
{
AutoThreadLocker locker(q->locker);
if (q->q.size() >= q->maxsize)
return -1;
avpacket_addref(pkt);
q->q.push(pkt);
q->event.Signal();
return 0;
}
struct avpacket_t* avpacket_queue_front_wait(struct avpacket_queue_t* q, int ms)
{
q->locker.Lock();
if (q->q.empty())
{
q->locker.Unlock();
if (0 != q->event.TimeWait(ms))
return NULL;
q->locker.Lock();
}
if (q->q.empty())
{
q->locker.Unlock();
return NULL;
}
struct avpacket_t* pkt = q->q.front();
avpacket_addref(pkt);
q->locker.Unlock();
return pkt;
}
int avpacket_queue_push_wait(struct avpacket_queue_t* q, struct avpacket_t* pkt, int ms)
{
q->locker.Lock();
if (q->q.size() >= q->maxsize)
{
q->locker.Unlock();
if (0 != q->event.TimeWait(ms))
return -1;
q->locker.Lock();
}
if (q->q.size() >= q->maxsize)
{
q->locker.Unlock();
return -1;
}
avpacket_addref(pkt);
q->q.push(pkt);
q->locker.Unlock();
return 0;
}

View File

@@ -1,51 +1,43 @@
#ifndef _avpacket_queue_h_
#define _avpacket_queue_h_
#include "avpacket.h"
#include <stdint.h>
struct avpacket_queue_t;
struct avpacket_queue_t* avpacket_queue_create(int size);
void avpacket_queue_destroy(struct avpacket_queue_t* q);
void avpacket_queue_clear(struct avpacket_queue_t* q);
int avpacket_queue_count(struct avpacket_queue_t* q);
int avpacket_queue_pop(struct avpacket_queue_t* q);
struct avpacket_t* avpacket_queue_front(struct avpacket_queue_t* q);
int avpacket_queue_push(struct avpacket_queue_t* q, struct avpacket_t* pkt);
struct avpacket_t* avpacket_queue_front_wait(struct avpacket_queue_t* q, int ms);
int avpacket_queue_push_wait(struct avpacket_queue_t* q, struct avpacket_t* pkt, int ms);
struct avpacket_t* avpacket_queue_cur(struct avpacket_queue_t* q);
bool avpacket_queue_end(struct avpacket_queue_t* q);
void avpacket_queue_reset(struct avpacket_queue_t* q);
#if defined(__cplusplus)
class AVPacketQueue
{
public:
AVPacketQueue(int size) :m_pkts(avpacket_queue_create(size)) {}
~AVPacketQueue() { if (m_pkts) avpacket_queue_destroy(m_pkts); }
public:
void Clear() { avpacket_queue_clear(m_pkts); }
int Count() const { return avpacket_queue_count(m_pkts); }
int Pop() { return avpacket_queue_pop(m_pkts); }
int Push(struct avpacket_t* pkt) { return avpacket_queue_push(m_pkts, pkt); }
int PushWait(struct avpacket_t* pkt, int ms) { return avpacket_queue_push_wait(m_pkts, pkt, ms); }
struct avpacket_t* Front() { return avpacket_queue_front(m_pkts); }
struct avpacket_t* FrontWait(int ms) { return avpacket_queue_front_wait(m_pkts, ms); }
struct avpacket_t* Cur() { return avpacket_queue_cur(m_pkts); };
bool End() { return avpacket_queue_end(m_pkts); };
void Reset() { return avpacket_queue_reset(m_pkts); };
private:
struct avpacket_queue_t* m_pkts;
};
#endif
#endif /* !_avpacket_queue_h_*/
#ifndef _avpacket_queue_h_
#define _avpacket_queue_h_
#include "avpacket.h"
#include <stdint.h>
struct avpacket_queue_t;
struct avpacket_queue_t* avpacket_queue_create(int size);
void avpacket_queue_destroy(struct avpacket_queue_t* q);
void avpacket_queue_clear(struct avpacket_queue_t* q);
int avpacket_queue_count(struct avpacket_queue_t* q);
int avpacket_queue_pop(struct avpacket_queue_t* q);
struct avpacket_t* avpacket_queue_front(struct avpacket_queue_t* q);
int avpacket_queue_push(struct avpacket_queue_t* q, struct avpacket_t* pkt);
struct avpacket_t* avpacket_queue_front_wait(struct avpacket_queue_t* q, int ms);
int avpacket_queue_push_wait(struct avpacket_queue_t* q, struct avpacket_t* pkt, int ms);
#if defined(__cplusplus)
class AVPacketQueue
{
public:
AVPacketQueue(int size) :m_pkts(avpacket_queue_create(size)) {}
~AVPacketQueue() { if (m_pkts) avpacket_queue_destroy(m_pkts); }
public:
void Clear() { avpacket_queue_clear(m_pkts); }
int Count() const { return avpacket_queue_count(m_pkts); }
int Pop() { return avpacket_queue_pop(m_pkts); }
int Push(struct avpacket_t* pkt) { return avpacket_queue_push(m_pkts, pkt); }
int PushWait(struct avpacket_t* pkt, int ms) { return avpacket_queue_push_wait(m_pkts, pkt, ms); }
struct avpacket_t* Front() { return avpacket_queue_front(m_pkts); }
struct avpacket_t* FrontWait(int ms) { return avpacket_queue_front_wait(m_pkts, ms); }
private:
struct avpacket_queue_t* m_pkts;
};
#endif
#endif /* !_avpacket_queue_h_*/

View File

@@ -1,210 +1,203 @@
#include "ps-file-reader.h"
#include "mpeg-util.h"
#include "mpeg-types.h"
#include "mov-format.h"
#include "avcodecid.h"
#include "rtsp-payloads.h"
#include <inttypes.h>
#include <map>
PSFileReader::PSFileReader(const char* file)
:m_fp(NULL), m_pos(0), m_v_start_ts(-1), m_v_end_ts(-1), m_v_codecid(-1), m_a_codecid(-1), m_duration(0), m_demuxer(NULL)
{
memset(&m_utils, 0, sizeof(m_utils));
m_fp = fopen(file, "rb");
if (m_fp)
{
static struct ps_demuxer_notify_t notify = {
PSOnStream,
};
m_demuxer = ps_demuxer_create(PSOnRead, this);
ps_demuxer_set_notify(m_demuxer, &notify, this);
m_pkts = std::shared_ptr<AVPacketQueue>(new AVPacketQueue(-1));
Init();
}
}
PSFileReader::~PSFileReader()
{
avpktutil_destroy(&m_utils);
if (m_demuxer)
{
ps_demuxer_destroy(m_demuxer);
m_demuxer = NULL;
}
if (m_fp)
fclose(m_fp);
}
int PSFileReader::Init()
{
int n, i = 0, r = 0;
while ((n = fread(m_packet + i, 1, sizeof(m_packet) - i, m_fp)) > 0)
{
r = ps_demuxer_input(m_demuxer, m_packet, n + i);
assert(r == n + i);
memmove(m_packet, m_packet + r, n + i - r);
i = n + i - r;
}
while (i > 0 && r > 0)
{
r = ps_demuxer_input(m_demuxer, m_packet, i);
memmove(m_packet, m_packet + r, i - r);
i -= r;
}
if (m_v_start_ts >= 0 && m_v_end_ts >= 0)
{
m_duration = (m_v_end_ts - m_v_start_ts) / 90;
}
return 0;
}
int PSFileReader::Seek(int64_t& dts)
{
int64_t fisrt_dts = -1;
while (1)
{
std::shared_ptr<avpacket_t> pkt(m_pkts->Cur(), avpacket_release);
if (NULL == pkt)
return -1;
if (fisrt_dts == -1)
fisrt_dts = pkt->dts / 90;
if (dts < fisrt_dts)
break;
if (dts >= (pkt->dts / 90))
{
// only audio
if (m_v_start_ts < 0)
return 0;
if (pkt->flags & AVPACKET_FLAG_KEY)
return 0;
}
}
m_pkts->Reset();
return 0;
}
int PSFileReader::OnPacket(struct avpacket_t* pkt)
{
int ret = m_pkts->Push(pkt);
m_pkts->Reset();
return ret;
}
int PSFileReader::GetNextFrame(int64_t& pts, int64_t& dts, const uint8_t*& ptr, size_t& bytes, int& codecid, int& flags)
{
if (m_pkts->End())
return -1; // file end
std::shared_ptr<avpacket_t> pkt(m_pkts->Cur(), avpacket_release);
ptr = pkt->data;
bytes = pkt->size;
pts = pkt->pts;
dts = pkt->dts;
flags = pkt->flags;
codecid = (pkt->stream->codecid >= AVCODEC_VIDEO_MPEG1 && pkt->stream->codecid <= AVCODEC_VIDEO_SVAC) ? m_v_codecid : m_a_codecid;
return 0;
}
void PSFileReader::PSOnStream(void* param, int stream, int codecid, const void* extra, int bytes, int finish)
{
printf("stream %d, codecid: %d, finish: %s\n", stream, codecid, finish ? "true" : "false");
PSFileReader* self = (PSFileReader*)param;
int r = avpayload_find_by_mpeg2(codecid);
if (r == -1)
return;
AVPACKET_CODEC_ID avcodecid = s_payloads[r].codecid;
if (avcodecid >= AVCODEC_VIDEO_MPEG1 && avcodecid <= AVCODEC_VIDEO_SVAC)
{
avpktutil_addvideo(&self->m_utils, stream, avcodecid, 0, 0, extra, bytes);
self->m_v_codecid = codecid;
}
else if (avcodecid >= AVCODEC_AUDIO_PCM && avcodecid <= AVCODEC_AUDIO_SVAC)
{
avpktutil_addaudio(&self->m_utils, stream, avcodecid, 0, 0, 0, extra, bytes);
self->m_a_codecid = codecid;
}
}
inline const char* ftimestamp(int64_t t, char* buf)
{
if (PTS_NO_VALUE == t)
{
sprintf(buf, "(null)");
}
else
{
t /= 90;
sprintf(buf, "%d:%02d:%02d.%03d", (int)(t / 3600000), (int)((t / 60000) % 60), (int)((t / 1000) % 60), (int)(t % 1000));
}
return buf;
}
int PSFileReader::PSOnRead(void* param, int stream, int avtype, int flags, int64_t pts, int64_t dts, const void* data, size_t bytes)
{
PSFileReader* self = (PSFileReader*)param;
static std::map<int, std::pair<int64_t, int64_t>> s_streams;
static char s_pts[64], s_dts[64];
auto it = s_streams.find(stream);
if (it == s_streams.end())
it = s_streams.insert(std::make_pair(stream, std::pair<int64_t, int64_t>(pts, dts))).first;
if (mpeg_stream_type_audio(avtype))
{
//assert(0 == a_dts || dts >= a_dts);
printf("[A] pts: %s(%" PRId64 "), dts: %s(%" PRId64 "), diff: %03d/%03d, size: %u\n",
ftimestamp(pts, s_pts), pts, ftimestamp(dts, s_dts), dts, (int)(pts - it->second.first) / 90,
(int)(dts - it->second.second) / 90, (unsigned int)bytes);
}
else if (mpeg_stream_type_video(avtype))
{
//assert(0 == v_dts || dts >= v_dts);
printf("[V] pts: %s(%" PRId64 "), dts: %s(%" PRId64 "), diff: %03d/%03d, size: %u%s\n",
ftimestamp(pts, s_pts), pts, ftimestamp(dts, s_dts), dts, (int)(pts - it->second.first) / 90,
(int)(dts - it->second.second) / 90, (unsigned int)bytes, (flags & MPEG_FLAG_IDR_FRAME) ? " [I]" : "");
if (self->m_v_start_ts == -1)
self->m_v_start_ts = dts < 0 ? pts : dts;
self->m_v_end_ts = dts < 0 ? pts : dts;
}
else
{
//assert(0);
//assert(0 == x_dts || dts >= x_dts);
printf("[X] pts: %s(%" PRId64 "), dts: %s(%" PRId64 "), diff: %03d/%03d\n",
ftimestamp(pts, s_pts), pts, ftimestamp(dts, s_dts), dts, (int)(pts - it->second.first), (int)(dts - it->second.second));
}
it->second = std::make_pair(pts, dts);
for (int i = 0; i < self->m_utils.count; i++)
{
if (self->m_utils.streams[i]->stream == stream)
{
struct avpacket_t* pkt = NULL;
avpktutil_input(&self->m_utils, self->m_utils.streams[i], data, bytes, pts, dts, flags, &pkt);
self->OnPacket(pkt);
return 0;
}
}
return -1;
}
#include "ps-file-reader.h"
#include "mpeg-util.h"
#include "mpeg-types.h"
#include "mov-format.h"
#include "avcodecid.h"
#include "rtsp-payloads.h"
#include <inttypes.h>
#include <map>
PSFileReader::PSFileReader(const char* file)
:m_pos(0), m_v_start_ts(-1), m_v_end_ts(-1), m_v_codecid(-1), m_a_codecid(-1), m_duration(0)
{
memset(&m_utils, 0, sizeof(m_utils));
Init(file);
m_it = m_pkts.begin();
}
PSFileReader::~PSFileReader()
{
avpktutil_destroy(&m_utils);
for (auto it = m_pkts.begin(); it != m_pkts.end(); ++it)
{
auto pkt = *it;
avpacket_release(pkt);
}
m_pkts.clear();
}
int PSFileReader::Init(const char* file)
{
FILE* fp = fopen(file, "rb");
if (!fp)
return -1;
static struct ps_demuxer_notify_t notify = {
PSOnStream,
};
ps_demuxer_t* demuxer = ps_demuxer_create(PSOnRead, this);
ps_demuxer_set_notify(demuxer, &notify, this);
int n, i = 0, r = 0;
while ((n = fread(m_packet + i, 1, sizeof(m_packet) - i, fp)) > 0)
{
r = ps_demuxer_input(demuxer, m_packet, n + i);
assert(r == n + i);
memmove(m_packet, m_packet + r, n + i - r);
i = n + i - r;
}
while (i > 0 && r > 0)
{
r = ps_demuxer_input(demuxer, m_packet, i);
memmove(m_packet, m_packet + r, i - r);
i -= r;
}
if (m_v_start_ts >= 0 && m_v_end_ts >= 0)
{
m_duration = (m_v_end_ts - m_v_start_ts) / 90;
}
ps_demuxer_destroy(demuxer);
fclose(fp);
return 0;
}
int PSFileReader::Seek(int64_t& dts)
{
int64_t fisrt_dts = -1;
for(m_it = m_pkts.begin(); m_it != m_pkts.end(); ++m_it)
{
auto pkt = *m_it;
if (fisrt_dts == -1)
fisrt_dts = pkt->dts / 90;
if (dts < fisrt_dts)
break;
if (dts >= (pkt->dts / 90))
{
// only audio
if (m_v_start_ts < 0)
return 0;
if (pkt->flags & AVPACKET_FLAG_KEY)
return 0;
}
}
return -1;
}
int PSFileReader::OnPacket(struct avpacket_t* pkt)
{
m_pkts.push_back(pkt);
return 0;
}
int PSFileReader::GetNextFrame(int64_t& pts, int64_t& dts, const uint8_t*& ptr, size_t& bytes, int& codecid, int& flags)
{
if (m_it == m_pkts.end())
return -1; // file end
ptr = (*m_it)->data;
bytes = (*m_it)->size;
pts = (*m_it)->pts;
dts = (*m_it)->dts;
flags = (*m_it)->flags;
codecid = ((*m_it)->stream->codecid >= AVCODEC_VIDEO_MPEG1 && (*m_it)->stream->codecid <= AVCODEC_VIDEO_SVAC) ? m_v_codecid : m_a_codecid;
++m_it;
return 0;
}
void PSFileReader::PSOnStream(void* param, int stream, int codecid, const void* extra, int bytes, int finish)
{
printf("stream %d, codecid: %d, finish: %s\n", stream, codecid, finish ? "true" : "false");
PSFileReader* self = (PSFileReader*)param;
int r = avpayload_find_by_mpeg2(codecid);
if (r == -1)
return;
AVPACKET_CODEC_ID avcodecid = s_payloads[r].codecid;
if (avcodecid >= AVCODEC_VIDEO_MPEG1 && avcodecid <= AVCODEC_VIDEO_SVAC)
{
avpktutil_addvideo(&self->m_utils, stream, avcodecid, 0, 0, extra, bytes);
self->m_v_codecid = codecid;
}
else if (avcodecid >= AVCODEC_AUDIO_PCM && avcodecid <= AVCODEC_AUDIO_SVAC)
{
avpktutil_addaudio(&self->m_utils, stream, avcodecid, 0, 0, 0, extra, bytes);
self->m_a_codecid = codecid;
}
}
inline const char* ftimestamp(int64_t t, char* buf)
{
if (PTS_NO_VALUE == t)
{
sprintf(buf, "(null)");
}
else
{
t /= 90;
sprintf(buf, "%d:%02d:%02d.%03d", (int)(t / 3600000), (int)((t / 60000) % 60), (int)((t / 1000) % 60), (int)(t % 1000));
}
return buf;
}
int PSFileReader::PSOnRead(void* param, int stream, int avtype, int flags, int64_t pts, int64_t dts, const void* data, size_t bytes)
{
PSFileReader* self = (PSFileReader*)param;
static std::map<int, std::pair<int64_t, int64_t>> s_streams;
static char s_pts[64], s_dts[64];
auto it = s_streams.find(stream);
if (it == s_streams.end())
it = s_streams.insert(std::make_pair(stream, std::pair<int64_t, int64_t>(pts, dts))).first;
if (mpeg_stream_type_audio(avtype))
{
//assert(0 == a_dts || dts >= a_dts);
printf("[A] pts: %s(%" PRId64 "), dts: %s(%" PRId64 "), diff: %03d/%03d, size: %u\n",
ftimestamp(pts, s_pts), pts, ftimestamp(dts, s_dts), dts, (int)(pts - it->second.first) / 90,
(int)(dts - it->second.second) / 90, (unsigned int)bytes);
}
else if (mpeg_stream_type_video(avtype))
{
//assert(0 == v_dts || dts >= v_dts);
printf("[V] pts: %s(%" PRId64 "), dts: %s(%" PRId64 "), diff: %03d/%03d, size: %u%s\n",
ftimestamp(pts, s_pts), pts, ftimestamp(dts, s_dts), dts, (int)(pts - it->second.first) / 90,
(int)(dts - it->second.second) / 90, (unsigned int)bytes, (flags & MPEG_FLAG_IDR_FRAME) ? " [I]" : "");
if (self->m_v_start_ts == -1)
self->m_v_start_ts = dts < 0 ? pts : dts;
self->m_v_end_ts = dts < 0 ? pts : dts;
}
else
{
//assert(0);
//assert(0 == x_dts || dts >= x_dts);
printf("[X] pts: %s(%" PRId64 "), dts: %s(%" PRId64 "), diff: %03d/%03d\n",
ftimestamp(pts, s_pts), pts, ftimestamp(dts, s_dts), dts, (int)(pts - it->second.first), (int)(dts - it->second.second));
}
it->second = std::make_pair(pts, dts);
for (int i = 0; i < self->m_utils.count; i++)
{
if (self->m_utils.streams[i]->stream == stream)
{
struct avpacket_t* pkt = NULL;
avpktutil_input(&self->m_utils, self->m_utils.streams[i], data, bytes, pts, dts, flags, &pkt);
self->OnPacket(pkt);
return 0;
}
}
return -1;
}

View File

@@ -1,48 +1,47 @@
#ifndef _ps_file_reader_h_
#define _ps_file_reader_h_
#include "vod-file-source.h"
#include "mpeg-ps.h"
#include "avpktutil.h"
#include <string>
#include <stdio.h>
#include <stdint.h>
class PSFileReader : std::enable_shared_from_this<PSFileReader>
{
public:
PSFileReader(const char* file);
virtual ~PSFileReader();
public:
virtual int OnPacket(struct avpacket_t* pkt);
int GetDuration(int64_t& duration) const { duration = m_duration; return 0; }
int GetNextFrame(int64_t& pts, int64_t& dts, const uint8_t*& ptr, size_t& bytes, int& codecid, int& flags);
int Seek(int64_t& dts);
private:
int Init();
static void PSOnStream(void* param, int stream, int codecid, const void* extra, int bytes, int finish);
static int PSOnRead(void* param, int stream, int avtype, int flags, int64_t pts, int64_t dts, const void* data, size_t bytes);
public:
int64_t m_v_start_ts;
int64_t m_v_end_ts;
int m_v_codecid;
int m_a_codecid;
private:
FILE* m_fp;
int64_t m_pos;
int64_t m_duration;
ps_demuxer_t* m_demuxer;
struct avpacket_t** m_pkt;
struct avpktutil_t m_utils;
uint8_t m_packet[2 * 1024 * 1024];
std::shared_ptr<AVPacketQueue> m_pkts;
};
#endif /* !_ps_file_reader_h_ */
#ifndef _ps_file_reader_h_
#define _ps_file_reader_h_
#include "vod-file-source.h"
#include "mpeg-ps.h"
#include "avpktutil.h"
#include <vector>
#include <string>
#include <stdio.h>
#include <stdint.h>
class PSFileReader : std::enable_shared_from_this<PSFileReader>
{
public:
PSFileReader(const char* file);
virtual ~PSFileReader();
public:
virtual int OnPacket(struct avpacket_t* pkt);
int GetDuration(int64_t& duration) const { duration = m_duration; return 0; }
int GetNextFrame(int64_t& pts, int64_t& dts, const uint8_t*& ptr, size_t& bytes, int& codecid, int& flags);
int Seek(int64_t& dts);
private:
int Init(const char* file);
static void PSOnStream(void* param, int stream, int codecid, const void* extra, int bytes, int finish);
static int PSOnRead(void* param, int stream, int avtype, int flags, int64_t pts, int64_t dts, const void* data, size_t bytes);
public:
int64_t m_v_start_ts;
int64_t m_v_end_ts;
int m_v_codecid;
int m_a_codecid;
private:
int64_t m_pos;
int64_t m_duration;
struct avpktutil_t m_utils;
uint8_t m_packet[2 * 1024 * 1024];
std::vector<avpacket_t*> m_pkts;
std::vector<avpacket_t*>::iterator m_it;
};
#endif /* !_ps_file_reader_h_ */