105 |
else if (mtIn->formattype == FORMAT_WaveFormatEx && m_Type == 2) { |
else if (mtIn->formattype == FORMAT_WaveFormatEx && m_Type == 2) { |
106 |
|
|
107 |
MPEGLAYER3WAVEFORMAT *pMp3 = (MPEGLAYER3WAVEFORMAT *)mtIn->pbFormat; |
MPEGLAYER3WAVEFORMAT *pMp3 = (MPEGLAYER3WAVEFORMAT *)mtIn->pbFormat; |
108 |
if (pMp3->wfx.nAvgBytesPerSec != 16000) |
if (pMp3->wfx.nChannels >= 2 && pMp3->wfx.nAvgBytesPerSec != m_AudioBitrate) |
109 |
return VFW_E_TYPE_NOT_ACCEPTED; |
return VFW_E_TYPE_NOT_ACCEPTED; |
|
|
|
|
// WAVEFORMATEX *pWaveFormat = (WAVEFORMATEX *)mtIn->pbFormat; |
|
|
// if (pWaveFormat->nChannels > 2) |
|
|
// return VFW_E_TYPE_NOT_ACCEPTED; |
|
|
|
|
110 |
} |
} |
111 |
else if (m_Type == 0) { |
else if (m_Type == 0) { |
112 |
return VFW_E_TYPE_NOT_ACCEPTED; |
return VFW_E_TYPE_NOT_ACCEPTED; |
123 |
pSample->GetTime(&osTime, &eTime); |
pSample->GetTime(&osTime, &eTime); |
124 |
sTime = osTime; |
sTime = osTime; |
125 |
int bSetTime = 0; |
int bSetTime = 0; |
126 |
|
DWORD SamplesSize = pSample->GetActualDataLength(); |
127 |
|
|
128 |
if (m_Type == 0) { // Video |
if (m_Type == 0) { // Video |
129 |
|
|
162 |
if (m_MediaType.subtype == MEDIASUBTYPE_MP3) { |
if (m_MediaType.subtype == MEDIASUBTYPE_MP3) { |
163 |
pMp3 = (MPEGLAYER3WAVEFORMAT *)m_MediaType.pbFormat; |
pMp3 = (MPEGLAYER3WAVEFORMAT *)m_MediaType.pbFormat; |
164 |
|
|
165 |
DWORD ThisSamples = (pMp3->wfx.nSamplesPerSec >= 32000 ? 576 : 1152) * pMp3->nFramesPerBlock; |
DWORD ThisSamples = (pMp3->wfx.nSamplesPerSec >= 32000 ? 1152 : 576) * pMp3->nFramesPerBlock; |
|
m_SampleCnt += ThisSamples; |
|
166 |
|
|
167 |
LONGLONG sDuration = eTime - sTime; |
LONGLONG sDuration = eTime - sTime; |
168 |
if (((m_SampleCnt || sTime) && sTime <= m_stopTime)) { |
if (((m_SampleCnt || sTime) && sTime <= m_stopTime)) { |
175 |
bSetTime = 1; |
bSetTime = 1; |
176 |
} |
} |
177 |
sTime = osTime; //!! |
sTime = osTime; //!! |
178 |
|
m_SampleCnt += ThisSamples; |
179 |
|
|
180 |
pSample->SetSyncPoint(TRUE); |
pSample->SetSyncPoint(TRUE); |
181 |
} |
} |
410 |
return S_OK; |
return S_OK; |
411 |
} |
} |
412 |
|
|
413 |
|
STDMETHODIMP |
414 |
|
CIRecProgressNotify::GetMeasuredTimes (LONGLONG &outStopTimeMin, LONGLONG &outStopTimeMax, LONGLONG &outStartTimeMin, LONGLONG &outStartTimeMax) |
415 |
|
{ |
416 |
|
outStopTimeMin = m_StopTimeMin; |
417 |
|
outStopTimeMax = m_StopTimeMax; |
418 |
|
outStartTimeMin = m_StartTimeMin; |
419 |
|
outStartTimeMax = m_StartTimeMax; |
420 |
|
return S_OK; |
421 |
|
} |
422 |
|
|
423 |
|
STDMETHODIMP |
424 |
|
CIRecProgressNotify::SetForceTimeParams (LONGLONG inStartTimeOffset, LONGLONG inFpsNom, LONGLONG inFpsDen) |
425 |
|
{ |
426 |
|
m_StartTimeMin = inStartTimeOffset; |
427 |
|
m_FpsNom = inFpsNom; |
428 |
|
m_FpsDen = inFpsDen; |
429 |
|
m_bForceTimeStamps = 1; |
430 |
|
return S_OK; |
431 |
|
} |
432 |
|
|
433 |
|
STDMETHODIMP |
434 |
|
CIRecProgressNotify::SetAudioBitrate (int Bitrate) |
435 |
|
{ |
436 |
|
m_AudioBitrate = Bitrate; |
437 |
|
return S_OK; |
438 |
|
} |
439 |
|
|
440 |
CIRecProgressNotify::CIRecProgressNotify() |
CIRecProgressNotify::CIRecProgressNotify() |
441 |
{ |
{ |
442 |
m_Pass = -1; |
m_Pass = -1; |
447 |
m_totalSize = 0; |
m_totalSize = 0; |
448 |
m_curSize = 0; |
m_curSize = 0; |
449 |
m_elapsedSize = 0; |
m_elapsedSize = 0; |
450 |
|
m_StopTimeMin = m_StopTimeMax = m_StartTimeMin = m_StartTimeMax = 0; |
451 |
|
m_bForceTimeStamps = 0; |
452 |
|
m_AudioBitrate = 1600; |
453 |
} |
} |
454 |
|
|
455 |
////////////////////////////////////////////////////////////////// |
////////////////////////////////////////////////////////////////// |
709 |
} |
} |
710 |
|
|
711 |
m_SampleCnt = 0; |
m_SampleCnt = 0; |
712 |
|
m_UnitDuration = (10000000LL * m_FpsDen)/m_FpsNom; |
713 |
|
m_UnitTimeDelta = m_UnitDuration / 5; |
714 |
|
if (m_UnitTimeDelta < 1000) m_UnitTimeDelta = m_UnitDuration > 2000 ? 1000 : m_UnitDuration/2; |
715 |
|
m_stopTime = m_startTime = 0; |
716 |
|
|
717 |
|
|
718 |
|
m_MaxStartTime = m_MaxStopTime = 0; |
719 |
|
|
720 |
return S_OK; |
return S_OK; |
721 |
} |
} |
722 |
else { // if (direction == PINDIR_OUTPUT) { |
else { // if (direction == PINDIR_OUTPUT) { |
742 |
else |
else |
743 |
return VFW_E_TYPE_NOT_ACCEPTED; |
return VFW_E_TYPE_NOT_ACCEPTED; |
744 |
|
|
745 |
|
if (m_bForceTimeStamps) { |
746 |
|
if (m_OutMediaType.formattype == FORMAT_VideoInfo || |
747 |
|
m_OutMediaType.formattype == FORMAT_MPEGVideo) { |
748 |
|
((VIDEOINFOHEADER *)m_OutMediaType.pbFormat)->AvgTimePerFrame = |
749 |
|
m_AvgTimeForFrame = (DWORD) (m_FpsNom/m_FpsDen); |
750 |
|
} else if (m_OutMediaType.formattype == FORMAT_VideoInfo2 || |
751 |
|
m_OutMediaType.formattype == FORMAT_MPEG2Video) { |
752 |
|
((VIDEOINFOHEADER2 *)m_OutMediaType.pbFormat)->AvgTimePerFrame = |
753 |
|
m_AvgTimeForFrame = (DWORD) (m_FpsNom/m_FpsDen); |
754 |
|
} |
755 |
|
} |
756 |
|
|
757 |
if (m_OutFcc == pBmp->biCompression) |
if (m_OutFcc == pBmp->biCompression) |
758 |
return S_OK; |
return S_OK; |
759 |
} |
} |
799 |
|
|
800 |
DWORD OutOffset = 0; |
DWORD OutOffset = 0; |
801 |
if (*((int *)pBufIn) != 0xB0010000 && m_pMpeg4Sequence) { |
if (*((int *)pBufIn) != 0xB0010000 && m_pMpeg4Sequence) { |
802 |
if (pIn->IsSyncPoint() == S_OK) { // I-VOP |
int FrameType = -1; |
803 |
|
for (int iOffset=0; iOffset < (int) (lSize - 5) && FrameType == -1; iOffset++) { |
804 |
|
if (*((int *)(&(pBufIn[iOffset]))) == 0xB6010000) { |
805 |
|
FrameType = (pBufIn[iOffset + 4] >> 6)& 3; |
806 |
|
} |
807 |
|
} |
808 |
|
pOut->SetSyncPoint(FrameType == 0 ? TRUE : FALSE); |
809 |
|
//if (pIn->IsSyncPoint() == S_OK) { // I-VOP // IsSyncPoint() is not reliable !! |
810 |
|
if (FrameType == 0) { |
811 |
memcpy(pBufOut, m_pMpeg4Sequence, m_Mpeg4SequenceSize); |
memcpy(pBufOut, m_pMpeg4Sequence, m_Mpeg4SequenceSize); |
812 |
OutOffset = m_Mpeg4SequenceSize; |
OutOffset = m_Mpeg4SequenceSize; |
813 |
} |
} |
815 |
|
|
816 |
pOut->SetActualDataLength(lSize + OutOffset); |
pOut->SetActualDataLength(lSize + OutOffset); |
817 |
memcpy(&pBufOut[OutOffset], pBufIn, lSize); |
memcpy(&pBufOut[OutOffset], pBufIn, lSize); |
818 |
LONGLONG UnitDuration = (10000000LL * m_FpsDen)/m_FpsNom; |
LONGLONG ExpectedStart = m_stopTime; |
819 |
LONGLONG NormalStart = (m_SampleCnt * 10000000LL * m_FpsDen)/m_FpsNom; |
LONGLONG ExpectedStop = m_stopTime + m_UnitDuration; |
|
LONGLONG NormalEnd = ((m_SampleCnt + 1) * 10000000LL * m_FpsDen)/m_FpsNom; |
|
820 |
|
|
821 |
LONGLONG sTime, eTime; |
LONGLONG sTime, eTime; |
822 |
pOut->GetTime(&sTime, &eTime); |
pOut->GetTime(&sTime, &eTime); |
823 |
int bSetTime = 0; |
int bSetTime = 0; |
824 |
LONGLONG sDuration = eTime - sTime; |
LONGLONG sDuration = eTime - sTime; |
825 |
|
|
826 |
|
if (m_Pass == 1) { |
827 |
|
if (m_SampleCnt == 0) { |
828 |
|
m_StopTimeMin = m_StopTimeMax = eTime; |
829 |
|
m_StartTimeMin = m_StartTimeMax = sTime; |
830 |
|
} else { |
831 |
|
if (m_StopTimeMin > eTime) m_StopTimeMin = eTime; |
832 |
|
if (m_StopTimeMax < eTime) m_StopTimeMax = eTime; |
833 |
|
if (m_StartTimeMin > sTime) m_StartTimeMin = sTime; |
834 |
|
if (m_StartTimeMax < sTime) m_StartTimeMax = sTime; |
835 |
|
} |
836 |
|
} else if (m_SampleCnt == 0 && m_bForceTimeStamps) { |
837 |
|
m_UnitDuration = m_FpsNom/m_FpsDen; |
838 |
|
m_UnitTimeDelta = m_UnitDuration / 5; |
839 |
|
if (m_UnitTimeDelta < 1000) m_UnitTimeDelta = m_UnitDuration > 2000 ? 1000 : m_UnitDuration/2; |
840 |
|
} |
841 |
|
|
842 |
|
int bForceStopTime = 0; |
843 |
|
if (abs((long)((LONGLONG)(ExpectedStop - m_MaxStopTime))) < m_UnitTimeDelta) { |
844 |
|
// re-use of time that had one of previous samples |
845 |
|
// in case when times of samples are reordered |
846 |
|
// to keep exactly in sync with speed of playing of original speed |
847 |
|
// in long distance. Any way of calculation based on |
848 |
|
// number of samples may fail if stream is long enough |
849 |
|
// and frame duration is calculated not with |
850 |
|
// absolute precision (NTSC - family framerates: 23.98, 29.97, etc...) |
851 |
|
|
852 |
|
ExpectedStop = m_MaxStopTime; |
853 |
|
bForceStopTime = 1; |
854 |
|
if (ExpectedStart + m_UnitDuration > ExpectedStop + m_UnitTimeDelta) { |
855 |
|
ExpectedStart = m_MaxStartTime; |
856 |
|
if (ExpectedStart + m_UnitDuration > ExpectedStop) |
857 |
|
ExpectedStart = ExpectedStop - m_UnitDuration; |
858 |
|
} |
859 |
|
} |
860 |
|
|
861 |
|
//LONGLONG eTimeN = eTime * m_FpsNom, Den0 = 10000000LL * m_FpsDen; |
862 |
|
//int SampleEMin = ((eTimeN < 100000) ? 0 : eTimeN - 10000)/Den0, SampleEMax = (eTimeN + 10000)/Den0; |
863 |
|
//int TimeEDiff = eTime - m_stopTime; |
864 |
|
LONGLONG MaxStartTime = max(m_MaxStartTime, sTime), |
865 |
|
MaxStopTime = max(m_MaxStopTime, eTime); |
866 |
|
|
867 |
// simply set correct end time - seems to work here... |
// simply set correct end time - seems to work here... |
868 |
if (eTime < sTime + UnitDuration) { |
|
869 |
eTime = sTime + UnitDuration; |
//if (m_Pass ==2 && m_bForceTimeStamps) { |
870 |
|
// sTime = m_SampleCnt * m_FpsNom / m_FpsDen; |
871 |
|
// eTime = (m_SampleCnt +1) * m_FpsNom / m_FpsDen; |
872 |
|
// bSetTime = 1; |
873 |
|
//} |
874 |
|
|
875 |
|
if (eTime + m_UnitTimeDelta < sTime + m_UnitDuration) { |
876 |
|
eTime = sTime + m_UnitDuration; |
877 |
bSetTime = 1; |
bSetTime = 1; |
878 |
} |
} |
879 |
|
|
880 |
if (bSetTime) pOut->SetTime(&sTime, &eTime); |
if ((bForceStopTime) || (eTime + m_UnitDuration < ExpectedStop)) { |
881 |
|
//if ((bForceStopTime) || (eTime > ExpectedStop + m_UnitTimeDelta) || (eTime + m_UnitTimeDelta < ExpectedStop)) { |
882 |
|
eTime = ExpectedStop; |
883 |
|
sTime = ExpectedStart; |
884 |
|
bSetTime = 1; |
885 |
|
} |
886 |
|
m_MaxStartTime = max(MaxStartTime, sTime); |
887 |
|
m_MaxStopTime = max(MaxStopTime, eTime); |
888 |
|
|
889 |
#if 0 |
if (bSetTime) pOut->SetTime(&sTime, &eTime); |
|
LONGLONG sTime=0, eTime=0; |
|
|
sTime = (m_SampleCnt * 10000000LL * m_FpsDen)/m_FpsNom; |
|
|
eTime = ((m_SampleCnt + 1) * 10000000LL * m_FpsDen)/m_FpsNom - 1; |
|
|
pOut->SetTime(&sTime, &eTime); |
|
|
#endif |
|
890 |
|
|
891 |
m_startTime = sTime; |
m_startTime = sTime; |
892 |
m_stopTime = eTime; |
m_stopTime = eTime; |