📄 umc_mp4_mux_common.cpp
字号:
/*//////////////////////////////////////////////////////////////////////////////
//
// INTEL CORPORATION PROPRIETARY INFORMATION
// This software is supplied under the terms of a license agreement or
// nondisclosure agreement with Intel Corporation and may not be copied
// or disclosed except in accordance with the terms of that agreement.
// Copyright(c) 2003-2007 Intel Corporation. All Rights Reserved.
//
*/
#include <stdio.h>
#include "ipps.h"
#include "umc_mp4_mux_defs.h"
#include "umc_mp4_mux.h"
namespace UMC
{
/* return the index of the shortest track; -1 if all are muxed */
Ipp32s MP4Muxer::FindMinTrackEnd(sMuxTMrack* sTrack, Ipp32s nTracksNum)
{
Ipp32s nEndIndex = 0;
Ipp64f dEnd = MAX_TIME;
Ipp32s nMuxedTracks = 0;
int i;
for (i = 0; i < nTracksNum; i++) {
if (sTrack[i].m_nTrackStatus == 1) { // track is muxed
nMuxedTracks++;
if (nMuxedTracks == nTracksNum) {
return -1;
} else {
continue;
}
}
if (sTrack[i].m_nTrackEnd < dEnd) {
dEnd = sTrack[i].m_nTrackEnd;
nEndIndex = i;
}
}
return nEndIndex;
}
Status MP4Muxer::Write_size(vm_file *dw, Ipp32u value)
{
Ipp8u data_char[4];
data_char[0] = (Ipp8u)((value & 0xff000000) >> 24);
data_char[1] = (Ipp8u)((value & 0xff0000) >> 16);
data_char[2] = (Ipp8u)((value & 0xff00) >> 8);
data_char[3] = (Ipp8u) (value & 0xff);
return vm_file_fwrite(data_char, 4, 1, dw) ? UMC_ERR_FAILED : UMC_OK;
}
Status MP4Muxer::InitTemporaryOutputFile1()
{
m_nMdatSize = 0;
m_fTempOutput1 = vm_file_tmpfile();
vm_file_fwrite("xxxxmdat", 8, 1, m_fTempOutput1);
return UMC_OK;
};
Status MP4Muxer::InitAdditionalTemporaryOutputFiles()
{
m_fTempOutput2 = new vm_file*[m_uiTotalNumStreams];
for (Ipp32u i = 0; i < m_uiTotalNumStreams; i++)
{
if (IS_AUDIO(i)) {
m_fTempOutput2[i] = vm_file_tmpfile();
} else {
m_fTempOutput2[i] = NULL;
}
}
return UMC_OK;
};
Status MP4Muxer::InitTracks(Ipp32s nTracks)
{
m_sTrack = _NEW_n(sMuxTMrack, nTracks);
for (Ipp32s i = 0; i < nTracks; i++)
{
m_sTrack[i].m_pSamples = _NEW_n(sMuxSample, INITIAL_TRACK_SIZE);
m_sTrack[i].m_nSamplesCount = 0;
m_sTrack[i].m_nTrackSize = INITIAL_TRACK_SIZE;
m_sTrack[i].m_nTrackEnd = 0;
m_sTrack[i].m_nTrackStatus = 0;
m_sTrack[i].m_nSttsEntries = 1; // at least 1 entry
m_sTrack[i].m_nCttsEntries = 0; // is not needed
}
return UMC_OK;
};
Status MP4Muxer::DisposeDataToFile()
{
vm_debug_trace1(VM_DEBUG_PROGRESS, VM_STRING("DisposeDataToFile %d"), (int)m_bMoov);
if (m_bMoov)
{
m_bMoov = false;
CalculateMvexExtendedSize(&m_headerMVEX);
WriteHeader();
}
else
{
WriteHeaderFragment();
}
//reopen file for data buffering
InitTemporaryOutputFile1();
InitAdditionalTemporaryOutputFiles();
for (Ipp32u i = 0; i < m_headerMPEG4.total_tracks; i++)
{
m_sTrack[i].m_nSamplesCount = 0;
}
m_nHeaderSize = CalculateFragmentSize(&m_headerMoof);
return UMC_OK;
};
Status MP4Muxer::GetBits(Ipp32s *data, Ipp32s nbits, Ipp32s *ptr, Ipp8u *buf)
{
Ipp32s num, maxNum, curNum;
Ipp32u bits;
num = 0;
*data = 0;
maxNum = BYTE_BIT - *ptr % BYTE_BIT;
while (num < nbits)
{
curNum = IPP_MIN(nbits - num, maxNum);
bits = (buf[*ptr / BYTE_BIT] >> (BYTE_BIT - *ptr % BYTE_BIT - curNum)) & ((1 << curNum) - 1);
*data |= bits << (nbits - num - curNum);
num += curNum;
*ptr += curNum;
maxNum = BYTE_BIT;
}
return UMC::UMC_OK;
}
FrameType MP4Muxer::GetPictureType(MediaData *lpData, Ipp32s nTrak)
{
if (!lpData) return NONE_PICTURE;
FrameType frame_type = lpData->GetFrameType();
if (frame_type != NONE_PICTURE) {
if (I_PICTURE == frame_type) {
vm_debug_trace_s(VM_DEBUG_PROGRESS, "GetPictureType: I_PICTURE _");
}
return frame_type;
}
if (UMC::H264_VIDEO == m_pTrackParams[nTrak].info.video->stream_type)
{
if (NAL_UT_IDR_SLICE == (((Ipp8s*)lpData->GetDataPointer())[4] & NAL_UNITTYPE_BITS))
{
vm_debug_trace_s(VM_DEBUG_PROGRESS, "GetPictureType: I_PICTURE");
return I_PICTURE;
} else {
vm_debug_trace_s(VM_DEBUG_PROGRESS, "GetPictureType: Unknown PICTURE");
return NONE_PICTURE;
}
}
if (UMC::MPEG4_VIDEO == m_pTrackParams[nTrak].info.video->stream_type)
{
// Ipp32s nSizeToRead = 6;
Ipp32s nCodingType = 0;
Ipp32s nBitPos = 32; // start code
GetBits(&nCodingType, 2/*two bits*/, &nBitPos, (Ipp8u*)lpData->GetBufferPointer());
switch (nCodingType)
{
case 0: return I_PICTURE;
case 1: return P_PICTURE;
case 2: return B_PICTURE;
case 3: return D_PICTURE; // SPRITE picture?
}
}
return NONE_PICTURE;
}
bool MP4Muxer::needNewFragment(MediaData *lpData, Ipp32s nTrak)
{
if (m_pParams->m_lFlags & FLAG_FRAGMENTED_BY_HEADER_SIZE) {
Ipp32u nHeaderSize = (m_bMoov ? m_nMoovSize : m_nMoofSize) - 28 * m_headerMPEG4.total_tracks;
if (m_nHeaderSize >= nHeaderSize && I_PICTURE == GetPictureType(lpData, nTrak)) {
vm_debug_trace_s(VM_DEBUG_PROGRESS, "needNewFragment");
return true;
}
}
/*if (m_pParams->m_lFlags & FLAG_FRAGMENTED_NUMBER_FRAMES) {
if ((m_sTrack[nTrak].m_nSamplesCount & 15) == 15) {
vm_debug_trace_s(VM_DEBUG_PROGRESS, "needNewFragment");
return true;
}
}*/
if (m_pParams->m_lFlags & FLAG_FRAGMENTED_AT_I_PICTURES) {
if (m_sTrack[nTrak].m_nSamplesCount > 10 && I_PICTURE == GetPictureType(lpData, nTrak)) {
vm_debug_trace_s(VM_DEBUG_PROGRESS, "needNewFragment");
return true;
}
}
return false;
}
Status MP4Muxer::TransferDataFromTemporaryFile(vm_file* fTemp)
{
DataWriter *m_lpDataWriter = m_pParams->m_lpDataWriter;
Ipp32s nsize = 0;
Ipp8s buffer[1024 + 16];
vm_debug_trace_s(VM_DEBUG_PROGRESS, "TransferDataFromTemporaryFile");
nsize = vm_file_fread(buffer, 1, 1024, fTemp);
while(0 != nsize)
{
m_lpDataWriter->PutData(buffer, nsize);
nsize = vm_file_fread(buffer, 1, 1024, fTemp);
}
vm_file_fclose(fTemp);
vm_debug_trace_s(VM_DEBUG_PROGRESS, "TransferDataFromTemporaryFile OK");
return UMC_OK;
};
Status MP4Muxer::WriteMdatSize()
{
_SEEK_FILE_START(m_fTempOutput1);
Write_size(m_fTempOutput1, m_nMdatSize + 8);
_SEEK_FILE_START(m_fTempOutput1);
return UMC_OK;
};
Status MP4Muxer::SetHeaderSizes(Ipp32s nMoovSize, Ipp32s nMoofSize)
{
m_nMoovSize = nMoovSize;
m_nMoofSize = nMoofSize;
return UMC_OK;
};
} // namespace UMC
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -