diff VideoPlayer.h @ 2345:182effc4b0ee

for MultimediaPlayer
author Ritor1
date Mon, 07 Apr 2014 19:15:13 +0600
parents ddb803517a48
children d57505d3c70c
line wrap: on
line diff
--- a/VideoPlayer.h	Wed Apr 02 23:21:34 2014 +0200
+++ b/VideoPlayer.h	Mon Apr 07 19:15:13 2014 +0600
@@ -1,6 +1,7 @@
 #pragma once
 #include "OSWindow.h"
 #include "Texture.h"
+#include "MediaPlayer.h"
 
 
 
@@ -388,6 +389,10 @@
 		do
 		{
 			int ret;
+//Функция avcodec_decode_video2 осуществляет декодирование пакета в фрейм с использованием кодека,
+//который мы получили раньше (codec_context). Функция устанавливает положительное значение frame_finished в случае
+//если фрейм декодирован целиком (то есть один фрейм может занимать несколько пакетов и frame_finished будет 
+//установлен только при декодировании последнего пакета).
 			if ((ret = avcodec_decode_video2(dec_ctx, f, (int *)&done, p)) < 0)
 				return ret;
 		} while (!done);
@@ -409,10 +414,10 @@
 	{
 		if (av_image_alloc(out_data, out_linesize, dst_width, dst_height, format, 1) < 0)
 			return false;
-
+// создание контекста для преобразования
 		SwsContext *converter = sws_getContext(frame->width, frame->height, (AVPixelFormat)frame->format,
-			dst_width, dst_height, format,
-			SWS_BICUBIC, nullptr, nullptr, nullptr);
+			dst_width, dst_height, format, SWS_BICUBIC, nullptr, nullptr, nullptr);
+// преобразование кадра
 		sws_scale(converter, frame->data, frame->linesize, 0, frame->height, out_data, out_linesize);
 		sws_freeContext(converter);
 
@@ -444,6 +449,7 @@
 		volatile int done = false;
 		do
 		{
+//Декодирование аудио-пакета осуществляется функцией avcodec_decode_audio4
 			int ret;
 			if ((ret = avcodec_decode_audio4(dec_ctx, f, (int *)&done, p)) < 0)
 				return ret;
@@ -522,7 +528,7 @@
 class MovieCached
 {
 public:
-	bool Stopped() { return stopped; }
+	//bool Stopped() { return stopped; }
 	int GetWidth() { return width; }
 	int GetHeight() { return height; }
 	inline ~MovieCached()
@@ -553,7 +559,7 @@
 		avioContext = nullptr;
 	}
 
-	bool LoadFromLOD(HANDLE h, int readFunction(void*, uint8_t*, int), int64_t seekFunction(void*, int64_t, int), int width, int height)
+	/*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
@@ -563,17 +569,28 @@
 			format_ctx = avformat_alloc_context();
 		format_ctx->pb = avioContext;
 		return Load("dummyFilename", width, height);
-	}
+	}  */
 
-	bool Load(const char *video_filename, int width, int height)
+	/*bool Load(const char *video_filename, int width, int height)
 	{
 		this->width = width;
 		this->height = height;
-		
+// Open video file
+//откроем входной файл(Шаг 2)
+//Функция avformat_open_input читает файловый заголовок и сохраняет информацию о найденных форматах в структуре
+//AVFormatContext. Остальные аргументы могут быть установлены в NULL, в этом случае libavformat использует 
+//автоматическое определение параметров.
 		if (avformat_open_input(&format_ctx, video_filename, nullptr, nullptr) >= 0)
 		{
+// Retrieve stream information
+//Т.к. avformat_open_input читает только заголовок файла, то следующим шагом нужно получить информацию о потоках
+//в файле. Это делается функцией avformat_find_stream_info.(Шаг 3)
 			if (avformat_find_stream_info(format_ctx, nullptr) >= 0)
 			{
+// Dump information about file onto standard error
+//После этого format_context->streams содержит все существующие потоки файла. 
+//Их количество равно format_context->nb_streams.
+//Вывести подробную информацию о файле и обо всех потоках можно функцией av_dump_format.
 				av_dump_format(format_ctx, 0, video_filename, 0);
 				
 				video_stream_idx = OpenStream(AVMEDIA_TYPE_VIDEO, &video_stream, &video_stream_dec, &video_stream_dec_ctx);
@@ -590,13 +607,17 @@
 					return Release(), false;
 
 				strcpy(movie_name, video_filename);
+//Данные из файла читаются пакетами (AVPacket)
 				packet = new AVPacket;
 				av_init_packet(packet);
 				return true;
 			}
+			fprintf(stderr, "ffmpeg: Unable to find stream info\n");
+			return Release(), false;
 		}
+		fprintf(stderr, "ffmpeg: Unable to open input file\n");
 		return Release(), false;
-	}
+	} */
 
 	bool Release()
 	{
@@ -612,6 +633,8 @@
 			video_stream_idx = -1;
 			video_stream = nullptr;
 			video_stream_dec = nullptr;
+
+			// закрытие видео кодека
 			avcodec_close(video_stream_dec_ctx);
 			video_stream_dec_ctx = nullptr;
 		}
@@ -621,6 +644,8 @@
 			audio_stream_idx = -1;
 			audio_stream = nullptr;
 			audio_stream_dec = nullptr;
+
+			// закрытие аудио кодека
 			avcodec_close(audio_stream_dec_ctx);
 
 		}
@@ -638,13 +663,15 @@
 	}
 
 
