@@ -28,7 +28,7 @@ extern "C" {
2828// - Stream ID: 1 byte
2929// - PES packet length: 2 bytes
3030// - Optional PES header fields
31- std::vector<uint8_t > createBasicPesVideoHeader (uint8_t streamId, bool withPts = false ) {
31+ std::vector<uint8_t > createBasicPesVideoHeader (uint8_t streamId, bool withPts = false , uint16_t pesLength = 0 ) {
3232 std::vector<uint8_t > data;
3333
3434 // Start code prefix
@@ -40,8 +40,8 @@ std::vector<uint8_t> createBasicPesVideoHeader(uint8_t streamId, bool withPts =
4040 data.push_back (streamId);
4141
4242 // PES packet length (0 = unspecified)
43- data.push_back (0x00 );
44- data.push_back (0x00 );
43+ data.push_back ((pesLength >> 8 ) & 0xFF );
44+ data.push_back (pesLength & 0xFF );
4545
4646 // PES extension
4747 data.push_back (0x80 ); // '10'xxxxxx (no PES scrambling control, PES priority, data alignment indicator, copyright, original or copy)
@@ -334,6 +334,116 @@ TEST_CASE("cPesVideo - Payload extraction", "[pes]") {
334334 }
335335}
336336
337+ TEST_CASE (" cPesVideo - Packet length" , " [pes]" ) {
338+ SECTION (" Get packet length for unbounded MPEG2 (length field = 0)" ) {
339+ auto data = createMpeg2PesPacket ();
340+ cPesVideo pes (data.data (), data.size ());
341+
342+ REQUIRE (pes.GetPacketLength () == static_cast <int >(data.size ()));
343+ }
344+
345+ SECTION (" Get packet length for unbounded H.264 (length field = 0)" ) {
346+ auto data = createH264PesPacket (false );
347+ cPesVideo pes (data.data (), data.size ());
348+
349+ REQUIRE (pes.GetPacketLength () == static_cast <int >(data.size ()));
350+ }
351+
352+ SECTION (" Get packet length with specified length field" ) {
353+ // Create a PES packet with a specific length
354+ // PES length field specifies bytes after the length field itself
355+ uint16_t pesPayloadLength = 20 ; // Header data (3 bytes) + actual payload
356+ auto data = createBasicPesVideoHeader (0xE0 , false , pesPayloadLength);
357+
358+ // Add some payload to match the specified length
359+ for (int i = data.size () - 6 ; i < pesPayloadLength; i++) {
360+ data.push_back (0x00 );
361+ }
362+
363+ cPesVideo pes (data.data (), data.size ());
364+
365+ REQUIRE (pes.GetPacketLength () == 6 + pesPayloadLength);
366+ }
367+
368+ SECTION (" Get packet length for packet with PTS and specified length" ) {
369+ // PTS takes 5 bytes, so header data length = 5
370+ // Total PES header = 9 (fixed header) + 5 (PTS) = 14 bytes
371+ // If we want total packet of 50 bytes, length field = 50 - 6 = 44
372+ uint16_t pesPayloadLength = 44 ;
373+ auto data = createBasicPesVideoHeader (0xE0 , true , pesPayloadLength);
374+
375+ // Add payload to make total packet 50 bytes
376+ int currentSize = data.size ();
377+ int targetTotalSize = 6 + pesPayloadLength;
378+ for (int i = currentSize; i < targetTotalSize; i++) {
379+ data.push_back (0x00 );
380+ }
381+
382+ cPesVideo pes (data.data (), data.size ());
383+
384+ REQUIRE (pes.GetPacketLength () == 50 );
385+ }
386+
387+ SECTION (" Get packet length when input buffer is larger than PES packet" ) {
388+ // Create a PES packet with specified length
389+ uint16_t pesPayloadLength = 20 ;
390+ auto data = createBasicPesVideoHeader (0xE0 , false , pesPayloadLength);
391+
392+ // Add payload matching the PES length
393+ for (int i = data.size () - 6 ; i < pesPayloadLength; i++) {
394+ data.push_back (0xAA );
395+ }
396+
397+ // Add extra data beyond the PES packet (simulating buffer with multiple packets)
398+ for (int i = 0 ; i < 50 ; i++) {
399+ data.push_back (0xFF );
400+ }
401+
402+ cPesVideo pes (data.data (), data.size ());
403+
404+ REQUIRE (pes.GetPacketLength () == 6 + pesPayloadLength);
405+ REQUIRE (pes.GetPacketLength () < static_cast <int >(data.size ()));
406+ }
407+
408+ SECTION (" Unbounded packet with buffer larger than actual data" ) {
409+ // Create an unbounded packet (length field = 0)
410+ auto data = createBasicPesVideoHeader (0xE0 , false , 0 );
411+
412+ // Add some actual payload
413+ for (int i = 0 ; i < 30 ; i++) {
414+ data.push_back (0xAA );
415+ }
416+
417+ // Store the actual data size
418+ int actualSize = data.size ();
419+
420+ // Add extra buffer space (simulating oversized buffer)
421+ for (int i = 0 ; i < 50 ; i++) {
422+ data.push_back (0xFF );
423+ }
424+
425+ cPesVideo pes (data.data (), data.size ());
426+
427+ REQUIRE (pes.GetPacketLength () == static_cast <int >(data.size ()));
428+ REQUIRE (pes.GetPacketLength () > actualSize);
429+ }
430+
431+ SECTION (" Get packet length for audio packet with specified length" ) {
432+ // Audio packets typically have bounded length
433+ uint16_t pesPayloadLength = 30 ;
434+ auto data = createBasicPesVideoHeader (0xC0 , false , pesPayloadLength);
435+
436+ // Add audio payload
437+ for (int i = data.size () - 6 ; i < pesPayloadLength; i++) {
438+ data.push_back (0xFF );
439+ }
440+
441+ cPesAudio pes (data.data (), data.size ());
442+
443+ REQUIRE (pes.GetPacketLength () == 6 + pesPayloadLength);
444+ }
445+ }
446+
337447TEST_CASE (" cPesVideo - Audio stream handling" , " [pes]" ) {
338448 SECTION (" Audio stream without codec parsing" ) {
339449 auto data = createAudioPesPacket ();
0 commit comments