Playback.cpp
上传用户:lusi_8715
上传日期:2007-01-08
资源大小:199k
文件大小:22k
源码类别:

流媒体/Mpeg4/MP4

开发平台:

Visual C++

  1. /**************************************************************************************
  2.  *                                                                                    *
  3.  * This application contains code from OpenDivX and is released as a "Larger Work"    *
  4.  * under that license. Consistant with that license, this application is released     *
  5.  * under the GNU General Public License.                                              *
  6.  *                                                                                    *
  7.  * The OpenDivX license can be found at: http://www.projectmayo.com/opendivx/docs.php *
  8.  * The GPL can be found at: http://www.gnu.org/copyleft/gpl.html                      *
  9.  *                                                                                    *
  10.  * Copyright (c) 2001 - Project Mayo                                                  *
  11.  *                                                                                    *
  12.  * Authors: Damien Chavarria <adrc at projectmayo.com>                                *
  13.  *                                                                                    *
  14.  **************************************************************************************/
  15. #include "Playback.h"
  16. /*
  17.  * Main Class
  18.  */
  19. /*
  20.  * Internal audio callback
  21.  * for audio streams in AVIs
  22.  *
  23.  */
  24. void audio_callback(void *lpData, void *buffer, unsigned int size)
  25. {
  26. Playback *playback = (Playback *) lpData;
  27. if(playback && playback->playing && !playback->paused) {
  28. playback->audio_bytes += size;
  29. if(playback->audioCodec)
  30. playback->audioCodec->Decompress(buffer, size);
  31. }
  32. else {
  33. memset(buffer, 0, size);
  34. }
  35. }
  36. /*
  37.  * Constructor : Does nothing
  38.  *
  39.  */
  40. Playback::Playback()
  41. {
  42. this->ok            = 0;
  43. this->codec         = NULL;
  44. this->decaps        = NULL;
  45. this->audioCodec    = NULL;
  46. this->videoRenderer = NULL;
  47. this->audioRenderer = NULL;
  48. this->subtitles     = NULL;
  49. this->playing       = 0;
  50. this->paused        = 0;
  51. this->use_bilinear  = 0;
  52. this->fullscreen    = 0;
  53. this->fast_forward  = 0;
  54. this->rewind        = 0;
  55. this->volume        = 100;
  56. this->has_subtitles = 0;
  57. this->use_subtitles = 0;
  58. this->playbackMutex = CreateMutex (NULL, FALSE, NULL);
  59. }
  60. /*
  61.  * Open : Tries to open a Playback
  62.  *
  63.  */
  64. int Playback::Open(char *lpFilename, int type, HWND hwnd)
  65. {
  66. /*
  67.  * Init everything
  68.  */
  69. this->ok            = 0;
  70. this->codec         = NULL;
  71. this->decaps        = NULL;
  72. this->audioCodec    = NULL;
  73. this->videoRenderer = NULL;
  74. this->audioRenderer = NULL;
  75. this->videoBuffer   = NULL;
  76. this->subtitles     = NULL;
  77. this->playing       = 0;
  78. this->paused        = 0;
  79. this->use_bilinear  = 0;
  80. this->fullscreen    = 0;
  81. this->fast_forward  = 0;
  82. this->rewind        = 0;
  83. this->volume        = 100;
  84. this->has_subtitles = 0;
  85. this->use_subtitles = 0;
  86. if(lpFilename) {
  87. this->hwnd = hwnd;
  88. decaps = new AviDecaps();
  89. if(decaps->Open(lpFilename, type)) {
  90. /*
  91.  * Audio
  92.    */
  93. this->audioCodec = new AudioCodec(decaps, decaps->WaveFormatEx());
  94. if(audioCodec->IsOK()) {
  95. audioRenderer = new AudioRenderer(audioCodec->GetFormat(), hwnd);
  96. audioRenderer->SetCallback(this, audio_callback);
  97. }
  98. /*
  99.  * Video
  100.  */
  101. codec = new Codec(decaps->BitmapInfoHeader());
  102. if(codec->IsOK()) {
  103. videoRenderer = new VideoRenderer();
  104. videoRenderer->SetBilinear(this->use_bilinear);
  105. if(videoRenderer->Open(hwnd, decaps->BitmapInfoHeader())) {
  106. /*
  107.  * get the video mode and try
  108.  * to set the codec into the same one.
  109.  */
  110. codec->SetVideoMode(videoRenderer->GetVideoMode());
  111. videoRenderer->SetCodecVideoMode(codec->GetVideoMode());
  112. this->fullscreen = 0;
  113. this->ok         = TRUE;
  114. this->videoBuffer = new VideoBuffer(this->decaps, this->codec);
  115. this->videoBuffer->Start();
  116. /*
  117.  * Try to find subtitles
  118.  */
  119. this->subtitles = new Subtitles();
  120. if(subtitles->Open(lpFilename)) {
  121. this->has_subtitles = 1;
  122. }
  123. }
  124. else {
  125. this->ok = 0;
  126. MessageBox(NULL, "Couldn't init video, make sure you have DirectX 7.0 installed", 
  127.    "Fatal Error", MB_OK);
  128. return 0;
  129. }
  130. playing = 0;
  131. paused  = 0;
  132. if(this->ok == TRUE) {
  133. return 1;
  134. }
  135. }
  136. else {
  137. MessageBox(NULL, "Could not initialize Codec", "Error", MB_OK);
  138. return 0;
  139. }
  140. }
  141. }
  142. return 0;
  143. }
  144. /*
  145.  * Destructor : CleanUp.
  146.  *
  147.  */
  148. Playback::~Playback()
  149. {
  150. CloseHandle(this->playbackMutex);
  151. }
  152. /*
  153.  * Return TRUE is object
  154.  * is ready for playing.
  155.  *
  156.  */
  157. int Playback::OK()
  158. {
  159. return this->ok;
  160. }
  161. /*
  162.  * Return the current 
  163.  * video time in ms
  164.  *
  165.  */
  166. unsigned long Playback::VideoTime()
  167. {
  168. /*
  169.  * time is in ms
  170.  */
  171. if(this->decaps && this->decaps->FrameRate() != 0) {
  172. return (unsigned long) ((double) this->video_frames * 1000.0 / (double) this->decaps->FrameRate());
  173. }
  174. else {
  175. return 0;
  176. }
  177. }
  178. /*
  179.  * Wrapper against the renderer call
  180.  * do not affect video only AVIs
  181.  *
  182.  */
  183. unsigned long Playback::AudioTime()
  184. {
  185. if(this->audioRenderer && this->audioCodec) {
  186. return this->audioRenderer->AudioTime();
  187. }
  188. else {
  189. return this->VideoTime();
  190. }
  191. }
  192. /*
  193.  * Gives Global Time
  194.  *
  195.  */
  196. int Playback::GetTime()
  197. {
  198. return VideoTime()/1000;
  199. }
  200. int Playback::GetTotalTime()
  201. {
  202. if(this->decaps) {
  203. return (int) (this->decaps->TotalFrames() / (double) this->decaps->FrameRate());
  204. }
  205. else {
  206. return 0;
  207. }
  208. }
  209. /*
  210.  * Internal Video
  211.  * Only Thread
  212.  *
  213.  */
  214. DWORD WINAPI VideoThreadFunc( LPVOID lpData)
  215. {
  216. Playback *playback = (Playback *) lpData;
  217. int time, timeDiff;
  218. char *frame = NULL;
  219. if(playback != NULL)
  220. {
  221. playback->baseTime = GetTickCount();
  222. while(playback->playing) {
  223. debut:
  224. frame = NULL;
  225. PM_DEBUG("One Framen", NULL);
  226. if(!playback->paused) {
  227. if(playback->fast_forward) {
  228. playback->decaps->NextKeyFrame();
  229. }
  230. else {
  231. if(playback->rewind) {
  232. playback->decaps->PreviousKeyFrame();
  233. }
  234. }
  235. /*
  236.  * synchro here
  237.  *
  238.  */
  239. if(!playback->fast_forward && !playback->rewind) {
  240. timeDiff = playback->VideoTime() - (GetTickCount() - playback->baseTime);
  241. if(timeDiff > 10) {
  242. Sleep(timeDiff/2);
  243. }
  244. if(timeDiff < -150) {
  245. /*
  246.  * drop here
  247.  */
  248. playback->videoBuffer->Drop();
  249. playback->video_frames++;
  250. }
  251. if(timeDiff < -230) {
  252. /*
  253.  * drop here
  254.  */
  255. playback->videoBuffer->Drop();
  256. playback->video_frames++;
  257. }
  258. }
  259. else {
  260. Sleep(80);
  261. }
  262. PM_DEBUG("Decodingn", NULL);
  263. frame = playback->videoBuffer->GiveMeAFrame();
  264. playback->video_frames++;
  265. if(frame == NULL) {
  266. PM_DEBUG("NULL FRAME! Stoppingn", NULL);
  267. if(!playback->loop)
  268. playback->Stop(TRUE);
  269. else {
  270. playback->decaps->Rewind();
  271. playback->displayed_frames = 0;
  272. playback->audio_bytes      = 0;
  273. playback->video_frames     = 0;
  274. playback->baseTime = GetTickCount();
  275. goto debut;
  276. }
  277. break;
  278. }
  279.        WaitForSingleObject(playback->playbackMutex, INFINITE);
  280. if(!playback->paused) {
  281. if(playback->fullscreen) {
  282. playback->videoRenderer->DrawFullscreen(frame);
  283. playback->displayed_frames++;
  284. }
  285. else {
  286. playback->videoRenderer->Draw(frame, playback->has_subtitles && playback->use_subtitles);
  287. playback->displayed_frames++;
  288. }
  289. if(playback->has_subtitles && playback->use_subtitles) {
  290. playback->subtitles->Apply(playback->hwnd, playback->video_frames, 
  291.                        playback->decaps->FrameRate(), playback->fullscreen);
  292. }
  293. }
  294. ReleaseMutex(playback->playbackMutex);
  295. PM_DEBUG("Frame Done!n", NULL);
  296. }
  297. }
  298. }
  299. else {
  300. MessageBox(NULL, "Playing : NULL playback engine!", "", MB_OK);
  301. }
  302. PM_DEBUG("Stop Playing Threadn", NULL);
  303. return 0;
  304. }
  305. /*
  306.  * Internal Video synced 
  307.  * on Audio thread
  308.  *
  309.  */
  310. DWORD WINAPI ThreadFunc( LPVOID lpData)
  311. {
  312. Playback *playback = (Playback *) lpData;
  313. long  timeDiff;
  314. char *frame = NULL;
  315. DWORD time;
  316. PM_DEBUG("Start Playing Threadn", NULL);
  317. if(playback != NULL)
  318. {
  319. while(playback->playing) {
  320. debut_audio:
  321. frame = NULL;
  322. if(!playback->paused) {
  323. if(playback->fast_forward) {
  324. playback->decaps->NextKeyFrame();
  325. }
  326. else {
  327. if(playback->rewind) {
  328. playback->decaps->PreviousKeyFrame();
  329. }
  330. }
  331. /*
  332.  * synchro here
  333.  *
  334.  */
  335. if(!playback->fast_forward && !playback->rewind) {
  336. timeDiff = playback->VideoTime() - playback->AudioTime() - 100;
  337. if(timeDiff == -100) {
  338. /*
  339.  * Nothing to do
  340.  */
  341. }
  342. else {
  343. if(timeDiff > 10) {
  344. Sleep(timeDiff/2);
  345. }
  346. if(timeDiff < -150) {
  347. /*
  348.  * drop here
  349.  */
  350. playback->videoBuffer->Drop();
  351. playback->video_frames++;
  352. }
  353. if(timeDiff < -230) {
  354. /*
  355.  * drop here
  356.  */
  357. playback->videoBuffer->Drop();
  358. playback->video_frames++;
  359. }
  360. }
  361. }
  362. else {
  363. Sleep(80);
  364. }
  365. frame = playback->videoBuffer->GiveMeAFrame();
  366. playback->video_frames++;
  367. if(frame == NULL) {
  368. /*
  369.  * We're at the end of the file
  370.  */
  371. if(!playback->loop) {
  372. if(playback->audioRenderer)
  373. playback->audioRenderer->Stop();
  374. playback->Stop(TRUE);
  375. }
  376. else {
  377. playback->decaps->Rewind();
  378. if(playback->audioRenderer)
  379. playback->audioRenderer->Stop();
  380. playback->displayed_frames = 0;
  381. playback->audio_bytes      = 0;
  382. playback->video_frames     = 0;
  383. if(playback->audioRenderer)
  384. playback->audioRenderer->Start();
  385. goto debut_audio;
  386. }
  387. break;
  388. }
  389. WaitForSingleObject(playback->playbackMutex, INFINITE);
  390. if(!playback->paused) {
  391. if(playback->fullscreen) {
  392. playback->videoRenderer->DrawFullscreen(frame);
  393. playback->displayed_frames++;
  394. }
  395. else {
  396. playback->videoRenderer->Draw(frame, playback->has_subtitles && playback->use_subtitles);
  397. playback->displayed_frames++;
  398. }
  399. if(playback->has_subtitles && playback->use_subtitles) {
  400. playback->subtitles->Apply(playback->hwnd, playback->video_frames, 
  401.                        playback->decaps->FrameRate(), playback->fullscreen);
  402. }
  403. }
  404. ReleaseMutex(playback->playbackMutex);
  405. }
  406. }
  407. }
  408. else {
  409. MessageBox(NULL, "Playing : NULL playback engine!", "", MB_OK);
  410. }
  411. PM_DEBUG("Stop Playing Threadn", NULL);
  412. return 0;
  413. }
  414. /*
  415.  * Returns the video width
  416.  *
  417.  */
  418. int Playback::Width()
  419. {
  420. if(this->decaps) {
  421. return this->decaps->Width();
  422. }
  423. else {
  424. return 0;
  425. }
  426. }
  427. /*
  428.  * Returns the video height
  429.  *
  430.  */
  431. int Playback::Height()
  432. {
  433. if(this->decaps) {
  434. return this->decaps->Height();
  435. }
  436. else {
  437. return 0;
  438. }
  439. }
  440. /*
  441.  * Tells if we're paused
  442.  *
  443.  */
  444. BOOL Playback::isPaused()
  445. {
  446. return this->paused;
  447. }
  448. BOOL Playback::isPlaying()
  449. {
  450. return this->playing;
  451. }
  452. /*
  453.  * Starts playing
  454.  *
  455.  */
  456. int Playback::Play()
  457. {
  458. if(this->ok == TRUE) {
  459. if(this->fast_forward) {
  460. this->fast_forward = 0;
  461. this->playing = 1;
  462. this->paused  = 0;
  463. this->video_frames     = 0;
  464. this->displayed_frames = 0;
  465. this->audio_bytes      = 0;
  466. if(this->decaps) {
  467. this->decaps->ReSeekAudio();
  468. }
  469. if(this->audioCodec)
  470. this->audioCodec->EmptyBuffers();
  471. if(this->audioCodec && this->audioCodec->IsOK() && this->audioRenderer) {
  472. this->audioRenderer->SetVolume(0);
  473. this->audioRenderer->Start();
  474. }
  475. if(this->paused)
  476. Pause();
  477. Sleep(600);
  478. if(this->audioCodec && this->audioCodec->IsOK() && this->audioRenderer) {
  479. this->audioRenderer->SetVolume(this->volume);
  480. }
  481. }
  482. else {
  483. if(this->rewind) {
  484. this->rewind = 0;
  485. this->playing = 1;
  486. this->paused  = 0;
  487. this->video_frames     = 0;
  488. this->displayed_frames = 0;
  489. this->audio_bytes      = 0;
  490. if(this->decaps) {
  491. this->decaps->ReSeekAudio();
  492. }
  493. if(this->audioCodec)
  494. this->audioCodec->EmptyBuffers();
  495. if(this->audioCodec && this->audioCodec->IsOK() && this->audioRenderer) {
  496. this->audioRenderer->SetVolume(0);
  497. this->audioRenderer->Start();
  498. }
  499. if(this->paused)
  500. Pause();
  501. Sleep(600);
  502. if(this->audioCodec && this->audioCodec->IsOK() && this->audioRenderer) {
  503. this->audioRenderer->SetVolume(this->volume);
  504. }
  505. }
  506. else {
  507. if(this->playing)
  508. return 0;
  509. this->playing = 1;
  510. this->paused  = 0;
  511. this->video_frames     = 0;
  512. this->displayed_frames = 0;
  513. this->audio_bytes      = 0;
  514. if(this->audioCodec && this->audioCodec->IsOK() && this->audioRenderer) {
  515. this->audioRenderer->SetVolume(this->volume);
  516. this->audioRenderer->Start();
  517. this->videoThread = CreateThread( NULL, 0, ThreadFunc, (LPVOID) this, 0, &id );
  518. }
  519. else {
  520. this->videoThread = CreateThread( NULL, 0, VideoThreadFunc, (LPVOID) this, 0, &id );
  521. }
  522. }
  523. }
  524. }
  525. return 1;
  526. }
  527. /*
  528.  * Pause video and audio
  529.  *
  530.  */
  531. int Playback::Pause()
  532. {
  533. /*
  534.  * Toggle Pause 
  535.  */
  536. if(this->playing) {
  537. if(this->paused) {
  538. if(this->audioRenderer) {
  539. this->audioRenderer->Pause();
  540. }
  541. this->paused = 0;
  542. ReleaseMutex(this->playbackMutex);
  543. this->baseTime += (GetTickCount() - this->stopTime);
  544. ResumeThread(this->videoThread);
  545. }
  546. else {
  547. WaitForSingleObject(this->playbackMutex, INFINITE);
  548. if(!this->fast_forward && !this->rewind) {
  549. if(this->audioRenderer) {
  550. this->audioRenderer->Pause();
  551. }
  552. }
  553. else {
  554. this->decaps->ReSeekAudio();
  555. this->audioCodec->EmptyBuffers();
  556. this->video_frames     = 0;
  557. this->displayed_frames = 0;
  558. this->audio_bytes      = 0;
  559. this->audioRenderer->Stop();
  560. this->audioRenderer->Start();
  561. this->audioRenderer->Pause();
  562. }
  563. this->fast_forward = 0;
  564. this->rewind       = 0;
  565. this->stopTime = GetTickCount();
  566. SuspendThread(this->videoThread);
  567. this->paused = 1;
  568. }
  569. }
  570. return 1;
  571. }
  572. /*
  573.  * Starts the Fast Forward Display
  574.  *
  575.  */
  576. int Playback::FastForward()
  577. {
  578. if(this->paused) {
  579. this->fast_forward = 1;
  580. this->paused = 0;
  581. ReleaseMutex(this->playbackMutex);
  582. this->baseTime += (GetTickCount() - this->stopTime);
  583. ResumeThread(this->videoThread);
  584. return 0;
  585. }
  586. if(this->ok && this->playing && !this->rewind && !this->fast_forward) {
  587. if(this->audioRenderer) {
  588. this->audioRenderer->Pause();
  589. }
  590. this->fast_forward = 1;
  591. }
  592. return 1;
  593. }
  594. int Playback::Rewind()
  595. {
  596. if(this->paused) {
  597. this->rewind = 1;
  598. this->paused = 0;
  599. ReleaseMutex(this->playbackMutex);
  600. this->baseTime += (GetTickCount() - this->stopTime);
  601. ResumeThread(this->videoThread);
  602. return 0;
  603. }
  604. if(this->ok && this->playing && !this->fast_forward && !this->rewind) {
  605. if(this->audioRenderer) {
  606. this->audioRenderer->Pause();
  607. }
  608. this->rewind = 1;
  609. }
  610. return 1;
  611. }
  612. /*
  613.  * Only display the next frame
  614.  *
  615.  *
  616.  */
  617. int Playback::NextFrame() 
  618. {
  619. if(this->paused) {
  620. /*
  621. long image_size;
  622. image_size = this->decaps->NextVideoFrame(this->video_in);
  623. this->codec->Decompress(this->video_in, image_size, (char *) this->videoRenderer->GetSurface());
  624. this->video_frames++;
  625. this->videoRenderer->Draw();
  626. this->displayed_frames++;
  627. */
  628. }
  629. return 1;
  630. }
  631. /*
  632.  * Set/UnSet Looping
  633.  *
  634.  */
  635. Playback::SetLoop(int loop) 
  636. {
  637. this->loop = loop;
  638. return 0;
  639. }
  640. /*
  641.  * Stops the playback
  642.  * TODO : rewind the stream
  643.  *
  644.  */
  645. int Playback::Stop(int redraw)
  646. {
  647. if(this->playing) {
  648. WaitForSingleObject(this->playbackMutex, INFINITE);
  649. TerminateThread(this->videoThread, 0);
  650. this->playing = 0;
  651. if(this->audioCodec && this->audioCodec->IsOK() && this->audioRenderer != NULL) {
  652. this->audioRenderer->Stop();
  653. }
  654. }
  655. this->fast_forward = 0;
  656. this->rewind       = 0;
  657. this->displayed_frames = 0;
  658. this->audio_bytes      = 0;
  659. this->video_frames     = 0;
  660. if(this->decaps)
  661. this->decaps->Rewind();
  662. if(this->audioCodec)
  663. this->audioCodec->EmptyBuffers();
  664. ReleaseMutex(this->playbackMutex);
  665. /*
  666.  * Do redraw here!
  667.  */
  668. RECT rect;
  669. if(redraw) {
  670. GetClientRect(this->hwnd, &rect);
  671. InvalidateRect(this->hwnd, &rect, TRUE); 
  672.   UpdateWindow(this->hwnd);
  673. }
  674. return 1;
  675. }
  676. /*
  677.  * Performs Seeking
  678.  *
  679.  *
  680.  */
  681. int Playback::Seek(int percent)
  682. {
  683. int has_to_play = 0;
  684. if(this->ok) {
  685. if(this->playing) {
  686. Stop(FALSE);
  687. has_to_play = 1;
  688. }
  689. this->decaps->Seek(percent);
  690. if(this->audioCodec)
  691. this->audioCodec->EmptyBuffers();
  692. if(has_to_play) {
  693. this->playing = 1;
  694. this->paused  = 0;
  695. this->video_frames     = 0;
  696. this->displayed_frames = 0;
  697. this->audio_bytes      = 0;
  698. if(this->audioCodec && this->audioCodec->IsOK() && this->audioRenderer) {
  699. this->audioRenderer->SetVolume(0);
  700. this->audioRenderer->Start();
  701. this->videoThread = CreateThread( NULL, 0, ThreadFunc, (LPVOID) this, 0, &id );
  702. }
  703. else {
  704. this->videoThread = CreateThread( NULL, 0, VideoThreadFunc, (LPVOID) this, 0, &id );
  705. }
  706. }
  707. Sleep(500);
  708. if(this->audioCodec && this->audioCodec->IsOK() && this->audioRenderer) {
  709. this->audioRenderer->SetVolume(this->volume);
  710. }
  711. }
  712. return 1;
  713. }
  714. /*
  715.  * Sets the volume
  716.  *
  717.  */
  718. int Playback::SetVolume(int volume)
  719. {
  720. this->volume = volume;
  721. if(this->audioRenderer) {
  722. this->audioRenderer->SetVolume(this->volume);
  723. }
  724. return 1;
  725. }
  726. /*
  727.  * Gives the current displayed FPS
  728.  *
  729.  */
  730. double Playback::GetCurrentFps()
  731. {
  732. double time;
  733. time = AudioTime() / 1000;
  734. if(time != 0) {
  735. return this->displayed_frames / time;
  736. }
  737. else {
  738. return 0;
  739. }
  740. }
  741. /*
  742.  * Gives the progress of the buffering
  743.  */
  744. int Playback::GetBufferingState() {
  745. if(this->decaps) {
  746. return this->decaps->GetBufferingState();
  747. }
  748. return 0;
  749. }
  750. /*
  751.  * Gives the video 
  752.  * position
  753.  *
  754.  */
  755. double Playback::GetProgress()
  756. {
  757. if(this->decaps) {
  758. return this->decaps->GetProgress();
  759. }
  760. return 0.0;
  761. }
  762. /*
  763.  * Set/Unset Forcing of fullscreen resolution
  764.  */
  765. int Playback::SetChangeFullscreenRes(int change) {
  766. if(this->videoRenderer != NULL) {
  767. this->videoRenderer->SetChangeFullscreenRes(change);
  768. return 1;
  769. }
  770. return 0;
  771. }
  772. /*
  773.  * use or not the subtitles
  774.  */
  775. int Playback::SetUseSubtitles(int useSubtitles) {
  776. this->use_subtitles = useSubtitles;
  777. return 1;
  778. }
  779. /*
  780.  * Set/unset the use of 
  781.  * bilinear filtering
  782.  *
  783.  */
  784. int Playback::SetBilinear(int use_bilinear)
  785. {
  786. if(this->use_bilinear != use_bilinear) {
  787. PM_DEBUG("Changing Bilinear Staten", NULL);
  788. this->use_bilinear = use_bilinear;
  789. if(this->ok) {
  790. int has_to_play = 0;
  791. if(this->playing) {
  792. WaitForSingleObject(this->playbackMutex, INFINITE);
  793. SuspendThread(this->videoThread);
  794. this->playing = 0;
  795. ReleaseMutex(this->playbackMutex);
  796. has_to_play = 1;
  797. }
  798. this->videoRenderer->Close();
  799. this->videoRenderer->SetBilinear(this->use_bilinear);
  800. if(this->fullscreen) {
  801. this->videoRenderer->OpenFullscreen(this->hwnd, this->decaps->BitmapInfoHeader());
  802. }
  803. else {
  804. this->videoRenderer->Open(this->hwnd, this->decaps->BitmapInfoHeader());
  805. }
  806. if(has_to_play) {
  807. this->playing = 1;
  808. ResumeThread(this->videoThread);
  809. }
  810. }
  811. }
  812. return 0;
  813. }
  814. /*
  815.  * Switch to Fullscreen
  816.  * mode...
  817.  */
  818. int Playback::Fullscreen(int active)
  819. {
  820. if(active) {
  821. if(this->ok && this->playing && !this->paused) {
  822. int has_to_play = 0;
  823. if(this->playing) {
  824. this->Pause();
  825. has_to_play = 1;
  826. }
  827. this->videoRenderer->Fullscreen(TRUE);
  828. this->fullscreen = 1;
  829. if(has_to_play) {
  830. this->Pause();
  831. }
  832. }
  833. }
  834. else {
  835. if(this->ok && this->playing && !this->paused) {
  836. int has_to_play = 0;
  837. if(this->playing) {
  838. this->Pause();
  839. has_to_play = 1;
  840. }
  841. this->videoRenderer->Fullscreen(FALSE);
  842. this->fullscreen = 0;
  843. if(has_to_play) {
  844. this->Pause();
  845. }
  846. }
  847. }
  848. return 1;
  849. }
  850. /*
  851.  * 
  852.  *
  853.  *
  854.  */
  855. int Playback::isInFullscreen()
  856. {
  857. return this->fullscreen;
  858. }
  859. /*
  860.  * Closes the playback
  861.  * (definitive)
  862.  *
  863.  */
  864. int Playback::Close()
  865. {
  866. if(this->ok == TRUE) {
  867. this->ok = FALSE;
  868. Stop(TRUE);
  869. if(this->codec != NULL) {
  870. this->codec->Close();
  871. delete this->codec;
  872. }
  873. if(this->audioCodec != NULL) {
  874. this->audioCodec->Close();
  875. delete this->audioCodec;
  876. }
  877. if(this->videoRenderer != NULL) {
  878. this->videoRenderer->Close();
  879. delete this->videoRenderer;
  880. }
  881. if(this->videoBuffer != NULL) {
  882. this->videoBuffer->Stop();
  883. delete this->videoBuffer;
  884. }
  885. if(this->audioRenderer != NULL) {
  886. this->audioRenderer->Close();
  887. delete this->audioRenderer;
  888. }
  889. if(this->decaps != NULL) {
  890. this->decaps->Close();
  891. delete this->decaps;
  892. }
  893. if(this->subtitles != NULL) {
  894. this->subtitles->Close();
  895. delete this->subtitles;
  896. }
  897. return 1;
  898. }
  899. else {
  900. return 0;
  901. }
  902. }