-	int OpenStream(AVMediaType type, AVStream **out_stream, AVCodec **out_dec, AVCodecContext **out_dec_ctx)
+	/*int OpenStream(AVMediaType type, AVStream **out_stream, AVCodec **out_dec, AVCodecContext **out_dec_ctx)
 	{
 		int stream_idx = av_find_best_stream(format_ctx, type, -1, -1, nullptr, 0);
 		if (stream_idx < 0)
 			return stream_idx;
 
 		auto stream = format_ctx->streams[stream_idx];
+//Информация о кодеке в потоке называется «контекстом кодека» (AVCodecContext).
+//Используя эту информацию, мы можем найти необходимый кодек (AVCodec) и открыть его.
 		auto dec_ctx = stream->codec;
 		auto dec = avcodec_find_decoder(dec_ctx->codec_id);
 		if (dec)
@@ -657,8 +684,9 @@
 				return stream_idx;
 			}
 		}
+		fprintf(stderr, "ffmpeg: Unable to open codec\n");
 		return -1;
-	}
+	}  */
 
 	MultimediaFrame::Ptr GetNextFrame()
 	{
@@ -666,6 +694,7 @@
 		packet->size = 0;
 
 		volatile int got_frame = false;
+		//чтение пакетов
 		do
 		{
 			if (av_read_frame(format_ctx, packet) < 0)
@@ -673,8 +702,8 @@
 				stopped = true;
 				return nullptr;
 			}
-		} while (packet->stream_index != video_stream_idx &&
-			packet->stream_index != audio_stream_idx);
+		} while (packet->stream_index != video_stream_idx &&  //пока пакет не пренадлежит к видеопотоку
+			packet->stream_index != audio_stream_idx); //и не принадлежит аудиопотоку
 
 		if (packet->stream_index == video_stream_idx)
 			return MultimediaFrame::Ptr(new MultimediaVideoFrame(AVMEDIA_TYPE_VIDEO, packet, video_stream_dec_ctx, width, height));
@@ -688,7 +717,7 @@
 	char                 movie_name[256];
 	int                  width;
 	int                  height;
-	bool                 stopped;
+	//bool                 stopped;
 	AVFormatContext     *format_ctx;
 	//AVFrame             *frame;
 	AVPacket            *packet;
@@ -696,23 +725,23 @@
 	OpenALSoundProvider *sound_provider;
 
 	int              video_stream_idx;
-	AVStream        *video_stream;
+	AVStream        *video_stream;//содержат информацию о видео потоке
 	AVCodec         *video_stream_dec;
 	AVCodecContext  *video_stream_dec_ctx;
 
 	int              audio_stream_idx;
-	AVStream        *audio_stream;
+	AVStream        *audio_stream;//содержат информацию о аудио потоке
 	AVCodec         *audio_stream_dec;
 	AVCodecContext  *audio_stream_dec_ctx;
 	unsigned char * ioBuffer;
 	AVIOContext *avioContext;
 };
-typedef MovieCached<10> Movie;
+//typedef MovieCached<10> Movie;
 
 
 
 
-class MultimediaPlayer
+/*class MultimediaPlayer
 {
 public:
 	inline MultimediaPlayer()
@@ -725,6 +754,11 @@
 		{
 			av_log_set_callback(Logger);
 			avcodec_register_all();
+
+// Register all available file formats and codecs
+//инициализируем библиотеку ffmpeg(Шаг 1)
+//Во время инициализации регистрируются все имеющиеся в библиотеке форматы файлов и кодеков.
+//После этого они будут использоваться автоматически при открытии файлов этого формата и с этими кодеками.
 			av_register_all();
 
 			libavcodec_initialized = true;
@@ -736,7 +770,7 @@
 		return true;
 	}
 
-	Movie *LoadMovieFromLOD(HANDLE h, int readFunction(void*, uint8_t*, int), int64_t seekFunction(void*, int64_t, int), int width, int height)
+	/*Movie *LoadMovieFromLOD(HANDLE h, int readFunction(void*, uint8_t*, int), int64_t seekFunction(void*, int64_t, int), int width, int height)
 	{
 		auto movie = new Movie(sound_provider);
 		if (movie)
@@ -758,9 +792,9 @@
 			delete movie;
 		}
 		return nullptr;
-	}
+	}  */
 
-	Movie *LoadMovie(const char *filename, int width, int height)
+	/*Movie *LoadMovie(const char *filename, int width, int height)
 	{
 		auto movie = new Movie(sound_provider);
 		if (movie)
@@ -774,7 +808,7 @@
 			delete movie;
 		}
 		return nullptr;
-	}
+	} 
 
 	inline char *DoFrame()
 	{
@@ -821,12 +855,12 @@
 	static void Logger(void *, int, const char *format, va_list args);
 
 	OpenALSoundProvider *sound_provider;
-	Movie               *current_movie;
+	//Movie               *current_movie;
 	int                  current_movie_width;
 	int                  current_movie_height;
 
 	static bool libavcodec_initialized;
-};
+};*/
 
 
 
@@ -900,8 +934,8 @@
   char pCurrentMovieName[64];
   char pVideoFrameTextureFilename[32];
   int field_104;
-  MultimediaPlayer *pPlayer;
-  Movie *pMovie;
+  Media::Player *pPlayer;
+  Media::IMovie *pMovie;
   HANDLE hVidFile;
   int uSize;
   int uOffset;
@@ -909,6 +943,8 @@
   static int readFunction(void *, uint8_t *, int);
   static int64_t seekFunction(void *, int64_t, int);
   void LoadMovie(const char *);
+  void PlayAudio(const wchar_t * pFilename);
+  void PlayMovie(const wchar_t * pFilename);
 };
 #pragma pack(pop)