changeset 2363:7966fc2949a7

Merge
author Grumpy7
date Thu, 01 May 2014 12:59:50 +0200
parents eb136041adf1 (current diff) d6bba1e6249d (diff)
children 94e5a9740727
files
diffstat 3 files changed, 73 insertions(+), 45 deletions(-) [+]
line wrap: on
line diff
--- a/MediaPlayer.cpp	Thu May 01 12:59:27 2014 +0200
+++ b/MediaPlayer.cpp	Thu May 01 12:59:50 2014 +0200
@@ -26,6 +26,7 @@
 Media::MPlayer *pMediaPlayer;
 Media::IMovie *pMovie;
 Media::ITrack *pTrack;
+Movie *movie;
 
 int mSourceID;
 
@@ -642,6 +643,8 @@
 
   //Освободить память выделенную для фрейма
   avcodec_free_frame(&frame);
+  delete frame;
+  av_free_packet(packet);
   delete packet;
 
   return true;
@@ -755,16 +758,6 @@
 class Movie: public Media::IMovie
 {
   public:
-	int              audio_stream_idx;
-	AVStream        *audio_stream;//содержат информацию о аудио потоке
-	AVCodec         *audio_stream_dec;
-	AVCodecContext  *audio_stream_dec_ctx;
-
-	int              video_stream_idx;
-	AVStream        *video_stream;//содержат информацию о видео потоке
-	AVCodec         *video_stream_dec;
-	AVCodecContext  *video_stream_dec_ctx;
-
     inline Movie()
     {
       this->movie_filename[0] = 0;
@@ -781,7 +774,7 @@
       memset(last_resampled_frame_data, 0, sizeof(last_resampled_frame_data));
       memset(last_resampled_frame_linesize, 0, sizeof(last_resampled_frame_linesize));
 
-		decoding_packet = nullptr;
+      decoding_packet = nullptr;
 		ioBuffer = nullptr;
 		format_ctx = nullptr;
 		avioContext = nullptr;
@@ -796,13 +789,30 @@
     {
       audio.Release();
       video.Release();
+
       if (format_ctx)
       {
 		// Close the video file
         // закрытие контекста файла(видео файла)
         av_close_input_file(format_ctx);
         format_ctx = nullptr;
+	  }
+	  if(avioContext)
+	  {
+		av_free(avioContext);
+		avioContext = nullptr;
+	  }
+	  if (ioBuffer)
+	  {
+		//av_free(ioBuffer);
+		ioBuffer = nullptr;
       }
+	  av_free_packet(decoding_packet);
+	  delete decoding_packet;
+      avcodec_free_frame(&decoding_frame);
+	  delete decoding_frame;
+      if (last_resampled_frame_data[0])
+        av_freep(&last_resampled_frame_data[0]);
     }
 
     bool Load(const wchar_t *filename, int dst_width, int dst_height, int cache_ms)	//Загрузка
@@ -858,7 +868,6 @@
 			current_movie_height = height;
 	      } 
 		  //
-
           decoding_packet = new AVPacket;
           av_init_packet(decoding_packet);
       
@@ -880,9 +889,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 +906,38 @@
       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 )
+            end_current_file = true;
+        }
         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;
+          av_free_packet(avpacket);
+		  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 +945,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);
@@ -959,6 +973,7 @@
         AVPixelFormat  rescaled_format = AV_PIX_FMT_RGB32;
         uint8_t       *rescaled_data[4] = {nullptr, nullptr, nullptr, nullptr};
         int            rescaled_linesize[4] = {0, 0, 0, 0};
+
         if (av_image_alloc(rescaled_data, rescaled_linesize, current_movie_width, current_movie_height, rescaled_format, 1) >= 0)
         {
           // создание контекста для преобразования
@@ -975,10 +990,14 @@
           last_resampled_frame_num = desired_frame_number;
           memcpy(last_resampled_frame_data, rescaled_data, sizeof(rescaled_data));
           memcpy(last_resampled_frame_linesize, rescaled_linesize, sizeof(rescaled_linesize));
+          //вроде должен быть av_freep(&rescaled_data[0]);
         }
       }
       else
         memset(dst_surface, 0, width * current_movie_height * 4);
+
+      // Free the packet that was allocated by av_read_frame
+      av_free_packet(avpacket);
     }
 
     virtual void Play()
@@ -1023,7 +1042,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 +1053,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 +1115,13 @@
   track->Play();
 }
 
+void MovieRelease()
+{
+  movie->Release();
+  delete movie;
+  movie = nullptr;
+}
+
 //////////////////////////////////////////////////////////////////////////
 //Included from a VideoPlayer.cpp file/вставлено из файла VideoPlayer.cpp/
 //////////////////////////////////////////////////////////////////////////
--- a/MediaPlayer.h	Thu May 01 12:59:27 2014 +0200
+++ b/MediaPlayer.h	Thu May 01 12:59:50 2014 +0200
@@ -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	Thu May 01 12:59:27 2014 +0200
+++ b/VideoPlayer.cpp	Thu May 01 12:59:50 2014 +0200
@@ -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();
 }