MediaPlayback.cpp
上传用户:tuheem
上传日期:2007-05-01
资源大小:21889k
文件大小:28k
源码类别:

多媒体编程

开发平台:

Visual C++

  1. /**************************************************************************************
  2.  *                                                                                    *
  3.  *                                                                                    *
  4.  **************************************************************************************/
  5. #include "MediaPlayback.h"
  6. #include "DebugFile.h"
  7. DebugFile *debug;
  8. /*
  9.  * 音频回调
  10.  *
  11.  */
  12. unsigned int PlaybackAudioCallback(void *lpData, void *buffer, unsigned int size);
  13. /*
  14.  * 回放类
  15.  * --------------
  16.  * 
  17.  *  ——为所有媒体类中的项和过滤器提供一个前端处理
  18.  *
  19.  */
  20. MediaPlayback::MediaPlayback()
  21. {
  22. this->input         = new MediaInput();
  23. this->decaps        = new MediaDecaps();
  24. this->videoDecoder  = new MediaVideoDecoder();
  25. this->videoBuffer   = new MediaVideoBuffer();
  26. this->videoRenderer = new MediaVideoRenderer();
  27. this->audioDecoder  = new MediaAudioDecoder();
  28. this->audioRenderer = new MediaAudioRenderer();
  29. this->subtitler     = new MediaSubtitler();
  30. this->hasVideo      = FALSE;
  31. this->hasAudio      = FALSE;
  32. this->hasSubtitles  = FALSE;
  33. this->fullscreen    = FALSE;
  34. this->fastForward   = FALSE;
  35. this->rewind        = FALSE;
  36. this->playing       = FALSE;  
  37. this->paused        = FALSE;
  38. this->buffering         = FALSE;
  39. this->bufferingProgress = 0;
  40. this->volume            = 100;
  41. this->playbackMutex = CreateMutex (NULL, FALSE, NULL);
  42. }
  43. MediaPlayback::~MediaPlayback()
  44. {
  45. delete this->input;
  46. delete this->decaps;
  47. delete this->videoDecoder;
  48. delete this->videoRenderer;
  49. delete this->videoBuffer;
  50. delete this->subtitler;
  51. CloseHandle(this->playbackMutex);
  52. }
  53. MP_RESULT     MediaPlayback::OpenMediaSource(char *lpFilename) 
  54. {
  55. this->hasVideo      = FALSE;
  56. this->fastForward   = FALSE;
  57. this->rewind        = FALSE;
  58. this->playing       = FALSE;  
  59. this->paused        = FALSE;
  60. this->hasVideo      = FALSE;
  61. this->hasAudio      = FALSE;
  62. this->hasSubtitles  = FALSE;
  63. this->buffering     = FALSE;
  64. this->hasToBuffer   = FALSE;
  65. this->bufferingProgress = 0;
  66. if(lpFilename) {
  67. if(this->input->Open(lpFilename, INPUT_OPEN_BINARY) == MP_RESULT_OK) {
  68. if(this->input->GetCaps() & MEDIA_CAPS_BUFFERIZE) {
  69. this->buffering         = TRUE;
  70. this->bufferingProgress = 0;
  71. }
  72. strcpy(this->filename, lpFilename);
  73. this->filename[strlen(lpFilename)] = '';
  74. return MP_RESULT_OK;
  75. }
  76. }
  77. return MP_RESULT_ERROR;
  78. }
  79. MP_RESULT     MediaPlayback::OpenMediaFromSource(HWND hwndPlayback)
  80. {
  81. if(this->input && hwndPlayback) {
  82. if(this->input->GetCaps() & MEDIA_CAPS_BUFFERIZE) {
  83. this->buffering = 0;
  84. }
  85. if(this->decaps->Connect(this->input) == MP_RESULT_OK) {
  86. /*
  87.  * 视频流
  88.  */
  89. if(this->decaps->GetNumberOfVideoStreams() > 0) {
  90. if(this->videoDecoder->Connect(decaps) == MP_RESULT_OK) {
  91. /*
  92.  * 我们有一个有效的解码器,因此现在我们
  93.  *尝试建立一个视频补偿器并得到相同的视频模式
  94.  *
  95.  */
  96. media_video_mode_t codecMode, rendererMode;
  97. codecMode = this->videoDecoder->GetVideoMode();
  98. if(this->fullscreen)  {
  99. if(this->videoRenderer->InitFullscreen(hwndPlayback, 
  100.    this->decaps->GetVideoWidth(0),
  101.    this->decaps->GetVideoHeight(0), 
  102.    codecMode) == MP_RESULT_OK) {
  103. rendererMode = this->videoRenderer->GetVideoMode();
  104. if(this->videoDecoder->SetVideoMode(rendererMode) == MP_RESULT_OK) {
  105. if(this->videoBuffer->Connect(this->videoDecoder) == MP_RESULT_OK) {
  106. this->hasVideo     = TRUE;
  107. this->hwndPlayback = hwndPlayback;
  108. this->end = FALSE;
  109. this->videoRect    = NULL;
  110. }
  111. }
  112. }
  113. }
  114. else {
  115. if(this->videoRenderer->Init(hwndPlayback, 
  116.  this->decaps->GetVideoWidth(0),
  117.  this->decaps->GetVideoHeight(0), 
  118.  codecMode) == MP_RESULT_OK) {
  119. rendererMode = this->videoRenderer->GetVideoMode();
  120. if(this->videoDecoder->SetVideoMode(rendererMode) == MP_RESULT_OK) {
  121. if(this->videoBuffer->Connect(this->videoDecoder) == MP_RESULT_OK) {
  122. this->hasVideo     = TRUE;
  123. this->hwndPlayback = hwndPlayback;
  124. this->end = FALSE;
  125. this->videoRect    = NULL;
  126. }
  127. }
  128. }
  129. }
  130. }
  131. }
  132. /*
  133.  * 音频流
  134.  */
  135. if(this->decaps->GetNumberOfAudioStreams() > 0) {
  136. if(this->audioDecoder->Connect(this->decaps) == MP_RESULT_OK) {
  137. /*
  138.  * 我们有一个有效的音频解码器,因此现在我们
  139.  * 在给定模式下尝试建立缺省的音频补偿器
  140.  *
  141.  */
  142. if(this->audioRenderer->Open(hwndPlayback, this->audioDecoder->GetAudioFormat()) == MP_RESULT_OK) {
  143. /*
  144.  * 建立回调
  145.  */
  146. this->audioRenderer->SetVolume(this->volume);
  147. this->audioRenderer->SetCallback((LPVOID) this, PlaybackAudioCallback);
  148. this->hasAudio = TRUE;
  149. }
  150. }
  151. }
  152. /*
  153.  * 字幕流
  154.  */
  155. if(this->HasVideo() && !(this->input->GetCaps() & MEDIA_CAPS_BUFFERIZE)) {
  156. char *subFilename;
  157. subFilename = (char *) new char[strlen(this->filename)];
  158. strncpy(subFilename, this->filename, strlen(this->filename) - 4);
  159. subFilename[strlen(this->filename) - 4] = '';
  160. strcat(subFilename, ".sub");
  161. if(this->subtitler->Open(subFilename) == MP_RESULT_OK) {
  162. if(this->videoRenderer->Connect(this->subtitler) == MP_RESULT_OK) {
  163. this->hasSubtitles = TRUE;
  164. }
  165. }
  166. }
  167. if(this->hasVideo) {
  168. return MP_RESULT_OK;
  169. }
  170. }
  171. }
  172. return MP_RESULT_ERROR;
  173. }
  174. MP_RESULT     MediaPlayback::OpenMedia(char *lpFilename, HWND hwndPlayback)
  175. {
  176. if(lpFilename && hwndPlayback) {
  177. if(this->OpenMediaSource(lpFilename) == MP_RESULT_OK) {
  178. if(this->OpenMediaFromSource(hwndPlayback) == MP_RESULT_OK) {
  179. return MP_RESULT_OK;
  180. }
  181. }
  182. }
  183. this->Close();
  184. return MP_RESULT_ERROR;
  185. }
  186. BOOL          MediaPlayback::HasVideo()
  187. {
  188. return this->hasVideo;
  189. }
  190. BOOL          MediaPlayback::HasAudio()
  191. {
  192. return this->hasAudio;
  193. }
  194. char         *MediaPlayback::GetFilename()
  195. {
  196. if(this->HasAudio() || this->HasVideo()) {
  197. return this->filename;
  198. }
  199. return NULL;
  200. }
  201. unsigned int  MediaPlayback::GetVideoWidth()
  202. {
  203. if(this->decaps)
  204. return this->decaps->GetVideoWidth(0);
  205. return 0;
  206. }
  207. unsigned int  MediaPlayback::GetVideoHeight()
  208. {
  209. if(this->decaps)
  210. return this->decaps->GetVideoHeight(0);
  211. return 0;
  212. }
  213. unsigned long MediaPlayback::GetVideoTime()
  214. {
  215. if(this->decaps) {
  216. return (unsigned long) ((double) this->videoFrames * 1000.0 / (double) this->decaps->GetVideoFrameRate(0));
  217. }
  218. return 0;
  219. }
  220. unsigned long MediaPlayback::GetAudioTime()
  221. {
  222. return this->audioRenderer->GetAudioTime();
  223. }
  224. double        MediaPlayback::GetPlaybackProgress()
  225. {
  226. if(this->HasAudio() || this->HasVideo()) {
  227. return (double) ((double) this->decaps->GetCurrentVideoFrame(0) * 100 / (double) this->decaps->GetTotalVideoFrames(0));
  228. }
  229. return 0;
  230. }
  231. unsigned int  MediaPlayback::GetActualTime()
  232. {
  233. if(this->HasVideo()) {
  234. return this->decaps->GetCurrentVideoFrame(0) / this->decaps->GetVideoFrameRate(0);
  235. }
  236. return 0;
  237. }
  238. BOOL          MediaPlayback::IsBuffering()
  239. {
  240. return this->buffering;
  241. }
  242. DWORD         MediaPlayback::GetBufferingProgress()
  243. {
  244. return this->bufferingProgress;
  245. }
  246. MP_RESULT     MediaPlayback::UpdateBuffering()
  247. {
  248. DWORD size;
  249. size = this->input->GetBufferSize();
  250. this->bufferingProgress = size * 100 / this->input->GetBufferingSize();
  251. return MP_RESULT_OK;
  252. }
  253. unsigned int  MediaPlayback::GetTotalTime()
  254. {
  255. if(this->HasVideo()) {
  256. return (unsigned int) ( (double) this->decaps->GetTotalVideoFrames(0)/ (double) this->decaps->GetVideoFrameRate(0));
  257. }
  258. return 0;
  259. }
  260. double        MediaPlayback::GetCurrentFps()
  261. {
  262. return 0;
  263. }
  264. BOOL          MediaPlayback::IsPaused()
  265. {
  266. return (this->paused || this->buffering);
  267. }
  268. BOOL          MediaPlayback::IsPlaying()
  269. {
  270. return this->playing;
  271. }
  272. BOOL          MediaPlayback::IsInFullscreen()
  273. {
  274. return this->fullscreen;
  275. }
  276. BOOL          MediaPlayback::IsOverlay()
  277. {
  278. if(this->videoRenderer) {
  279. return (strstr(this->videoRenderer->GetName(), "Overlay") != NULL);
  280. }
  281. return FALSE;
  282. }
  283. /**************************************************************
  284.  *                                                            *
  285.  *                      音频回调方法                          *
  286.  *                 -----------------------                    *
  287.  *                                                            *
  288.  **************************************************************/
  289. unsigned int PlaybackAudioCallback(void *lpData, void *buffer, unsigned int size)
  290. {
  291. int real_size;
  292. MediaPlayback *playback = (MediaPlayback *) lpData;
  293. if(playback && playback->playing && !playback->paused) {
  294. playback->audioBytes += size;
  295. if(playback->audioDecoder) {
  296. if((real_size = playback->audioDecoder->Decompress(buffer, size)) != size) {
  297. if(playback->input->GetCaps() & MEDIA_CAPS_BUFFERIZE) {
  298.  
  299. if(!(playback->input->GetBufferSize() >= playback->input->GetSize())) {
  300. playback->hasToBuffer = TRUE;
  301. return real_size;
  302. }
  303. else {
  304. if(!playback->end) {
  305. playback->end = TRUE;
  306. playback->Pause();
  307. playback->decaps->UpdateForSize();
  308. playback->Pause();
  309. return real_size;
  310. }
  311. else {
  312. memset(buffer, 0, size);
  313. return size;
  314. }
  315. }
  316. }
  317. else {
  318. memset(buffer, 0, size);
  319. return size;
  320. }
  321. }
  322. return size;
  323. }
  324. }
  325. else {
  326. memset(buffer, 0, size);
  327. return size;
  328. }
  329. return 0;
  330. }
  331. /**************************************************************
  332.  *                                                            *
  333.  *                       视频线程方法                         *
  334.  *                 -----------------------                    *
  335.  *                                                            *
  336.  **************************************************************/
  337. /*
  338.  * 仅有视频的线程 
  339.  *
  340.  */
  341. DWORD WINAPI PlaybackVideoOnlyThreadFunc( LPVOID lpData)
  342. {
  343. MediaPlayback *playback = (MediaPlayback *) lpData;
  344. int timeDiff;
  345. MediaBuffer *frame = NULL;
  346. if(playback != NULL) {
  347. playback->baseTime = GetTickCount();
  348. while(playback->playing) {
  349. /*
  350.  * 检查是否正在缓冲
  351.  *
  352.  */
  353. if(playback->input->GetCaps() & MEDIA_CAPS_BUFFERIZE) {
  354. if((playback->input->GetBufferPosition() > 0.95*playback->input->GetBufferSize()) && 
  355.   !(playback->input->GetBufferSize() >= playback->input->GetSize())) {
  356. startBuffering:
  357. DWORD size  = playback->input->GetBufferSize();
  358. DWORD sizeI = playback->input->GetBufferSize();
  359. /*
  360.  * 等待更多缓冲
  361.  */
  362. playback->bufferingProgress = 0;
  363. playback->buffering = TRUE;
  364. while(size < sizeI + playback->input->GetBufferingSize() && !(playback->input->GetBufferSize() >= playback->input->GetSize())) {
  365. Sleep(10);
  366. size = playback->input->GetBufferSize();
  367. playback->bufferingProgress = (size - sizeI) * 100 / playback->input->GetBufferingSize();
  368. }
  369. playback->buffering = FALSE;
  370. playback->decaps->UpdateForSize();
  371. playback->baseTime = GetTickCount();
  372. playback->videoFrames = 0;
  373. RECT rect;
  374. GetClientRect(playback->hwndPlayback, &rect);
  375. InvalidateRect(playback->hwndPlayback, &rect, TRUE); 
  376.   UpdateWindow(playback->hwndPlayback);
  377. }
  378. }
  379. startPlaying:
  380. frame = NULL;
  381. if(!playback->paused) {
  382. if(playback->fastForward) {
  383. playback->decaps->SeekNextKeyFrame(0);
  384. }
  385. else {
  386. if(playback->rewind) {
  387. playback->decaps->SeekPreviousKeyFrame(0);
  388. }
  389. }
  390. /*
  391.  * 合成
  392.  *
  393.  */
  394. if(!playback->fastForward && !playback->rewind) {
  395. timeDiff = playback->GetVideoTime() - (GetTickCount() - playback->baseTime);
  396. if(timeDiff > 10) {
  397. Sleep(timeDiff/2);
  398. }
  399. if(timeDiff < -150) {
  400. /*
  401.  * 跳过,即不进行补偿
  402.  */
  403. playback->videoBuffer->DropOneFrame();
  404. playback->videoFrames++;
  405. }
  406. if(timeDiff < -230) {
  407. /*
  408.  * 跳过,即不进行补偿
  409.  */
  410. playback->videoBuffer->DropOneFrame();
  411. playback->videoFrames++;
  412. }
  413. }
  414. else {
  415. Sleep(80);
  416. }
  417. frame = playback->videoBuffer->GetOneFrame();
  418. playback->videoFrames++;
  419. if(frame == NULL) {
  420. if(playback->input->GetCaps() & MEDIA_CAPS_BUFFERIZE) {
  421. if(playback->input->GetBufferSize() < playback->input->GetSize()) {
  422. goto startBuffering;
  423. }
  424. }
  425. if(!playback->loop) {
  426. SendMessage(playback->hwndPlayback, WM_PLAYA_PLAYBACK_END, 0, 0);
  427. playback->Stop(TRUE);
  428. }
  429. else {
  430. playback->decaps->Rewind(0, 0);
  431. playback->videoBuffer->StopBuffering();
  432. playback->videoBuffer->StartBuffering(playback->decaps->GetVideoWidth(0));
  433. playback->videoFrames = 0;
  434. playback->baseTime    = GetTickCount();
  435. goto startPlaying;
  436. }
  437. break;
  438. }
  439. WaitForSingleObject(playback->playbackMutex, INFINITE);
  440. if(!playback->paused) {
  441.     if(playback->fullscreen) {
  442. playback->videoRenderer->DrawFullscreen(frame, playback->decaps->GetCurrentVideoFrame(0), 
  443. playback->videoDecoder->GetInvertFlag(), playback->desktopMode);
  444. }
  445. else {
  446. playback->videoRenderer->Draw(frame, playback->videoRect, playback->decaps->GetCurrentVideoFrame(0), 
  447.   playback->videoDecoder->GetInvertFlag());
  448. }
  449. }
  450. ReleaseMutex(playback->playbackMutex);
  451. }
  452. }
  453. }
  454. else {
  455. MessageBox(playback->hwndPlayback, "Playing : NULL playback engine!", "", MB_OK);
  456. }
  457. return 0;
  458. }
  459. /*
  460.  * 视频与音频线程(即主线程)同步
  461.  */
  462. DWORD WINAPI PlaybackVideoAndAudioThreadFunc( LPVOID lpData)
  463. {
  464. MediaPlayback *playback = (MediaPlayback *) lpData;
  465. long  timeDiff;
  466. MediaBuffer *frame = NULL;
  467. if(playback != NULL)
  468. {
  469. while(playback->playing) {
  470. if(playback->input->GetCaps() & MEDIA_CAPS_BUFFERIZE) {
  471. if(((playback->input->GetBufferPosition() > 0.95*playback->input->GetBufferSize()) && 
  472.   !(playback->input->GetBufferSize() >= playback->input->GetSize())) || playback->hasToBuffer) {
  473. startBufferingWAudio:
  474. if(!playback->audioRenderer->paused)
  475. playback->audioRenderer->Pause();
  476. if(playback->input->GetBufferSize() >= playback->input->GetSize()) {
  477. playback->decaps->UpdateForSize();
  478. if(playback->audioRenderer->paused)
  479. playback->audioRenderer->Pause();
  480. goto startPlayingWAudio;
  481. }
  482. DWORD size  = playback->input->GetBufferSize();
  483. DWORD sizeI = playback->input->GetBufferSize();
  484. /*
  485.  * 等待更多缓冲
  486.  */
  487. playback->bufferingProgress = 0;
  488. playback->buffering = TRUE;
  489. while(size < sizeI + playback->input->GetBufferingSize() && !(playback->input->GetBufferSize() >= playback->input->GetSize())) {
  490. Sleep(10);
  491. size = playback->input->GetBufferSize();
  492. playback->bufferingProgress = (size - sizeI) * 100 / playback->input->GetBufferingSize();
  493. }
  494. playback->buffering   = FALSE;
  495. playback->hasToBuffer = FALSE;
  496. playback->decaps->UpdateForSize();
  497. RECT rect;
  498. GetClientRect(playback->hwndPlayback, &rect);
  499. InvalidateRect(playback->hwndPlayback, &rect, TRUE); 
  500.   UpdateWindow(playback->hwndPlayback);
  501. if(playback->audioRenderer->paused)
  502. playback->audioRenderer->Pause();
  503. }
  504. }
  505. startPlayingWAudio:
  506. frame = NULL;
  507. if(!playback->paused) {
  508. if(playback->fastForward) {
  509. playback->decaps->SeekNextKeyFrame(0);
  510. }
  511. else {
  512. if(playback->rewind) {
  513. playback->decaps->SeekPreviousKeyFrame(0);
  514. }
  515. }
  516. /*
  517.  * 同步
  518.  *
  519.  */
  520. if(!playback->fastForward && !playback->rewind) {
  521. timeDiff = playback->GetVideoTime() - playback->GetAudioTime();
  522. if(timeDiff == 0) {
  523. /*
  524.  * 什么也不做
  525.  */
  526. }
  527. else {
  528. if(timeDiff > 10) {
  529. Sleep(timeDiff/2);
  530. }
  531. if(timeDiff < -150) {
  532. /*
  533.  * 跳过,不进行补偿
  534.  */
  535. playback->videoBuffer->DropOneFrame();
  536. playback->videoFrames++;
  537. }
  538. if(timeDiff < -230) {
  539. /*
  540.  * 跳过,不进行补偿
  541.  */
  542. playback->videoBuffer->DropOneFrame();
  543. playback->videoFrames++;
  544. }
  545. }
  546. }
  547. else {
  548. Sleep(120);
  549. }
  550. frame = playback->videoBuffer->GetOneFrame();
  551. playback->videoFrames++;
  552. if(frame == NULL) {
  553. /*
  554.  * 在文件或缓冲末尾
  555.  */
  556. if(playback->input->GetCaps() & MEDIA_CAPS_BUFFERIZE) {
  557. if(playback->input->GetBufferSize() < playback->input->GetSize()) {
  558. goto startBufferingWAudio;
  559. }
  560. else {
  561. if(!playback->audioRenderer->paused)
  562. playback->audioRenderer->Pause();
  563. playback->decaps->UpdateForSize();
  564. frame = playback->videoBuffer->GetOneFrame();
  565. if(playback->audioRenderer->paused)
  566. playback->audioRenderer->Pause();
  567. }
  568. }
  569. }
  570. if(frame == NULL) {
  571. if(!playback->loop) {
  572. SendMessage(playback->hwndPlayback, WM_PLAYA_PLAYBACK_END, 0, 0);
  573. playback->Stop(TRUE);
  574. }
  575. else {
  576. playback->decaps->Rewind(0, 0);
  577. if(!playback->fastForward && !playback->rewind) {
  578. if(playback->hasAudio)
  579. playback->audioRenderer->Stop();
  580. if(playback->hasAudio)
  581. playback->audioDecoder->EmptyAudioBuffer();
  582. }
  583. playback->audioBytes      = 0;
  584. playback->videoFrames     = 0;
  585. playback->videoBuffer->StopBuffering();
  586. playback->videoBuffer->StartBuffering(playback->decaps->GetVideoWidth(0));
  587. if(!playback->fastForward && !playback->rewind) {
  588. if(playback->hasAudio)
  589. playback->audioRenderer->Start();
  590. }
  591. goto startPlayingWAudio;
  592. }
  593. break;
  594. }
  595. WaitForSingleObject(playback->playbackMutex, INFINITE);
  596. if(!playback->paused) {
  597. if(playback->fullscreen) {
  598. playback->videoRenderer->DrawFullscreen(frame, playback->decaps->GetCurrentVideoFrame(0), playback->videoDecoder->GetInvertFlag(), playback->desktopMode);
  599. }
  600. else {
  601. playback->videoRenderer->Draw(frame, playback->videoRect, playback->decaps->GetCurrentVideoFrame(0), playback->videoDecoder->GetInvertFlag());
  602. }
  603. }
  604. ReleaseMutex(playback->playbackMutex);
  605. }
  606. }
  607. }
  608. return 0;
  609. }
  610. /*
  611.  * 图形设备接口(GDI)方法
  612.  *
  613.  */
  614. MP_RESULT     MediaPlayback::FlipToGDI() 
  615. {
  616. return MP_RESULT_OK;
  617. }
  618. /**************************************************************
  619.  *                                                            *
  620.  *                      视频回调方法                          *
  621.  *                 ------------------------                   *
  622.  *                                                            *
  623.  **************************************************************/
  624. MP_RESULT     MediaPlayback::Play()
  625. {
  626. if(this->HasAudio() || this->HasVideo()) {
  627. if(this->fastForward) {
  628. this->fastForward = FALSE;
  629. this->baseTime = GetTickCount();
  630. this->videoFrames = 0;
  631. this->audioBytes  = 0;
  632. if(this->decaps) {
  633. this->decaps->ReSeekAudio(0);
  634. }
  635. if(this->hasAudio) {
  636. this->audioDecoder->EmptyAudioBuffer();
  637. this->audioRenderer->SetVolume(this->volume);
  638. this->audioRenderer->Stop();
  639. this->audioRenderer->Start();
  640. }
  641. }
  642. else {
  643. if(this->rewind) {
  644. this->rewind  = FALSE;
  645. this->baseTime = GetTickCount();
  646. this->videoFrames     = 0;
  647. this->audioBytes      = 0;
  648. if(this->decaps) {
  649. this->decaps->ReSeekAudio(0);
  650. }
  651. if(this->hasAudio) {
  652. this->audioDecoder->EmptyAudioBuffer();
  653. this->audioRenderer->SetVolume(this->volume);
  654. this->audioRenderer->Stop();
  655. this->audioRenderer->Start();
  656. }
  657. }
  658. else {
  659. if(this->paused) {
  660. this->Pause();
  661. return MP_RESULT_OK;
  662. }
  663. if(this->playing)
  664. return MP_RESULT_ERROR;
  665. this->playing = TRUE;
  666. this->paused  = FALSE;
  667. this->videoFrames = 0;
  668. this->audioBytes  = 0;
  669. this->decaps->Rewind(0, 0);
  670. if(this->HasAudio()) {
  671. this->audioDecoder->EmptyAudioBuffer();
  672. this->audioRenderer->SetVolume(this->volume);
  673. this->videoBuffer->StartBuffering(this->decaps->GetVideoWidth(0));
  674. if(this->audioRenderer->paused && (this->input->GetCaps() & MEDIA_CAPS_BUFFERIZE)) {
  675. this->audioRenderer->Pause();
  676. this->audioRenderer->Stop();
  677. this->audioRenderer->Start();
  678. }
  679. else {
  680. this->audioRenderer->Start();
  681. }
  682. this->videoThread = CreateThread( NULL, 0, PlaybackVideoAndAudioThreadFunc, (LPVOID) this, 0, &this->videoThreadId );
  683. return MP_RESULT_OK;
  684. }
  685. else {
  686. if(this->HasVideo()) {
  687. this->videoBuffer->StartBuffering(this->decaps->GetVideoWidth(0));
  688. this->videoThread = CreateThread( NULL, 0, PlaybackVideoOnlyThreadFunc, (LPVOID) this, 0, &this->videoThreadId );
  689. return MP_RESULT_OK;
  690. }
  691. }
  692. }
  693. }
  694. }
  695. return MP_RESULT_ERROR;
  696. }
  697. MP_RESULT     MediaPlayback::Pause()
  698. {
  699. if(this->playing) {
  700. if(this->paused) {
  701. if(this->hasAudio) {
  702. this->audioRenderer->Pause();
  703. }
  704. this->paused = FALSE;
  705. ReleaseMutex(this->playbackMutex);
  706. this->baseTime += (GetTickCount() - this->stopTime);
  707. ResumeThread(this->videoThread);
  708. }
  709. else {
  710. WaitForSingleObject(this->playbackMutex, INFINITE);
  711. if(!this->fastForward && !this->rewind) {
  712. if(this->hasAudio) {
  713. this->audioRenderer->Pause();
  714. }
  715. }
  716. else {
  717. this->videoFrames     = 0;
  718. if(this->hasAudio) {
  719. this->decaps->ReSeekAudio(0);
  720. this->audioDecoder->EmptyAudioBuffer();
  721. this->audioBytes     = 0;
  722. this->audioRenderer->Stop();
  723. this->audioRenderer->Start();
  724. this->audioRenderer->Pause();
  725. }
  726. }
  727. this->fastForward = FALSE;
  728. this->rewind      = FALSE;
  729. this->stopTime = GetTickCount();
  730. SuspendThread(this->videoThread);
  731. this->paused = TRUE;
  732. }
  733. }
  734. return MP_RESULT_ERROR;
  735. }
  736. MP_RESULT     MediaPlayback::NextFrame()
  737. {
  738. return MP_RESULT_ERROR;
  739. }
  740. MP_RESULT     MediaPlayback::Stop(int redrawWindow)
  741. {
  742. if(this->paused)
  743. this->Pause();
  744. if(this->playing) {
  745. WaitForSingleObject(this->playbackMutex, INFINITE);
  746. if(this->hasAudio) {
  747. this->audioRenderer->Stop();
  748. }
  749. this->playing = FALSE;
  750. this->buffering = FALSE;
  751. this->bufferingProgress = 0;
  752. if(this->HasVideo()) {
  753. this->videoBuffer->StopBuffering();
  754. }
  755. ReleaseMutex(this->playbackMutex);
  756. }
  757. this->fastForward  = FALSE;
  758. this->rewind       = FALSE;
  759. this->playing      = FALSE;
  760. this->paused       = FALSE;
  761. this->audioBytes      = 0;
  762. this->videoFrames     = 0;
  763. this->decaps->Rewind(0, 0);
  764. if(this->hasAudio)
  765. this->audioDecoder->EmptyAudioBuffer();
  766. if(this->videoRenderer)
  767. this->videoRenderer->Stop();
  768. /*
  769.  * 刷新
  770.  */
  771. RECT rect;
  772. if(redrawWindow) {
  773. GetClientRect(this->hwndPlayback, &rect);
  774. InvalidateRect(this->hwndPlayback, &rect, TRUE); 
  775.   UpdateWindow(this->hwndPlayback);
  776. }
  777. TerminateThread(this->videoThread, 0);
  778. return MP_RESULT_ERROR;
  779. }
  780. MP_RESULT     MediaPlayback::FastForward()
  781. {
  782. if(this->paused) {
  783. this->fastForward = TRUE;
  784. this->paused      = FALSE;
  785. ReleaseMutex(this->playbackMutex);
  786. this->baseTime += (GetTickCount() - this->stopTime);
  787. ResumeThread(this->videoThread);
  788. return MP_RESULT_OK;
  789. }
  790. if(this->playing && !this->rewind && !this->fastForward) {
  791. if(this->hasAudio) {
  792. this->audioRenderer->Stop();
  793. }
  794. this->stopTime = GetTickCount();
  795. this->fastForward = TRUE;
  796. }
  797. return MP_RESULT_OK;
  798. }
  799. MP_RESULT     MediaPlayback::Rewind()
  800. {
  801. if(this->paused) {
  802. this->rewind = TRUE;
  803. this->paused = FALSE;
  804. ReleaseMutex(this->playbackMutex);
  805. this->baseTime += (GetTickCount() - this->stopTime);
  806. ResumeThread(this->videoThread);
  807. return MP_RESULT_OK;
  808. }
  809. if(this->playing && !this->fastForward && !this->rewind) {
  810. if(this->hasAudio) {
  811. this->audioRenderer->Stop();
  812. }
  813. this->stopTime = GetTickCount();
  814. this->rewind = TRUE;
  815. }
  816. return MP_RESULT_OK;
  817. }
  818. MP_RESULT     MediaPlayback::MaintainImage()
  819. {
  820. if(this->HasVideo()) {
  821. if(this->fullscreen) {
  822. this->videoRenderer->DrawFullscreen(this->videoBuffer->GetLastFrame(), 0, this->videoDecoder->GetInvertFlag(), this->desktopMode);
  823. }
  824. else {
  825. this->videoRenderer->Draw(this->videoBuffer->GetLastFrame(), this->videoRect, 0, this->videoDecoder->GetInvertFlag());
  826. }
  827. }
  828. return MP_RESULT_OK;
  829. }
  830. MP_RESULT     MediaPlayback::Seek(int percent)
  831. {
  832. int has_to_play = 0;
  833. RECT rect;
  834. if(this->HasAudio() || this->HasVideo()) {
  835. if(this->playing) {
  836. Stop(FALSE);
  837. has_to_play = 1;
  838. }
  839. this->decaps->Seek(0, 0, percent);
  840. if(this->input->GetCaps() & MEDIA_CAPS_BUFFERIZE) {
  841. this->decaps->UpdateForSize();
  842. }
  843. if(this->hasAudio)
  844. this->audioDecoder->EmptyAudioBuffer();
  845. if(has_to_play) {
  846. this->playing = TRUE;
  847. this->paused  = FALSE;
  848. this->videoFrames     = 0;
  849. this->audioBytes      = 0;
  850. if(this->HasAudio()) {
  851. this->audioRenderer->Start();
  852. this->videoThread = CreateThread( NULL, 0, PlaybackVideoAndAudioThreadFunc, (LPVOID) this, 0, &this->videoThreadId );
  853. }
  854. else {
  855. this->videoThread = CreateThread( NULL, 0, PlaybackVideoOnlyThreadFunc, (LPVOID) this, 0, &this->videoThreadId );
  856. }
  857. }
  858. GetClientRect(this->hwndPlayback, &rect);
  859. InvalidateRect(this->hwndPlayback, &rect, TRUE); 
  860.   UpdateWindow(this->hwndPlayback);
  861. }
  862. return MP_RESULT_ERROR;
  863. }
  864. MP_RESULT     MediaPlayback::SetFullscreen(int active, HWND hwnd)
  865. {
  866. if(active && !this->fullscreen) {
  867. int has_to_play = 0;
  868. if(this->playing && !this->paused) {
  869. this->Pause();
  870. has_to_play = 1;
  871. }
  872. this->fullscreen = TRUE;
  873. if(this->videoRenderer->InitFullscreen(hwnd, this->decaps->GetVideoWidth(0), this->decaps->GetVideoHeight(0)) != MP_RESULT_OK) {
  874. this->videoRenderer->Init(hwnd, this->decaps->GetVideoWidth(0), this->decaps->GetVideoHeight(0));
  875. this->fullscreen = FALSE;
  876. return MP_RESULT_ERROR;
  877. }
  878. if(has_to_play) {
  879. this->Pause();
  880. }
  881. }
  882. else {
  883. if(this->fullscreen) {
  884. int has_to_play = 0;
  885. if(this->playing && !this->paused) {
  886. this->Pause();
  887. has_to_play = 1;
  888. }
  889. this->videoRenderer->Init(hwnd, this->decaps->GetVideoWidth(0), this->decaps->GetVideoHeight(0));
  890. this->fullscreen = FALSE;
  891. if(has_to_play) {
  892. this->Pause();
  893. }
  894. }
  895. }
  896. return MP_RESULT_ERROR;
  897. }
  898. MP_RESULT     MediaPlayback::SetVolume(int volume)
  899. {
  900. this->volume = volume;
  901. if(this->hasAudio) {
  902. this->audioRenderer->SetVolume(this->volume);
  903. }
  904. return MP_RESULT_OK;
  905. }
  906. MP_RESULT     MediaPlayback::SetLoop(int loop)
  907. {
  908. this->loop = loop;
  909. return MP_RESULT_OK;
  910. }
  911. MP_RESULT     MediaPlayback::SetDesktopMode(BOOL on)
  912. {
  913. this->desktopMode = on;
  914. return MP_RESULT_OK;
  915. }
  916. MP_RESULT     MediaPlayback::SetVideoRect(RECT *rect)
  917. {
  918. this->videoRect = rect;
  919. return MP_RESULT_OK;
  920. }
  921. MP_RESULT     MediaPlayback::Close()
  922. {
  923. if(this->input)
  924. this->input->Close();
  925. if(this->HasVideo()) {
  926. /*
  927.  * 清除视频
  928.  *
  929.  */
  930. this->Stop(FALSE);
  931. this->videoRenderer->Close();
  932. this->videoBuffer->StopBuffering();
  933. this->videoBuffer->ReleaseConnections();
  934. this->videoDecoder->ReleaseConnections();
  935. this->decaps->ReleaseConnections();
  936. }
  937. if(this->HasAudio()) {
  938. /*
  939.  * 清除音频
  940.  *
  941.  */
  942. this->audioRenderer->Close();
  943. this->audioDecoder->ReleaseConnections();
  944. }
  945. if(this->hasSubtitles) {
  946. this->subtitler->ReleaseConnections();
  947. this->subtitler->Close();
  948. }
  949. return MP_RESULT_OK;
  950. }