changeset 2360:63ad4e3606f4

MovieRelease();
author Ritor1
date Wed, 16 Apr 2014 17:36:47 +0600
parents 5b9fb75b6f54
children d6bba1e6249d
files MediaPlayer.cpp MediaPlayer.h VideoPlayer.cpp
diffstat 3 files changed, 64 insertions(+), 34 deletions(-) [+]
line wrap: on
line diff
--- a/MediaPlayer.cpp	Sat Apr 12 02:29:26 2014 +0600
+++ b/MediaPlayer.cpp	Wed Apr 16 17:36:47 2014 +0600
@@ -26,6 +26,7 @@
 Media::MPlayer *pMediaPlayer;
 Media::IMovie *pMovie;
 Media::ITrack *pTrack;
+Movie *movie;
 
 int mSourceID;
 
@@ -802,7 +803,18 @@
         // закрытие контекста файла(видео файла)
         av_close_input_file(format_ctx);
         format_ctx = nullptr;
+	  }
+	  if(avioContext)
+	  {
+		av_free(avioContext);
+		avioContext = nullptr;
+	  }
+	  if (ioBuffer)
+	  {
+		av_free(ioBuffer);
+		ioBuffer = nullptr;
       }
+	  delete decoding_packet;
     }
 
     bool Load(const wchar_t *filename, int dst_width, int dst_height, int cache_ms)	//Загрузка
@@ -858,7 +870,6 @@
 			current_movie_height = height;
 	      } 
 		  //
-
           decoding_packet = new AVPacket;
           av_init_packet(decoding_packet);
       
