Mercurial > mm7
changeset 2347:d57505d3c70c
VideoPlayer cleaning
author | Ritor1 |
---|---|
date | Tue, 08 Apr 2014 17:39:59 +0600 |
parents | 37bb43874e59 |
children | 4100fb5c4913 08c4f1799ca1 |
files | Bink_Smacker.h Build/Visual Studio 2012/World of Might and Magic.vcxproj.user Game.cpp MMT.cpp MediaPlayer.cpp MediaPlayer.h VideoPlayer.cpp VideoPlayer.h |
diffstat | 8 files changed, 162 insertions(+), 1949 deletions(-) [+] |
line wrap: on
line diff
--- a/Bink_Smacker.h Mon Apr 07 19:15:31 2014 +0600 +++ b/Bink_Smacker.h Tue Apr 08 17:39:59 2014 +0600 @@ -23,23 +23,7 @@ int __stdcall BinkBufferSetOffset(void *, int, int); int __stdcall BinkBufferSetScale(void *, unsigned int uWidth, unsigned int uHeight); - - - - - - - - - - - - - - - - -void SMACKW32_DLL_Initialize(); + void SMACKW32_DLL_Initialize(); struct _SMACK {
--- a/Build/Visual Studio 2012/World of Might and Magic.vcxproj.user Mon Apr 07 19:15:31 2014 +0600 +++ b/Build/Visual Studio 2012/World of Might and Magic.vcxproj.user Tue Apr 08 17:39:59 2014 +0600 @@ -4,6 +4,6 @@ <LocalDebuggerCommand>$(OutDir)$(TargetName)$(TargetExt)</LocalDebuggerCommand> <LocalDebuggerWorkingDirectory>$(OutDir)</LocalDebuggerWorkingDirectory> <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor> - <LocalDebuggerCommandArguments>-nomarg, -novideo</LocalDebuggerCommandArguments> + <LocalDebuggerCommandArguments>-nomarg,</LocalDebuggerCommandArguments> </PropertyGroup> </Project> \ No newline at end of file
--- a/Game.cpp Mon Apr 07 19:15:31 2014 +0600 +++ b/Game.cpp Tue Apr 08 17:39:59 2014 +0600 @@ -4489,18 +4489,19 @@ pVideoPlayer->bStopBeforeSchedule = 1; viewparams->bRedrawGameUI = 1; viewparams->field_48 = 1; - if ( !GetCurrentMenuID() || GetCurrentMenuID() == MENU_MMT_MAIN_MENU || GetCurrentMenuID() == MENU_CREATEPARTY || GetCurrentMenuID() == MENU_NAMEPANELESC ) + if ( GetCurrentMenuID() == MENU_MAIN || GetCurrentMenuID() == MENU_MMT_MAIN_MENU + || GetCurrentMenuID() == MENU_CREATEPARTY || GetCurrentMenuID() == MENU_NAMEPANELESC ) { //if ( pCurrentScreen == SCREEN_VIDEO ) //pVideoPlayer->FastForwardToFrame(pVideoPlayer->pResetflag); - if (GetCurrentMenuID() == MENU_NAMEPANELESC) + if (GetCurrentMenuID() == MENU_NAMEPANELESC) //из панели изменения имени { - SetCurrentMenuID(MENU_CREATEPARTY); + SetCurrentMenuID(MENU_CREATEPARTY);//в окно создания группы break; } - if (GetCurrentMenuID() == MENU_CREDITSPROC) + if (GetCurrentMenuID() == MENU_CREDITSPROC) //из окна Создатели { - SetCurrentMenuID(MENU_CREDITSCLOSE); + SetCurrentMenuID(MENU_CREDITSCLOSE);//в закрытие Создатели break; } pMessageQueue_50CBD0->AddMessage(UIMSG_ChangeGameState, 0, 0);
--- a/MMT.cpp Mon Apr 07 19:15:31 2014 +0600 +++ b/MMT.cpp Tue Apr 08 17:39:59 2014 +0600 @@ -168,16 +168,11 @@ { GUIButton *pButton; // eax@27 unsigned int pControlParam; // ecx@35 -// int v10; // ecx@36 -// int v11; // ecx@37 unsigned int pX; unsigned int pY; // [sp-18h] [bp-54h]@39 Texture *pTexture; // [sp-14h] [bp-50h]@39 -// GUIButton *pButton2; // [sp+0h] [bp-3Ch]@27 char pContainerName[64]; - - pCurrentScreen = SCREEN_GAME; pGUIWindow2 = 0; @@ -197,8 +192,7 @@ sprintf(pContainerName, "data\\New_Icons/%s", "mm6_button_oval.png"); Texture* MMT_MM6 = LoadPNG(pContainerName); - - + Texture* MMT_MM7 = pIcons_LOD->LoadTexturePtr("title_load", TEXTURE_16BIT_PALETTE); Texture* MMT_MM8 = pIcons_LOD->LoadTexturePtr("title_cred", TEXTURE_16BIT_PALETTE); Texture* MMT_Continue = pIcons_LOD->LoadTexturePtr("title_exit", TEXTURE_16BIT_PALETTE);
--- a/MediaPlayer.cpp Mon Apr 07 19:15:31 2014 +0600 +++ b/MediaPlayer.cpp Tue Apr 08 17:39:59 2014 +0600 @@ -22,8 +22,7 @@ #include "MediaPlayer.h" using namespace Media; - - + class MemoryStream { public: @@ -90,7 +89,7 @@ current_pos = data_size; } - inline size_t Unwind(size_t bytes) + inline size_t Unwind(size_t bytes)//зациклить??? { if (bytes > current_pos) current_pos = 0; @@ -118,7 +117,6 @@ size_t current_pos; }; - bool end_current_file; bool loop_current_file; DWORD time_video_begin; @@ -127,8 +125,6 @@ OpenALSoundProvider *provider = nullptr; - - static int av_num_bytes_per_sample(AVSampleFormat sample_fmt) { switch (sample_fmt) @@ -158,8 +154,6 @@ return 0; } - - struct AVStreamWrapper { inline AVStreamWrapper() @@ -179,6 +173,7 @@ dec = nullptr; if (dec_ctx) { + // Close the codec // закрытие видео кодека avcodec_close(dec_ctx); dec_ctx = nullptr; @@ -218,19 +213,23 @@ static bool av_open_stream(AVFormatContext *format_ctx, AVMediaType type, AVStreamWrapper *out_stream) { -// номер видеопотока + // найдем первый stream int stream_idx = av_find_best_stream(format_ctx, type, -1, -1, nullptr, 0); if (stream_idx >= 0) { auto stream = format_ctx->streams[stream_idx]; -//Информация о кодеке в потоке называется «контекстом кодека» (AVCodecContext). -//Используя эту информацию, мы можем найти необходимый кодек (AVCodec) и открыть его. + //Информация о кодеке в потоке называется «контекстом кодека» (AVCodecContext). + //Используя эту информацию, мы можем найти необходимый кодек (AVCodec) и открыть его. + // получаемм кодек auto dec_ctx = stream->codec; + + // Find the decoder for the video stream // ищем декодер auto dec = avcodec_find_decoder(dec_ctx->codec_id); if (dec) { - // открываем декодер + // Open codec + // открываем кодек if (avcodec_open2(dec_ctx, dec, nullptr) >= 0) { out_stream->type = type; @@ -240,10 +239,14 @@ out_stream->dec_ctx = dec_ctx; return true; } + fprintf(stderr, "ffmpeg: Could not open codec\n");// Не открылся кодек + return false; } - fprintf(stderr, "ffmpeg: Unable to open codec\n"); + fprintf(stderr, "ffmpeg: Unable to open codec\n");// Кодек не найден + return false; } - return false; + fprintf(stderr, "ffmpeg: Didn't find a stream\n");// Не найден stream + return false; } static bool av_open_audio_stream(AVFormatContext *format_ctx, AVAudioStream *out_stream) @@ -273,8 +276,6 @@ return true; } - - void InterleaveAudioData(MemoryStream *stream, AVSampleFormat src_format, int num_channels, int num_samples, uint8_t **channels) { unsigned int bytes_per_sample; @@ -343,14 +344,12 @@ } } - - bool DecodeAudioFrame(AVCodecContext *dec_ctx, AVPacket *avpacket, AVFrame *avframe, MemoryStream *out_audio_data, int *out_num_audio_samples) { volatile int decoded = false; do { -//Декодирование аудио-пакета осуществляется функцией avcodec_decode_audio4 + //Декодирование аудио-пакета осуществляется функцией avcodec_decode_audio4 if (avcodec_decode_audio4(dec_ctx, avframe, (int *)&decoded, avpacket) < 0) { log("Cannot decode audio frame\n"); @@ -469,22 +468,26 @@ return true; } - bool LoadAudioTrack(AVFormatContext *format_ctx, AVCodecContext *dec_ctx, int audio_stream_idx, MemoryStream *out_audio_stream, int *out_num_audio_frames, int *out_num_audio_samples) { out_audio_stream->Reset(); -//воспроизведение audio. -//Данные из файла читаются пакетами (AVPacket), а для воспроизведения используется фрейм (AVFrame). + //Чтение аудио данных. + //Данные из файла читаются пакетами (AVPacket), а для воспроизведения используется фрейм (AVFrame). + + //Выделим память для фрейма AVFrame *frame = avcodec_alloc_frame(); + AVPacket *packet = new AVPacket; av_init_packet(packet); int num_audio_frames = 0; int num_audio_samples = 0; + //чтение пакетов while (av_read_frame(format_ctx, packet) >= 0) { + // Is this a packet from the audio stream? //Принадлежит ли пакет к аудиопотоку if (packet->stream_index != audio_stream_idx) { @@ -492,6 +495,8 @@ continue; } + // Decode audio frame + //Декодируем аудио фрейм int num_samples_decoded; DecodeAudioFrame(dec_ctx, packet, frame, out_audio_stream, &num_samples_decoded); @@ -501,13 +506,13 @@ *out_num_audio_frames = num_audio_frames; *out_num_audio_samples = num_audio_samples; + //Освободить память выделенную для фрейма avcodec_free_frame(&frame); delete packet; return true; } - class Track: public Media::ITrack { public: @@ -533,28 +538,29 @@ } } - bool Load(const wchar_t *filename) + bool LoadAudio(const wchar_t *filename) //Загрузка из папки для mp3 { char filenamea[1024]; sprintf(filenamea, "%S", filename); -// Open audio file -//откроем входной файл(Шаг 2) -//Функция avformat_open_input читает файловый заголовок и сохраняет информацию о найденных форматах в структуре -//AVFormatContext. Остальные аргументы могут быть установлены в NULL, в этом случае libavformat использует -//автоматическое определение параметров. + // Open audio file + //откроем входной файл(Шаг 2) + //Функция avformat_open_input читает файловый заголовок и сохраняет информацию о найденных форматах в структуре + //AVFormatContext. Остальные аргументы могут быть установлены в NULL, в этом случае libavformat использует + //автоматическое определение параметров. if (avformat_open_input(&format_ctx, filenamea, nullptr, nullptr) >= 0) { -// Retrieve stream information -//Т.к. avformat_open_input читает только заголовок файла, то следующим шагом нужно получить информацию о потоках -//в файле. Это делается функцией avformat_find_stream_info. + // Retrieve stream information + //Т.к. avformat_open_input читает только заголовок файла, то следующим шагом нужно получить информацию о потоках + //в файле. Это делается функцией avformat_find_stream_info. 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. + // Dump information about file onto standard error + //После этого format_context->streams содержит все существующие потоки файла. + //Их количество равно format_context->nb_streams. + //Вывести подробную информацию о файле и обо всех потоках можно функцией av_dump_format. av_dump_format(format_ctx, 0, filenamea, 0); + //Открыть поток if (!av_open_audio_stream(format_ctx, &audio)) { Error("Cannot open strack: %s", filenamea); @@ -564,6 +570,8 @@ MemoryStream audio_plain_data; int num_audio_frames; int num_audio_samples; + + //Загрузить аудио трек if (LoadAudioTrack(format_ctx, audio.dec_ctx, audio.stream_idx, &audio_plain_data, &num_audio_frames, &num_audio_samples)) { /*#ifdef _DEBUG @@ -587,10 +595,10 @@ } } Release(); - fprintf(stderr, "ffmpeg: Unable to find stream info\n"); + fprintf(stderr, "ffmpeg: Unable to find stream info\n"); //Не найден поток return false; } - fprintf(stderr, "ffmpeg: Unable to open input file\n"); + fprintf(stderr, "ffmpeg: Unable to open input file\n"); //Не может открыть файл return false; } @@ -598,8 +606,7 @@ { provider->PlayTrack16(device_buffer, loop); } - - + protected: AVFormatContext *format_ctx; AVAudioStream audio; @@ -610,8 +617,6 @@ OpenALSoundProvider::TrackBuffer *device_buffer; }; - - class Movie: public Media::IMovie { public: @@ -624,8 +629,6 @@ AVStream *video_stream;//содержат информацию о видео потоке AVCodec *video_stream_dec; AVCodecContext *video_stream_dec_ctx; - bool Stopped() { return stopped; } - bool End_file() { return end_of_file; } inline Movie() { @@ -648,8 +651,7 @@ format_ctx = nullptr; avioContext = nullptr; } - - + inline void Release() { ReleaseAVCodec(); @@ -661,13 +663,14 @@ video.Release(); if (format_ctx) { - // закрытия контекста файла + // Close the video file + // закрытие контекста файла(видео файла) av_close_input_file(format_ctx); format_ctx = nullptr; } } - bool Load(const wchar_t *filename, int dst_width, int dst_height, int cache_ms) + bool Load(const wchar_t *filename, int dst_width, int dst_height, int cache_ms) //Загрузка { char filenamea[1024]; sprintf(filenamea, "%S", filename); @@ -675,24 +678,27 @@ width = dst_width; height = dst_height; -// Open video file -//откроем входной файл(Шаг 2) -//Функция avformat_open_input читает файловый заголовок и сохраняет информацию о найденных форматах в структуре -//AVFormatContext. Остальные аргументы могут быть установлены в NULL, в этом случае libavformat использует -//автоматическое определение параметров. + // Open video file + //откроем входной файл(Шаг 2) + //Функция avformat_open_input читает файловый заголовок и сохраняет информацию о найденных форматах в структуре + //AVFormatContext. Остальные аргументы могут быть установлены в NULL, в этом случае libavformat использует + //автоматическое определение параметров. Последние 2 аргумента используются для формата файла и опций. if (avformat_open_input(&format_ctx, filenamea, nullptr, nullptr) >= 0) { -// Retrieve stream information -//Т.к. avformat_open_input читает только заголовок файла, то следующим шагом нужно получить информацию о потоках -//в файле. Это делается функцией avformat_find_stream_info.(Шаг 3) + // 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. + // Dump information about file onto standard error + //Инициализируем pFormatCtx->streams + //После этого format_context->streams содержит все существующие потоки файла. + //Их количество равно format_context->nb_streams. + //Вывести подробную информацию о файле и обо всех потоках можно функцией av_dump_format. av_dump_format(format_ctx, 0, filenamea, 0); + //pFormatCtx->streams - массив указателей, размера pFormatCtx->nb_streams, поищем тут потоки. if (!av_open_audio_stream(format_ctx, &audio)) { Error("Cannot open audio stream: %s", filenamea); @@ -704,21 +710,25 @@ Error("Cannot open video stream: %s", filenamea); return Release(), false; } - - if (_stricmp("binkvideo", video.dec->name) ) - { + + //Ritor1: include + if (_stricmp("binkvideo", video.dec->name) ) + { current_movie_width = video.dec_ctx->width; current_movie_height = video.dec_ctx->height; - } - else - { + } + else + { current_movie_width = width; current_movie_height = height; - } + } + // decoding_packet = new AVPacket; av_init_packet(decoding_packet); + // Allocate video frame + //Выделим память для фрейма decoding_frame = avcodec_alloc_frame(); audio_data_in_device = provider->CreateStreamingTrack16(audio.dec_ctx->channels, audio.dec_ctx->sample_rate, 2); @@ -726,11 +736,12 @@ return true; } fprintf(stderr, "ffmpeg: Unable to find stream info\n"); - return false; + return Release(), false; // Не найдена информация о потоке } fprintf(stderr, "ffmpeg: Unable to open input file\n"); - return false; + return Release(), false; // Не может открыть файл } + bool LoadFromLOD(HANDLE h, int readFunction(void*, uint8_t*, int), int64_t seekFunction(void*, int64_t, int), int width, int height) { if (!ioBuffer) @@ -743,91 +754,15 @@ return Load(L"dummyFilename", width, height, 0); } - 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); - if (video_stream_idx < 0) - return Release(), false; - if (_stricmp("binkvideo", video_stream_dec->name) )//Ritor1: include - { - this->width = video_stream_dec_ctx->width; - this->height = video_stream_dec_ctx->height; - } - - audio_stream_idx = OpenStream(AVMEDIA_TYPE_AUDIO, &audio_stream, &audio_stream_dec, &audio_stream_dec_ctx); - if (audio_stream_idx < 0) - return Release(), false; - - strcpy(movie_filename, video_filename); -//Данные из файла читаются пакетами (AVPacket) - decoding_packet = new AVPacket; - av_init_packet(decoding_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; - } - 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) - { - if (avcodec_open2(dec_ctx, dec, nullptr) >= 0) - { - *out_stream = stream; - *out_dec = dec; - *out_dec_ctx = dec_ctx; - return stream_idx; - } - } - fprintf(stderr, "ffmpeg: Unable to open codec\n"); - return -1; - } - - virtual void Play() - { - } - - virtual void GetNextFrame(double dt, void *dst_surface)// рисует сразу на экран + virtual void GetNextFrame(double dt, void *dst_surface)// Получить следующий фрейм { playback_time += dt;//изменение времени -//Данные из файла читаются пакетами (AVPacket), а для отображения используется фрейм (AVFrame). -//(помните мы сохранили номер видео потока в переменной video_stream). + //Данные из файла читаются пакетами (AVPacket), а для отображения используется фрейм (AVFrame). AVPacket *avpacket = decoding_packet; AVFrame *avframe = decoding_frame; -//декодтрование + + //??? 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); @@ -837,47 +772,32 @@ return; } - volatile int decoded = false; + volatile int frameFinished = false; //чтение пакетов - // keep reading packets until we hit the end or find a video packet + // keep reading packets until we hit the end or find a video packet while (av_read_frame(format_ctx, avpacket) >= 0) { - /*if (av_read_frame(format_ctx, avpacket) < 0) //воспроизведение завершено - { - if (loop_current_file) - { - av_seek_frame(format_ctx, video.stream_idx, 0, AVSEEK_FLAG_ANY); - } - else - { - // probably movie is finished - //__debugbreak(); - end_of_file = true; - end_current_file = true; - return;// nullptr; - } - } */ - // Is this a packet from the video stream? // audio packet - queue into playing //Принадлежит ли пакет к аудиопотоку if (avpacket->stream_index == audio.stream_idx) { MemoryStream audio_data; + //Декодирование аудио фрейма if (DecodeAudioFrame(audio.dec_ctx, avpacket, avframe, &audio_data, &num_audio_samples)) - provider->Stream16(audio_data_in_device, num_audio_samples, audio_data.Ptr()); + provider->Stream16(audio_data_in_device, num_audio_samples, audio_data.Ptr()); //отправляем на воспроизведение continue; } // Decode video frame //пакет к видеопотоку else if (avpacket->stream_index == video.stream_idx) { -//Функция avcodec_decode_video2 осуществляет декодирование пакета в фрейм с использованием кодека, -//который мы получили раньше (codec_context). Функция устанавливает положительное значение frame_finished в случае -//если фрейм декодирован целиком (то есть один фрейм может занимать несколько пакетов и frame_finished будет -//установлен только при декодировании последнего пакета). - avcodec_decode_video2(video.dec_ctx, avframe, (int *)&decoded, avpacket); - if (decoded) + //Функция avcodec_decode_video2 осуществляет декодирование пакета в фрейм с использованием кодека, + //который мы получили раньше (codec_context). Функция устанавливает положительное значение frame_finished в случае + //если фрейм декодирован целиком (то есть один фрейм может занимать несколько пакетов и frame_finished будет + //установлен только при декодировании последнего пакета). + avcodec_decode_video2(video.dec_ctx, avframe, (int *)&frameFinished, avpacket); + if (frameFinished) { if (last_resampled_frame_data[0]) av_freep(&last_resampled_frame_data[0]); @@ -891,10 +811,11 @@ SwsContext *converter = sws_getContext(avframe->width, avframe->height, (AVPixelFormat)avframe->format, current_movie_width, current_movie_height, rescaled_format, SWS_BICUBIC, nullptr, nullptr, nullptr); - // преобразование кадра + // преобразование кадра(масштабирование) sws_scale(converter, avframe->data, avframe->linesize, 0, avframe->height, rescaled_data, rescaled_linesize); sws_freeContext(converter); + //копирование в возвращаемую переменную memcpy(dst_surface, rescaled_data[0], current_movie_height * rescaled_linesize[0]); last_resampled_frame_num = desired_frame_number; @@ -903,12 +824,13 @@ } } else - memset(dst_surface, 0, current_movie_width * current_movie_height * 4); + memset(dst_surface, 0, current_movie_width * current_movie_height * 4); //записать 0 в выходную переменную } return; }// while (avpacket->stream_index != video.stream_idx || // avpacket->pts != desired_frame_number); - if (loop_current_file) + //завершение пакетов + if (loop_current_file) //зациклен ли файл { av_seek_frame(format_ctx, video.stream_idx, 0, AVSEEK_FLAG_ANY); } @@ -922,44 +844,9 @@ } } - /*inline char *DoFrame() - { - if (!current_movie) - return nullptr; - - while (true) - { - auto frame = current_movie->GetNextFrame(); - if (!frame) - return nullptr; - - if (frame->Type() == AVMEDIA_TYPE_AUDIO) - { - //continue; -// uint8_t *data; - if (frame->Decode() >= 0) - { - auto f = frame->GetAVFrame(); - provider->PlaySample(f->channels, f->sample_rate, f->nb_samples, frame->GetData()); - Sleep(20); - continue; - } - } - else if (frame->Type() == AVMEDIA_TYPE_VIDEO) - { - uint8_t *dst_data[4] = { 0 }; - int dst_linesize[4] = { 0 }; - if (frame->Decode() >= 0) - { - auto image = new char[current_movie_width * current_movie_height * 4]; - memcpy(image, frame->GetData(), current_movie_height * frame->GetDataPitch()); - - return image; - } - } - return nullptr; - } - }*/ + virtual void Play() + { + } protected: char movie_filename[256]; @@ -984,13 +871,12 @@ int last_resampled_frame_num; uint8_t *last_resampled_frame_data[4]; int last_resampled_frame_linesize[4]; -}; +}; - -ITrack *Player::LoadTrack(const wchar_t *filename) +ITrack *Player::LoadTrack(const wchar_t *filename) //Загрузить mp3 { auto track = new Track; - if (!track->Load(filename)) + if (!track->LoadAudio(filename)) { delete track; track = nullptr; @@ -998,8 +884,7 @@ return track; } - -IMovie *Player::LoadMovie(const wchar_t *filename, int width, int height, int cache_ms) +IMovie *Player::LoadMovie(const wchar_t *filename, int width, int height, int cache_ms) //Загрузить видео { auto movie = new Movie; if (!movie->Load(filename, width, height, cache_ms)) @@ -1010,10 +895,17 @@ return movie; } - - - - +IMovie *Player::LoadMovieFromLOD(HANDLE h, int readFunction(void*, uint8_t*, int), int64_t seekFunction(void*, int64_t, int), int width, int height) +{ + auto movie = new Movie; + if (movie) + { + if (movie->LoadFromLOD(h, readFunction, seekFunction, width, height)) + return movie; + delete movie; + } + return nullptr; +} void av_logger(void *, int, const char *format, va_list args) { @@ -1035,10 +927,10 @@ av_log_set_callback(av_logger); avcodec_register_all(); -// Register all available file formats and codecs -//инициализируем библиотеку ffmpeg(Шаг 1) -//Во время инициализации регистрируются все имеющиеся в библиотеке форматы файлов и кодеков. -//После этого они будут использоваться автоматически при открытии файлов этого формата и с этими кодеками. + // Register all available file formats and codecs + //инициализируем библиотеку ffmpeg(Шаг 1) + //Во время инициализации регистрируются все имеющиеся в библиотеке форматы файлов и кодеков. + //После этого они будут использоваться автоматически при открытии файлов этого формата и с этими кодеками. av_register_all(); libavcodec_initialized = true; @@ -1054,26 +946,3 @@ Player::~Player() { } - IMovie *Player::LoadMovieFromLOD(HANDLE h, int readFunction(void*, uint8_t*, int), int64_t seekFunction(void*, int64_t, int), int width, int height) - { - auto movie = new Movie; - if (movie) - { - if (movie->LoadFromLOD(h, readFunction, seekFunction, width, height)) - { - /*if (_stricmp("binkvideo", movie->video_stream_dec->name) ) - { - current_movie_width = movie->video_stream_dec_ctx->width; - current_movie_height = movie->video_stream_dec_ctx->height; - } - else - { - current_movie_width = width; - current_movie_height = height; - } */ - return movie; - } - delete movie; - } - return nullptr; - } \ No newline at end of file
--- a/MediaPlayer.h Mon Apr 07 19:15:31 2014 +0600 +++ b/MediaPlayer.h Tue Apr 08 17:39:59 2014 +0600 @@ -11,8 +11,6 @@ { public: virtual void Play() = 0; virtual void GetNextFrame(double dt, void *target_surface) = 0; - bool Stopped(); - bool End_file(); }; class Player @@ -24,9 +22,6 @@ ITrack *LoadTrack(const wchar_t *name); IMovie *LoadMovie(const wchar_t *name, int width, int height, int cache_ms); IMovie *LoadMovieFromLOD(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); - char *DoFrame(); - }; }; @@ -35,3 +30,6 @@ extern DWORD time_video_begin; extern int current_movie_width; extern int current_movie_height; + +int64_t seekFunction(void* opaque, int64_t offset, int whence); +
--- a/VideoPlayer.cpp Mon Apr 07 19:15:31 2014 +0600 +++ b/VideoPlayer.cpp Tue Apr 08 17:39:59 2014 +0600 @@ -19,16 +19,9 @@ #include "texts.h" #include "UI\UIHouses.h" - VideoPlayer *pVideoPlayer = nullptr; - - - - - - -#pragma comment(lib, "Version.lib") + #pragma comment(lib, "Version.lib") bool GetDllVersion(const wchar_t *pDllName, uint *pMajor, uint *pMinor) { uint uVersionSize = GetFileVersionInfoSizeW(pDllName, nullptr); @@ -52,229 +45,8 @@ return true; } - -// 3.15.1.0: -// 3 15 1 0 -// 0x0003000F00010000 unsigned __int64 uBinkVersion; - - - - -bool BinkLockBuffer(struct _BINKBUF *_this); -void BinkUnlockBuffer(struct _BINKBUF *_this); - -//----- (004BFE2D) -------------------------------------------------------- -_BINKBUF *VideoPlayer::CreateBinkBuffer(unsigned int uWidth, unsigned int uHeight, char a4) -{ - _BINKBUF *v5; // esi@3 -// HRESULT v6; // eax@5 - IDirectDrawSurface *v7; // eax@6 -// HRESULT v8; // eax@9 - DDSURFACEDESC2 v11; // [sp+Ch] [bp-108h]@7 -// DDSURFACEDESC Dst; // [sp+88h] [bp-8Ch]@3 - IDirectDrawSurface4 *v15; // [sp+108h] [bp-Ch]@7 -// IDirectDrawSurface2 *a2; // [sp+10Ch] [bp-8h]@3 - - //if (pVersion->pVersionInfo.dwPlatformId != VER_PLATFORM_WIN32_NT || - //pVersion->pVersionInfo.dwMajorVersion >= 5u ) - { - v15 = 0; - - if (uBinkVersion == 0x0001000500150000) - { - v5 = new _BINKBUF_1_5_21_0; - memset(v5, 0, sizeof(_BINKBUF_1_5_21_0)); - } - else if (uBinkVersion == 0x0003000000000000) - { - v5 = new _BINKBUF_3_0_0_0; - memset(v5, 0, sizeof(_BINKBUF_3_0_0_0)); - } - else __debugbreak(); - - memset(&v11, 0, 0x7C); - v11.dwSize = 124; - v11.dwWidth = uWidth; - v11.dwFlags = 0x1007; // DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT - v11.ddsCaps.dwCaps = 0x4040; // DDSCAPS_OFFSCREENPLAIN | DDSCAPS_VIDEOMEMORY - v11.dwHeight = uHeight; - *(_QWORD *)&v11.ddpfPixelFormat.dwSize = 0x400000020ui64;// DDPF_FOURCC - v11.ddpfPixelFormat.dwFourCC = 0x32595559; - if (FAILED(pRenderer->pDirectDraw4->CreateSurface(&v11, &v15, 0))) - { - memset(&v11.ddpfPixelFormat, 0, sizeof(DDPIXELFORMAT)); - - v11.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT; - v11.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY; - - long hr = pRenderer->pDirectDraw4->CreateSurface(&v11, &v15, 0); - ErrD3D(hr); - } - v5->uWidth = v11.dwWidth; - v5->uHeight = v11.dwHeight; - v5->uBinkDDSurfaceType = BinkDDSurfaceType((IDirectDrawSurface *)v15); - v5->field_38 = 0; - v7 = (IDirectDrawSurface *)v15; - } - /*else - { - v4 = 0; - a2 = 0; - - - if (uBinkVersion == 0x0001000500150000) - { - v5 = new _BINKBUF_1_5_21_0; - memset(v5, 0, sizeof(_BINKBUF_1_5_21_0)); - } - else if (uBinkVersion == 0x0003000000000000) - { - v5 = new _BINKBUF_3_0_0_0; - memset(v5, 0, sizeof(_BINKBUF_3_0_0_0)); - } - else __debugbreak(); - - memset(&Dst, 0, 0x6Cu); - Dst.dwSize = 108; - Dst.dwWidth = uWidth; - Dst.dwFlags = 4103; - Dst.ddsCaps.dwCaps = 16448; - Dst.dwHeight = uHeight; - Dst.ddpfPixelFormat.dwSize = 32; - Dst.ddpfPixelFormat.dwFlags = 4; - Dst.ddpfPixelFormat.dwFourCC = 844715353; - if (FAILED(pRenderer->pDirectDraw2->CreateSurface(&Dst, (LPDIRECTDRAWSURFACE *)&a2, 0))) - { - memset(&Dst.ddpfPixelFormat, 0, sizeof(DDPIXELFORMAT)); - - Dst.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT; - Dst.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY; - - long hr = pRenderer->pDirectDraw2->CreateSurface(&Dst, (LPDIRECTDRAWSURFACE *)&a2, 0); - ErrD3D(hr); - } - v5->uWidth = Dst.dwWidth; - v5->uHeight = Dst.dwHeight; - v5->uBinkDDSurfaceType = BinkDDSurfaceType((IDirectDrawSurface *)a2); - v5->field_38 = 0; - v7 = (IDirectDrawSurface *)a2; - }*/ - v5->pTargetDDrawSurface = v7; - v5->hWnd = window->GetApiHandle(); - v5->field_4C = 0; - v5->field_68 = 0; - v5->field_5C = 0; - v5->field_74 = a4 & 0x1F; - v5->field_78 = 1; - v5->target_width = GetSystemMetrics(SM_CXSCREEN); - v5->target_height = GetSystemMetrics(SM_CYSCREEN); - v5->field_2C = 16; - - RECT Rect; - GetWindowRect(window->GetApiHandle(), &Rect); - v5->field_8 = window->GetWidth(); - v5->field_C = window->GetHeight(); - v5->field_1C = Rect.left; - v5->field_20 = Rect.top; - Rect.left = 0; - Rect.top = 0; - ClientToScreen(window->GetApiHandle(), (POINT *)&Rect); - v5->field_1C = Rect.left - v5->field_1C; - v5->field_20 = Rect.top - v5->field_20; - GetClientRect(window->GetApiHandle(), &Rect); - v5->field_30 = v5->field_8 - Rect.right; - v5->field_34 = v5->field_C - Rect.bottom; - v5->field_8 = v5->uWidth + v5->field_30; - v5->field_C = v5->uHeight + v5->field_34; - BinkBufferSetOffset(v5, 0, 0); - BinkBufferSetScale(v5, v5->uWidth, v5->uHeight); - return v5; -} - - -//----- (004C0133) -------------------------------------------------------- -bool BinkLockBuffer(_BINKBUF *_this) -{ -// IDirectDrawSurface *v2; // edi@5 - IDirectDrawSurface4 *v6; // edi@11 - - //if ( pVersion->pVersionInfo.dwPlatformId != VER_PLATFORM_WIN32_NT || pVersion->pVersionInfo.dwMajorVersion >= 5u ) - { - DDSURFACEDESC2 v8; // [sp+Ch] [bp-7Ch]@4 - if ( _this->pTargetDDrawSurface ) - { - memset(&v8, 0, 0x7C); - v8.dwSize = 124; - while ( 1 ) - { - v6 = (IDirectDrawSurface4 *)_this->pTargetDDrawSurface; - if ( !v6->Lock(0, &v8, 1, 0) ) - break; - - if (uBinkVersion < 0x0003000000000000) - _this->uBinkDDSurfaceType |= 0x80000000; - else - _this->uBinkDDSurfaceType |= 0x4000000; - - if ( v6->Restore() ) - return 0; - } - _this->pDDrawSurfaceData_ = v8.lpSurface; - _this->pDDrawSurfaceData = v8.lpSurface; - _this->uDDrawSurfacePitch = v8.lPitch; - return 1; - } - } - /*else - { - DDSURFACEDESC v8; // [sp+Ch] [bp-7Ch]@4 - if ( _this->pTargetDDrawSurface ) - { - memset(&v8.lPitch, 0, 0x6Cu); - v8.lPitch = 108; - while ( 1 ) - { - v2 = _this->pTargetDDrawSurface; - if ( !v2->Lock(0, (LPDDSURFACEDESC)&v8.lPitch, 1, 0) ) - break; - - if (uBinkVersion < 0x0003000000000000) - __asm int 3; - else - BYTE3(_this->uBinkDDSurfaceType) |= 4u; - - if ( v2->Restore() ) - return 0; - } - _this->pDDrawSurfaceData_ = v8.lpSurface; - _this->pDDrawSurfaceData = v8.lpSurface; - _this->uDDrawSurfacePitch = v8.dwReserved; - return 1; - } - }*/ - return 1; -} - -//----- (004C01FB) -------------------------------------------------------- -void BinkUnlockBuffer(_BINKBUF *_this) -{ - IDirectDrawSurface *v2; // eax@1 - - v2 = _this->pTargetDDrawSurface; - if ( v2 ) - { - v2->Unlock(0); - _this->uDDrawSurfacePitch = 0; - _this->pDDrawSurfaceData = 0; - - if (uBinkVersion < 0x0003000000000000) - BYTE3(_this->uBinkDDSurfaceType) &= 0x7F; - else - BYTE3(_this->uBinkDDSurfaceType) &= 0xFB; - } -} //----- (004BF794) -------------------------------------------------------- void ShowMM7IntroVideo_and_LoadingScreen() { @@ -323,29 +95,18 @@ void VideoPlayer::MovieLoop(const char *pMovieName, int a2, int ScreenSizeFlag, int a4) { int v4; // ebp@1 - const char *pName; // edi@1 MSG Msg; // [sp+Ch] [bp-1Ch]@12 v4 = a2; - pName = pMovieName; if ( !(dword_6BE364_game_settings_1 & (GAME_SETTINGS_NO_HOUSE_ANIM | GAME_SETTINGS_NO_INTRO)) ) { if ( a2 == 2 ) v4 = 0; - ShowCursor(0); - OpenGlobalMovie(pName, 0, ScreenSizeFlag); + ShowCursor(0);//Убрать курсор + OpenGlobalMovie(pMovieName, 0, ScreenSizeFlag); bPlayingMovie = 1; field_44 = v4; - //if ( pRenderer->pRenderD3D ) - { - pRenderer->ClearTarget(0); - } - /* else - { - pRenderer->BeginScene(); - pRenderer->ClearTarget(0); - pRenderer->EndScene(); - }*/ + pRenderer->ClearTarget(0); pCurrentScreen = SCREEN_VIDEO; auto hwnd = pVideoPlayer->window->GetApiHandle(); @@ -358,9 +119,12 @@ HDC back_dc = CreateCompatibleDC(dc); HBITMAP back_bmp; SelectObject(back_dc, back_bmp = CreateCompatibleBitmap(dc, client_width, client_height)); - DWORD t = GetTickCount(); - end_current_file = false; - while (true) + + DWORD t = GetTickCount();//текущее время от запуска ОС + + end_current_file = false;//установить флаг конца видеоролика + + while (true) //Цикл воспроизведения видеоролика { if ( pVideoPlayer->bStopBeforeSchedule ) break; @@ -373,9 +137,8 @@ TranslateMessage(&Msg); DispatchMessageA(&Msg); } - GUI_MainMenuMessageProc(); - double dt = (GetTickCount() - t) / 1000.0; + double dt = (GetTickCount() - t) / 1000.0; //изменение времени //dt = 1.0/15.0; t = GetTickCount(); @@ -383,9 +146,11 @@ auto image = new char[client_width * client_height * 4]; - pMovie->GetNextFrame(dt, image); - if (end_current_file) + pMovie->GetNextFrame(dt, image); //получить следующий кадр + + if (end_current_file)//достигнут ли конец видео? break; + if (image) { // draw to hwnd @@ -405,90 +170,29 @@ SetDIBits(back_dc, back_bmp, 0, client_height, image, &bmi, DIB_RGB_COLORS); BitBlt(dc, 0, 0, client_width, client_height, back_dc, 0, 0, SRCCOPY); - delete[] image; + delete[] image;//удалить кадр } - if (pVideoPlayer->bStopBeforeSchedule == 1) - Sleep(1000); - } - pVideoPlayer->Unload(); - /* - if ( pVideoPlayer->uMovieFormat == 2 ) - { - if ( pVideoPlayer->pBinkMovie ) - { - //pVideoPlayer->BinkDrawFrame(v4, ScreenSizeFlag); + + GUI_MainMenuMessageProc(); //после отрисовки, т.к. иначе вылетает dt = 0.03, image - ??? - } + if (pVideoPlayer->bStopBeforeSchedule == 1)//остановка видео + Sleep(1000); //пауза после видеоролика } - if ( pVideoPlayer->bStopBeforeSchedule == 1 ) - Sleep(0x3E8u); - }*/ - /* - if ( pVideoPlayer->uMovieFormat == 1 ) - { - if ( pVideoPlayer->pSmackerMovie ) - { - pVideoPlayer->SmackDrawFrame(v4, ScreenSizeFlag); - while ( pVideoPlayer->pSmackerMovie ) - { - if ( pVideoPlayer->bStopBeforeSchedule ) - break; - while ( PeekMessageW(&Msg, 0, 0, 0, 1) ) - { - if (Msg.message == WM_QUIT) - Game_DeinitializeAndTerminate(0); - if (Msg.message == WM_PAINT) - break; - TranslateMessage(&Msg); - DispatchMessageW(&Msg); - } - GUI_MainMenuMessageProc(); - if ( !pVideoPlayer->pSmackerMovie ) - break; - if ( !SmackWait(pVideoPlayer->pSmackerMovie) && !pVideoPlayer->bStopBeforeSchedule ) - pVideoPlayer->SmackDrawFrame(v4, ScreenSizeFlag); - } - } - } - */ + + pVideoPlayer->Unload(); + if (a4 == 1) pCurrentScreen = SCREEN_GAME; + pVideoPlayer->bPlayingMovie = 0; - ShowCursor(1); + + ShowCursor(1);//вернуть курсор + if ( pCurrentScreen == SCREEN_VIDEO ) pCurrentScreen = SCREEN_GAME; } } -//----- (004BE95A) -------------------------------------------------------- -unsigned int VideoPlayer::SmackCheckSurfaceFromat() -{ - DDPIXELFORMAT a2; // [sp+0h] [bp-20h]@1 - - a2.dwSize = 32; - a2.dwFlags = 64; - pRenderer->GetTargetPixelFormat(&a2); - if (a2.dwRGBBitCount == 32) - return SMACKBUFFER565; - if ( a2.dwRGBBitCount != 8 ) - { - if ( a2.dwRBitMask == 0xF800 ) - { - if ( a2.dwGBitMask == 0x7E0 && a2.dwBBitMask == 0x1F ) - return SMACKBUFFER565; - } - else - { - if ( a2.dwRBitMask == 0x7C00 - && a2.dwGBitMask == 0x3E0 - && a2.dwBBitMask == 0x1F ) - return SMACKBUFFER555; - } - MessageBoxA(0, "Unsupported pixel format.", "Smacker Error", 0); - } - return 0; -} - //----- (004BE9D8) -------------------------------------------------------- void VideoPlayer::Initialize(OSWindow *target_window) { @@ -538,28 +242,6 @@ ReadFile(hMagicVid, pMagicVideoHeaders, 44 * uNumMagicVideoHeaders, &NumberOfBytesRead, 0); } -//----- (004BEB41) -------------------------------------------------------- -void VideoPlayer::Prepare() -{ - pEventTimer->Pause(); - if ( pAudioPlayer->hAILRedbook ) - AIL_redbook_pause(pAudioPlayer->hAILRedbook); - - bStopBeforeSchedule = false; - bBufferLoaded = 1; - /* - pSmackerMovie = 0; - pSmackerBuffer = 0; - pBinkMovie = 0; - pBinkBuffer = 0; - */ - bPlayingMovie = false; - bFirstFrame = false; - bUsingSmackerMMX = SmackUseMMX(1); - BinkSetSoundSystem(BinkOpenMiles, pAudioPlayer->hDigDriver); - uBinkDirectDrawSurfaceType = BinkDDSurfaceType((IDirectDrawSurface *)pRenderer->pBackBuffer4); -} - //----- (004BEBD7) -------------------------------------------------------- void VideoPlayer::Unload() { @@ -615,249 +297,8 @@ } } -//----- (004BECD5) -------------------------------------------------------- -/* -void VideoPlayer::FastForwardToFrame(unsigned int uDstFrameNum) -{ - VideoPlayer *v2; // esi@1 - unsigned int v3; // eax@1 - - v2 = this; - v3 = this->uMovieFormat; - if ( v3 == 2 ) - { - if (uDstFrameNum) - { - int *pCurrentFrame = uBinkVersion == 0x0001000500150000 ? &((_BINK_1_5_21_0 *)pBinkMovie)->uCurrentFrame : - uBinkVersion == 0x0003000000000000 ? &((_BINK_3_0_0_0 *)pBinkMovie)->uCurrentFrame : - nullptr; - while (*pCurrentFrame < uDstFrameNum) - { - BinkDoFrame(pBinkMovie); - BinkNextFrame(pBinkMovie); - } - } - } - else - { - if ( v3 != 1 ) - return; - SmackSoundOnOff(this->pSmackerMovie, 0); - if (uDstFrameNum) - { - while ( v2->pSmackerMovie->FrameNum < uDstFrameNum) - { - SmackDoFrame(v2->pSmackerMovie); - SmackNextFrame(v2->pSmackerMovie); - } - } - } - Unload(); -} - - -//----- (004BED4F) -------------------------------------------------------- -void VideoPlayer::BinkDrawFrame(int a3, int a4) -{ - //VideoPlayer *v4; // esi@1 - _BINKBUF *v5; // eax@5 - LONG v6; // edx@6 - int v7; // ecx@6 - LONG v8; // edx@6 - struct tagRECT a3a; // [sp+8h] [bp-20h]@10 - struct tagRECT a1; // [sp+18h] [bp-10h]@6 - - //v4 = this; - if ( this->pBinkMovie && this->pBinkBuffer ) - { - BinkDoFrame(pBinkMovie); - BinkGetRects(pBinkMovie, pBinkBuffer->uBinkDDSurfaceType); - if ( BinkLockBuffer(pBinkBuffer) ) - { - BinkCopyToBuffer(pBinkMovie, pBinkBuffer->pDDrawSurfaceData, pBinkBuffer->uDDrawSurfacePitch, pBinkBuffer->uHeight, - 0, 0, pBinkBuffer->uBinkDDSurfaceType); - BinkUnlockBuffer(pBinkBuffer); - } - v5 = pBinkBuffer; - if ( pRenderer->bWindowMode ) - { - v6 = v5->uRectX; - a1.left = v6; - a1.top = v5->uRectY; - v7 = v6 + v5->uWidth; - a1.right = v6 + v5->uWidth; - v8 = a1.top + v5->uHeight; - } - else - { - a1.left = 0; - a1.top = 0; - v7 = v5->uWidth; - a1.right = v5->uWidth; - v8 = v5->uHeight; - } - a1.bottom = v8; - if ( a4 ) - { - a1.right = v5->uWidth + v7; - a1.bottom = v5->uHeight + v8; - } - a3a.left = 0; - a3a.top = 0; - a3a.right = v5->uWidth; - a3a.bottom = v5->uHeight; - pRenderer->BltToFront(&a1, v5->pTargetDDrawSurface, &a3a, 0x1000000u); - - - int *pCurrentFrame = uBinkVersion == 0x0001000500150000 ? &((_BINK_1_5_21_0 *)pBinkMovie)->uCurrentFrame : - uBinkVersion == 0x0003000000000000 ? &((_BINK_3_0_0_0 *)pBinkMovie)->uCurrentFrame: - nullptr; - int *pNumFrames = uBinkVersion == 0x0001000500150000 ? &((_BINK_1_5_21_0 *)pBinkMovie)->uNumFrames : - uBinkVersion == 0x0003000000000000 ? &((_BINK_3_0_0_0 *)pBinkMovie)->uNumFrames : - nullptr; - - if (*pCurrentFrame != *pNumFrames - 1 || bLoopPlaying) - BinkNextFrame(pBinkMovie); - else - Unload(); - } -} - - - -//----- (004BEE6B) -------------------------------------------------------- -void VideoPlayer::SmackDrawFrame(int a3, int a4) -{ - VideoPlayer *v4; // esi@1 - _SMACK *v5; // eax@3 - unsigned int v6; // eax@5 - char v7; // zf@5 - int v8; // eax@11 - _SMACK *v9; // eax@13 - _SMACK *v10; // eax@16 - _SMACK *v11; // eax@20 - unsigned int v12; // [sp-1Ch] [bp-34h]@7 - LONG v13; // [sp-18h] [bp-30h]@7 - LONG v14; // [sp-14h] [bp-2Ch]@7 - signed int v15; // [sp-10h] [bp-28h]@7 - signed int v16; // [sp-Ch] [bp-24h]@7 - signed int v17; // [sp-8h] [bp-20h]@7 - struct tagPOINT Point; // [sp+8h] [bp-10h]@7 - unsigned short *pOutSurface; // [sp+10h] [bp-8h]@5 - unsigned int uPixelsPerRow; // [sp+14h] [bp-4h]@5 - - v4 = this; - if ( !pRenderer->bWindowMode || window->Focused()) - { - v5 = v4->pSmackerMovie; - if ( v5->NewPalette ) - SmackBlitSetPalette(v4->pSmackMovieBlit, v5->Palette, v5->PalType); - SmackDoFrame(v4->pSmackerMovie); - pRenderer->LockFrontBuffer((void **)&pOutSurface, &uPixelsPerRow); - v6 = 2 * uPixelsPerRow; - v7 = v4->bFirstFrame == 0; - uPixelsPerRow *= 2; - if ( !v7 ) - { - if ( pRenderer->bWindowMode ) - { - Point.y = 0; - Point.x = 0; - ClientToScreen(window->GetApiHandle(), &Point); - v17 = -1; - v16 = 480; - v15 = 640; - v14 = Point.y; - v13 = Point.x; - v12 = uPixelsPerRow; - } - else - { - v17 = -1; - v16 = 480; - v15 = 640; - v14 = 0; - v13 = 0; - v12 = v6; - } - SmackBlitClear(v4->pSmackMovieBlit, pOutSurface, v12, v13, v14, v15, v16, v17); - v4->bFirstFrame = 0; - } - pRenderer->RestoreFrontBuffer(); - if ( pRenderer->bWindowMode ) - { - Point.y = 0; - Point.x = 0; - ClientToScreen(window->GetApiHandle(), &Point); - v8 = SmackToBufferRect(v4->pSmackerMovie, 0); - if ( a4 ) - { - while ( v8 ) - { - v9 = v4->pSmackerMovie; - SmackBlit( - v4->pSmackMovieBlit, - pOutSurface, - uPixelsPerRow, - v9->LastRectx + Point.x / 2, - a3 + v9->LastRecty + Point.y / 2, - v4->pSomeSmackerBuffer, - v9->Width, - v9->LastRectx, - v9->LastRecty, - v9->LastRectw, - v9->LastRecth); - v8 = SmackToBufferRect(v4->pSmackerMovie, 0); - } - } - else - { - while ( v8 ) - { - v10 = v4->pSmackerMovie; - SmackBlit(v4->pSmackMovieBlit, pOutSurface, uPixelsPerRow, Point.x + v10->LastRectx, a3 + Point.y + v10->LastRecty, - v4->pSomeSmackerBuffer, v10->Width, v10->LastRectx, v10->LastRecty, v10->LastRectw, v10->LastRecth); - v8 = SmackToBufferRect(v4->pSmackerMovie, 0); - } - } - } - else - { - while ( SmackToBufferRect(v4->pSmackerMovie, 0) ) - { - v11 = v4->pSmackerMovie; - SmackBlit(v4->pSmackMovieBlit, pOutSurface, uPixelsPerRow, v11->LastRectx, a3 + v11->LastRecty, v4->pSomeSmackerBuffer, - v11->Width, v11->LastRectx, v11->LastRecty, v11->LastRectw, v11->LastRecth); - } - } - pRenderer->UnlockFrontBuffer(); - if ( v4->pSmackerMovie->FrameNum != v4->pSmackerMovie->Frames - 1 || v4->bLoopPlaying ) - SmackNextFrame(v4->pSmackerMovie); - else - Unload(); - } -} -*/ void VideoPlayer::_inlined_in_463149() { - /* - if ( pSmackMovie && !SmackWait(pSmackerMovie) ) - { - pRenderer->BeginScene(); - pMouse->DrawCursorToTarget(); - SmackUpdatePalette(); - pMouse->ReadCursorWithItem(); - pRenderer->EndScene(); - } - else if ( pBinkMovie && !BinkWait(pBinkMovie) ) - { - pRenderer->BeginScene(); - pMouse->DrawCursorToTarget(); - BinkUpdatePalette(); - pMouse->ReadCursorWithItem(); - pRenderer->EndScene(); - } - */ if (pMovie) { pRenderer->BeginScene(); @@ -867,7 +308,6 @@ pRenderer->EndScene(); } } -//auto pixels = new unsigned short[640 * 480]; void VideoPlayer::UpdatePalette() { @@ -914,123 +354,7 @@ } pRenderer->EndScene(); } -/* -//----- (004BF08B) -------------------------------------------------------- -void VideoPlayer::SmackUpdatePalette() -{ - //VideoPlayer *v2; // esi@1 - unsigned __int16 *v3; // ebx@1 - unsigned int v4; // edi@1 - unsigned int v5; // eax@1 - //_SMACK *v6; // eax@1 - Log::Warning(L"smacker"); - - pRenderer->BeginScene(); - - v3 = pixels;//pRenderer->pTargetSurface; - v4 = 640;//pRenderer->uTargetSurfacePitch; - v5 = SmackCheckSurfaceFromat(); - - SmackToBuffer(pSmackerMovie, 8, 8, 2 * v4, pRenderer->field_14, v3, v5); - - - for (unsigned int y = 8; y < 8 + pSmackerMovie->Height; ++y) - for (unsigned int x = 8; x < 8 + pSmackerMovie->Width; ++x) - { - pRenderer->WritePixel16(x, y, pixels[x + y * 640]); - } - //delete [] pixels; - - //v6 = pSmackerMovie; - while (true) - { - if ( pSmackerMovie->NewPalette ) - { - SmackBufferNewPalette(pSmackerBuffer, pSmackerMovie->Palette, (pSmackerMovie->PalType)); - SmackColorRemapWithTrans( - pSmackerMovie, - pSmackerBuffer->Palette, - pSmackerBuffer->MaxPalColors, - pSmackerBuffer->PalType, - 1000); - } - SmackDoFrame(pSmackerMovie); - if ( pSmackerMovie->FrameNum != pSmackerMovie->Frames - 1 || bLoopPlaying ) - SmackNextFrame(pSmackerMovie); - else - Unload(); - - pRenderer->EndScene(); -} -*/ - - - -/* -//----- (004BF141) -------------------------------------------------------- -_BINK *VideoPlayer::OpenBink(const char *pName) -{ - //VideoPlayer *v2; // esi@1 - signed int v3; // edi@1 - int v4; // ebx@2 - signed int v5; // edi@5 - int v6; // ebx@6 - HANDLE v8; // [sp-8h] [bp-18h]@10 - unsigned int v9; // [sp-4h] [bp-14h]@10 - - for (uint i = 0; i < uNumMightVideoHeaders; ++i) - if (!_stricmp(pName, pMightVideoHeaders[i].pVideoName)) - { - SetFilePointer(hMightVid, pMightVideoHeaders[i].uFileOffset, 0, FILE_BEGIN); - - if (uBinkVersion < 0x0003000000000000) - return BinkOpen(hMightVid, 0x8800000); - else - return BinkOpen(hMightVid, 0x82000000); - } - - for (uint i = 0; i < uNumMagicVideoHeaders; ++i) - if (!_stricmp(pName, pMagicVideoHeaders[i].pVideoName)) - { - SetFilePointer(hMagicVid, pMagicVideoHeaders[i].uFileOffset, 0, FILE_BEGIN); - - if (uBinkVersion < 0x0003000000000000) - return BinkOpen(hMagicVid, BINKNOTHREADEDIO | BINKFILEHANDLE);//0x8800000); - else - return BinkOpen(hMagicVid, BINKIOPROCESSOR | BINKCOPYALL);//0x82000000); - } - - return nullptr; -} -//----- (004BF1E6) -------------------------------------------------------- -_SMACK *VideoPlayer::OpenSmack(const char *pFilename) -{ - if ( this->uNumMightVideoHeaders ) - { - for ( uint i = 0; i < (signed int)this->uNumMightVideoHeaders; ++i) - { - if ( !_stricmp(this->pMightVideoHeaders[i].pVideoName, pFilename) ) - { - SetFilePointer(this->hMightVid, this->pMightVideoHeaders[i].uFileOffset, 0, 0); - return SmackOpen(this->hMightVid, SMACKTRACK2|SMACKTRACK1|SMACKFILEHANDLE|SMACKLOADEXTRA|SMACKNEEDVOLUME, -1);//0x7140, - } - } - } - if ( this->uNumMagicVideoHeaders ) - { - for ( uint i = 0; i < (signed int)this->uNumMagicVideoHeaders; ++i ) - { - if ( !_stricmp(this->pMagicVideoHeaders[i].pVideoName, pFilename) ) - { - SetFilePointer(this->hMagicVid, this->pMagicVideoHeaders[i].uFileOffset, 0, 0); - return SmackOpen(this->hMagicVid, SMACKTRACK2|SMACKTRACK1|SMACKFILEHANDLE|SMACKLOADEXTRA|SMACKNEEDVOLUME, -1); - } - } - } - return 0; -} -*/ //----- (004BF28F) -------------------------------------------------------- void VideoPlayer::OpenHouseMovie(const char *pMovieName, unsigned int a3_1) { @@ -1043,12 +367,6 @@ bStopBeforeSchedule = false; bBufferLoaded = 1; - /* - pSmackerMovie = 0; - pSmackerBuffer = 0; - pBinkMovie = 0; - pBinkBuffer = 0; - */ bPlayingMovie = false; bFirstFrame = false; bUsingSmackerMMX = SmackUseMMX(1); @@ -1062,28 +380,6 @@ LoadMovie(pMovieName); time_video_begin = GetTickCount(); - /* - this->pSmackerMovie = OpenSmack(Str2); - if ( !this->pSmackerMovie ) - { - this->Unload(); - sprintf(pTmpBuf.data(), "Can't load %s", &Str2); - MessageBoxA(nullptr, pTmpBuf.data(), "E:\\WORK\\MSDEV\\MM7\\MM7\\Code\\Video.cpp:937", 0); - return; - } - */ - - /* - this->pSmackerBuffer = (_SMACKBUF *)SmackBufferOpen(window->GetApiHandle(), 4, LOWORD(this->pSmackerMovie->Width), LOWORD(this->pSmackerMovie->Height), LOWORD(this->pSmackerMovie->Width), LOWORD(this->pSmackerMovie->Height)); - if ( this->pSmackerBuffer ) - { - pRenderer->BeginScene(); - SmackToBuffer(this->pSmackerMovie, 8, 8, 2 * pRenderer->uTargetSurfacePitch, pRenderer->field_14, pRenderer->pTargetSurface, SmackCheckSurfaceFromat()); - pRenderer->EndScene(); - } - SmackVolumePan(this->pSmackerMovie, 1040384, (signed __int64)(pSoundVolumeLevels[(char)uSoundVolumeMultiplier] * 32767.0), 32767); - */ - } } @@ -1100,89 +396,22 @@ if (!this->bBufferLoaded) { - //Prepare(); pEventTimer->Pause(); if (pAudioPlayer->hAILRedbook) AIL_redbook_pause(pAudioPlayer->hAILRedbook); bStopBeforeSchedule = false; bBufferLoaded = 1; - /* - pSmackerMovie = 0; - pSmackerBuffer = 0; - pBinkMovie = 0; - pBinkBuffer = 0; - */ bPlayingMovie = false; bFirstFrame = false; bUsingSmackerMMX = SmackUseMMX(1); this->bLoopPlaying = bLoop; LoadMovie(pFilename); return; - - - /* - sprintf(pVideoName, "%s.bik", pFilename); - this->pBinkMovie = OpenBink(pVideoName); - if ( this->pBinkMovie ) - { - this->uMovieFormat = 2; - strcpy(this->pCurrentMovieName, pFilename); - pBinkMovie = this->pBinkMovie; - this->uMovieFormatSwapped = 1; - if ( pBinkMovie ) - this->pBinkBuffer = CreateBinkBuffer(pBinkMovie->uWidth, pBinkMovie->uHeight, 0); - } - else - { - Unload(); - sprintfex(pVideoName, "%s.smk", pFilename); - this->pSmackerMovie = OpenSmack(pVideoName); - if ( !this->pSmackerMovie ) - { - Unload(); - sprintf(pVideoName, "Can't load file - anims\\%s.smk", pFilename); - MessageBoxA(0, pVideoName, "Smacker Error", 0); - return; - } - this->uMovieFormat = 1; - strcpy(this->pCurrentMovieName, pFilename); - this->uMovieFormatSwapped = 2; - this->pSomeSmackerBuffer = (char *)malloc(this->pSmackerMovie->Width * this->pSmackerMovie->Height); - if ( !this->pSomeSmackerBuffer ) - { - Unload(); - sprintf(pVideoName, "Can't allocate memory for buffer"); - MessageBoxA(0, pVideoName, "Smacker Error", 0); - return; - } - SmackToBuffer(this->pSmackerMovie, 0, 0, this->pSmackerMovie->Width, this->pSmackerMovie->Height, this->pSomeSmackerBuffer, 0); - - v10 = SmackCheckSurfaceFromat(); - if ( a4 ) - { - v10 |= SMACKBLIT2X; - - if (uCPUSpeed >= 165 ) - v10 |= SMACKBLIT2XSMOOTHING; - else - Log::Warning(L"Smacker seems to use lower resolution because it thinks CPU is slow"); - } - - this->pSmackMovieBlit = SmackBlitOpen(v10); - if ( !this->pSmackMovieBlit ) - { - Unload(); - sprintf(pVideoName, "Failed to open Blit API"); - MessageBoxA(0, pVideoName, "Smacker Error", 0); - return; - } - }*/ } } - -//----- (004BF5B2) -------------------------------------------------------- + //----- (004BF5B2) -------------------------------------------------------- void VideoPlayer::_4BF5B2() { //__debugbreak(); @@ -1265,17 +494,6 @@ //pBinkMovie = nullptr; } -//bool MultimediaPlayer::libavcodec_initialized = false; - -/*void MultimediaPlayer::Logger(void *, int, const char *format, va_list args) -{ - char msg[1024]; - vsprintf(msg, format, args); - - DWORD w; - WriteConsoleA(GetStdHandle(STD_OUTPUT_HANDLE), msg, lstrlenA(msg), &w, nullptr); -} */ - int VideoPlayer::readFunction(void* opaque, uint8_t* buf, int buf_size) { HANDLE stream = (HANDLE)opaque;
--- a/VideoPlayer.h Mon Apr 07 19:15:31 2014 +0600 +++ b/VideoPlayer.h Tue Apr 08 17:39:59 2014 +0600 @@ -3,97 +3,10 @@ #include "Texture.h" #include "MediaPlayer.h" - - - - #pragma pack(push, 1) - - -struct _BINK -{ - int uWidth; - int uHeight; -}; - -struct _BINK_1_5_21_0: public _BINK -{ - int uNumFrames; - int uCurrentFrame; - int Data1; - int uFrameRate; - int field_18[3]; - int uFlags; -}; - -struct _BINK_3_0_0_0: public _BINK -{ - int unk_0; - int unk_1; - int uNumFrames; - int uCurrentFrame; - int _unk2; - int _unk_[10]; -}; - - -struct _BINKBUF -{ - int uWidth; - int uHeight; - int field_8; - int field_C; - int uBinkDDSurfaceType; - void *pDDrawSurfaceData; - int uDDrawSurfacePitch; - int field_1C; - int field_20; - int target_width; - int target_height; - int field_2C; - int field_30; - int field_34; - int field_38; - int field_3C; - int field_40; - int field_44; - struct IDirectDrawSurface *pTargetDDrawSurface; - int field_4C; - int uRectX; - int uRectY; - HWND hWnd; - int field_5C; - float field_60; - float field_64; - int field_68; - int field_6C; - void *pDDrawSurfaceData_; - int field_74; - int field_78; -}; -struct _BINKBUF_1_5_21_0: public _BINKBUF -{ - int field_7C; - int field_80; - int field_84; - int field_88; - int field_8C; - int field_90; - int field_94; - int field_98; - int field_9C; - int field_A0; -}; - -struct _BINKBUF_3_0_0_0: public _BINKBUF -{ -}; #pragma pack(pop) - - - #pragma pack(push, 1) struct MovieHeader { @@ -102,10 +15,6 @@ }; #pragma pack(pop) - - - - void ShowMM7IntroVideo_and_LoadingScreen(); extern "C" @@ -117,7 +26,6 @@ #include "lib/libswscale/swscale.h" #include "lib/libswresample/swresample.h" #include "lib/libavutil/opt.h" - //#include "libavutil/samplefmt.h" } #pragma comment(lib, "avcodec.lib") #pragma comment(lib, "avformat.lib") @@ -129,744 +37,6 @@ #include "lib/OpenAL/alc.h" #pragma comment(lib, "OpenAL32.lib") - - -template<int MAX_SAMPLES_BUFFERS> -class OpenALSoundProviderGeneric -{ -public: - inline OpenALSoundProviderGeneric() - { - this->device = nullptr; - this->context = nullptr; - this->samples_current_buffer = 0; - - this->samples_source_id = -1; - for (int i = 0; i < MAX_SAMPLES_BUFFERS; ++i) - samples_buffer_id[i] = -1; - } - - inline bool Initialize() - { - auto device_names = alcGetString(nullptr, ALC_ALL_DEVICES_SPECIFIER); - if (!device_names) - device_names = alcGetString(nullptr, ALC_DEVICE_SPECIFIER); - if (device_names) - { - for (auto device_name = device_names; device_name[0]; device_name += strlen(device_name)) - { - continue; - } - } - - device = alcOpenDevice(nullptr); - if (!device || CheckError()) - return false; - - context = alcCreateContext(device, nullptr); - if (!context || CheckError()) - return Release(), false; - - alcMakeContextCurrent(context); - - bool eax2 = alIsExtensionPresent("EAX2.0"); - bool eax3 = alIsExtensionPresent("EAX3.0"); - bool eax4 = alIsExtensionPresent("EAX4.0"); - bool eax5 = alIsExtensionPresent("EAX5.0"); - - auto vendor = alGetString(AL_VERSION); - auto version = alGetString(AL_VERSION); - auto extensions = alcGetString(device, ALC_EXTENSIONS); - - alGenBuffers(MAX_SAMPLES_BUFFERS, samples_buffer_id); - if (CheckError()) - return Release(), false; - - alGenSources(1, &samples_source_id); - if (CheckError()) - return Release(), false; - - float sound_pos[] = { 0.0f, 0.0f, 0.0f }; - alSourcefv(samples_source_id, AL_POSITION, sound_pos); - alSourcei(samples_source_id, AL_LOOPING, AL_FALSE); - - return true; - } - - void Release() - { - if (samples_source_id != -1) - { - alDeleteSources(1, &samples_source_id); - samples_source_id = -1; - } - - for (int i = 0; i < MAX_SAMPLES_BUFFERS; ++i) - { - if (samples_buffer_id[i] != -1) - alDeleteBuffers(1, &samples_buffer_id[i]); - samples_buffer_id[i] = -1; - } - - alcMakeContextCurrent(nullptr); - if (context) - { - alcDestroyContext(context); - context = nullptr; - } - if (device) - { - alcCloseDevice(device); - device = nullptr; - } - } - - void PlaySample(int num_channels, int sample_rate, int num_samples, void *samples) - { - //char msg[256];sprintf(msg, "chan %u rate %5u num %5u ptr %p\n", num_channels, sample_rate, num_samples, samples); - //log(msg); - ALenum sound_format; - switch (num_channels) - { - case 1: sound_format = AL_FORMAT_MONO16; break; - case 2: sound_format = AL_FORMAT_STEREO16; break; - default: - if (bool multichannel = alIsExtensionPresent("AL_EXT_MCFORMATS")) - { - switch (num_channels) - { - case 4: sound_format = alGetEnumValue("AL_FORMAT_QUAD16"); break; - case 6: sound_format = alGetEnumValue("AL_FORMAT_51CHN16"); break; - case 7: sound_format = alGetEnumValue("AL_FORMAT_61CHN16"); break; - case 8: sound_format = alGetEnumValue("AL_FORMAT_71CHN16"); break; - } - } - __debugbreak(); - } - - float listener_pos[] = { 0.0f, 0.0f, 0.0f }; - float listener_vel[] = { 0.0f, 0.0f, 0.0f }; - float listener_orientation[] = { 0.0f, 0.0f, -1.0f, // direction - 0.0f, 1.0f, 0.0f }; // up vector - alListenerfv(AL_POSITION, listener_pos); - alListenerfv(AL_VELOCITY, listener_vel); - alListenerfv(AL_ORIENTATION, listener_orientation); - - unsigned int *next_buffer = samples_buffer_id + samples_current_buffer; - - alBufferData(*next_buffer, sound_format, samples, num_samples * sizeof(__int16), sample_rate); - CheckError(); - - - int num_processed_buffers; - alGetSourcei(samples_source_id, AL_BUFFERS_PROCESSED, &num_processed_buffers); - /*while (num_processed_buffers) - { - unsigned int processed_buffers_id[4]; - alSourceUnqueueBuffers(samples_source_id, min(4, num_processed_buffers), processed_buffers_id); - CheckError(); - alGetSourcei(samples_source_id, AL_BUFFERS_PROCESSED, &num_processed_buffers); - }*/ - for (int i = 0; i < num_processed_buffers; ++i) - { - unsigned int processed_buffer_id; - alSourceUnqueueBuffers(samples_source_id, 1, &processed_buffer_id); - if (!CheckError()) - alDeleteBuffers(1, &processed_buffer_id); - } - - int num_queued_buffers; - alGetSourcei(samples_source_id, AL_BUFFERS_QUEUED, &num_queued_buffers); - if (num_queued_buffers >= MAX_SAMPLES_BUFFERS) - { - __debugbreak(); - } - - alSourceQueueBuffers(samples_source_id, 1, next_buffer); - CheckError(); - - int status; - alGetSourcei(samples_source_id, AL_SOURCE_STATE, &status); - if (status != AL_PLAYING) - { - alSourcePlay(samples_source_id); - CheckError(); - } - - if (++samples_current_buffer >= MAX_SAMPLES_BUFFERS) - samples_current_buffer = 0; - } - - - -protected: - ALCdevice *device; - ALCcontext *context; - unsigned int samples_buffer_id[MAX_SAMPLES_BUFFERS]; - unsigned int samples_source_id; - int samples_current_buffer; - - - bool CheckError() - { - ALenum code = alcGetError(device); - if (code != ALC_NO_ERROR) - { - DWORD w; - const char *message = alcGetString(device, code); - WriteConsoleA(GetStdHandle(STD_OUTPUT_HANDLE), message, lstrlenA(message), &w, nullptr); - return true; - } - return false; - } -}; -typedef OpenALSoundProviderGeneric<64> OpenALSoundProvider; - - - -void av_logger(void *, int, const char *format, va_list args); - - - -#include <memory> -using std::tr1::shared_ptr; -using std::tr1::make_shared; - -class MultimediaFrame -{ -public: - typedef shared_ptr<MultimediaFrame> Ptr; - inline MultimediaFrame(AVMediaType type, AVPacket *packet, AVCodecContext *dec_ctx) - { - this->type = type; - this->f = nullptr; - this->p = packet; - this->dec_ctx = dec_ctx; - } - virtual ~MultimediaFrame() { return; } - - - AVMediaType Type() const { return type; } - AVFrame *GetAVFrame() { return f; } - - virtual int Decode() = 0; - virtual void *GetData() = 0; - virtual int GetDataPitch() = 0; - - -protected: - AVMediaType type; - AVFrame *f; - AVPacket *p; - AVCodecContext *dec_ctx; -}; - - - -class MultimediaVideoFrame : public MultimediaFrame -{ -public: - inline MultimediaVideoFrame(AVMediaType type, AVPacket *packet, AVCodecContext *dec_ctx, int width, int height) : - MultimediaFrame(type, packet, dec_ctx) - { - this->width = width; - this->height = height; - this->rescaled_data[0] = nullptr; - this->rescaled_linesize[0] = 0; - } - virtual ~MultimediaVideoFrame() - { - av_freep(&rescaled_data); - av_frame_free(&f); - } - - int Decode() override - { - f = avcodec_alloc_frame(); - avcodec_get_frame_defaults(f); - - volatile int done = false; - 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); - if (Rescale(f, width, height, AV_PIX_FMT_RGB32, rescaled_data, rescaled_linesize)) - return 0; - else return -1; - } - - virtual void *GetData() { return rescaled_data[0]; } - virtual int GetDataPitch() { return rescaled_linesize[0]; } - -protected: - int width; - int height; - uint8_t *rescaled_data[8]; - int rescaled_linesize[8]; - - bool Rescale(AVFrame *frame, int dst_width, int dst_height, AVPixelFormat format, uint8_t **out_data, int *out_linesize) - { - 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); -// преобразование кадра - sws_scale(converter, frame->data, frame->linesize, 0, frame->height, out_data, out_linesize); - sws_freeContext(converter); - - return true; - } -}; - - - -class MultimediaAudioFrame : public MultimediaFrame -{ -public: - inline MultimediaAudioFrame(AVMediaType type, AVPacket *packet, AVCodecContext *dec_ctx) : - MultimediaFrame(type, packet, dec_ctx) - { - this->resampled_data = nullptr; - } - virtual ~MultimediaAudioFrame() - { - av_free(resampled_data); - av_frame_free(&f); - } - - int Decode() override - { - f = avcodec_alloc_frame(); - avcodec_get_frame_defaults(f); - - volatile int done = false; - do - { -//Декодирование аудио-пакета осуществляется функцией avcodec_decode_audio4 - int ret; - if ((ret = avcodec_decode_audio4(dec_ctx, f, (int *)&done, p)) < 0) - return ret; - } while (!done); - if (Resample(f, f->channel_layout, f->sample_rate, - f->channel_layout, f->sample_rate, AV_SAMPLE_FMT_S16, &resampled_data)) - return 0; - else return -1; - } - - virtual void *GetData() { return resampled_data; } - virtual int GetDataPitch() { return 2 * f->nb_samples; } - -protected: - uint8_t *resampled_data; - - bool Resample(AVFrame *frame, - int64_t src_channel_layout, int src_sample_rate, - int64_t dst_channel_layout, int dst_sample_rate, AVSampleFormat dst_format, uint8_t **out_data) - { - SwrContext *converter = swr_alloc(); - - av_opt_set_int(converter, "in_channel_layout", src_channel_layout, 0); - av_opt_set_int(converter, "in_sample_rate", src_sample_rate, 0); - av_opt_set_sample_fmt(converter, "in_sample_fmt", (AVSampleFormat)frame->format, 0); - - av_opt_set_int(converter, "out_channel_layout", dst_channel_layout, 0); - av_opt_set_int(converter, "out_sample_rate", dst_sample_rate, 0); - av_opt_set_sample_fmt(converter, "out_sample_fmt", dst_format, 0); - - if (swr_init(converter) < 0) - return false; - - int dst_nb_samples; - int max_dst_nb_samples = dst_nb_samples = av_rescale_rnd(frame->nb_samples, dst_sample_rate, src_channel_layout, AV_ROUND_UP); - - uint8_t **dst_data; - int dst_linesize; - int dst_nb_channels = av_get_channel_layout_nb_channels(dst_channel_layout); - if (av_samples_alloc_array_and_samples(&dst_data, &dst_linesize, dst_nb_channels, dst_nb_samples, dst_format, 0) < 0) - { - swr_free(&converter); - return false; - } - - dst_nb_samples = av_rescale_rnd(swr_get_delay(converter, src_sample_rate) + frame->nb_samples, dst_sample_rate, src_sample_rate, AV_ROUND_UP); - if (dst_nb_samples > max_dst_nb_samples) - { - av_free(dst_data[0]); - if (av_samples_alloc(dst_data, &dst_linesize, dst_nb_channels, dst_nb_samples, dst_format, 1) < 0) - { - swr_free(&converter); - return false; - } - max_dst_nb_samples = dst_nb_samples; - } - - - if (swr_convert(converter, dst_data, dst_nb_samples, (const uint8_t **)frame->data, frame->nb_samples) < 0) - { - av_free(dst_data[0]); - swr_free(&converter); - return false; - } - - *out_data = dst_data[0]; - return true; - } -}; - -int readFunction(void* opaque, uint8_t* buf, int buf_size); - -int64_t seekFunction(void* opaque, int64_t offset, int whence); - -template<int NUM_PRECACHED_FRAMES> -class MovieCached -{ -public: - //bool Stopped() { return stopped; } - int GetWidth() { return width; } - int GetHeight() { return height; } - inline ~MovieCached() - { - Release(); - } -protected: - friend class MultimediaPlayer; - inline MovieCached(OpenALSoundProvider *sound_provider) - { - this->format_ctx = nullptr; - this->sound_provider = sound_provider; - this->stopped = false; - - this->video_stream_idx = -1; - this->video_stream = nullptr; - this->video_stream_dec = nullptr; - this->video_stream_dec_ctx = nullptr; - - this->audio_stream_idx = -1; - this->audio_stream = nullptr; - this->audio_stream_dec = nullptr; - this->audio_stream_dec_ctx = nullptr; - - packet = nullptr; - ioBuffer = nullptr; - format_ctx = nullptr; - avioContext = nullptr; - } - - /*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 - if (!avioContext) - avioContext = avio_alloc_context(ioBuffer, 16384, 0, h, &readFunction, NULL, &seekFunction); - if (!format_ctx) - format_ctx = avformat_alloc_context(); - format_ctx->pb = avioContext; - return Load("dummyFilename", width, 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); - if (video_stream_idx < 0) - return Release(), false; - if (_stricmp("binkvideo", video_stream_dec->name) )//Ritor1: include - { - this->width = video_stream_dec_ctx->width; - this->height = video_stream_dec_ctx->height; - } - - audio_stream_idx = OpenStream(AVMEDIA_TYPE_AUDIO, &audio_stream, &audio_stream_dec, &audio_stream_dec_ctx); - if (audio_stream_idx < 0) - 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() - { - if (packet) - { - av_free_packet(packet); - delete packet; - packet = nullptr; - } - - if (video_stream_idx >= 0) - { - video_stream_idx = -1; - video_stream = nullptr; - video_stream_dec = nullptr; - - // закрытие видео кодека - avcodec_close(video_stream_dec_ctx); - video_stream_dec_ctx = nullptr; - } - - if (audio_stream_idx >= 0) - { - audio_stream_idx = -1; - audio_stream = nullptr; - audio_stream_dec = nullptr; - - // закрытие аудио кодека - avcodec_close(audio_stream_dec_ctx); - - } - if (avioContext) - { - av_free(avioContext); - avioContext = nullptr; - } - if (format_ctx) - { - avformat_free_context(format_ctx); - format_ctx = nullptr; - } - return true; - } - - - /*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) - { - if (avcodec_open2(dec_ctx, dec, nullptr) >= 0) - { - *out_stream = stream; - *out_dec = dec; - *out_dec_ctx = dec_ctx; - return stream_idx; - } - } - fprintf(stderr, "ffmpeg: Unable to open codec\n"); - return -1; - } */ - - MultimediaFrame::Ptr GetNextFrame() - { - packet->data = nullptr; - packet->size = 0; - - volatile int got_frame = false; - //чтение пакетов - do - { - if (av_read_frame(format_ctx, packet) < 0) - { - stopped = true; - return nullptr; - } - } 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)); - else if (packet->stream_index == audio_stream_idx) - return MultimediaFrame::Ptr(new MultimediaAudioFrame(AVMEDIA_TYPE_AUDIO, packet, audio_stream_dec_ctx)); - return nullptr; - } - - - - char movie_name[256]; - int width; - int height; - //bool stopped; - AVFormatContext *format_ctx; - //AVFrame *frame; - AVPacket *packet; - //MultimediaFrame *frames[NUM_PRECACHED_FRAMES]; - OpenALSoundProvider *sound_provider; - - int video_stream_idx; - AVStream *video_stream;//содержат информацию о видео потоке - AVCodec *video_stream_dec; - AVCodecContext *video_stream_dec_ctx; - - int audio_stream_idx; - AVStream *audio_stream;//содержат информацию о аудио потоке - AVCodec *audio_stream_dec; - AVCodecContext *audio_stream_dec_ctx; - unsigned char * ioBuffer; - AVIOContext *avioContext; -}; -//typedef MovieCached<10> Movie; - - - - -/*class MultimediaPlayer -{ -public: - inline MultimediaPlayer() - { - } - - bool Initialize() - { - if (!libavcodec_initialized) - { - av_log_set_callback(Logger); - avcodec_register_all(); - -// Register all available file formats and codecs -//инициализируем библиотеку ffmpeg(Шаг 1) -//Во время инициализации регистрируются все имеющиеся в библиотеке форматы файлов и кодеков. -//После этого они будут использоваться автоматически при открытии файлов этого формата и с этими кодеками. - av_register_all(); - - libavcodec_initialized = true; - } - - sound_provider = new OpenALSoundProvider; - sound_provider->Initialize(); - - return true; - } - - /*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) - { - if (movie->LoadFromLOD(h, readFunction, seekFunction, width, height)) - { - if (_stricmp("binkvideo", movie->video_stream_dec->name) ) - { - current_movie_width = movie->video_stream_dec_ctx->width; - current_movie_height = movie->video_stream_dec_ctx->height; - } - else - { - current_movie_width = width; - current_movie_height = height; - } - return current_movie = movie; - } - delete movie; - } - return nullptr; - } */ - - /*Movie *LoadMovie(const char *filename, int width, int height) - { - auto movie = new Movie(sound_provider); - if (movie) - { - if (movie->Load(filename, width, height)) - { - current_movie_width = width; - current_movie_height = height; - return current_movie = movie; - } - delete movie; - } - return nullptr; - } - - inline char *DoFrame() - { - if (!current_movie) - return nullptr; - - while (true) - { - auto frame = current_movie->GetNextFrame(); - if (!frame) - return nullptr; - - if (frame->Type() == AVMEDIA_TYPE_AUDIO) - { - //continue; -// uint8_t *data; - if (frame->Decode() >= 0) - { - auto f = frame->GetAVFrame(); - sound_provider->PlaySample(f->channels, f->sample_rate, f->nb_samples, frame->GetData()); - Sleep(20); - continue; - } - } - else if (frame->Type() == AVMEDIA_TYPE_VIDEO) - { - uint8_t *dst_data[4] = { 0 }; - int dst_linesize[4] = { 0 }; - if (frame->Decode() >= 0) - { - auto image = new char[current_movie_width * current_movie_height * 4]; - memcpy(image, frame->GetData(), current_movie_height * frame->GetDataPitch()); - - return image; - } - } - return nullptr; - } - } - - - -protected: - static void Logger(void *, int, const char *format, va_list args); - - OpenALSoundProvider *sound_provider; - //Movie *current_movie; - int current_movie_width; - int current_movie_height; - - static bool libavcodec_initialized; -};*/ - - - - - - #pragma pack(push, 1) struct VideoPlayer { @@ -880,32 +50,17 @@ } void PlayDeathMovie(); - unsigned int SmackCheckSurfaceFromat(); void Initialize(OSWindow *window); - void Prepare(); void Unload(); - void FastForwardToFrame(unsigned int uFrameNum); - void BinkDrawFrame(int a3, int a4); - void BinkUpdatePalette() {} - void SmackDrawFrame(int a3, int a4); - void SmackUpdatePalette(); - _BINK *OpenBink(const char *pName); - struct _SMACK *OpenSmack(const char *pFilename); void OpenHouseMovie(const char *pMovieName, unsigned int a3_1);//0x4BF28F bool AnyMovieLoaded(); void OpenGlobalMovie(const char *pFilename, unsigned int bLoop, int a4); void _4BF5B2(); void SelectMovieType();//0x4BF73A - _BINKBUF *CreateBinkBuffer(unsigned int uWidth, unsigned int uHeight, char a4); void _inlined_in_463149(); - void MovieLoop(const char *pMovieName, int a2, int a3, int a4); - RGBTexture pVideoFrame; - //struct _SMACK *pSmackerMovie; - //struct _SMACKBUF *pSmackerBuffer; - //char *pSomeSmackerBuffer; int field_34; MovieHeader *pMightVideoHeaders; MovieHeader *pMagicVideoHeaders; @@ -921,13 +76,10 @@ unsigned int bLoopPlaying; int field_68; unsigned int bStopBeforeSchedule; - //HWND hWindow; OSWindow *window; struct _SMACKBLIT *pSmackMovieBlit; HANDLE hMightVid; HANDLE hMagicVid; - //_BINK *pBinkMovie; - //_BINKBUF *pBinkBuffer; char field_88[20]; unsigned int uMovieFormat; int uMovieFormatSwapped; @@ -939,6 +91,7 @@ HANDLE hVidFile; int uSize; int uOffset; + void UpdatePalette(); static int readFunction(void *, uint8_t *, int); static int64_t seekFunction(void *, int64_t, int); @@ -948,9 +101,5 @@ }; #pragma pack(pop) - - - - extern VideoPlayer *pVideoPlayer; extern LRESULT __stdcall wWinProc(HWND hwnd, unsigned int msg, WPARAM wparam, LPARAM lparam); \ No newline at end of file