Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
83 changes: 48 additions & 35 deletions lib/ts_stream.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -587,7 +587,15 @@ namespace TS{
realPayloadSize = paySize - offset - pesOffset;
}else{
const char *pesPayload = pesHeader + pesOffset;
parseBitstream(tid, pesPayload, realPayloadSize, timeStamp, timeOffset, bPos, pesHeader[6] & 0x04);
// A PES is aligned (= starts a new access unit) if the data_alignment_indicator bit is
// set OR if it carries a PTS (PTS_flags != 0). Continuation PES packets never carry a PTS,
// so PTS_flags==0 is the only reliable indicator of a mid-access-unit continuation.
// Some encoders do not set data_alignment_indicator even for the first
// PES of an access unit, so relying solely on that bit causes all their frames to be
// treated as continuations (align=0) and dropped.
uint8_t pts_flags = (pesHeader[7] >> 6) & 0x3;
bool alignment = (pesHeader[6] & 0x04) || (pts_flags != 0);
parseBitstream(tid, pesPayload, realPayloadSize, timeStamp, timeOffset, bPos, alignment);
lastms[tid] = timeStamp;
}

Expand Down Expand Up @@ -775,48 +783,53 @@ namespace TS{
const char *pesEnd = pesPayload + realPayloadSize;
bool isKeyFrame = false;
uint32_t nalSize = 0;
// For continuation PES packets (alignment==0), never scan for Annex B start codes.
// The raw payload is a fragment of an ongoing NAL and may contain false-positive 00 00 01
// sequences inside compressed data. Always extend the previous NAL directly.
if (!alignment) {
if (!buildPacket.count(tid)) {
FAIL_MSG("Continuation PES (align=0) for track %zu ts=%" PRIu64 " but no build packet exists", tid, timeStamp);
return;
}
DTSC::Packet &bp = buildPacket[tid];
if (timeStamp && timeStamp != bp.getTime()) {
FAIL_MSG("Continuation PES (align=0) for track %zu ts=%" PRIu64 " does not match build packet ts=%" PRIu64 ", can't merge", tid, timeStamp, bp.getTime());
return;
}
bp.upgradeNal(pesPayload, realPayloadSize);
return;
}

nextPtr = nalu::scanAnnexB(pesPayload, realPayloadSize);
if (!nextPtr){
nextPtr = pesEnd;
nalSize = realPayloadSize;
if (!alignment && timeStamp && buildPacket.count(tid) && timeStamp != buildPacket[tid].getTime()){
FAIL_MSG("No startcode in packet @ %" PRIu64 " ms, and time is not equal to %" PRIu64
" ms so can't merge",
timeStamp, buildPacket[tid].getTime());
return;
}
DTSC::Packet &bp = buildPacket[tid];
if (alignment){
// If the timestamp differs from current PES timestamp, send the previous packet out and
// fill a new one.
if (bp.getTime() != timeStamp){
// Add the finished DTSC packet to our output buffer
out.push_back(bp);

size_t size;
char *tmp;
bp.getString("data", tmp, size);

INFO_MSG("buildpacket: size: %zu, timestamp: %" PRIu64, size, bp.getTime())

// Create a new empty packet with the key frame bit set to true
bp.null();
bp.genericFill(timeStamp, timeOffset, tid, 0, 0, bPos, true);
bp.setKeyFrame(false);
}
// If the timestamp differs from current PES timestamp, send the previous packet out and
// fill a new one.
if (bp.getTime() != timeStamp){
// Add the finished DTSC packet to our output buffer
out.push_back(bp);

size_t size;
char *tmp;
bp.getString("data", tmp, size);

INFO_MSG("buildpacket: size: %zu, timestamp: %" PRIu64, size, bp.getTime())

// Create a new empty packet with the key frame bit set to true
bp.null();
bp.genericFill(timeStamp, timeOffset, tid, 0, 0, bPos, true);
bp.setKeyFrame(false);
}

// Check if this is a keyframe
parseNal(tid, pesPayload, nextPtr, isKeyFrame);
// If yes, set the keyframe flag
if (isKeyFrame){bp.setKeyFrame(true);}
// Check if this is a keyframe
parseNal(tid, pesPayload, nextPtr, isKeyFrame);
// If yes, set the keyframe flag
if (isKeyFrame){bp.setKeyFrame(true);}

// No matter what, now append the current NAL unit to the current packet
bp.appendNal(pesPayload, nalSize);
}else{
bp.upgradeNal(pesPayload, nalSize);
return;
}
// No matter what, now append the current NAL unit to the current packet
bp.appendNal(pesPayload, nalSize);
}

while (nextPtr < pesEnd){
Expand Down