Skip to content

Commit f347ecb

Browse files
committed
fix: bitstream parse uvlc error with 0 leading zeros
1 parent 447e3b8 commit f347ecb

6 files changed

Lines changed: 94 additions & 132 deletions

File tree

libflv/include/mpeg4-bits.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,7 @@ static inline uint64_t mpeg4_bits_read_uvlc(struct mpeg4_bits_t* bits)
135135
if (leadingZeros >= 32)
136136
return (1ULL << 32) - 1;
137137

138-
value = mpeg4_bits_read_n(bits, leadingZeros);
138+
value = leadingZeros > 0 ? mpeg4_bits_read_n(bits, leadingZeros) : 0;
139139
return (1ULL << leadingZeros) - 1 + value;
140140
}
141141

libflv/test/flv-read-write-test.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,9 @@ static int flv_onmuxer(void* flv, int type, const void* data, size_t bytes, uint
1212
return flv_writer_input(flv, type, data, bytes, timestamp);
1313
}
1414

15-
static int flv_ondemuxer(void* param, int codec, const void* data, size_t bytes, uint32_t pts, uint32_t dts, int format)
15+
static int flv_ondemuxer(void* param, int codec, const void* data, size_t bytes, uint32_t pts, uint32_t dts, int flags)
1616
{
17+
printf("[%d] pts: %u, dts: %u, bytes: %u%s\n", codec, pts, dts, (unsigned int)bytes, flags?" [I]":"");
1718
flv_muxer_t* muxer = (flv_muxer_t*)param;
1819
switch (codec)
1920
{

librtp/test/mov-rtp-test.cpp

Lines changed: 48 additions & 124 deletions
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,14 @@
77
#include "aom-av1.h"
88
#include "rtp-payload.h"
99
#include "rtp-profile.h"
10-
#include "mpeg-ps.h"
11-
#include "mpeg-ts.h"
10+
#include "rtsp-muxer.h"
1211
#include <stdio.h>
1312
#include <stdlib.h>
1413
#include <string.h>
1514
#include <assert.h>
1615
#include <time.h>
1716

18-
//#define RTP_VIDEO_WITH_PS
17+
#define RTP_VIDEO_WITH_PS
1918

2019
#define RTP_LOST_PERCENT 5
2120

@@ -37,35 +36,21 @@ struct mov_rtp_test_stream_t
3736
int av;
3837
int object;
3938
int track;
40-
int psi;
39+
int mid;
4140
int64_t dts;
42-
43-
void* encoder;
44-
void* decoder;
4541
};
4642

4743
struct mov_rtp_test_t
4844
{
4945
struct mov_rtp_test_stream_t a, v;
5046

51-
struct ps_muxer_t* psenc;
52-
struct ps_demuxer_t* psdec;
47+
struct rtsp_muxer_t* muxer;
48+
int rtp_ps_pid;
5349
};
5450

5551
static unsigned char packet[8 * 1024 * 1024];
5652

57-
static void* rtp_alloc(void* /*param*/, int bytes)
58-
{
59-
static uint8_t buffer[2 * 1024 * 1024 + 4] = { 0, 0, 0, 1, };
60-
assert(bytes <= sizeof(buffer) - 4);
61-
return buffer + 4;
62-
}
63-
64-
static void rtp_free(void* /*param*/, void * /*packet*/)
65-
{
66-
}
67-
68-
static int rtp_encode_packet(void* param, const void *packet, int bytes, uint32_t timestamp, int /*flags*/)
53+
static int rtp_encode_packet(void* param, int pid, const void* data, int bytes, uint32_t timestamp, int flags)
6954
{
7055
struct mov_rtp_test_stream_t* ctx = (struct mov_rtp_test_stream_t*)param;
7156

@@ -76,41 +61,16 @@ static int rtp_encode_packet(void* param, const void *packet, int bytes, uint32_
7661
// return 0;
7762
//}
7863

79-
int r = rtp_payload_decode_input(ctx->decoder, packet, bytes);
80-
return r >= 0 ? 0 : r;
81-
}
82-
83-
static int rtp_decode_packet(void* param, const void *packet, int bytes, uint32_t timestamp, int flags)
84-
{
85-
struct mov_rtp_test_stream_t* ctx = (struct mov_rtp_test_stream_t*)param;
86-
printf("RTP Decode: [%s] timestamp: %u, bytes: %d\n", ctx->av ? "V" : "A", (unsigned int)timestamp, bytes);
87-
88-
#if defined(RTP_VIDEO_WITH_PS)
89-
if(ctx == &ctx->ctx->v)
90-
{
91-
size_t r = ps_demuxer_input(ctx->ctx->psdec, (const uint8_t*)packet, bytes);
92-
assert(r == bytes);
93-
return r;
94-
}
95-
#endif
96-
97-
return 0;
98-
}
99-
100-
static int rtp_payload_codec_create(struct mov_rtp_test_stream_t* ctx, int payload, const char* encoding, uint16_t seq, uint32_t ssrc)
101-
{
102-
struct rtp_payload_t handler1;
103-
handler1.alloc = rtp_alloc;
104-
handler1.free = rtp_free;
105-
handler1.packet = rtp_decode_packet;
106-
ctx->decoder = rtp_payload_decode_create(payload, encoding, &handler1, ctx);
107-
108-
struct rtp_payload_t handler2;
109-
handler2.alloc = rtp_alloc;
110-
handler2.free = rtp_free;
111-
handler2.packet = rtp_encode_packet;
112-
ctx->encoder = rtp_payload_encode_create(payload, encoding, seq, ssrc, &handler2, ctx);
113-
64+
//int r = rtp_payload_decode_input(ctx->decoder, packet, bytes);
65+
//return r >= 0 ? 0 : r;
66+
67+
uint8_t len[2];
68+
static FILE* fp = fopen("2.mp4.rtp", "wb");
69+
len[0] = bytes >> 8;
70+
len[1] = bytes;
71+
fwrite(len, 1, 2, fp);
72+
fwrite(data, 1, bytes, fp);
73+
fflush(fp);
11474
return 0;
11575
}
11676

@@ -154,21 +114,15 @@ static void onread(void* param, uint32_t track, const void* buffer, size_t bytes
154114
printf("[V] pts: %s, dts: %s, diff: %03d/%03d, %d%s\n", ftimestamp(pts, s_pts), ftimestamp(dts, s_dts), (int)(pts - v_pts), (int)(dts - v_dts), (int)n, flags ? " [I]" : "");
155115
v_pts = pts;
156116
v_dts = dts;
157-
#if defined(RTP_VIDEO_WITH_PS)
158-
if(MOV_OBJECT_H264 == ctx->v.object || MOV_OBJECT_HEVC == ctx->v.object)
159-
{
160-
ctx->v.dts = dts;
161-
ps_muxer_input(ctx->psenc, ctx->v.psi, (MOV_AV_FLAG_KEYFREAME&flags)?0x0001:0, pts, dts, s_packet, n);
162-
return;
163-
}
164-
#endif
165-
assert(0 == rtp_payload_encode_input(ctx->v.encoder, s_packet, n, (unsigned int)dts));
117+
assert(0 == rtsp_muxer_input(ctx->muxer, ctx->v.mid, pts, dts, s_packet, n, (MOV_AV_FLAG_KEYFREAME & flags) ? 0x0001 : 0));
166118
}
167119
else if (ctx->a.track == track)
168120
{
169121
if (MOV_OBJECT_AAC == ctx->a.object)
170122
{
171123
n = mpeg4_aac_adts_save(&s_aac, bytes, s_packet, sizeof(s_packet));
124+
memcpy(s_packet + n, buffer, bytes);
125+
n += bytes;
172126
}
173127
else if(MOV_OBJECT_OPUS == ctx->a.object)
174128
{
@@ -182,7 +136,7 @@ static void onread(void* param, uint32_t track, const void* buffer, size_t bytes
182136
printf("[A] pts: %s, dts: %s, diff: %03d/%03d, %d\n", ftimestamp(pts, s_pts), ftimestamp(dts, s_dts), (int)(pts - a_pts), (int)(dts - a_dts), (int)n);
183137
a_pts = pts;
184138
a_dts = dts;
185-
assert(0 == rtp_payload_encode_input(ctx->a.encoder, s_packet, n, (unsigned int)dts));
139+
assert(0 == rtsp_muxer_input(ctx->muxer, ctx->a.mid, pts, dts, s_packet, n, 0));
186140
}
187141
else
188142
{
@@ -200,35 +154,40 @@ static void mov_video_info(void* param, uint32_t track, uint8_t object, int /*wi
200154
if (MOV_OBJECT_H264 == object)
201155
{
202156
#if defined(RTP_VIDEO_WITH_PS)
203-
ctx->v.psi = ps_muxer_add_stream(ctx->psenc, PSI_STREAM_H264, NULL, 0);
204-
#else
205-
assert(0 == rtp_payload_codec_create(&ctx->v, 96, "H264", 0, 0));
157+
int pid = ctx->rtp_ps_pid;
158+
#else
159+
int pid = rtsp_muxer_add_payload(ctx->muxer, "RTP/AVP", 90000, 96, "H264", 0, 0, 0, extra, bytes);
206160
#endif
207-
assert(bytes == mpeg4_avc_decoder_configuration_record_load((const uint8_t*)extra, bytes, &s_avc));
161+
ctx->v.mid = rtsp_muxer_add_media(ctx->muxer, pid, RTP_PAYLOAD_H264, extra, bytes);
162+
assert(bytes >= mpeg4_avc_decoder_configuration_record_load((const uint8_t*)extra, bytes, &s_avc));
208163

209164
}
210165
else if (MOV_OBJECT_HEVC == object)
211166
{
212167
#if defined(RTP_VIDEO_WITH_PS)
213-
ctx->v.psi = ps_muxer_add_stream(ctx->psenc, PSI_STREAM_H265, NULL, 0);
214-
#else
215-
assert(0 == rtp_payload_codec_create(&ctx->v, 96, "H265", 0, 0));
168+
int pid = ctx->rtp_ps_pid;
169+
#else
170+
int pid = rtsp_muxer_add_payload(ctx->muxer, "RTP/AVP", 90000, 96, "H265", 0, 0, 0, extra, bytes);
216171
#endif
172+
ctx->v.mid = rtsp_muxer_add_media(ctx->muxer, pid, RTP_PAYLOAD_H265, extra, bytes);
217173
assert(bytes == mpeg4_hevc_decoder_configuration_record_load((const uint8_t*)extra, bytes, &s_hevc));
218174
}
219175
else if (MOV_OBJECT_AV1 == object)
220176
{
221-
assert(0 == rtp_payload_codec_create(&ctx->v, 96, "AV1", 0, 0));
177+
int pid = rtsp_muxer_add_payload(ctx->muxer, "RTP/AVP", 90000, RTP_PAYLOAD_AV1X, "AV1X", 0, 0, 0, extra, bytes);
178+
ctx->v.mid = rtsp_muxer_add_media(ctx->muxer, pid, RTP_PAYLOAD_AV1X, extra, bytes);
222179
assert(bytes == aom_av1_codec_configuration_record_load((const uint8_t*)extra, bytes, &s_av1));
223180
}
224181
else if (MOV_OBJECT_VP9 == object)
225182
{
226-
assert(0 == rtp_payload_codec_create(&ctx->v, 96, "VP9", 0, 0));
183+
int pid = rtsp_muxer_add_payload(ctx->muxer, "RTP/AVP", 90000, 96, "VP9", 0, 0, 0, extra, bytes);
184+
ctx->v.mid = rtsp_muxer_add_media(ctx->muxer, pid, RTP_PAYLOAD_VP9, extra, bytes);
227185
assert(bytes == webm_vpx_codec_configuration_record_load((const uint8_t*)extra, bytes, &s_vpx));
228186
}
229187
else if (MOV_OBJECT_VP8 == object)
230188
{
231-
assert(0 == rtp_payload_codec_create(&ctx->v, 96, "VP8", 0, 0));
189+
int pid = rtsp_muxer_add_payload(ctx->muxer, "RTP/AVP", 90000, 96, "VP8", 0, 0, 0, extra, bytes);
190+
ctx->v.mid = rtsp_muxer_add_media(ctx->muxer, pid, RTP_PAYLOAD_VP8, extra, bytes);
232191
assert(bytes == webm_vpx_codec_configuration_record_load((const uint8_t*)extra, bytes, &s_vpx));
233192
}
234193
else
@@ -237,7 +196,7 @@ static void mov_video_info(void* param, uint32_t track, uint8_t object, int /*wi
237196
}
238197
}
239198

240-
static void mov_audio_info(void* param, uint32_t track, uint8_t object, int /*channel_count*/, int /*bit_per_sample*/, int /*sample_rate*/, const void* extra, size_t bytes)
199+
static void mov_audio_info(void* param, uint32_t track, uint8_t object, int /*channel_count*/, int /*bit_per_sample*/, int sample_rate, const void* extra, size_t bytes)
241200
{
242201
struct mov_rtp_test_t* ctx = (struct mov_rtp_test_t*)param;
243202
ctx->a.track = track;
@@ -246,58 +205,35 @@ static void mov_audio_info(void* param, uint32_t track, uint8_t object, int /*ch
246205

247206
if (MOV_OBJECT_AAC == object)
248207
{
249-
assert(0 == rtp_payload_codec_create(&ctx->a, 97, "MP4A-LATM", 0, 0));
208+
#if defined(RTP_VIDEO_WITH_PS)
209+
int pid = ctx->rtp_ps_pid;
210+
#else
211+
int pid = rtsp_muxer_add_payload(ctx->muxer, "RTP/AVP", sample_rate, 97, "MP4A-LATM", 0, 0, 0, extra, bytes);
212+
#endif
213+
ctx->a.mid = rtsp_muxer_add_media(ctx->muxer, pid, RTP_PAYLOAD_LATM, extra, bytes);
250214
assert(bytes == mpeg4_aac_audio_specific_config_load((const uint8_t*)extra, bytes, &s_aac));
251215
}
252216
else if (MOV_OBJECT_OPUS == object)
253217
{
254-
assert(0 == rtp_payload_codec_create(&ctx->a, 97, "OPUS", 0, 0));
218+
int pid = rtsp_muxer_add_payload(ctx->muxer, "RTP/AVP", sample_rate, 97, "OPUS", 0, 0, 0, extra, bytes);
219+
ctx->a.mid = rtsp_muxer_add_media(ctx->muxer, pid, RTP_PAYLOAD_OPUS, extra, bytes);
255220
}
256221
else
257222
{
258223
assert(0);
259224
}
260225
}
261226

262-
static void* ps_alloc(void* /*param*/, size_t bytes)
263-
{
264-
static char s_buffer[2 * 1024 * 1024];
265-
assert(bytes <= sizeof(s_buffer));
266-
return s_buffer;
267-
}
268-
269-
static void ps_free(void* /*param*/, void* /*packet*/)
270-
{
271-
return;
272-
}
273-
274-
static int ps_write(void* param, int stream, void* packet, size_t bytes)
275-
{
276-
struct mov_rtp_test_t* ctx = (struct mov_rtp_test_t*)param;
277-
return rtp_payload_encode_input(ctx->v.encoder, packet, bytes, (unsigned int)ctx->v.dts);
278-
}
279-
280-
static int ps_onpacket(void* ps, int stream, int codecid, int flags, int64_t pts, int64_t dts, const void* data, size_t bytes)
281-
{
282-
printf("PS Decode [V] pts: %08lu, dts: %08lu, bytes: %u, %s\n", (unsigned long)pts, (unsigned long)dts, (unsigned int)bytes, flags ? " [I]" : "");
283-
return 0;
284-
}
285-
286227
void mov_rtp_test(const char* mp4)
287228
{
288229
struct mov_rtp_test_t ctx;
289230
memset(&ctx, 0, sizeof(ctx));
290231
ctx.a.ctx = &ctx;
291232
ctx.v.ctx = &ctx;
292-
233+
ctx.muxer = rtsp_muxer_create(rtp_encode_packet, &ctx);
234+
293235
#if defined(RTP_VIDEO_WITH_PS)
294-
struct ps_muxer_func_t handler;
295-
handler.alloc = ps_alloc;
296-
handler.write = ps_write;
297-
handler.free = ps_free;
298-
ctx.psenc = ps_muxer_create(&handler, &ctx);
299-
ctx.psdec = ps_demuxer_create(ps_onpacket, &ctx);
300-
assert(0 == rtp_payload_codec_create(&ctx.v, 96, "MP2P", 0, 0));
236+
ctx.rtp_ps_pid = rtsp_muxer_add_payload(ctx.muxer, "RTP/AVP", 90000, 96, "MP2P", 0, 0, 0, NULL, 0);
301237
#endif
302238

303239
FILE* fp = fopen(mp4, "rb");
@@ -312,19 +248,7 @@ void mov_rtp_test(const char* mp4)
312248
{
313249
}
314250

315-
if(ctx.a.decoder)
316-
rtp_payload_decode_destroy(ctx.a.decoder);
317-
if(ctx.a.encoder)
318-
rtp_payload_encode_destroy(ctx.a.encoder);
319-
if(ctx.v.decoder)
320-
rtp_payload_decode_destroy(ctx.v.decoder);
321-
if(ctx.v.encoder)
322-
rtp_payload_encode_destroy(ctx.v.encoder);
323-
324-
#if defined(RTP_VIDEO_WITH_PS)
325-
ps_demuxer_destroy(ctx.psdec);
326-
ps_muxer_destroy(ctx.psenc);
327-
#endif
251+
rtsp_muxer_destroy(ctx.muxer);
328252
mov_reader_destroy(mov);
329253
fclose(fp);
330254
}

librtp/test/rtp-dump-test.cpp

Lines changed: 34 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,16 @@
11
#define RTP_DEMUXER 0
22

33
#include "rtp-dump.h"
4+
extern "C" {
5+
#include "rtp-packet.h"
6+
}
47
#if RTP_DEMUXER
58
#include "rtp-demuxer.h"
69
#else
710
#include "rtsp-demuxer.h"
811
#endif
912
#include "avpkt2bs.h"
13+
#include "aom-av1.h"
1014
#include <stdio.h>
1115
#include <assert.h>
1216
#include <stdint.h>
@@ -45,13 +49,16 @@ static int rtsp_onpacket(void* param, struct avpacket_t* pkt)
4549
static int64_t s_dts[8] = { 0 };
4650
if (0 == s_dts[pkt->stream->stream])
4751
s_dts[pkt->stream->stream] = pkt->dts;
48-
printf("[%d:0x%x] pts: %" PRId64 ", dts: %" PRId64 ", cts: %" PRId64 ", diff: %" PRId64 ", bytes: %d\n", pkt->stream->stream, (unsigned int)pkt->stream->codecid, pkt->pts, pkt->dts, pkt->pts - pkt->dts, pkt->dts - s_dts[pkt->stream->stream], pkt->size);
52+
printf("[%d:0x%x] pts: %" PRId64 ", dts: %" PRId64 ", cts: %" PRId64 ", diff: %" PRId64 ", bytes: %d%s\n", pkt->stream->stream, (unsigned int)pkt->stream->codecid, pkt->pts, pkt->dts, pkt->pts - pkt->dts, pkt->dts - s_dts[pkt->stream->stream], pkt->size, (pkt->flags& AVPACKET_FLAG_KEY)?"[I]":"");
4953
s_dts[pkt->stream->stream] = pkt->dts;
5054

5155
if (avstream_type(pkt->stream) != AVSTREAM_VIDEO)
5256
return 0;
5357

5458
r = avpkt2bs_input(&ctx->bs, pkt);
59+
//struct aom_av1_t av1;
60+
//memset(&av1, 0, sizeof(av1));
61+
//aom_av1_codec_configuration_record_init(&av1, ctx->bs.ptr, r);
5562
fwrite(ctx->bs.ptr, 1, r, ctx->fp);
5663
//r = (int)fwrite(pkt->data, 1, pkt->size, ctx->fp);
5764
//assert(r == pkt->size);
@@ -76,10 +83,15 @@ void rtp_dump_test(const char* file)
7683
#else
7784
avpkt2bs_create(&ctx.bs);
7885
ctx.demuxer = rtsp_demuxer_create(0, 100, rtsp_onpacket, &ctx);
79-
//r = rtsp_demuxer_add_payload(ctx.demuxer, 90000, 96, "PS", "");
80-
r = rtsp_demuxer_add_payload(ctx.demuxer, 90000, 100, "H264", "100 profile-level-id=420028;sprop-parameter-sets=Z0IAKOkBQHsg,aM44gA==");
86+
r = rtsp_demuxer_add_payload(ctx.demuxer, 90000, 96, "H264", "");
87+
r = rtsp_demuxer_add_payload(ctx.demuxer, 90000, 100, "PS", "");
88+
r = rtsp_demuxer_add_payload(ctx.demuxer, 90000, 101, "VP9", "");
89+
r = rtsp_demuxer_add_payload(ctx.demuxer, 90000, 102, "H264", "96 profile-level-id=42e01f");
90+
r = rtsp_demuxer_add_payload(ctx.demuxer, 90000, 98, "H265", "");
91+
r = rtsp_demuxer_add_payload(ctx.demuxer, 90000, 104, "H266", "");
8192
//r = rtsp_demuxer_add_payload(ctx.demuxer, 90000, 99, "H264", "99 packetization-mode=1;profile-level-id=4D4033; sprop-parameter-sets=Z01AM5pkAeACH/4C3AQEBQAAAwPoAAB1MOhgAJ/8AAE/8i7y40MABP/gAAn/kXeXCgA=,aO44gA==");
82-
//r = rtsp_demuxer_add_payload(ctx.demuxer, 44100, 121, "MP4A-LATM", "121 config=4000242000;cpresent=0;object=2;profile-level-id=1");
93+
r = rtsp_demuxer_add_payload(ctx.demuxer, 44100, 117, "MP4A-LATM", "117 config=400024200000;cpresent=0;object=2;profile-level-id=1");
94+
r = rtsp_demuxer_add_payload(ctx.demuxer, 44100, 118, "MP4A-LATM", "118 config=400023200000;cpresent=0;object=2;profile-level-id=1");
8395
assert(0 == r);
8496
#endif
8597
while (1)
@@ -91,9 +103,26 @@ void rtp_dump_test(const char* file)
91103
#if RTP_DEMUXER
92104
r = rtp_demuxer_input(ctx.demuxer, data, r);
93105
#else
106+
107+
#if 0
108+
// RTX
109+
if ((((const uint8_t*)data)[1] & 0x7F) == 99)
110+
{
111+
struct rtp_packet_t pkt;
112+
memset(&pkt, 0, sizeof(pkt));
113+
if (0 == rtp_packet_deserialize(&pkt, data, r) && pkt.payloadlen > 2)
114+
{
115+
// overwrite rtx seq
116+
data[2] = ((const uint8_t*)pkt.payload)[0];
117+
data[3] = ((const uint8_t*)pkt.payload)[1];
118+
memmove((void*)pkt.payload, (const uint8_t*)pkt.payload + 2, (const uint8_t*)data + r - 2 - (const uint8_t*)pkt.payload);
119+
r -= 2;
120+
}
121+
}
122+
#endif
94123
r = rtsp_demuxer_input(ctx.demuxer, data, r);
95124
#endif
96-
assert(r >= 0);
125+
//assert(r >= 0);
97126
}
98127

99128
#if RTP_DEMUXER

0 commit comments

Comments
 (0)