@@ -880,9 +891,9 @@
 	bool LoadFromLOD(HANDLE h, int readFunction(void*, uint8_t*, int), int64_t seekFunction(void*, int64_t, int), int width, int height)
 	{
 		if (!ioBuffer)
-			ioBuffer = (unsigned char *)av_malloc(16384 + FF_INPUT_BUFFER_PADDING_SIZE); // can get av_free()ed by libav
+			ioBuffer = (unsigned char *)av_malloc(0x4000 + FF_INPUT_BUFFER_PADDING_SIZE); // can get av_free()ed by libav
 		if (!avioContext)
-			avioContext = avio_alloc_context(ioBuffer, 16384, 0, h, readFunction, NULL, seekFunction);
+			avioContext = avio_alloc_context(ioBuffer, 0x4000, 0, h, readFunction, NULL, seekFunction);
 		if (!format_ctx)
 			format_ctx = avformat_alloc_context();
 		format_ctx->pb = avioContext;
@@ -897,40 +908,43 @@
       AVPacket *avpacket = decoding_packet;
       AVFrame *avframe = decoding_frame;
       
-	  //???
+	  //Инизиализируем avframe
       avcodec_get_frame_defaults(avframe);
 
       int desired_frame_number = floor(playback_time * video.dec_ctx->time_base.den / video.dec_ctx->time_base.num + 0.5);
       if (last_resampled_frame_num == desired_frame_number)
       {
-        memcpy(dst_surface, last_resampled_frame_data[0], height * last_resampled_frame_linesize[0]);
+        memcpy(dst_surface, last_resampled_frame_data[0], current_movie_height * last_resampled_frame_linesize[0]);
         return;
       }
 
       volatile int frameFinished = false;
+
+	  //чтение пакетов
+      // keep reading packets until we hit the end or find a video packet
       do
       {
+        if (loop_current_file)
+        {
+          //Now seek back to the beginning of the stream
+          if (video.dec_ctx->frame_number >= video.stream->duration - 1 )
+		  {
+          //  if (av_seek_frame(format_ctx, video.stream_idx, format_ctx->start_time, AVSEEK_FLAG_BACKWARD) < 0)
+          //    fprintf(stderr, "%s: error while seeking\n", format_ctx->filename);		  
+		  //}
+          end_current_file = true;
+		 // return;
+		  }
+        }
         if (av_read_frame(format_ctx, avpacket) < 0) //воспроизведение завершено
         {
-          if (loop_current_file)
-          {
-            if (av_seek_frame(format_ctx, video.stream_idx, format_ctx->start_time, AVSEEK_FLAG_BACKWARD) < 0);
-              fprintf(stderr, "%s: error while seeking\n", format_ctx->filename);
-            while (avpacket->stream_index!=video.stream_idx)
-            {    
-              av_free_packet(avpacket);
-              if (av_read_frame(format_ctx, avpacket)<0)
-                av_seek_frame(format_ctx, -1, format_ctx->start_time, AVSEEK_FLAG_BACKWARD);
-            }
-          }
-          else
-		  {
-            end_current_file = true;
-		   return;
-		  }
           // probably movie is finished
-          //__debugbreak();
+          end_current_file = true;
+		  return;
         }
+		// Is this a packet from the video stream?
+        // audio packet - queue into playing
+        //Принадлежит ли пакет к аудиопотоку
         if (avpacket->stream_index == audio.stream_idx)
         {
           MemoryStream audio_data;
@@ -938,11 +952,18 @@
             provider->Stream16(audio_data_in_device, num_audio_samples, audio_data.Ptr());
           //continue;
         }
+
+		// Decode video frame
+        //пакет к видеопотоку
         // video packet - decode & maybe show
         else if (avpacket->stream_index == video.stream_idx)
         {
           do
           {
+	       //Функция avcodec_decode_video2 осуществляет декодирование пакета в фрейм с использованием кодека,
+           //который мы получили раньше (codec_context). Функция устанавливает положительное значение frame_finished в случае
+           //если фрейм декодирован целиком (то есть один фрейм может занимать несколько пакетов и frame_finished будет 
+           //установлен только при декодировании последнего пакета).
             if (avcodec_decode_video2(video.dec_ctx, avframe, (int *)&frameFinished, avpacket) < 0)
               __debugbreak();
           } while (!frameFinished);
@@ -1023,7 +1044,7 @@
 
 IMovie *MPlayer::LoadMovie(const wchar_t *filename, int width, int height, int cache_ms)	//Загрузить видео
 {
-  auto movie = new Movie;
+  movie = new Movie;
   if (!movie->Load(filename, width, height, cache_ms))
   {
     delete movie;
@@ -1034,7 +1055,7 @@
 
 IMovie *MPlayer::LoadMovieFromLOD(HANDLE h, int readFunction(void*, uint8_t*, int), int64_t seekFunction(void*, int64_t, int), int width, int height)
 {
-	auto movie = new Movie;
+	movie = new Movie;
 	if (movie)
 	{
 		if (movie->LoadFromLOD(h, readFunction, seekFunction, width, height))
@@ -1096,6 +1117,13 @@
   track->Play();
 }
 
+void MovieRelease()
+{
+  movie->Release();
+  delete movie;
+  movie = nullptr;
+}
+
 //////////////////////////////////////////////////////////////////////////
 //Included from a VideoPlayer.cpp file/вставлено из файла VideoPlayer.cpp/
 //////////////////////////////////////////////////////////////////////////
--- a/MediaPlayer.h	Sat Apr 12 02:29:26 2014 +0600
+++ b/MediaPlayer.h	Wed Apr 16 17:36:47 2014 +0600
@@ -28,6 +28,7 @@
 extern Media::MPlayer *pMediaPlayer;
 extern Media::IMovie *pMovie;
 extern Media::ITrack *pTrack;
+extern class Movie *movie;
 
 extern bool end_current_file;
 extern bool loop_current_file;
@@ -37,9 +38,10 @@
 
 extern int mSourceID;
 
-int64_t seekFunction(void* opaque, int64_t offset, int whence);
+//int64_t seekFunction(void* opaque, int64_t offset, int whence);
 extern void PlayMovie(const wchar_t * pFilename);
 extern void PlayAudio(const wchar_t * pFilename);
+extern void MovieRelease();
 
 //////////////////////////////////////////////////////////////////////////
 //Included from a VideoPlayer.h file/вставлено из файла VideoPlayer.h/
--- a/VideoPlayer.cpp	Sat Apr 12 02:29:26 2014 +0600
+++ b/VideoPlayer.cpp	Wed Apr 16 17:36:47 2014 +0600
@@ -278,20 +278,21 @@
 void VideoPlayer::UpdatePalette() //UpdateVideo
 {
   Log::Warning(L"smacker");
-  loop_current_file = true;
+  loop_current_file = true;//зацикленный ролик
   pRenderer->BeginScene();
-  /*if (end_current_file)//видео завершено/перезагрузка
+  if (end_current_file)//видео завершено/перезагрузка
   {
     int width = game_viewport_width;
     int height = game_viewport_height;
-    delete pMovie;
+	MovieRelease();
 
     SetFilePointer(hVidFile, uOffset, nullptr, FILE_BEGIN);
-
-    //pMovie = pPlayer->LoadMovieFromLOD(hVidFile, &readFunction, &seekFunction, width, height);
+    pMovie = nullptr;
+    pMovie = pMediaPlayer->LoadMovieFromLOD(hVidFile, &readFunction, &seekFunction, width, height);
+	end_current_file = false;
   }
-  else */
-  {
+  //else 
+  //{
       double dt = (GetTickCount() - time_video_begin) / 1000.0;
       //dt = 1.0/15.0;
       time_video_begin = GetTickCount();
@@ -301,7 +302,6 @@
       auto image = new char[current_movie_width * current_movie_height * 4];
 
       pMovie->GetNextFrame(dt, image);
-      Sleep(60);  //Ritor1:it's my include
 
     int image_array[460 * 344];//game_viewport_width * game_viewport_height
     if (image)
@@ -317,7 +317,7 @@
       }
       delete[] image;
     }
-  }
+  //}
   pRenderer->EndScene();
 }