Skip to content

Commit fdebfd9

Browse files
authored
fix: ps file read and write for rtsp (#356)
* fix: ps file read and write for rtsp * fix: ps file seek for rtsp test * fix: ps file seek reset for rtsp test
1 parent 4e1a89c commit fdebfd9

11 files changed

+345
-22
lines changed

librtsp/test/media/avpacket-queue.cpp

+45-10
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
#include "avpacket-queue.h"
22
#include "sys/sync.hpp"
3-
#include <queue>
3+
#include <deque>
44

55
struct avpacket_queue_t
66
{
7-
std::queue<avpacket_t*>::size_type maxsize;
8-
std::queue<avpacket_t*> q;
7+
std::deque<avpacket_t*>::size_type maxsize;
8+
std::deque<avpacket_t*> q;
9+
std::deque<avpacket_t*>::iterator it;
910
ThreadLocker locker;
1011
ThreadEvent event;
1112
};
@@ -14,6 +15,7 @@ struct avpacket_queue_t* avpacket_queue_create(int size)
1415
{
1516
struct avpacket_queue_t* q = new struct avpacket_queue_t;
1617
q->maxsize = size;
18+
q->it = q->q.begin();
1719
return q;
1820
}
1921

@@ -30,8 +32,9 @@ void avpacket_queue_clear(struct avpacket_queue_t* q)
3032
{
3133
struct avpacket_t* pkt = q->q.front();
3234
avpacket_release(pkt);
33-
q->q.pop();
35+
q->q.pop_front();
3436
}
37+
q->it = q->q.begin();
3538
}
3639

3740
int avpacket_queue_count(struct avpacket_queue_t* q)
@@ -49,10 +52,13 @@ int avpacket_queue_pop(struct avpacket_queue_t* q)
4952
return -1;
5053

5154
pkt = q->q.front();
52-
q->q.pop();
55+
q->q.pop_front();
5356
q->event.Signal();
5457
}
5558

59+
if (*q->it == pkt)
60+
q->it++;
61+
5662
avpacket_release(pkt);
5763
return 0;
5864
}
@@ -72,11 +78,11 @@ struct avpacket_t* avpacket_queue_front(struct avpacket_queue_t* q)
7278
int avpacket_queue_push(struct avpacket_queue_t* q, struct avpacket_t* pkt)
7379
{
7480
AutoThreadLocker locker(q->locker);
75-
if (q->q.size() >= q->maxsize)
81+
if (q->maxsize > 0 && q->q.size() >= q->maxsize)
7682
return -1;
7783

7884
avpacket_addref(pkt);
79-
q->q.push(pkt);
85+
q->q.push_back(pkt);
8086
q->event.Signal();
8187
return 0;
8288
}
@@ -107,22 +113,51 @@ struct avpacket_t* avpacket_queue_front_wait(struct avpacket_queue_t* q, int ms)
107113
int avpacket_queue_push_wait(struct avpacket_queue_t* q, struct avpacket_t* pkt, int ms)
108114
{
109115
q->locker.Lock();
110-
if (q->q.size() >= q->maxsize)
116+
if (q->maxsize > 0 && q->q.size() >= q->maxsize)
111117
{
112118
q->locker.Unlock();
113119
if (0 != q->event.TimeWait(ms))
114120
return -1;
115121
q->locker.Lock();
116122
}
117123

118-
if (q->q.size() >= q->maxsize)
124+
if (q->maxsize > 0 && q->q.size() >= q->maxsize)
119125
{
120126
q->locker.Unlock();
121127
return -1;
122128
}
123129

124130
avpacket_addref(pkt);
125-
q->q.push(pkt);
131+
q->q.push_back(pkt);
126132
q->locker.Unlock();
127133
return 0;
128134
}
135+
136+
struct avpacket_t* avpacket_queue_cur(struct avpacket_queue_t* q)
137+
{
138+
struct avpacket_t* pkt;
139+
AutoThreadLocker locker(q->locker);
140+
if (q->q.empty())
141+
return NULL;
142+
143+
if (q->it == q->q.end())
144+
return NULL;
145+
146+
pkt = *q->it++;
147+
avpacket_addref(pkt);
148+
return pkt;
149+
}
150+
151+
bool avpacket_queue_end(struct avpacket_queue_t* q)
152+
{
153+
AutoThreadLocker locker(q->locker);
154+
155+
return q->it == q->q.end();
156+
}
157+
158+
void avpacket_queue_reset(struct avpacket_queue_t* q)
159+
{
160+
AutoThreadLocker locker(q->locker);
161+
162+
q->it = q->q.begin();
163+
}

