Skip to content

Commit

Permalink
[demuxers/MpegTS] Disambiguate frames and fields in interlaced video …
Browse files Browse the repository at this point in the history
…streams, double frame rate for field encoded video irrespectively of the codec, fix wrong picture structure written to index, detect presence of interlacing in H.264 streams and write the corresponding property to the index file
  • Loading branch information
eumagga0x2a committed Feb 19, 2020
1 parent 8bd1c1b commit cbe5214
Show file tree
Hide file tree
Showing 8 changed files with 153 additions and 138 deletions.
2 changes: 1 addition & 1 deletion avidemux_plugins/ADM_demuxers/MpegTS/ADM_ts.cpp
Expand Up @@ -260,7 +260,7 @@ uint8_t tsHeader::close(void)

tsHeader::tsHeader( void ) : vidHeader()
{
interlaced=false;
fieldEncoded=false;
lastFrame=0xffffffff;
videoPid=0;
videoNeedEscaping=false;
Expand Down
2 changes: 1 addition & 1 deletion avidemux_plugins/ADM_demuxers/MpegTS/ADM_ts.h
Expand Up @@ -110,7 +110,7 @@ class tsHeader :public vidHeader
{
protected:

bool interlaced;
bool fieldEncoded;
bool readVideo(indexFile *index);
bool readAudio(indexFile *index,const char *name);
bool readIndex(indexFile *index);
Expand Down
33 changes: 24 additions & 9 deletions avidemux_plugins/ADM_demuxers/MpegTS/ADM_tsComputeTimeStamp.cpp
Expand Up @@ -7,6 +7,7 @@
#include "ADM_default.h"
#include "fourcc.h"
#include "DIA_coreToolkit.h"
#include "ADM_coreUtils.h"
#include "ADM_indexFile.h"
#include "ADM_ts.h"

Expand Down Expand Up @@ -74,16 +75,30 @@ bool tsHeader::updatePtsDts(void)

// Make sure everyone starts at 0
// Search first timestamp (audio/video)

switch( _videostream.dwRate)
if(fieldEncoded) // Set fps to field rate, necessary for copy mode
{
case 50000: dtsIncrement=20000;break;
case 25000: dtsIncrement=40000;break;
case 23976: dtsIncrement=41708;break;
case 29970: dtsIncrement=33367;break;
default : dtsIncrement=1;
printf("[psDemux] Fps not handled for DTS increment\n");

if(_videostream.dwRate<=45000)
_videostream.dwRate*=2;
else if(!(_videostream.dwScale%2))
_videostream.dwScale/=2;
_mainaviheader.dwMicroSecPerFrame/=2;
printf("[processVideoIndex] Doubling fps for field-encoded video, new time base: %d / %d\n",_videostream.dwScale,_videostream.dwRate);
}
if(_mainaviheader.dwMicroSecPerFrame)
{
dtsIncrement=_mainaviheader.dwMicroSecPerFrame;
}else
{
if(_videostream.dwScale==1000)
dtsIncrement=ADM_UsecFromFps1000(_videostream.dwRate);
else if(_videostream.dwScale && _videostream.dwRate)
{
double f=_videostream.dwScale;
f*=1000.*1000.;
f/=_videostream.dwRate;
f+=0.49;
dtsIncrement=(uint64_t)f;
}
}
uint64_t startDts=ListOfFrames[0]->dts;
uint64_t startPts=ListOfFrames[0]->pts;
Expand Down
19 changes: 8 additions & 11 deletions avidemux_plugins/ADM_demuxers/MpegTS/ADM_tsIndex.cpp
Expand Up @@ -244,10 +244,9 @@ bool TsIndexerBase::dumpUnits(indexerData &data,uint64_t nextConsumed,const dmxP
{
switch(listOfUnits[i].unitType)
{
case unitTypeSps: mustFlush=true;;break;
case unitTypeSps: mustFlush=true; break;
case unitTypePic:
picIndex=i;
pictStruct=listOfUnits[i].imageStructure;
if(listOfUnits[i].imageType==1 || listOfUnits[i].imageType==4)
mustFlush=true;
break;
Expand Down Expand Up @@ -295,7 +294,7 @@ bool TsIndexerBase::dumpUnits(indexerData &data,uint64_t nextConsumed,const dmxP
else deltaDts=pic->dts-data.beginDts;


qfprintf(index," %c%c",Type[picUnit->imageType],Structure[pictStruct&3]);
qfprintf(index," %c%c",Type[picUnit->imageType],Structure[pictStruct%6]);
int32_t delta=(int32_t)(nextConsumed-beginConsuming);

// printf("%d -- %d = %d\n",nextConsumed, beginConsuming,delta);
Expand Down Expand Up @@ -347,14 +346,12 @@ bool TsIndexerBase::updateLastUnitStructure(int t)
H264Unit &lastUnit=listOfUnits[n-1];
switch(t)
{
case 3:
lastUnit.imageStructure=pictureFrame;
break;
case 1: lastUnit.imageStructure=pictureTopField;
break;
case 2: lastUnit.imageStructure=pictureBottomField;
break;
default: ADM_warning("frame type 0 met, this is illegal\n");
case 3 : lastUnit.imageStructure=pictureFrame;break;
case 1 : lastUnit.imageStructure=pictureFieldTop;break;
case 2 : lastUnit.imageStructure=pictureFieldBottom;break;
case 4 : lastUnit.imageStructure=pictureTopFirst;break;
case 5 : lastUnit.imageStructure=pictureBottomFirst;break;
default: ADM_warning("frame type %d met, this is illegal\n",t);break;
}
return true;
}
Expand Down
69 changes: 30 additions & 39 deletions avidemux_plugins/ADM_demuxers/MpegTS/ADM_tsIndex.h
Expand Up @@ -41,7 +41,7 @@ using std::string;
#else
#define aprintf printf
#endif
static const char Structure[4]={'X','T','B','F'}; // X Top Bottom Frame
static const char Structure[6]={'X','T','B','F','C','S'}; // Invalid, Top, Bottom, Frame, Frame+TFF, Frame+BFF
static const char Type[5]={'X','I','P','B','D'};
#define VC1_MAX_SEQ_SIZE 64
#if 1
Expand All @@ -67,8 +67,10 @@ class TSVideo
typedef enum
{
pictureFrame=3,
pictureTopField=1,
pictureBottomField=2
pictureFieldTop=1,
pictureFieldBottom=2,
pictureTopFirst=4,
pictureBottomFirst=5
}pictureStructure;

typedef struct
Expand Down Expand Up @@ -150,22 +152,28 @@ virtual uint8_t run(const char *file,ADM_TS_TRACK *videoTrac)=0;
bool writeSystem(const char *filename,bool append=false);
bool updateLastUnitStructure(int structure);
bool updatePicStructure(TSVideo &video,const uint32_t t)
{
switch(t)
{
case 3: video.frameCount++;
thisUnit.imageStructure=pictureFrame;
break;
case 1: thisUnit.imageStructure=pictureTopField;
video.fieldCount++;
break;
case 2: thisUnit.imageStructure=pictureBottomField;
video.fieldCount++;
break;
default: ADM_warning("frame type 0 met, this is illegal\n");
}
return true;
}
{
switch(t)
{
case 3: video.frameCount++;
thisUnit.imageStructure=pictureFrame;
break;
case 1: thisUnit.imageStructure=pictureFieldTop;
video.fieldCount++;
break;
case 2: thisUnit.imageStructure=pictureFieldBottom;
video.fieldCount++;
break;
case 4: video.frameCount++;
thisUnit.imageStructure=pictureTopFirst;
break;
case 5: video.frameCount++;
thisUnit.imageStructure=pictureBottomFirst;
break;
default: ADM_warning("frame type 0 met, this is illegal\n");
}
return true;
}
};

/**
Expand All @@ -178,7 +186,7 @@ class TsIndexerH264 : public TsIndexerBase

protected:
ADM_SPSInfo spsInfo;
bool decodeSEI(uint32_t nalSize, uint8_t *org,uint32_t *recoveryLength,pictureStructure *nextpicstruct);
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];
public:
Expand All @@ -191,23 +199,6 @@ class TsIndexerH264 : public TsIndexerBase

}
uint8_t run(const char *file,ADM_TS_TRACK *videoTrac);
bool updatePicStructure(TSVideo &video,const uint32_t t)
{
switch(t)
{
case 3: video.frameCount++;
thisUnit.imageStructure=pictureFrame;
break;
case 1: thisUnit.imageStructure=pictureTopField;
video.fieldCount++;
break;
case 2: thisUnit.imageStructure=pictureBottomField;
video.fieldCount++;
break;
default: ADM_warning("frame type 0 met, this is illegal\n");
}
return true;
}
};

class TsIndexerVC1: public TsIndexerBase
Expand Down Expand Up @@ -334,10 +325,10 @@ class TsIndexer
case 3: video.frameCount++;
thisUnit.imageStructure=pictureFrame;
break;
case 1: thisUnit.imageStructure=pictureTopField;
case 1: thisUnit.imageStructure=pictureFieldTop;
video.fieldCount++;
break;
case 2: thisUnit.imageStructure=pictureBottomField;
case 2: thisUnit.imageStructure=pictureFieldBottom;
video.fieldCount++;
break;
default: ADM_warning("frame type 0 met, this is illegal\n");
Expand Down

0 comments on commit cbe5214

Please sign in to comment.