Changeset 373 for dsfilters/demux_mpc/src/mpc_filter.cpp
- Timestamp:
- 12/15/07 19:09:12 (16 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
dsfilters/demux_mpc/src/mpc_filter.cpp
r372 r373 54 54 rtStop(0xFFFFFFFFFFFFFF), 55 55 rate(1.0), 56 ev_abort(TRUE) 56 ev_abort(TRUE), 57 ev_seek_ready(TRUE) 57 58 { 58 59 input = new CMPCInputPin(NAME("MPC Input Pin"), this, phr, L"In"); … … 61 62 62 63 ev_abort.Reset(); 64 ev_seek_ready.Set(); 63 65 } 64 66 … … 311 313 } 312 314 315 316 317 // IMediaSeeking 318 319 STDMETHODIMP CMPCDemux::GetCapabilities(DWORD* pCapabilities) 320 { 321 return pCapabilities ? *pCapabilities = 322 AM_SEEKING_CanGetStopPos|AM_SEEKING_CanGetDuration|AM_SEEKING_CanSeekAbsolute|AM_SEEKING_CanSeekForwards|AM_SEEKING_CanSeekBackwards, 323 S_OK : E_POINTER; 324 } 325 STDMETHODIMP CMPCDemux::CheckCapabilities(DWORD* pCapabilities) 326 { 327 CheckPointer(pCapabilities, E_POINTER); 328 if (*pCapabilities == 0) return S_OK; 329 DWORD caps; 330 GetCapabilities(&caps); 331 if ((caps&*pCapabilities) == 0) return E_FAIL; 332 if (caps == *pCapabilities) return S_OK; 333 return S_FALSE; 334 } 335 STDMETHODIMP CMPCDemux::IsFormatSupported(const GUID* pFormat) {return !pFormat ? E_POINTER : *pFormat == TIME_FORMAT_MEDIA_TIME ? S_OK : S_FALSE;} 336 STDMETHODIMP CMPCDemux::QueryPreferredFormat(GUID* pFormat) {return GetTimeFormat(pFormat);} 337 STDMETHODIMP CMPCDemux::GetTimeFormat(GUID* pFormat) {return pFormat ? *pFormat = TIME_FORMAT_MEDIA_TIME, S_OK : E_POINTER;} 338 STDMETHODIMP CMPCDemux::IsUsingTimeFormat(const GUID* pFormat) {return IsFormatSupported(pFormat);} 339 STDMETHODIMP CMPCDemux::SetTimeFormat(const GUID* pFormat) {return S_OK == IsFormatSupported(pFormat) ? S_OK : E_INVALIDARG;} 340 STDMETHODIMP CMPCDemux::GetStopPosition(LONGLONG* pStop) {return this->rtStop; } 341 STDMETHODIMP CMPCDemux::GetCurrentPosition(LONGLONG* pCurrent) {return E_NOTIMPL;} 342 STDMETHODIMP CMPCDemux::ConvertTimeFormat(LONGLONG* pTarget, const GUID* pTargetFormat, LONGLONG Source, const GUID* pSourceFormat) {return E_NOTIMPL;} 343 344 STDMETHODIMP CMPCDemux::SetPositions(LONGLONG* pCurrent, DWORD dwCurrentFlags, LONGLONG* pStop, DWORD dwStopFlags) 345 { 346 return SetPositionsInternal(0, pCurrent, dwCurrentFlags, pStop, dwStopFlags); 347 } 348 349 STDMETHODIMP CMPCDemux::GetPositions(LONGLONG* pCurrent, LONGLONG* pStop) 350 { 351 if(pCurrent) *pCurrent = rtCurrent; 352 if(pStop) *pStop = rtStop; 353 return S_OK; 354 } 355 STDMETHODIMP CMPCDemux::GetAvailable(LONGLONG* pEarliest, LONGLONG* pLatest) 356 { 357 if(pEarliest) *pEarliest = 0; 358 return GetDuration(pLatest); 359 } 360 STDMETHODIMP CMPCDemux::SetRate(double dRate) {return dRate > 0 ? rate = dRate, S_OK : E_INVALIDARG;} 361 STDMETHODIMP CMPCDemux::GetRate(double* pdRate) {return pdRate ? *pdRate = rate, S_OK : E_POINTER;} 362 STDMETHODIMP CMPCDemux::GetPreroll(LONGLONG* pllPreroll) {return pllPreroll ? *pllPreroll = 0, S_OK : E_POINTER;} 363 364 STDMETHODIMP CMPCDemux::GetDuration(LONGLONG* pDuration) 365 { 366 CheckPointer(pDuration, E_POINTER); 367 *pDuration = 0; 368 369 if (file) { 370 if (pDuration) *pDuration = file->duration_10mhz; 371 } 372 return S_OK; 373 } 374 375 STDMETHODIMP CMPCDemux::SetPositionsInternal(int iD, LONGLONG* pCurrent, DWORD dwCurrentFlags, LONGLONG* pStop, DWORD dwStopFlags) 376 { 377 // only our first pin can seek 378 if (iD != 0) return NOERROR; 379 380 381 CAutoLock cAutoLock(&lock_filter); 382 383 if (!pCurrent && !pStop || (dwCurrentFlags&AM_SEEKING_PositioningBitsMask) == AM_SEEKING_NoPositioning 384 && (dwStopFlags&AM_SEEKING_PositioningBitsMask) == AM_SEEKING_NoPositioning) 385 return S_OK; 386 387 REFERENCE_TIME rtCurrent = this->rtCurrent, rtStop = this->rtStop; 388 389 if (pCurrent) { 390 switch(dwCurrentFlags&AM_SEEKING_PositioningBitsMask) { 391 case AM_SEEKING_NoPositioning: break; 392 case AM_SEEKING_AbsolutePositioning: rtCurrent = *pCurrent; break; 393 case AM_SEEKING_RelativePositioning: rtCurrent = rtCurrent + *pCurrent; break; 394 case AM_SEEKING_IncrementalPositioning: rtCurrent = rtCurrent + *pCurrent; break; 395 } 396 } 397 398 if (pStop) { 399 switch(dwStopFlags&AM_SEEKING_PositioningBitsMask) { 400 case AM_SEEKING_NoPositioning: break; 401 case AM_SEEKING_AbsolutePositioning: rtStop = *pStop; break; 402 case AM_SEEKING_RelativePositioning: rtStop += *pStop; break; 403 case AM_SEEKING_IncrementalPositioning: rtStop = rtCurrent + *pStop; break; 404 } 405 } 406 407 if (this->rtCurrent == rtCurrent && this->rtStop == rtStop) { 408 return S_OK; 409 } 410 411 this->rtCurrent = rtCurrent; 412 this->rtStop = rtStop; 413 414 // now there are new valid Current and Stop positions 415 ev_seek_ready.Wait(); 416 ev_seek_ready.Reset(); 417 HRESULT hr = DoNewSeek(); 418 ev_seek_ready.Set(); 419 return hr; 420 } 421 422 423 STDMETHODIMP CMPCDemux::Pause() 424 { 425 CAutoLock lck(&lock_filter); 426 427 if (m_State == State_Stopped) { 428 429 ev_abort.Reset(); 430 431 // activate pins 432 for (int i=0; i<output.GetCount(); i++) output[i]->Active(); 433 if (input) input->Active(); 434 435 // seekneme na danu poziciu 436 DoNewSeek(); 437 438 // pustime parser thread 439 if (!ThreadExists()) { 440 Create(); 441 CallWorker(CMD_RUN); 442 } 443 } 444 445 m_State = State_Paused; 446 return NOERROR; 447 } 448 449 STDMETHODIMP CMPCDemux::Stop() 450 { 451 CAutoLock lock(&lock_filter); 452 HRESULT hr = NOERROR; 453 454 if (m_State != State_Stopped) { 455 456 // set abort 457 ev_abort.Set(); 458 if (reader) reader->BeginFlush(); 459 460 // deaktivujeme piny 461 if (input) input->Inactive(); 462 for (int i=0; i<output.GetCount(); i++) output[i]->Inactive(); 463 464 // zrusime parser thread 465 if (ThreadExists()) { 466 CallWorker(CMD_EXIT); 467 Close(); 468 } 469 470 if (reader) reader->EndFlush(); 471 ev_abort.Reset(); 472 } 473 474 475 m_State = State_Stopped; 476 return hr; 477 } 478 479 480 HRESULT CMPCDemux::DoNewSeek() 481 { 482 CMPCOutputPin *pin = output[0]; 483 HRESULT hr; 484 485 if (!pin->IsConnected()) return NOERROR; 486 487 // stop first 488 ev_abort.Set(); 489 if (reader) reader->BeginFlush(); 490 491 FILTER_STATE state = m_State; 492 493 // abort 494 if (state != State_Stopped) { 495 if (pin->ThreadExists()) { 496 pin->ev_abort.Set(); 497 hr = pin->DeliverBeginFlush(); 498 if (FAILED(hr)) { 499 ASSERT(FALSE); 500 } 501 if (ThreadExists()) { 502 CallWorker(CMD_STOP); 503 } 504 pin->CallWorker(CMD_STOP); 505 506 hr = pin->DeliverEndFlush(); 507 if (FAILED(hr)) { 508 ASSERT(FALSE); 509 } 510 pin->FlushQueue(); 511 } 512 } 513 514 pin->DoNewSegment(rtCurrent, rtStop, rate); 515 if (reader) reader->EndFlush(); 516 517 // seek the file 518 if (file) { 519 int64 sample_pos = (rtCurrent * file->sample_rate) / 10000000; 520 file->Seek(sample_pos); 521 } 522 523 ev_abort.Reset(); 524 525 if (state != State_Stopped) { 526 // spustime aj jeho thread 527 pin->FlushQueue(); 528 pin->ev_abort.Reset(); 529 if (pin->ThreadExists()) { 530 pin->CallWorker(CMD_RUN); 531 } 532 if (ThreadExists()) { 533 CallWorker(CMD_RUN); 534 } 535 } 536 537 return NOERROR; 538 } 539 313 540 DWORD CMPCDemux::ThreadProc() 314 541 { … … 318 545 switch (cmd) { 319 546 case CMD_EXIT: Reply(NOERROR); return 0; 320 case CMD_STOP: Reply(NOERROR); break; 547 case CMD_STOP: 548 { 549 Reply(NOERROR); 550 } 551 break; 321 552 case CMD_RUN: 322 553 { … … 361 592 REFERENCE_TIME tStart = (current_sample * 10000000) / file->sample_rate; 362 593 REFERENCE_TIME tStop = ((current_sample + 1152*file->audio_block_frames) * 10000000) / file->sample_rate; 363 packet.tStart = tStart; 364 packet.tStop = tStop; 594 595 packet.tStart = tStart - rtCurrent; 596 packet.tStop = tStop - rtCurrent; 365 597 366 598 // deliver packet 367 599 hr = output[0]->DeliverPacket(packet); 368 if (FAILED(hr)) break; 600 if (FAILED(hr)) { 601 break; 602 } 369 603 370 604 delivered++; … … 382 616 } 383 617 384 385 // IMediaSeeking386 387 STDMETHODIMP CMPCDemux::GetCapabilities(DWORD* pCapabilities)388 {389 return pCapabilities ? *pCapabilities =390 AM_SEEKING_CanGetStopPos|AM_SEEKING_CanGetDuration|AM_SEEKING_CanSeekAbsolute|AM_SEEKING_CanSeekForwards|AM_SEEKING_CanSeekBackwards,391 S_OK : E_POINTER;392 }393 STDMETHODIMP CMPCDemux::CheckCapabilities(DWORD* pCapabilities)394 {395 CheckPointer(pCapabilities, E_POINTER);396 if (*pCapabilities == 0) return S_OK;397 DWORD caps;398 GetCapabilities(&caps);399 if ((caps&*pCapabilities) == 0) return E_FAIL;400 if (caps == *pCapabilities) return S_OK;401 return S_FALSE;402 }403 STDMETHODIMP CMPCDemux::IsFormatSupported(const GUID* pFormat) {return !pFormat ? E_POINTER : *pFormat == TIME_FORMAT_MEDIA_TIME ? S_OK : S_FALSE;}404 STDMETHODIMP CMPCDemux::QueryPreferredFormat(GUID* pFormat) {return GetTimeFormat(pFormat);}405 STDMETHODIMP CMPCDemux::GetTimeFormat(GUID* pFormat) {return pFormat ? *pFormat = TIME_FORMAT_MEDIA_TIME, S_OK : E_POINTER;}406 STDMETHODIMP CMPCDemux::IsUsingTimeFormat(const GUID* pFormat) {return IsFormatSupported(pFormat);}407 STDMETHODIMP CMPCDemux::SetTimeFormat(const GUID* pFormat) {return S_OK == IsFormatSupported(pFormat) ? S_OK : E_INVALIDARG;}408 STDMETHODIMP CMPCDemux::GetStopPosition(LONGLONG* pStop) {return this->rtStop; }409 STDMETHODIMP CMPCDemux::GetCurrentPosition(LONGLONG* pCurrent) {return E_NOTIMPL;}410 STDMETHODIMP CMPCDemux::ConvertTimeFormat(LONGLONG* pTarget, const GUID* pTargetFormat, LONGLONG Source, const GUID* pSourceFormat) {return E_NOTIMPL;}411 412 STDMETHODIMP CMPCDemux::SetPositions(LONGLONG* pCurrent, DWORD dwCurrentFlags, LONGLONG* pStop, DWORD dwStopFlags)413 {414 return SetPositionsInternal(0, pCurrent, dwCurrentFlags, pStop, dwStopFlags);415 }416 417 STDMETHODIMP CMPCDemux::GetPositions(LONGLONG* pCurrent, LONGLONG* pStop)418 {419 if(pCurrent) *pCurrent = rtCurrent;420 if(pStop) *pStop = rtStop;421 return S_OK;422 }423 STDMETHODIMP CMPCDemux::GetAvailable(LONGLONG* pEarliest, LONGLONG* pLatest)424 {425 if(pEarliest) *pEarliest = 0;426 return GetDuration(pLatest);427 }428 STDMETHODIMP CMPCDemux::SetRate(double dRate) {return dRate > 0 ? rate = dRate, S_OK : E_INVALIDARG;}429 STDMETHODIMP CMPCDemux::GetRate(double* pdRate) {return pdRate ? *pdRate = rate, S_OK : E_POINTER;}430 STDMETHODIMP CMPCDemux::GetPreroll(LONGLONG* pllPreroll) {return pllPreroll ? *pllPreroll = 0, S_OK : E_POINTER;}431 432 STDMETHODIMP CMPCDemux::GetDuration(LONGLONG* pDuration)433 {434 CheckPointer(pDuration, E_POINTER);435 *pDuration = 0;436 437 if (file) {438 if (pDuration) *pDuration = file->duration_10mhz;439 }440 return S_OK;441 }442 443 STDMETHODIMP CMPCDemux::SetPositionsInternal(int iD, LONGLONG* pCurrent, DWORD dwCurrentFlags, LONGLONG* pStop, DWORD dwStopFlags)444 {445 // only our first pin can seek446 if (iD != 0) return NOERROR;447 CAutoLock cAutoLock(&lock_filter);448 449 if (!pCurrent && !pStop || (dwCurrentFlags&AM_SEEKING_PositioningBitsMask) == AM_SEEKING_NoPositioning450 && (dwStopFlags&AM_SEEKING_PositioningBitsMask) == AM_SEEKING_NoPositioning)451 return S_OK;452 453 REFERENCE_TIME rtCurrent = this->rtCurrent, rtStop = this->rtStop;454 455 if (pCurrent) {456 switch(dwCurrentFlags&AM_SEEKING_PositioningBitsMask) {457 case AM_SEEKING_NoPositioning: break;458 case AM_SEEKING_AbsolutePositioning: rtCurrent = *pCurrent; break;459 case AM_SEEKING_RelativePositioning: rtCurrent = rtCurrent + *pCurrent; break;460 case AM_SEEKING_IncrementalPositioning: rtCurrent = rtCurrent + *pCurrent; break;461 }462 }463 464 if (pStop) {465 switch(dwStopFlags&AM_SEEKING_PositioningBitsMask) {466 case AM_SEEKING_NoPositioning: break;467 case AM_SEEKING_AbsolutePositioning: rtStop = *pStop; break;468 case AM_SEEKING_RelativePositioning: rtStop += *pStop; break;469 case AM_SEEKING_IncrementalPositioning: rtStop = rtCurrent + *pStop; break;470 }471 }472 473 if (this->rtCurrent == rtCurrent && this->rtStop == rtStop) return S_OK;474 475 this->rtCurrent = rtCurrent;476 this->rtStop = rtStop;477 478 // now there are new valid Current and Stop positions479 HRESULT hr = DoNewSeek();480 return hr;481 }482 483 HRESULT CMPCDemux::DoNewSeek()484 {485 // stop first486 ev_abort.Set();487 if (reader) reader->BeginFlush();488 489 CMPCOutputPin *pin = output[0];490 FILTER_STATE state = m_State;491 492 if (pin->IsConnected()) {493 // abort494 if (state != State_Stopped) {495 if (pin->ThreadExists()) {496 pin->ev_abort.Set();497 pin->DeliverBeginFlush();498 499 pin->CallWorker(CMD_STOP);500 pin->FlushQueue();501 }502 }503 }504 505 if (reader) reader->EndFlush();506 507 if (pin->IsConnected()) {508 if (state != State_Stopped) {509 if (pin->ThreadExists()) {510 pin->ev_abort.Reset();511 pin->DeliverEndFlush();512 }513 }514 pin->DoNewSegment(rtCurrent, rtStop, rate);515 }516 517 if (ThreadExists()) {518 CallWorker(CMD_STOP);519 }520 521 // seek the file522 if (file) {523 int64 sample_pos = rtCurrent * file->sample_rate / 10000000;524 file->Seek(sample_pos);525 }526 527 ev_abort.Reset();528 if (ThreadExists()) {529 CallWorker(CMD_RUN);530 }531 532 if (pin->IsConnected()) {533 if (state != State_Stopped) {534 // spustime aj jeho thread535 if (pin->ThreadExists()) {536 pin->FlushQueue();537 pin->CallWorker(CMD_RUN);538 }539 }540 }541 542 return NOERROR;543 }544 545 546 STDMETHODIMP CMPCDemux::Pause()547 {548 CAutoLock lck(&lock_filter);549 550 if (m_State == State_Stopped) {551 552 ev_abort.Reset();553 554 // activate pins555 for (int i=0; i<output.GetCount(); i++) output[i]->Active();556 if (input) input->Active();557 558 // seekneme na danu poziciu559 DoNewSeek();560 561 // pustime parser thread562 if (!ThreadExists()) {563 Create();564 CallWorker(CMD_RUN);565 }566 }567 568 m_State = State_Paused;569 return NOERROR;570 }571 572 STDMETHODIMP CMPCDemux::Stop()573 {574 CAutoLock lock(&lock_filter);575 HRESULT hr = NOERROR;576 577 if (m_State != State_Stopped) {578 579 // set abort580 ev_abort.Set();581 if (reader) reader->BeginFlush();582 583 // deaktivujeme piny584 if (input) input->Inactive();585 for (int i=0; i<output.GetCount(); i++) output[i]->Inactive();586 587 // zrusime parser thread588 if (ThreadExists()) {589 CallWorker(CMD_EXIT);590 Close();591 }592 593 if (reader) reader->EndFlush();594 ev_abort.Reset();595 }596 597 598 m_State = State_Stopped;599 return hr;600 }
Note: See TracChangeset
for help on using the changeset viewer.