librtsp/test/media/avpacket-queue.h

+8
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,10 @@ int avpacket_queue_push(struct avpacket_queue_t* q, struct avpacket_t* pkt);
1919
struct avpacket_t* avpacket_queue_front_wait(struct avpacket_queue_t* q, int ms);
2020
int avpacket_queue_push_wait(struct avpacket_queue_t* q, struct avpacket_t* pkt, int ms);
2121

22+
struct avpacket_t* avpacket_queue_cur(struct avpacket_queue_t* q);
23+
bool avpacket_queue_end(struct avpacket_queue_t* q);
24+
void avpacket_queue_reset(struct avpacket_queue_t* q);
25+
2226
#if defined(__cplusplus)
2327
class AVPacketQueue
2428
{
@@ -36,6 +40,10 @@ class AVPacketQueue
3640
struct avpacket_t* Front() { return avpacket_queue_front(m_pkts); }
3741
struct avpacket_t* FrontWait(int ms) { return avpacket_queue_front_wait(m_pkts, ms); }
3842

43+
struct avpacket_t* Cur() { return avpacket_queue_cur(m_pkts); };
44+
bool End() { return avpacket_queue_end(m_pkts); };
45+
void Reset() { return avpacket_queue_reset(m_pkts); };
46+
3947
private:
4048
struct avpacket_queue_t* m_pkts;
4149
};

librtsp/test/media/h264-file-source.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@ int H264FileSource::GetSDPMedia(std::string& sdp) const
117117
if(parameters.empty())
118118
{
119119
snprintf(base64, sizeof(base64), pattern,
120-
RTP_PAYLOAD_H264, RTP_PAYLOAD_H264,RTP_PAYLOAD_H264,
120+
RTP_PAYLOAD_H264, RTP_PAYLOAD_H264, RTP_PAYLOAD_H264,
121121
(unsigned int)(it->first[1]), (unsigned int)(it->first[2]), (unsigned int)(it->first[3]));
122122
sdp = base64;
123123
}

librtsp/test/media/h265-file-source.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@ int H265FileSource::GetSDPMedia(std::string& sdp) const
119119
if(parameters.empty())
120120
{
121121
snprintf(base64, sizeof(base64), pattern,
122-
RTP_PAYLOAD_H265, RTP_PAYLOAD_H265,RTP_PAYLOAD_H265,
122+
RTP_PAYLOAD_H265, RTP_PAYLOAD_H265, RTP_PAYLOAD_H265,
123123
(unsigned int)(it->first[1]), (unsigned int)(it->first[2]), (unsigned int)(it->first[3]));
124124
sdp = base64;
125125
}

librtsp/test/media/ps-file-reader.cpp

