📄 umc_avi_splitter.cpp
字号:
if (AVI_FOURCC_vids == track.m_StreamHeader.fccType)
((BitmapInfoHeader *)track.m_pStreamFormat)->SwapBigEndian();
else if (AVI_FOURCC_auds == track.m_StreamHeader.fccType)
((WaveFormatEx *)track.m_pStreamFormat)->SwapBigEndian();
// Ascend from 'strf'
umcRes = m_AviChunkReader.Ascend();
if (UMC_OK != umcRes)
return umcRes;
umcRes = m_AviChunkReader.DescendChunk(AVI_FOURCC_INDX);
if (umcRes == UMC_OK)
{
// index buffer doesn't include chunk header!
track.m_uiIndexSize = m_AviChunkReader.GetChunkSize();
track.m_pIndex = ippsMalloc_8u(track.m_uiIndexSize);
if (!track.m_pIndex)
return UMC_ERR_ALLOC;
m_AviChunkReader.GetData(track.m_pIndex, track.m_uiIndexSize);
if (UMC_OK != umcRes)
return umcRes;
// Ascend from 'indx'
umcRes = m_AviChunkReader.Ascend();
}
// Ascend from LIST
umcRes = m_AviChunkReader.Ascend();
if (UMC_OK != umcRes)
return umcRes;
return UMC_OK;
}
Status AVISplitter::FillAudioStreamInfo(Ipp32u uiTrack, TrackInfo *pInfo)
{
Status umcRes = UMC_OK;
AviTrack &rTrack = m_pTrack[uiTrack];
AudioStreamInfo *pAInfo = (AudioStreamInfo *)pInfo->m_pStreamInfo;
WaveFormatEx *pWavFmt = (WaveFormatEx *)rTrack.m_pStreamFormat;
if (!pWavFmt)
return UMC_ERR_FAILED;
pAInfo->channels = pWavFmt->nChannels;
pAInfo->sample_frequency = pWavFmt->nSamplesPerSec;
pAInfo->bitrate = pWavFmt->nAvgBytesPerSec * 8;
pAInfo->bitPerSample = pWavFmt->wBitsPerSample ? pWavFmt->wBitsPerSample: 16;
IndexEntry entry;
umcRes = m_pTrackIndex[uiTrack].Last(entry);
pAInfo->duration = UMC_OK == umcRes ? entry.GetTimeStamp() : 0.0;
pAInfo->stream_type = UNDEF_AUDIO;
pAInfo->stream_subtype = UNDEF_AUDIO_SUBTYPE;
if (WAVE_FORMAT_PCM == pWavFmt->wFormatTag)
{
pAInfo->stream_type = PCM_AUDIO;
pInfo->m_Type = TRACK_PCM;
}
else if (WAVE_FORMAT_MPEGLAYER3 == pWavFmt->wFormatTag)
{
pAInfo->stream_type = (pWavFmt->nSamplesPerSec >= 32000) ? MP1L3_AUDIO : MP2L3_AUDIO;
pInfo->m_Type = TRACK_MPEGA;
}
else if (WAVE_FORMAT_DVM == pWavFmt->wFormatTag)
{
pAInfo->stream_type = AC3_AUDIO;
pInfo->m_Type = TRACK_AC3;
}
else if (WAVE_FORMAT_AAC == pWavFmt->wFormatTag)
{
pAInfo->stream_type = AAC_AUDIO;
pInfo->m_Type = TRACK_AAC;
}
else if (WAVE_FORMAT_ALAW == pWavFmt->wFormatTag)
{
pAInfo->stream_type = ALAW_AUDIO;
pInfo->m_Type = TRACK_AMR;
}
else if (WAVE_FORMAT_MULAW == pWavFmt->wFormatTag)
{
pAInfo->stream_type = MULAW_AUDIO;
pInfo->m_Type = TRACK_AMR;
}
pAInfo->channel_mask = 0;
if (1 == pWavFmt->nChannels)
pAInfo->channel_mask = CHANNEL_FRONT_CENTER;
else if (2 == pWavFmt->nChannels)
pAInfo->channel_mask = CHANNEL_FRONT_LEFT | CHANNEL_FRONT_RIGHT;
else if (3 == pWavFmt->nChannels)
pAInfo->channel_mask = CHANNEL_FRONT_LEFT | CHANNEL_FRONT_RIGHT | CHANNEL_FRONT_CENTER;
else if (4 == pWavFmt->nChannels)
pAInfo->channel_mask = CHANNEL_FRONT_LEFT | CHANNEL_FRONT_RIGHT | CHANNEL_FRONT_CENTER | CHANNEL_TOP_CENTER;
else if (5 == pWavFmt->nChannels)
pAInfo->channel_mask = CHANNEL_FRONT_LEFT | CHANNEL_FRONT_RIGHT | CHANNEL_FRONT_CENTER |
CHANNEL_BACK_LEFT | CHANNEL_BACK_RIGHT;
else if (6 == pWavFmt->nChannels)
pAInfo->channel_mask = CHANNEL_FRONT_LEFT | CHANNEL_FRONT_RIGHT | CHANNEL_FRONT_CENTER |
CHANNEL_BACK_LEFT | CHANNEL_BACK_RIGHT | CHANNEL_LOW_FREQUENCY;
else if (7 == pWavFmt->nChannels)
pAInfo->channel_mask = CHANNEL_FRONT_LEFT | CHANNEL_FRONT_RIGHT | CHANNEL_FRONT_CENTER | CHANNEL_BACK_LEFT |
CHANNEL_BACK_RIGHT | CHANNEL_LOW_FREQUENCY | CHANNEL_FRONT_LEFT_OF_CENTER | CHANNEL_FRONT_RIGHT_OF_CENTER;
return UMC_OK;
}
Status AVISplitter::FillVideoStreamInfo(Ipp32u uiTrack, TrackInfo *pInfo)
{
Status umcRes = UMC_OK;
AviTrack &rTrack = m_pTrack[uiTrack];
VideoStreamInfo *pVInfo = (VideoStreamInfo *)pInfo->m_pStreamInfo;
BitmapInfoHeader* pBmpHdr = (BitmapInfoHeader *)rTrack.m_pStreamFormat;
if (!pBmpHdr)
return UMC_ERR_FAILED;
pVInfo->clip_info.width = pBmpHdr->biWidth;
pVInfo->clip_info.height = pBmpHdr->biHeight;
pVInfo->bitrate = 8 * m_AviHdr.uiMaxBytesPerSec;
pVInfo->framerate = (Ipp64f)rTrack.m_StreamHeader.uiRate / rTrack.m_StreamHeader.uiScale;
IndexEntry entry;
umcRes = m_pTrackIndex[uiTrack].Last(entry);
pVInfo->duration = (UMC_OK == umcRes) ? entry.GetTimeStamp() : 0.0;
pVInfo->stream_type = UNDEF_VIDEO;
pVInfo->stream_subtype = UNDEF_VIDEO_SUBTYPE;
Ipp32u fccHandler = rTrack.m_StreamHeader.fccHandler;
if (AVI_FOURCC_DIVX == fccHandler || AVI_FOURCC_divx == fccHandler ||
AVI_FOURCC_DX50 == fccHandler || AVI_FOURCC_dx50 == fccHandler ||
AVI_FOURCC_DIV4 == fccHandler || AVI_FOURCC_div4 == fccHandler ||
AVI_FOURCC_XVID == fccHandler || AVI_FOURCC_xvid == fccHandler ||
AVI_FOURCC_MP4V == fccHandler || AVI_FOURCC_mp4v == fccHandler)
{
pInfo->m_Type = TRACK_MPEG4V;
pVInfo->stream_type = MPEG4_VIDEO;
if (AVI_FOURCC_DX50 == fccHandler || AVI_FOURCC_dx50 == fccHandler)
pVInfo->stream_subtype = MPEG4_VIDEO_DIVX5;
}
else if (AVI_FOURCC_DVHP == fccHandler || AVI_FOURCC_dvhp == fccHandler ||
AVI_FOURCC_DVHD == fccHandler || AVI_FOURCC_dvhd == fccHandler ||
AVI_FOURCC_DVH1 == fccHandler || AVI_FOURCC_dvh1 == fccHandler)
{
pVInfo->stream_type = DIGITAL_VIDEO_HD;
pInfo->m_Type = TRACK_DVHD;
}
else if (AVI_FOURCC_DV50 == fccHandler || AVI_FOURCC_dv50 == fccHandler)
{
pVInfo->stream_type = DIGITAL_VIDEO_50;
pInfo->m_Type = TRACK_DV50;
}
else if (AVI_FOURCC_DVSD == fccHandler || AVI_FOURCC_dvsd == fccHandler ||
AVI_FOURCC_DSVD == fccHandler || AVI_FOURCC_dsvd == fccHandler ||
AVI_FOURCC_VIDV == fccHandler || AVI_FOURCC_vidv == fccHandler ||
AVI_FOURCC_DVSL == fccHandler || AVI_FOURCC_dvsl == fccHandler ||
AVI_FOURCC_SLDV == fccHandler || AVI_FOURCC_sldv == fccHandler)
{
pInfo->m_Type = TRACK_DVSD;
pVInfo->stream_type = DIGITAL_VIDEO_SD;
}
else if (AVI_FOURCC_WMV3 == fccHandler)
{
pInfo->m_Type = TRACK_WMV;
pVInfo->stream_type = WMV_VIDEO;
}
else if (AVI_FOURCC_H263 == fccHandler || AVI_FOURCC_h263 == fccHandler ||
AVI_FOURCC_I263 == fccHandler || AVI_FOURCC_i263 == fccHandler ||
AVI_FOURCC_M263 == fccHandler || AVI_FOURCC_m263 == fccHandler ||
AVI_FOURCC_VIVO == fccHandler || AVI_FOURCC_vivo == fccHandler)
{
pInfo->m_Type = TRACK_H263;
pVInfo->stream_type = H263_VIDEO;
}
else if (AVI_FOURCC_H261 == fccHandler || AVI_FOURCC_h261 == fccHandler)
{
pInfo->m_Type = TRACK_H261;
pVInfo->stream_type = H261_VIDEO;
}
else if (AVI_FOURCC_MJPG == fccHandler || AVI_FOURCC_mjpg == fccHandler ||
AVI_FOURCC_MJPX == fccHandler || AVI_FOURCC_mjpx == fccHandler ||
AVI_FOURCC_dmb1 == fccHandler)
{
pInfo->m_Type = TRACK_MJPEG;
pVInfo->stream_type = MJPEG_VIDEO;
}
else if (AVI_FOURCC_ILV4 == fccHandler || AVI_FOURCC_ilv4 == fccHandler ||
AVI_FOURCC_VSSH == fccHandler || AVI_FOURCC_vssh == fccHandler)
{
pInfo->m_Type = TRACK_H264;
pVInfo->stream_type = H264_VIDEO;
}
else if (AVI_FOURCC_DIB == fccHandler)
{
Ipp32u biCompression = ((BitmapInfoHeader *)rTrack.m_pStreamFormat)->biCompression;
pVInfo->stream_type = UNCOMPRESSED_VIDEO;
pVInfo->stream_subtype = (VideoStreamSubType)biCompression;
pInfo->m_Type = TRACK_YUV;
}
else
{
// There are many codecs, which can produce uncompressed video.
// So we compare not a codec handler, but the compression type.
Ipp32u biCompression = ((BitmapInfoHeader *)rTrack.m_pStreamFormat)->biCompression;
if (AVI_FOURCC_IYUV == biCompression)
{
pInfo->m_Type = TRACK_YUV;
pVInfo->stream_type = UNCOMPRESSED_VIDEO;
pVInfo->stream_subtype = (VideoStreamSubType)biCompression;
}
}
return UMC_OK;
}
Status AVISplitter::FillDvStreamInfo(Ipp32u uiTrack, TrackInfo *pInfo)
{
Status umcRes = UMC_OK;
AviTrack &rTrack = m_pTrack[uiTrack];
VideoStreamInfo *pVInfo = (VideoStreamInfo *)pInfo->m_pStreamInfo;
IndexEntry entry;
umcRes = m_pTrackIndex[uiTrack].Last(entry);
pVInfo->duration = (UMC_OK == umcRes) ? entry.GetTimeStamp() : 0.0;
pVInfo->bitrate = 8 * m_AviHdr.uiMaxBytesPerSec;
pVInfo->stream_type = UNDEF_VIDEO;
pVInfo->stream_subtype = UNDEF_VIDEO_SUBTYPE;
Ipp32u fccHandler = rTrack.m_StreamHeader.fccHandler;
if (AVI_FOURCC_DVHP == fccHandler || AVI_FOURCC_dvhp == fccHandler ||
AVI_FOURCC_DVHD == fccHandler || AVI_FOURCC_dvhd == fccHandler ||
AVI_FOURCC_DVH1 == fccHandler || AVI_FOURCC_dvh1 == fccHandler)
{
pVInfo->stream_type = DIGITAL_VIDEO_HD;
pInfo->m_Type = TRACK_DVHD;
}
else if (AVI_FOURCC_DV50 == fccHandler || AVI_FOURCC_dv50 == fccHandler)
{
pVInfo->stream_type = DIGITAL_VIDEO_50;
pInfo->m_Type = TRACK_DV50;
}
else if (AVI_FOURCC_DVSD == fccHandler || AVI_FOURCC_dvsd == fccHandler ||
AVI_FOURCC_DSVD == fccHandler || AVI_FOURCC_dsvd == fccHandler ||
AVI_FOURCC_VIDV == fccHandler || AVI_FOURCC_vidv == fccHandler ||
AVI_FOURCC_DVSL == fccHandler || AVI_FOURCC_dvsl == fccHandler ||
AVI_FOURCC_SLDV == fccHandler || AVI_FOURCC_sldv == fccHandler)
{
pInfo->m_Type = TRACK_DVSD;
pVInfo->stream_type = DIGITAL_VIDEO_SD;
}
else
{
return UMC_ERR_FAILED;
}
Ipp32u uiDVVAuxSrc = ((DvInfo *)rTrack.m_pStreamFormat)->uiDVVAuxSrc;
Ipp32u uiFieldsNum = (uiDVVAuxSrc >> 21) & 0x1;
Ipp32u uiSType = (uiDVVAuxSrc >> 16) & 0x1f;
switch (uiSType)
{
case 0: case 1: case 4:
pVInfo->clip_info.width = 720;
pVInfo->clip_info.height = (0 == uiFieldsNum) ? 480 : 576;
pVInfo->framerate = (0 == uiFieldsNum) ? 29.97 : 25.00;
break;
case 20:
pVInfo->clip_info.width = 1920;
pVInfo->clip_info.height = 1080;
pVInfo->framerate = (0 == uiFieldsNum) ? 29.97 : 25.00;
break;
case 24:
pVInfo->clip_info.width = 1280;
pVInfo->clip_info.height = 720;
pVInfo->framerate = 59.94;
break;
default:
pVInfo->framerate = (Ipp64f)rTrack.m_StreamHeader.uiRate / rTrack.m_StreamHeader.uiScale;
pVInfo->clip_info.width = rTrack.m_StreamHeader.rcFrame.right - rTrack.m_StreamHeader.rcFrame.left;
pVInfo->clip_info.height = rTrack.m_StreamHeader.rcFrame.bottom - rTrack.m_StreamHeader.rcFrame.top;
if (pVInfo->clip_info.width <= 0) pVInfo->clip_info.width = m_AviHdr.uiWidth;
if (pVInfo->clip_info.height <= 0) pVInfo->clip_info.height = m_AviHdr.uiHeight;
}
return UMC_OK;
}
inline
Ipp32u GetTrackId(Ipp32u fourCC)
{
return 10 * ((fourCC & 0xFF) - '0') + (((fourCC >> 8) & 0xFF) - '0');
}
inline
bool IsAudio(Ipp32u fourCC)
{
return ((fourCC & 0xFFFF0000) == AVI_FOURCC_WB);
}
inline
bool IsVideo(Ipp32u fourCC)
{
return (((fourCC & 0xFFFF0000) == AVI_FOURCC_DC) || ((fourCC & 0xFFFF0000) == AVI_FOURCC_DB));
}
inline
bool IsAudioOrVideo(Ipp32u fourCC)
{
return (IsAudio(fourCC) || IsVideo(fourCC));
}
inline
Ipp64f GetSampleDuration(bool bIsVideoTrack, bool bIsVBRAudio, Ipp64f dFrameDuration, Ipp32u nBlockAlign, Ipp32u nSampleSize)
{
if (bIsVideoTrack)
{
return dFrameDuration;
}
else
{
if (bIsVBRAudio)
return dFrameDuration * ((nSampleSize - 1) / nBlockAlign + 1);
else
return dFrameDuration * nSampleSize / nBlockAlign;
}
}
Status AVISplitter::GenerateIndex()
{
Status umcRes = UMC_OK;
bool bUseOldIndex = false;
Ipp32u i;
for(i = 0; i < m_AviHdr.uiStreams; i++)
{
if (AVI_FOURCC_auds == m_pTrack[i].m_StreamHeader.fccType ||
AVI_FOURCC_vids == m_pTrack[i].m_StreamHeader.fccType ||
AVI_FOURCC_iavs == m_pTrack[i].m_StreamHeader.fccType ||
AVI_FOURCC_ivas == m_pTrack[i].m_StreamHeader.fccType)
{
if (NULL == m_pTrack[i].m_pIndex || 0 == m_pTrack[i].m_uiIndexSize)
bUseOldIndex = true;
}
}
if (bUseOldIndex)
{
Ipp32u riffType = AVI_FOURCC_AVI_;
bool bExtension = false;
while (umcRes == UMC_OK)
{
if (bExtension)
riffType = AVI_FOURCC_AVIX;
umcRes = m_AviChunkReader.DescendRIFF(riffType);
if (umcRes != UMC_OK)
return bExtension ? UMC_OK : umcRes;
umcRes = m_AviChunkReader.DescendLIST(AVI_FOURCC_MOVI);
if (umcRes != UMC_OK)
return umcRes;
// offset in idx1 can be absolute offset, or position relatively to
// the first byte of "movi" indentificator.
Ipp64u nMoviChunkStartAddr = m_AviChunkReader.GetChunkHead() - 4;
Ipp64u nMoviChunkEndAddr = nMoviChunkStartAddr + m_AviChunkReader.GetChunkSize();
m_AviChunkReader.Ascend();
umcRes = m_AviChunkReader.DescendChunk(AVI_FOURCC_IDX1);
if (umcRes != UMC_OK)
return bExtension ? UMC_OK : umcRes;
Ipp32u nIndexSize = m_AviChunkReader.GetChunkSize();
Ipp8u *pIndex = ippsMalloc_8u(nIndexSize);
if (pIndex == NULL)
return UMC_ERR_ALLOC;
umcRes = m_AviChunkReader.GetData(pIndex, nIndexSize);
if (UMC_OK != umcRes)
{
ippsFree(pIndex);
return umcRes;
}
#ifdef _BIG_ENDIAN_
ippsSwapBytes_32u_I((Ipp32u *)pIndex, nIndexSize / 4);
#endif
InitIndexUsingOldAVIIndex(pIndex, nIndexSize, nMoviChunkStartAddr, nMoviChunkEndAddr);
ippsFree(pIndex);
// ascend from idx1
m_AviChunkReader.Ascend();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -