MPEG2VIDEOINFO *CLAVFVideoHelper::CreateMPEG2VI(const AVStream *avstream, ULONG *size, std::string container, BOOL bConvertToAVC1) { int extra = 0; BYTE *extradata = nullptr; // Create a VIH that we'll convert VIDEOINFOHEADER2 *vih2 = CreateVIH2(avstream, size, container); if (!vih2) return nullptr; if(avstream->codec->extradata_size > 0) { extra = avstream->codec->extradata_size; extradata = avstream->codec->extradata; } MPEG2VIDEOINFO *mp2vi = (MPEG2VIDEOINFO *)CoTaskMemAlloc(sizeof(MPEG2VIDEOINFO) + max(extra - 4, 0)); if (!mp2vi) return nullptr; memset(mp2vi, 0, sizeof(MPEG2VIDEOINFO)); memcpy(&mp2vi->hdr, vih2, sizeof(VIDEOINFOHEADER2)); mp2vi->hdr.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); // Set profile/level if we know them mp2vi->dwProfile = (avstream->codec->profile != FF_PROFILE_UNKNOWN) ? avstream->codec->profile : 0; mp2vi->dwLevel = (avstream->codec->level != FF_LEVEL_UNKNOWN) ? avstream->codec->level : 0; //mp2vi->dwFlags = 4; // where do we get flags otherwise..? if(extra > 0) { BOOL bCopyUntouched = FALSE; if(avstream->codec->codec_id == AV_CODEC_ID_H264) { int ret = ProcessH264Extradata(extradata, extra, mp2vi, bConvertToAVC1); if (ret < 0) bCopyUntouched = TRUE; } else if (avstream->codec->codec_id == AV_CODEC_ID_HEVC) { int ret = ProcessHEVCExtradata(extradata, extra, mp2vi); if (ret < 0) bCopyUntouched = TRUE; } else if (avstream->codec->codec_id == AV_CODEC_ID_MPEG2VIDEO) { CExtradataParser parser = CExtradataParser(extradata, extra); mp2vi->cbSequenceHeader = (DWORD)parser.ParseMPEGSequenceHeader((BYTE *)&mp2vi->dwSequenceHeader[0]); mp2vi->hdr.bmiHeader.biPlanes = 1; mp2vi->hdr.bmiHeader.biCompression = 0; } else { bCopyUntouched = TRUE; } if (bCopyUntouched) { mp2vi->cbSequenceHeader = extra; memcpy(&mp2vi->dwSequenceHeader[0], extradata, extra); } } // Free the VIH2 that we converted CoTaskMemFree(vih2); *size = SIZE_MPEG2VIDEOINFO(mp2vi); return mp2vi; }
MPEG1VIDEOINFO *CLAVFVideoHelper::CreateMPEG1VI(const AVStream* avstream, ULONG *size, std::string container) { int extra = 0; BYTE *extradata = NULL; // Create a VIH that we'll convert VIDEOINFOHEADER *vih = CreateVIH(avstream, size, container); if (!vih) return NULL; if(avstream->codec->extradata_size > 0) { extra = avstream->codec->extradata_size; extradata = avstream->codec->extradata; } MPEG1VIDEOINFO *mp1vi = (MPEG1VIDEOINFO *)CoTaskMemAlloc(sizeof(MPEG1VIDEOINFO) + extra); if (!mp1vi) return NULL; memset(mp1vi, 0, sizeof(MPEG1VIDEOINFO)); // The MPEG1VI is a thin wrapper around a VIH, so its easy! memcpy(&mp1vi->hdr, vih, sizeof(VIDEOINFOHEADER)); mp1vi->hdr.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); mp1vi->dwStartTimeCode = 0; // is this not 0 anywhere..? mp1vi->hdr.bmiHeader.biPlanes = 0; mp1vi->hdr.bmiHeader.biCompression = 0; // copy extradata over if(extra) { CExtradataParser parser = CExtradataParser(extradata, extra); mp1vi->cbSequenceHeader = (DWORD)parser.ParseMPEGSequenceHeader(mp1vi->bSequenceHeader); } // Free the VIH that we converted CoTaskMemFree(vih); *size = SIZE_MPEG1VIDEOINFO(mp1vi); return mp1vi; }