Skip to content

Commit

Permalink
[demuxers/Matroska] Try to extract missing AV1 extradata from a keyframe
Browse files Browse the repository at this point in the history
This should fix the inability to save some Matroska files with AV1 video
track as Matroska in copy mode.
  • Loading branch information
eumagga0x2a committed May 19, 2022
1 parent 72d938e commit f3a9f2c
Show file tree
Hide file tree
Showing 3 changed files with 23 additions and 0 deletions.
2 changes: 2 additions & 0 deletions avidemux_plugins/ADM_demuxers/Matroska/ADM_mkv.h
Expand Up @@ -69,6 +69,7 @@ class mkvTrak
_defaultFrameDuration=0;
language=ADM_UNKNOWN_LANGUAGE;
_needBuffering=0;
_needExtraData=0;
_secondField=false;
_nalSize=-1;
}
Expand Down Expand Up @@ -97,6 +98,7 @@ class mkvTrak
uint32_t _defaultFrameDuration; // Duration of ONE frame in us!
std::string language;
int _needBuffering;
int _needExtraData; // Positive and no extradata: try to extract. Negative: give up.
bool _secondField; // Used to clear keyframe flag from the second field
uint32_t _nalSize; // Used to decode frame type in H.264 and HEVC streams
};
Expand Down
2 changes: 2 additions & 0 deletions avidemux_plugins/ADM_demuxers/Matroska/ADM_mkvEntries.cpp
Expand Up @@ -246,6 +246,8 @@ uint8_t mkvHeader::analyzeOneTrack(void *head,uint32_t headlen)
{
_tracks[0].extraData=entry.extraData;
_tracks[0].extraDataLen=entry.extraDataLen;
if(fourCC::check(entry.fcc,(uint8_t *)"av01") && !entry.extraDataLen)
_tracks[0]._needExtraData = 1; // try to extract it from the first keyframe during indexing
}
if(isH264Compatible(entry.fcc) && _tracks[0].extraData
&& _tracks[0].extraDataLen > 8 // FIXME
Expand Down
19 changes: 19 additions & 0 deletions avidemux_plugins/ADM_demuxers/Matroska/ADM_mkvIndexer.cpp
Expand Up @@ -201,10 +201,28 @@ uint8_t mkvHeader::addIndexEntry(uint32_t track,ADM_ebml_file *parser,uint64_t w
delete [] readBuffer;
readBufferSize=size*2;
readBuffer=new uint8_t[readBufferSize];
memset(readBuffer,0,readBufferSize);
}
if(!track)
{
aprintf("adding image at 0x%llx , time = %d\n",where,timecodeMS);
if(Track->_needExtraData > 0 && (flags & AVI_KEY_FRAME))
{
if(rpt)
memcpy(readBuffer,_tracks[0].headerRepeat,rpt);
parser->readBin(readBuffer+rpt,size-3);
uint8_t *dest = NULL;
int l = ADM_extractVideoExtraData(_videostream.fccHandler, size, readBuffer, &dest);
if(l < 0)
{
Track->_needExtraData = l;
}else if(l > 0)
{
Track->extraData = dest;
Track->extraDataLen = l;
Track->_needExtraData = 0;
}
}
}
// since frame type is unreliable for mkv, we scan each frame
// For the 2 most common cases : mp4 & h264.
Expand Down Expand Up @@ -609,6 +627,7 @@ uint8_t mkvHeader::indexClusters(ADM_ebml_file *parser)

readBufferSize = 200*1024;
readBuffer = new uint8_t[readBufferSize];
memset(readBuffer,0,readBufferSize);

// Search segment
fileSize=parser->getFileSize();
Expand Down

0 comments on commit f3a9f2c

Please sign in to comment.