[svn] / trunk / xvidextra / src / apps / miniconvert / filters.cpp Repository:
ViewVC logotype

Annotation of /trunk/xvidextra/src/apps/miniconvert/filters.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2014 - (view) (download)

1 : Irhall 2014 /*****************************************************************************
2 :     *
3 :     * Xvid MiniConvert
4 :     * - Helper filters -
5 :     *
6 :     * Copyright(C) 2011 Xvid Solutions GmbH
7 :     *
8 :     * This program is free software ; you can redistribute it and/or modify
9 :     * it under the terms of the GNU General Public License as published by
10 :     * the Free Software Foundation ; either version 2 of the License, or
11 :     * (at your option) any later version.
12 :     *
13 :     * This program is distributed in the hope that it will be useful,
14 :     * but WITHOUT ANY WARRANTY ; without even the implied warranty of
15 :     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 :     * GNU General Public License for more details.
17 :     *
18 :     * You should have received a copy of the GNU General Public License
19 :     * along with this program ; if not, write to the Free Software
20 :     * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 :     *
22 :     * $Id$
23 :     *
24 :     ****************************************************************************/
25 :     /*
26 :     * Author(s): Ireneusz Hallmann
27 :     *
28 :     ****************************************************************************/
29 :    
30 :     #include "stdafx.h"
31 :     #include "filters.h"
32 :     #include "mmreg.h" // WAVE_FORMAT_MPEGLAYER3 format structure
33 :    
34 :     //////////////////////////////////////////////////////////////////////////////////////////////////
35 :    
36 :     CUnknown * WINAPI
37 :     CProgressNotifyFilter::CreateInstance(IUnknown *pUnk, HRESULT *phr, int Type)
38 :     {
39 :     CUnknown *pNewFilter = new CProgressNotifyFilter(pUnk, phr, Type);
40 :    
41 :     if (phr) {
42 :     if (pNewFilter == NULL) *phr = E_OUTOFMEMORY;
43 :     else *phr = S_OK;
44 :     }
45 :    
46 :     return pNewFilter;
47 :     }
48 :    
49 :     CProgressNotifyFilter::CProgressNotifyFilter(LPUNKNOWN pUnk, HRESULT *phr, int Type) :
50 :     CTransInPlaceFilter("ProgressNotify", pUnk, CLSID_ProgressNotifyFilter, phr, false)
51 :     {
52 :     m_MessageWnd = 0;
53 :     m_SampleCnt = 0;
54 :     m_Pass = 1;
55 :     m_Type = Type;
56 :     m_startTime = 0;
57 :     m_stopTime = 0;
58 :     m_Width = 0, m_Height = 0;
59 :     m_AvgTimeForFrame = 0;
60 :    
61 :     if (*phr) *phr = S_OK;
62 :     }
63 :    
64 :    
65 :     CProgressNotifyFilter::~CProgressNotifyFilter(void)
66 :     {
67 :     }
68 :    
69 :     HRESULT
70 :     CProgressNotifyFilter::NonDelegatingQueryInterface(REFIID riid, void ** ppv)
71 :     {
72 :     if (riid == IID_IRecProgressNotify)
73 :     return GetInterface((IRecProgressNotify*)this, ppv);
74 :    
75 :     return CBaseFilter::NonDelegatingQueryInterface (riid, ppv);
76 :     }
77 :    
78 :     HRESULT
79 :     CProgressNotifyFilter::CheckInputType(const CMediaType *mtIn)
80 :     {
81 :     if (mtIn->majortype != MEDIATYPE_Video &&
82 :     mtIn->majortype != MEDIATYPE_Audio) {
83 :    
84 :     return VFW_E_TYPE_NOT_ACCEPTED;
85 :     }
86 :    
87 :     if (mtIn->formattype != FORMAT_None) {
88 :    
89 :     if (mtIn->formattype == FORMAT_VideoInfo ||
90 :     mtIn->formattype == FORMAT_MPEGVideo) {
91 :    
92 :     m_AvgTimeForFrame = ((VIDEOINFOHEADER *)mtIn->pbFormat)->AvgTimePerFrame;
93 :     m_Width = ((VIDEOINFOHEADER *)mtIn->pbFormat)->bmiHeader.biWidth;
94 :     m_Height = ((VIDEOINFOHEADER *)mtIn->pbFormat)->bmiHeader.biHeight;
95 :    
96 :     }
97 :     else if (mtIn->formattype == FORMAT_VideoInfo2 ||
98 :     mtIn->formattype == FORMAT_MPEG2Video) {
99 :    
100 :     m_AvgTimeForFrame = ((VIDEOINFOHEADER2 *)mtIn->pbFormat)->AvgTimePerFrame;
101 :     m_Width = ((VIDEOINFOHEADER2 *)mtIn->pbFormat)->bmiHeader.biWidth;
102 :     m_Height = ((VIDEOINFOHEADER2 *)mtIn->pbFormat)->bmiHeader.biHeight;
103 :    
104 :     }
105 :     else if (mtIn->formattype == FORMAT_WaveFormatEx && m_Type == 2) {
106 :    
107 :     MPEGLAYER3WAVEFORMAT *pMp3 = (MPEGLAYER3WAVEFORMAT *)mtIn->pbFormat;
108 :     if (pMp3->wfx.nAvgBytesPerSec != 16000)
109 :     return VFW_E_TYPE_NOT_ACCEPTED;
110 :    
111 :     // WAVEFORMATEX *pWaveFormat = (WAVEFORMATEX *)mtIn->pbFormat;
112 :     // if (pWaveFormat->nChannels > 2)
113 :     // return VFW_E_TYPE_NOT_ACCEPTED;
114 :    
115 :     }
116 :     else if (m_Type == 0) {
117 :     return VFW_E_TYPE_NOT_ACCEPTED;
118 :     }
119 :     }
120 :    
121 :     return S_OK;
122 :     }
123 :    
124 :     HRESULT
125 :     CProgressNotifyFilter::Transform(IMediaSample *pSample)
126 :     {
127 :     LONGLONG osTime, sTime, eTime;
128 :     pSample->GetTime(&osTime, &eTime);
129 :     sTime = osTime;
130 :     int bSetTime = 0;
131 :    
132 :     if (m_Type == 0) { // Video
133 :    
134 :     #if 0 // emms instruction - for debug
135 :     #ifdef __FUNCTION__
136 :     // Visual Studio
137 :     __asm emms;
138 :     #else
139 :     __asm ("emms");
140 :     #endif
141 :     #endif
142 :    
143 :     m_TotalDataSize += pSample->GetActualDataLength();
144 :     m_SampleCnt++;
145 :    
146 :     int CurPos = (int) (m_TotalFrames ? (((double)(100 * m_SampleCnt/m_TotalFrames) + 0.5)) : 0);
147 :    
148 :     if (m_Pass == 0) {
149 :     CurPos /= 2;
150 :     }
151 :     else if (m_Pass == 2) {
152 :     CurPos = CurPos/2 + 50;
153 :     }
154 :    
155 :     if (m_totalSize > 0) {
156 :     CurPos = ((CurPos*m_curSize) / m_totalSize);
157 :     CurPos += ((100*m_elapsedSize) / m_totalSize);
158 :     }
159 :    
160 :     if (m_MessageWnd)
161 :     PostMessage(m_MessageWnd, PBM_SETPOS, CurPos, 0);
162 :     }
163 :     else { // Audio
164 :     MPEGLAYER3WAVEFORMAT *pMp3 = 0;
165 :    
166 :     if (m_MediaType.subtype == MEDIASUBTYPE_MP3) {
167 :     pMp3 = (MPEGLAYER3WAVEFORMAT *)m_MediaType.pbFormat;
168 :    
169 :     DWORD ThisSamples = (pMp3->wfx.nSamplesPerSec >= 32000 ? 576 : 1152) * pMp3->nFramesPerBlock;
170 :     m_SampleCnt += ThisSamples;
171 :    
172 :     LONGLONG sDuration = eTime - sTime;
173 :     if (((m_SampleCnt || sTime) && sTime <= m_stopTime)) {
174 :     sTime = m_stopTime + 1;
175 :     bSetTime = 1;
176 :     }
177 :     if (eTime <= sTime || sDuration != (ThisSamples * 10000000LL * m_FpsDen)/m_FpsNom) {
178 :     sDuration = (ThisSamples * 10000000LL * m_FpsDen)/m_FpsNom - 1;
179 :     eTime = sTime + sDuration;
180 :     bSetTime = 1;
181 :     }
182 :     sTime = osTime; //!!
183 :    
184 :     pSample->SetSyncPoint(TRUE);
185 :     }
186 :     }
187 :    
188 :     if (bSetTime)
189 :     pSample->SetTime(&sTime, &eTime);
190 :    
191 :     m_startTime = sTime;
192 :     m_stopTime = eTime;
193 :    
194 :     return S_OK;
195 :     }
196 :    
197 :     HRESULT
198 :     CProgressNotifyFilter::CompleteConnect(PIN_DIRECTION direction, IPin *pReceivePin)
199 :     {
200 :     HRESULT hr = pReceivePin->ConnectionMediaType(&m_MediaType);
201 :     m_MinSampleSize = 0;
202 :    
203 :     if (hr == S_OK) {
204 :     if (m_MediaType.formattype == FORMAT_VideoInfo
205 :     || m_MediaType.formattype == FORMAT_MPEGVideo) {
206 :    
207 :     m_AvgTimeForFrame = ((VIDEOINFOHEADER *)m_MediaType.pbFormat)->AvgTimePerFrame;
208 :    
209 :     if (direction == PINDIR_INPUT) {
210 :     if (m_MediaType.bTemporalCompression || m_MediaType.lSampleSize <=1) {
211 :     m_MinSampleSize = ((VIDEOINFOHEADER *)m_MediaType.pbFormat)->bmiHeader.biHeight *
212 :     ((VIDEOINFOHEADER *)m_MediaType.pbFormat)->bmiHeader.biWidth * 4;
213 :     }
214 :     }
215 :     }
216 :     else if (m_MediaType.formattype == FORMAT_VideoInfo2 ||
217 :     m_MediaType.formattype == FORMAT_MPEG2Video) {
218 :     m_AvgTimeForFrame = ((VIDEOINFOHEADER2 *)m_MediaType.pbFormat)->AvgTimePerFrame;
219 :    
220 :     if (direction == PINDIR_INPUT) {
221 :     if (m_MediaType.bTemporalCompression || m_MediaType.lSampleSize <=1) {
222 :     m_MinSampleSize = ((VIDEOINFOHEADER2 *)m_MediaType.pbFormat)->bmiHeader.biHeight *
223 :     ((VIDEOINFOHEADER2 *)m_MediaType.pbFormat)->bmiHeader.biWidth * 4;
224 :     }
225 :     }
226 :     }
227 :     else if (m_Type == 0) {
228 :     hr = VFW_E_TYPE_NOT_ACCEPTED;
229 :     }
230 :    
231 :     if (m_AvgTimeForFrame) {
232 :    
233 :     switch (m_AvgTimeForFrame) {
234 :     case 416666: // 24.0 FPS
235 :     m_FpsNom = 24;
236 :     m_FpsDen = 1;
237 :     break;
238 :    
239 :     case 417083: // 23.97 FPS
240 :     m_FpsNom = 24000;
241 :     m_FpsDen = 1001;
242 :     break;
243 :    
244 :     case 333333: // 30.0 FPS
245 :     m_FpsNom = 30;
246 :     m_FpsDen = 1;
247 :     break;
248 :    
249 :     case 333666: // 29.97 FPS
250 :     m_FpsNom = 30000;
251 :     m_FpsDen = 1001;
252 :     break;
253 :    
254 :     default:
255 :     m_FpsNom = (int) (10000000 / m_AvgTimeForFrame);
256 :     m_FpsDen = 1;
257 :     }
258 :     }
259 :     else if (m_Type == 1 || m_Type == 2) {
260 :     WAVEFORMATEX *pWave = (WAVEFORMATEX *)m_MediaType.pbFormat;
261 :     m_FpsNom = pWave->nSamplesPerSec;
262 :     m_FpsDen = 1;
263 :     }
264 :     }
265 :    
266 :     return hr;
267 :     }
268 :    
269 :     HRESULT
270 :     CProgressNotifyFilter::DecideBufferSize(IMemAllocator *pAlloc,
271 :     ALLOCATOR_PROPERTIES *pProperties)
272 :     {
273 :     ALLOCATOR_PROPERTIES Request, Actual;
274 :     HRESULT hr;
275 :    
276 :     // If we are connected upstream, get his views
277 :     if (m_pInput->IsConnected()) {
278 :     // Get the input pin allocator, and get its size and count.
279 :     // we don't care about his alignment and prefix.
280 :    
281 :     hr = InputPin()->PeekAllocator()->GetProperties(&Request);
282 :    
283 :     if (FAILED(hr)) {
284 :     // Input connected but with a secretive allocator - enough!
285 :     return hr;
286 :     }
287 :    
288 :     if (m_MinSampleSize && (m_Type == 0)) {
289 :     if (Request.cbBuffer < m_MinSampleSize) {
290 :     Request.cbBuffer = m_MinSampleSize;
291 :     }
292 :     }
293 :     }
294 :     else {
295 :     // We're reduced to blind guessing. Let's guess one byte and if
296 :     // this isn't enough then when the other pin does get connected
297 :     // we can revise it.
298 :    
299 :     ZeroMemory(&Request, sizeof(Request));
300 :     Request.cBuffers = 1;
301 :     Request.cbBuffer = 1;
302 :     }
303 :    
304 :     #ifdef _DEBUG
305 :     DbgLog((LOG_MEMORY,1,TEXT("Setting Allocator Requirements")));
306 :     DbgLog((LOG_MEMORY,1,TEXT("Count %d, Size %d"), Request.cBuffers, Request.cbBuffer));
307 :     #endif
308 :    
309 :     // Pass the allocator requirements to our output side
310 :     // but do a little sanity checking first or we'll just hit
311 :     // asserts in the allocator.
312 :    
313 :     pProperties->cBuffers = Request.cBuffers;
314 :     pProperties->cbBuffer = Request.cbBuffer;
315 :     pProperties->cbAlign = Request.cbAlign;
316 :    
317 :     if (pProperties->cBuffers<=0) {
318 :     pProperties->cBuffers = 1;
319 :     }
320 :    
321 :     if (pProperties->cbBuffer<=0) {
322 :     pProperties->cbBuffer = 1;
323 :     }
324 :    
325 :     hr = pAlloc->SetProperties(pProperties, &Actual);
326 :     if (FAILED(hr)) {
327 :     return hr;
328 :     }
329 :    
330 :     #ifdef _DEBUG
331 :     DbgLog((LOG_MEMORY,1,TEXT("Obtained Allocator Requirements")));
332 :     DbgLog((LOG_MEMORY,1,TEXT("Count %d, Size %d, Alignment %d"),
333 :     Actual.cBuffers, Actual.cbBuffer, Actual.cbAlign));
334 :     #endif
335 :    
336 :     // Make sure we got the right alignment and at least the minimum required
337 :     if ((Request.cBuffers > Actual.cBuffers) ||
338 :     (Request.cbBuffer > Actual.cbBuffer) ||
339 :     (Request.cbAlign > Actual.cbAlign))
340 :     {
341 :     return E_FAIL;
342 :     }
343 :    
344 :     return NOERROR;
345 :     }
346 :    
347 :     //////////////////////////////////////////////////////////////////////////////////////////
348 :    
349 :     HRESULT
350 :     CIRecProgressNotify::GetDimensions(DWORD &Width, DWORD &Height)
351 :     {
352 :     Width = m_Width;
353 :     Height = m_Height;
354 :    
355 :     return S_OK;
356 :     }
357 :    
358 :     HRESULT
359 :     CIRecProgressNotify::GetBitrate(DWORD &OutFramesCount,
360 :     LONGLONG &OutTotalDataSize)
361 :     {
362 :     OutFramesCount = m_SampleCnt;
363 :     OutTotalDataSize = m_TotalDataSize;
364 :    
365 :     return S_OK;
366 :     }
367 :    
368 :     HRESULT
369 :     CIRecProgressNotify::SetPass(int in_Pass)
370 :     {
371 :     m_Pass = in_Pass;
372 :     m_SampleCnt = 0;
373 :    
374 :     return S_OK;
375 :     }
376 :    
377 :     HRESULT
378 :     CIRecProgressNotify::SetTotalFrames(DWORD in_TotalFrames)
379 :     {
380 :     m_TotalFrames = in_TotalFrames;
381 :    
382 :     return S_OK;
383 :     }
384 :    
385 :     HRESULT
386 :     CIRecProgressNotify::SetNotifyWnd(HWND in_hWnd)
387 :     {
388 :     m_MessageWnd = in_hWnd;
389 :    
390 :     return S_OK;
391 :     }
392 :    
393 :     STDMETHODIMP
394 :     CIRecProgressNotify::SetTotalSize(int nbTotal)
395 :     {
396 :     m_totalSize = nbTotal;
397 :    
398 :     return S_OK;
399 :     }
400 :    
401 :     STDMETHODIMP
402 :     CIRecProgressNotify::SetCurSize(int nbCur)
403 :     {
404 :     m_curSize = nbCur;
405 :    
406 :     return S_OK;
407 :     }
408 :    
409 :     STDMETHODIMP
410 :     CIRecProgressNotify::SetElapsedSize(int nbElapsed)
411 :     {
412 :     m_elapsedSize = nbElapsed;
413 :    
414 :     return S_OK;
415 :     }
416 :    
417 :     CIRecProgressNotify::CIRecProgressNotify()
418 :     {
419 :     m_Pass = -1;
420 :     m_MessageWnd = 0;
421 :     m_TotalFrames = 0;
422 :     m_SampleCnt = 0;
423 :     m_TotalDataSize = 0;
424 :     m_totalSize = 0;
425 :     m_curSize = 0;
426 :     m_elapsedSize = 0;
427 :     }
428 :    
429 :     //////////////////////////////////////////////////////////////////
430 :    
431 :     CUnknown * WINAPI
432 :     ChangeSubtypeT::CreateInstance(IUnknown *pUnk, HRESULT *phr)
433 :     {
434 :     CUnknown *pNewFilter = new ChangeSubtypeT(pUnk, phr );
435 :    
436 :     if (phr) {
437 :     if (pNewFilter == NULL) *phr = E_OUTOFMEMORY;
438 :     else *phr = S_OK;
439 :     }
440 :    
441 :     return pNewFilter;
442 :     }
443 :    
444 :     ChangeSubtypeT::ChangeSubtypeT(LPUNKNOWN pUnk, HRESULT *phr) :
445 :     CTransformFilter("ChangeSubtypeT", pUnk, CLSID_ChangeSubtypeT)
446 :     {
447 :     m_OutFcc = 'DIVX'; // == FCC('xvid')
448 :     m_SubtypeID = FOURCCMap('divx'); // FCC('XVID')
449 :     m_SampleCnt = 0;
450 :    
451 :     if (*phr) *phr = S_OK;
452 :    
453 :     m_pMpeg4Sequence = 0;
454 :     m_Mpeg4SequenceSize = 0;
455 :     }
456 :    
457 :     ChangeSubtypeT::~ChangeSubtypeT(void)
458 :     {
459 :     }
460 :    
461 :     HRESULT
462 :     ChangeSubtypeT::NonDelegatingQueryInterface(REFIID riid, void ** ppv)
463 :     {
464 :     if (riid == IID_IRecProgressNotify)
465 :     return GetInterface((IRecProgressNotify*)this, ppv);
466 :    
467 :     return CBaseFilter::NonDelegatingQueryInterface (riid, ppv);
468 :     }
469 :    
470 :     HRESULT
471 :     ChangeSubtypeT::CheckInputType(const CMediaType *pmt)
472 :     {
473 :     if (!pmt)
474 :     return E_POINTER;
475 :    
476 :     if (pmt->majortype != MEDIATYPE_Video)
477 :     return S_FALSE;
478 :    
479 :     return S_OK;
480 :     }
481 :    
482 :     HRESULT
483 :     ChangeSubtypeT::CheckTransform (const CMediaType *pmtIn, const CMediaType *pmtOut)
484 :     {
485 :     if (!m_pInput->IsConnected())
486 :     return E_UNEXPECTED;
487 :    
488 :     if (pmtIn->majortype != MEDIATYPE_Video)
489 :     return VFW_E_TYPE_NOT_ACCEPTED;
490 :    
491 :     BITMAPINFOHEADER *pBmp = 0;
492 :    
493 :     if (pmtOut->majortype == MEDIATYPE_Video) {
494 :    
495 :     if (m_SubtypeID != pmtOut->subtype)
496 :     return VFW_E_TYPE_NOT_ACCEPTED;
497 :    
498 :     if (!pmtOut->pbFormat)
499 :     return S_OK;
500 :    
501 :     if (pmtOut->formattype == FORMAT_VideoInfo ||
502 :     pmtOut->formattype == FORMAT_MPEGVideo)
503 :     {
504 :     pBmp = &((VIDEOINFOHEADER *)pmtOut->pbFormat)->bmiHeader;
505 :     }
506 :     else if (pmtOut->formattype == FORMAT_VideoInfo2 ||
507 :     pmtOut->formattype == FORMAT_MPEG2Video)
508 :     {
509 :     pBmp = &((VIDEOINFOHEADER2 *)pmtOut->pbFormat)->bmiHeader;
510 :     }
511 :     else
512 :     return VFW_E_TYPE_NOT_ACCEPTED;
513 :    
514 :     if (m_OutFcc == pBmp->biCompression)
515 :     return S_OK;
516 :     }
517 :    
518 :     return VFW_E_TYPE_NOT_ACCEPTED;
519 :     }
520 :    
521 :     HRESULT
522 :     ChangeSubtypeT::DecideBufferSize(IMemAllocator * pAlloc,
523 :     ALLOCATOR_PROPERTIES * ppropInputRequest)
524 :     {
525 :     if (!m_pInput->IsConnected())
526 :     return E_UNEXPECTED;
527 :    
528 :     HRESULT hr = NOERROR;
529 :     BITMAPINFOHEADER *pBmp = 0;
530 :    
531 :     if (!m_OutMediaType.pbFormat)
532 :     return VFW_E_TYPE_NOT_ACCEPTED;
533 :    
534 :     if (m_OutMediaType.formattype == FORMAT_VideoInfo ||
535 :     m_OutMediaType.formattype == FORMAT_MPEGVideo)
536 :     {
537 :     pBmp = &((VIDEOINFOHEADER *)m_OutMediaType.pbFormat)->bmiHeader;
538 :     }
539 :     else if (m_OutMediaType.formattype == FORMAT_VideoInfo2 ||
540 :     m_OutMediaType.formattype == FORMAT_MPEG2Video)
541 :     {
542 :     pBmp = &((VIDEOINFOHEADER2 *)m_OutMediaType.pbFormat)->bmiHeader;
543 :     }
544 :     else
545 :     return VFW_E_TYPE_NOT_ACCEPTED;
546 :    
547 :     ppropInputRequest->cBuffers = 1;
548 :     ppropInputRequest->cbBuffer = pBmp->biHeight*pBmp->biWidth * (pBmp->biBitCount+7)/8;
549 :    
550 :     ALLOCATOR_PROPERTIES Actual;
551 :     hr = pAlloc->SetProperties(ppropInputRequest,&Actual);
552 :     if (FAILED(hr))
553 :     return hr;
554 :    
555 :     if (ppropInputRequest->cBuffers > Actual.cBuffers ||
556 :     ppropInputRequest->cbBuffer > Actual.cbBuffer)
557 :     return E_FAIL;
558 :    
559 :     return S_OK;
560 :     }
561 :    
562 :     HRESULT
563 :     ChangeSubtypeT::GetMediaType(int iPosition, CMediaType *pMediaType)
564 :     {
565 :     if (!m_pInput->IsConnected()) {
566 :     return E_UNEXPECTED;
567 :     }
568 :     else if (iPosition < 0) {
569 :     return E_INVALIDARG;
570 :     }
571 :     else if (iPosition > 0) {
572 :     return VFW_S_NO_MORE_ITEMS;
573 :     }
574 :     else { //if (iPosition == 0)
575 :     *pMediaType = m_OutMediaType;
576 :     return S_OK;
577 :     }
578 :     }
579 :    
580 :     HRESULT
581 :     ChangeSubtypeT::CompleteConnect(PIN_DIRECTION direction, IPin *pReceivePin)
582 :     {
583 :     CMediaType mt;
584 :     BITMAPINFOHEADER *pBmp = 0;
585 :     pReceivePin->ConnectionMediaType(&mt);
586 :    
587 :     if (mt.majortype == MEDIATYPE_Video) {
588 :     if (direction == PINDIR_INPUT) {
589 :    
590 :     // if (m_pOutput->IsConnected()) {
591 :     // m_pInput->BreakConnection();
592 :     // }
593 :    
594 :     m_InMediaType = mt;
595 :     m_OutMediaType = mt;
596 :     m_OutMediaType.subtype = m_SubtypeID;
597 :    
598 :     int NewSequenceSize = 0;
599 :    
600 :     if (m_InMediaType.formattype == FORMAT_VideoInfo ||
601 :     m_InMediaType.formattype == FORMAT_MPEGVideo)
602 :     {
603 :     pBmp = &((VIDEOINFOHEADER *)m_InMediaType.pbFormat)->bmiHeader;
604 :     m_AvgTimeForFrame = (DWORD) ((VIDEOINFOHEADER *)m_InMediaType.pbFormat)->AvgTimePerFrame;
605 :     }
606 :     else {
607 :     if (m_OutMediaType.formattype == FORMAT_VideoInfo2 ||
608 :     m_OutMediaType.formattype == FORMAT_MPEG2Video)
609 :     {
610 :     pBmp = &((VIDEOINFOHEADER2 *)m_InMediaType.pbFormat)->bmiHeader;
611 :     m_AvgTimeForFrame = (DWORD) ((VIDEOINFOHEADER2 *)m_InMediaType.pbFormat)->AvgTimePerFrame;
612 :     }
613 :     else
614 :     return VFW_E_TYPE_NOT_ACCEPTED;
615 :     }
616 :    
617 :     if (*m_InMediaType.FormatType() == FORMAT_MPEG2Video) {
618 :     MPEG2VIDEOINFO *mpeg2info=(MPEG2VIDEOINFO*)m_InMediaType.Format();
619 :    
620 :     if (mpeg2info->hdr.bmiHeader.biCompression!=0 && mpeg2info->cbSequenceHeader>0) {
621 :    
622 :     if (m_pMpeg4Sequence)
623 :     free(m_pMpeg4Sequence);
624 :    
625 :     m_Mpeg4SequenceSize = mpeg2info->cbSequenceHeader;
626 :    
627 :     if (m_Mpeg4SequenceSize > 0) {
628 :     m_pMpeg4Sequence = (BYTE *)malloc(m_Mpeg4SequenceSize*sizeof(BYTE));
629 :     memcpy(m_pMpeg4Sequence, (const BYTE *)mpeg2info->dwSequenceHeader, m_Mpeg4SequenceSize);
630 :     }
631 :     }
632 :     }
633 :    
634 :     VIDEOINFOHEADER * pVih = (VIDEOINFOHEADER*)m_OutMediaType.ReallocFormatBuffer(sizeof(VIDEOINFOHEADER));
635 :     if (pVih==NULL) {
636 :     return E_OUTOFMEMORY;
637 :     }
638 :    
639 :     ZeroMemory(pVih, sizeof (VIDEOINFOHEADER));
640 :     CopyMemory(&pVih->bmiHeader, pBmp, sizeof(BITMAPINFOHEADER));
641 :    
642 :     /* set output format */
643 :     m_OutMediaType.SetType(&MEDIATYPE_Video);
644 :     m_OutMediaType.SetFormatType(&FORMAT_VideoInfo);
645 :    
646 :     m_OutMediaType.SetSubtype(&m_SubtypeID);
647 :     pVih->bmiHeader.biCompression = m_OutFcc;
648 :    
649 :     pVih->AvgTimePerFrame = m_AvgTimeForFrame;
650 :     pVih->dwBitErrorRate = 0;
651 :     pVih->dwBitRate = 8 * (DWORD)(((float)pVih->bmiHeader.biSizeImage * 10000000) / m_AvgTimeForFrame);
652 :    
653 :     m_OutMediaType.SetTemporalCompression(TRUE);
654 :     m_OutMediaType.SetVariableSize();
655 :    
656 :     if (m_AvgTimeForFrame) {
657 :     switch (m_AvgTimeForFrame) {
658 :    
659 :     case 416666: // 24.0 FPS
660 :     m_FpsNom = 24;
661 :     m_FpsDen = 1;
662 :     break;
663 :    
664 :     case 417083: // 23.97 FPS
665 :     m_FpsNom = 24000;
666 :     m_FpsDen = 1001;
667 :     break;
668 :    
669 :     case 333333: // 30.0 FPS
670 :     m_FpsNom = 30;
671 :     m_FpsDen = 1;
672 :     break;
673 :    
674 :     case 333666: // 29.97 FPS
675 :     m_FpsNom = 30000;
676 :     m_FpsDen = 1001;
677 :     break;
678 :    
679 :     default:
680 :     m_FpsNom = (int) (10000000 / m_AvgTimeForFrame);
681 :     m_FpsDen = 1;
682 :     }
683 :     }
684 :    
685 :     m_SampleCnt = 0;
686 :     return S_OK;
687 :     }
688 :     else { // if (direction == PINDIR_OUTPUT) {
689 :     if (!m_pInput->IsConnected())
690 :     return E_UNEXPECTED;
691 :    
692 :     if (m_SubtypeID != mt.subtype)
693 :     return VFW_E_TYPE_NOT_ACCEPTED;
694 :    
695 :     if (!mt.pbFormat)
696 :     return VFW_E_TYPE_NOT_ACCEPTED;
697 :    
698 :     if (mt.formattype == FORMAT_VideoInfo ||
699 :     mt.formattype == FORMAT_MPEGVideo)
700 :     {
701 :     pBmp = &((VIDEOINFOHEADER *)mt.pbFormat)->bmiHeader;
702 :     }
703 :     else if (mt.formattype == FORMAT_VideoInfo2 ||
704 :     mt.formattype == FORMAT_MPEG2Video)
705 :     {
706 :     pBmp = &((VIDEOINFOHEADER2 *)mt.pbFormat)->bmiHeader;
707 :     }
708 :     else
709 :     return VFW_E_TYPE_NOT_ACCEPTED;
710 :    
711 :     if (m_OutFcc == pBmp->biCompression)
712 :     return S_OK;
713 :     }
714 :     }
715 :    
716 :     return VFW_E_TYPE_NOT_ACCEPTED;
717 :     }
718 :    
719 :     HRESULT
720 :     ChangeSubtypeT::Transform(IMediaSample *pIn, IMediaSample *pOut)
721 :     {
722 :     BITMAPINFOHEADER *pBmpIn=0, *pBmpOut=0;
723 :     HRESULT hr = S_FALSE;
724 :    
725 :     if (m_InMediaType.formattype == FORMAT_VideoInfo ||
726 :     m_InMediaType.formattype == FORMAT_MPEGVideo)
727 :     {
728 :     pBmpIn = &((VIDEOINFOHEADER *)m_InMediaType.pbFormat)->bmiHeader;
729 :     }
730 :     else if (m_InMediaType.formattype == FORMAT_VideoInfo2 ||
731 :     m_InMediaType.formattype == FORMAT_MPEG2Video)
732 :     {
733 :     pBmpIn = &((VIDEOINFOHEADER2 *)m_InMediaType.pbFormat)->bmiHeader;
734 :     }
735 :    
736 :     if (m_OutMediaType.formattype == FORMAT_VideoInfo ||
737 :     m_OutMediaType.formattype == FORMAT_MPEGVideo)
738 :     {
739 :     pBmpOut = &((VIDEOINFOHEADER *)m_OutMediaType.pbFormat)->bmiHeader;
740 :     }
741 :     else if (m_OutMediaType.formattype == FORMAT_VideoInfo2 ||
742 :     m_OutMediaType.formattype == FORMAT_MPEG2Video)
743 :     {
744 :     pBmpOut = &((VIDEOINFOHEADER2 *)m_OutMediaType.pbFormat)->bmiHeader;
745 :     }
746 :    
747 :     if (pBmpIn && pBmpOut && m_InMediaType.lSampleSize == m_OutMediaType.lSampleSize)
748 :     {
749 :     BYTE *pBufIn, *pBufOut;
750 :     pIn->GetPointer(&pBufIn);
751 :     pOut->GetPointer(&pBufOut);
752 :     DWORD lSize = pIn->GetActualDataLength();
753 :    
754 :     DWORD OutOffset = 0;
755 :     if (*((int *)pBufIn) != 0xB0010000 && m_pMpeg4Sequence) {
756 :     if (pIn->IsSyncPoint() == S_OK) { // I-VOP
757 :     memcpy(pBufOut, m_pMpeg4Sequence, m_Mpeg4SequenceSize);
758 :     OutOffset = m_Mpeg4SequenceSize;
759 :     }
760 :     }
761 :    
762 :     pOut->SetActualDataLength(lSize + OutOffset);
763 :     memcpy(&pBufOut[OutOffset], pBufIn, lSize);
764 :     LONGLONG UnitDuration = (10000000LL * m_FpsDen)/m_FpsNom;
765 :     LONGLONG NormalStart = (m_SampleCnt * 10000000LL * m_FpsDen)/m_FpsNom;
766 :     LONGLONG NormalEnd = ((m_SampleCnt + 1) * 10000000LL * m_FpsDen)/m_FpsNom;
767 :    
768 :     LONGLONG sTime, eTime;
769 :     pOut->GetTime(&sTime, &eTime);
770 :     int bSetTime = 0;
771 :     LONGLONG sDuration = eTime - sTime;
772 :    
773 :     // simply set correct end time - seems to work here...
774 :     if (eTime < sTime + UnitDuration) {
775 :     eTime = sTime + UnitDuration;
776 :     bSetTime = 1;
777 :     }
778 :    
779 :     if (bSetTime) pOut->SetTime(&sTime, &eTime);
780 :    
781 :     #if 0
782 :     LONGLONG sTime=0, eTime=0;
783 :     sTime = (m_SampleCnt * 10000000LL * m_FpsDen)/m_FpsNom;
784 :     eTime = ((m_SampleCnt + 1) * 10000000LL * m_FpsDen)/m_FpsNom - 1;
785 :     pOut->SetTime(&sTime, &eTime);
786 :     #endif
787 :    
788 :     m_startTime = sTime;
789 :     m_stopTime = eTime;
790 :     m_SampleCnt ++;
791 :    
792 :     int CurPos = (int) ((double)(100.0 * m_SampleCnt/m_TotalFrames) + 0.5);
793 :     if (m_Pass == 0)
794 :     CurPos /= 2;
795 :     else if (m_Pass == 2)
796 :     CurPos = CurPos /2 + 50;
797 :    
798 :     if (m_MessageWnd)
799 :     PostMessage(m_MessageWnd, PBM_SETPOS, CurPos, 0);
800 :    
801 :     hr = S_OK;
802 :     }
803 :    
804 :     return hr;
805 :     }

No admin address has been configured
ViewVC Help
Powered by ViewVC 1.0.4