Mercurial > mm7
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(); }