+210
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,210 @@
1+
#include "ps-file-reader.h"
2+
#include "mpeg-util.h"
3+
#include "mpeg-types.h"
4+
#include "mov-format.h"
5+
#include "avcodecid.h"
6+
#include "rtsp-payloads.h"
7+
#include <inttypes.h>
8+
#include <map>
9+
10+
PSFileReader::PSFileReader(const char* file)
11+
:m_fp(NULL), m_pos(0), m_v_start_ts(-1), m_v_end_ts(-1), m_duration(0), m_demuxer(NULL)
12+
{
13+
memset(&m_utils, 0, sizeof(m_utils));
14+
m_fp = fopen(file, "rb");
15+
if (m_fp)
16+
{
17+
static struct ps_demuxer_notify_t notify = {
18+
PSOnStream,
19+
};
20+
m_demuxer = ps_demuxer_create(PSOnRead, this);
21+
ps_demuxer_set_notify(m_demuxer, &notify, this);
22+
23+
m_pkts = std::shared_ptr<AVPacketQueue>(new AVPacketQueue(-1));
24+
25+
Init();
26+
}
27+
}
28+
29+
PSFileReader::~PSFileReader()
30+
{
31+
avpktutil_destroy(&m_utils);
32+
33+
if (m_demuxer)
34+
{
35+
ps_demuxer_destroy(m_demuxer);
36+
m_demuxer = NULL;
37+
}
38+
39+
if (m_fp)
40+
fclose(m_fp);
41+
}
42+
43+
int PSFileReader::Init()
44+
{
45+
int n, i = 0, r = 0;
46+
while ((n = fread(m_packet + i, 1, sizeof(m_packet) - i, m_fp)) > 0)
47+
{
48+
r = ps_demuxer_input(m_demuxer, m_packet, n + i);
49+
assert(r == n + i);
50+
memmove(m_packet, m_packet + r, n + i - r);
51+
i = n + i - r;
52+
}
53+
while (i > 0 && r > 0)
54+
{
55+
r = ps_demuxer_input(m_demuxer, m_packet, i);
56+
memmove(m_packet, m_packet + r, i - r);
57+
i -= r;
58+
}
59+
60+
if (m_v_start_ts >= 0 && m_v_end_ts >= 0)
61+
{
62+
m_duration = (m_v_end_ts - m_v_start_ts) / 90;
63+
}
64+
65+
return 0;
66+
}
67+
68+
int PSFileReader::Seek(int64_t& dts)
69+
{
70+
int64_t fisrt_dts = -1;
71+
72+
while (1)
73+
{
74+
std::shared_ptr<avpacket_t> pkt(m_pkts->Cur(), avpacket_release);
75+
if (NULL == pkt)
76+
return -1;
77+
78+
if (fisrt_dts == -1)
79+
fisrt_dts = pkt->dts / 90;
80+
81+
if (dts < fisrt_dts)
82+
break;
83+
84+
if (dts >= (pkt->dts / 90))
85+
{
86+
// only audio
87+
if (m_v_start_ts < 0)
88+
return 0;
89+
90+
if (pkt->flags & AVPACKET_FLAG_KEY)
91+
return 0;
92+
}
93+
}
94+
95+
m_pkts->Reset();
96+
return 0;
97+
}
98+
99+
int PSFileReader::OnPacket(struct avpacket_t* pkt)
100+
{
101+
int ret = m_pkts->Push(pkt);
102+
m_pkts->Reset();
103+
104+
return ret;
105+
}
106+
107+
int PSFileReader::GetNextFrame(int64_t& pts, int64_t& dts, const uint8_t*& ptr, size_t& bytes, int& codecid, int& flags)
108+
{
109+
if (m_pkts->End())
110+
return -1; // file end
111+
112+
std::shared_ptr<avpacket_t> pkt(m_pkts->Cur(), avpacket_release);
113+
114+
ptr = pkt->data;
115+
bytes = pkt->size;
116+
pts = pkt->pts;
117+
dts = pkt->dts;
118+
flags = pkt->flags;
119+
codecid = pkt->stream->stream_codecid;
120+
121+
return 0;
122+
}
123+
124+
void PSFileReader::PSOnStream(void* param, int stream, int codecid, const void* extra, int bytes, int finish)
125+
{
126+
printf("stream %d, codecid: %d, finish: %s\n", stream, codecid, finish ? "true" : "false");
127+
128+
PSFileReader* self = (PSFileReader*)param;
129+
int r = avpayload_find_by_mpeg2(codecid);
130+
if (r == -1)
131+
return;
132+
133+
AVPACKET_CODEC_ID avcodecid = s_payloads[r].codecid;
134+
if (avcodecid >= AVCODEC_VIDEO_MPEG1 && avcodecid <= AVCODEC_VIDEO_SVAC)
135+
{
136+
struct avstream_t* avstream = avpktutil_addvideo(&self->m_utils, stream, avcodecid, 0, 0, extra, bytes);
137+
avstream->stream_codecid = codecid;
138+
}
139+
else if (avcodecid >= AVCODEC_AUDIO_PCM && avcodecid <= AVCODEC_AUDIO_SVAC)
140+
{
141+
struct avstream_t* avstream = avpktutil_addaudio(&self->m_utils, stream, avcodecid, 0, 0, 0, extra, bytes);
142+
avstream->stream_codecid = codecid;
143+
}
144+
}
145+
146+
inline const char* ftimestamp(int64_t t, char* buf)
147+
{
148+
if (PTS_NO_VALUE == t)
149+
{
150+
sprintf(buf, "(null)");
151+
}
152+
else
153+
{
154+
t /= 90;
155+
sprintf(buf, "%d:%02d:%02d.%03d", (int)(t / 3600000), (int)((t / 60000) % 60), (int)((t / 1000) % 60), (int)(t % 1000));
156+
}
157+
return buf;
158+
}
159+
160+
int PSFileReader::PSOnRead(void* param, int stream, int avtype, int flags, int64_t pts, int64_t dts, const void* data, size_t bytes)
161+
{
162+
PSFileReader* self = (PSFileReader*)param;
163+
static std::map<int, std::pair<int64_t, int64_t>> s_streams;
164+
static char s_pts[64], s_dts[64];
165+
166+
auto it = s_streams.find(stream);
167+
if (it == s_streams.end())
168+
it = s_streams.insert(std::make_pair(stream, std::pair<int64_t, int64_t>(pts, dts))).first;
169+
170+
if (mpeg_stream_type_audio(avtype))
171+
{
172+
//assert(0 == a_dts || dts >= a_dts);
173+
printf("[A] pts: %s(%" PRId64 "), dts: %s(%" PRId64 "), diff: %03d/%03d, size: %u\n",
174+
ftimestamp(pts, s_pts), pts, ftimestamp(dts, s_dts), dts, (int)(pts - it->second.first) / 90,
175+
(int)(dts - it->second.second) / 90, (unsigned int)bytes);
176+
}
177+
else if (mpeg_stream_type_video(avtype))
178+
{
179+
//assert(0 == v_dts || dts >= v_dts);
180+
printf("[V] pts: %s(%" PRId64 "), dts: %s(%" PRId64 "), diff: %03d/%03d, size: %u%s\n",
181+
ftimestamp(pts, s_pts), pts, ftimestamp(dts, s_dts), dts, (int)(pts - it->second.first) / 90,
182+
(int)(dts - it->second.second) / 90, (unsigned int)bytes, (flags & MPEG_FLAG_IDR_FRAME) ? " [I]" : "");
183+
184+
if (self->m_v_start_ts == -1)
185+
self->m_v_start_ts = dts < 0 ? pts : dts;
186+
self->m_v_end_ts = dts < 0 ? pts : dts;
187+
}
188+
else
189+
{
190+
//assert(0);
191+
//assert(0 == x_dts || dts >= x_dts);
192+
printf("[X] pts: %s(%" PRId64 "), dts: %s(%" PRId64 "), diff: %03d/%03d\n",
193+
ftimestamp(pts, s_pts), pts, ftimestamp(dts, s_dts), dts, (int)(pts - it->second.first), (int)(dts - it->second.second));
194+
}
195+
196+
it->second = std::make_pair(pts, dts);
197+
198+
for (int i = 0; i < self->m_utils.count; i++)
199+
{
200+
if (self->m_utils.streams[i]->stream == stream)
201+
{
202+
struct avpacket_t* pkt = NULL;
203+
avpktutil_input(&self->m_utils, self->m_utils.streams[i], data, bytes, pts, dts, flags, &pkt);
204+
self->OnPacket(pkt);
205+
return 0;
206+
}
207+
}
208+
209+
return -1;
210+
}

0 commit comments

Comments
 (0)