Skip to content

Commit

Permalink
[demuxers/MpegTS] Check for H.264 SPS changing midstream, stop indexi…
Browse files Browse the repository at this point in the history
…ng if size change is detected
  • Loading branch information
eumagga0x2a committed Apr 30, 2020
1 parent ab7d165 commit 0a7883a
Show file tree
Hide file tree
Showing 2 changed files with 58 additions and 1 deletion.
5 changes: 4 additions & 1 deletion avidemux_plugins/ADM_demuxers/MpegTS/ADM_tsIndex.h
Expand Up @@ -189,10 +189,13 @@ class TsIndexerH264 : public TsIndexerBase
uint8_t decodeSEI(uint32_t nalSize, uint8_t *org,uint32_t *recoveryLength,pictureStructure *nextpicstruct);
#define ADM_NAL_BUFFER_SIZE (2*1024) // only used to decode SEI, should plenty enough
uint8_t payloadBuffer[ADM_NAL_BUFFER_SIZE];
uint8_t spsCache[ADM_NAL_BUFFER_SIZE];
uint32_t spsLen;
public:
TsIndexerH264(listOfTsAudioTracks *tr) : TsIndexerBase(tr)
{
memset(&spsInfo,0,sizeof(spsInfo));
memset(&spsInfo,0,sizeof(spsInfo));
spsLen=0;
}
~TsIndexerH264()
{
Expand Down
54 changes: 54 additions & 0 deletions avidemux_plugins/ADM_demuxers/MpegTS/ADM_tsIndexH264.cpp
Expand Up @@ -115,6 +115,10 @@ bool TsIndexerH264::findH264SPS(tsPacketLinearTracker *pkt,TSVideo &video)
video.w=spsInfo.width;
video.h=spsInfo.height;
video.fps=spsInfo.fps1000;
spsLen=SEI_nal.payloadSize-3;
if(spsLen>ADM_NAL_BUFFER_SIZE)
spsLen=ADM_NAL_BUFFER_SIZE;
memcpy(spsCache,SEI_nal.payload,spsLen);
continue;
}
if(startCode==NAL_SPS && sps_found) // most likely the next keyframe
Expand Down Expand Up @@ -347,6 +351,56 @@ uint8_t TsIndexerH264::run(const char *file, ADM_TS_TRACK *videoTrac)
{
thisUnit.consumedSoFar=pkt->getConsumed();
}
SEI_nal.empty();
uint32_t code=0xffff+0xffff0000;
while(((0xffffff&code)!=1) && pkt->stillOk())
{
uint8_t r=pkt->readi8();
code=(code<<8)+r;
SEI_nal.pushByte(r);
}
if(!pkt->stillOk()) goto resume;
uint32_t tmpLen=SEI_nal.payloadSize;
aprintf("[SPS] Nal size :%d\n",tmpLen);
if(tmpLen>=7 && tmpLen<=ADM_NAL_BUFFER_SIZE+3)
{
tmpLen-=3;
bool match=!memcmp(spsCache, SEI_nal.payload, (spsLen > tmpLen)? tmpLen : spsLen);
if(!match)
{
ADM_warning("SPS changing midstream? Checking deeper...\n");
ADM_SPSInfo tmpInfo;
if(extractSPSInfo(SEI_nal.payload, tmpLen, &tmpInfo))
{
if(spsInfo.width!=tmpInfo.width || spsInfo.height!=tmpInfo.height)
{
GUI_Info_HIG(ADM_LOG_IMPORTANT, QT_TRANSLATE_NOOP("tsdemuxer","Size Change"),
QT_TRANSLATE_NOOP("tsdemuxer","The size of the video changes at frame %u from %ux%u to %ux%u. "
"This is unsupported, stopping here."),
data.nbPics, spsInfo.width, spsInfo.height, tmpInfo.width, tmpInfo.height);
result=1;
goto the_end;
}
match=true;
#define MATCH(x) if(spsInfo.x != tmpInfo.x) { ADM_warning("%s value does not match.\n",#x); spsInfo.x = tmpInfo.x; match=false; }

MATCH(CpbDpbToSkip)
MATCH(hasPocInfo)
MATCH(log2MaxFrameNum)
MATCH(log2MaxPocLsb)
MATCH(frameMbsOnlyFlag)
MATCH(refFrames)

if(!match)
{
ADM_warning("Codec parameters change on the fly at frame %u, expect problems.\n",data.nbPics);
// Nevertheless, update the cached SPS
memcpy(spsCache, SEI_nal.payload, tmpLen);
spsLen=tmpLen;
}
}
}
}
}
if(!addUnit(data,unitTypeSps,thisUnit,startCodeLength))
{
Expand Down

0 comments on commit 0a7883a

Please sign in to comment.