diff --git a/src/arch/MovieTexture/MovieTexture_FFMpeg.cpp b/src/arch/MovieTexture/MovieTexture_FFMpeg.cpp index 5fa4f408dc..70cd33fcd1 100644 --- a/src/arch/MovieTexture/MovieTexture_FFMpeg.cpp +++ b/src/arch/MovieTexture/MovieTexture_FFMpeg.cpp @@ -14,62 +14,62 @@ static void FixLilEndian() { - if constexpr ( !Endian::little ) { + if constexpr (!Endian::little) { return; } static bool Initialized = false; - if( Initialized ) + if (Initialized) return; Initialized = true; - for( int i = 0; i < AVPixelFormats[i].bpp; ++i ) + for (int i = 0; i < AVPixelFormats[i].bpp; ++i) { - AVPixelFormat_t &pf = AVPixelFormats[i]; + AVPixelFormat_t& pf = AVPixelFormats[i]; - if( !pf.bByteSwapOnLittleEndian ) + if (!pf.bByteSwapOnLittleEndian) continue; - for( int mask = 0; mask < 4; ++mask) + for (int mask = 0; mask < 4; ++mask) { int m = pf.masks[mask]; - switch( pf.bpp ) + switch (pf.bpp) { - case 24: m = Swap24(m); break; - case 32: m = Swap32(m); break; - default: - FAIL_M(ssprintf("Unsupported BPP value: %i", pf.bpp)); + case 24: m = Swap24(m); break; + case 32: m = Swap32(m); break; + default: + FAIL_M(ssprintf("Unsupported BPP value: %i", pf.bpp)); } pf.masks[mask] = m; } } } -static int FindCompatibleAVFormat( bool bHighColor ) +static int FindCompatibleAVFormat(bool bHighColor) { - for( int i = 0; AVPixelFormats[i].bpp; ++i ) + for (int i = 0; AVPixelFormats[i].bpp; ++i) { - AVPixelFormat_t &fmt = AVPixelFormats[i]; - if( fmt.YUV != PixelFormatYCbCr_Invalid ) + AVPixelFormat_t& fmt = AVPixelFormats[i]; + if (fmt.YUV != PixelFormatYCbCr_Invalid) { - EffectMode em = MovieTexture_Generic::GetEffectMode( fmt.YUV ); - if( !DISPLAY->IsEffectModeSupported(em) ) + EffectMode em = MovieTexture_Generic::GetEffectMode(fmt.YUV); + if (!DISPLAY->IsEffectModeSupported(em)) continue; } - else if( fmt.bHighColor != bHighColor ) + else if (fmt.bHighColor != bHighColor) { continue; } - RagePixelFormat pixfmt = DISPLAY->FindPixelFormat( fmt.bpp, - fmt.masks[0], - fmt.masks[1], - fmt.masks[2], - fmt.masks[3], - true /* realtime */ - ); + RagePixelFormat pixfmt = DISPLAY->FindPixelFormat(fmt.bpp, + fmt.masks[0], + fmt.masks[1], + fmt.masks[2], + fmt.masks[3], + true /* realtime */ + ); - if( pixfmt == RagePixelFormat_Invalid ) + if (pixfmt == RagePixelFormat_Invalid) continue; return i; @@ -78,145 +78,142 @@ static int FindCompatibleAVFormat( bool bHighColor ) return -1; } -RageSurface *RageMovieTextureDriver_FFMpeg::AVCodecCreateCompatibleSurface( int iTextureWidth, int iTextureHeight, bool bPreferHighColor, int &iAVTexfmt, MovieDecoderPixelFormatYCbCr &fmtout ) +RageSurface* RageMovieTextureDriver_FFMpeg::AVCodecCreateCompatibleSurface(int iTextureWidth, int iTextureHeight, bool bPreferHighColor, int& iAVTexfmt, MovieDecoderPixelFormatYCbCr& fmtout) { FixLilEndian(); - int iAVTexfmtIndex = FindCompatibleAVFormat( bPreferHighColor ); - if( iAVTexfmtIndex == -1 ) - iAVTexfmtIndex = FindCompatibleAVFormat( !bPreferHighColor ); + int iAVTexfmtIndex = FindCompatibleAVFormat(bPreferHighColor); + if (iAVTexfmtIndex == -1) + iAVTexfmtIndex = FindCompatibleAVFormat(!bPreferHighColor); - if( iAVTexfmtIndex == -1 ) + if (iAVTexfmtIndex == -1) { /* No dice. Use the first avcodec format of the preferred bit depth, * and let the display system convert. */ - for( iAVTexfmtIndex = 0; AVPixelFormats[iAVTexfmtIndex].bpp; ++iAVTexfmtIndex ) - if( AVPixelFormats[iAVTexfmtIndex].bHighColor == bPreferHighColor ) + for (iAVTexfmtIndex = 0; AVPixelFormats[iAVTexfmtIndex].bpp; ++iAVTexfmtIndex) + if (AVPixelFormats[iAVTexfmtIndex].bHighColor == bPreferHighColor) break; - ASSERT( AVPixelFormats[iAVTexfmtIndex].bpp != 0 ); + ASSERT(AVPixelFormats[iAVTexfmtIndex].bpp != 0); } - const AVPixelFormat_t *pfd = &AVPixelFormats[iAVTexfmtIndex]; + const AVPixelFormat_t* pfd = &AVPixelFormats[iAVTexfmtIndex]; iAVTexfmt = pfd->pf; fmtout = pfd->YUV; - LOG->Trace( "Texture pixel format: %i %i (%ibpp, %08x %08x %08x %08x)", iAVTexfmt, fmtout, - pfd->bpp, pfd->masks[0], pfd->masks[1], pfd->masks[2], pfd->masks[3] ); + LOG->Trace("Texture pixel format: %i %i (%ibpp, %08x %08x %08x %08x)", iAVTexfmt, fmtout, + pfd->bpp, pfd->masks[0], pfd->masks[1], pfd->masks[2], pfd->masks[3]); - if( pfd->YUV == PixelFormatYCbCr_YUYV422 ) + if (pfd->YUV == PixelFormatYCbCr_YUYV422) iTextureWidth /= 2; - return CreateSurface( iTextureWidth, iTextureHeight, pfd->bpp, - pfd->masks[0], pfd->masks[1], pfd->masks[2], pfd->masks[3] ); + return CreateSurface(iTextureWidth, iTextureHeight, pfd->bpp, + pfd->masks[0], pfd->masks[1], pfd->masks[2], pfd->masks[3]); } MovieDecoder_FFMpeg::MovieDecoder_FFMpeg() { FixLilEndian(); - m_fctx = nullptr; - m_pStream = nullptr; - m_iCurrentPacketOffset = -1; - m_Frame = avcodec::av_frame_alloc(); + av_format_context_ = nullptr; + av_stream_ = nullptr; + current_packet_offset_ = -1; Init(); } MovieDecoder_FFMpeg::~MovieDecoder_FFMpeg() { - if (m_swsctx) + if (av_sws_context_) { - avcodec::sws_freeContext(m_swsctx); - m_swsctx = nullptr; + avcodec::sws_freeContext(av_sws_context_); + av_sws_context_ = nullptr; } - if (m_avioContext != nullptr ) + if (av_io_context_ != nullptr) { - RageFile *file = (RageFile *)m_avioContext->opaque; + RageFile* file = (RageFile*)av_io_context_->opaque; file->Close(); delete file; - avcodec::av_free(m_avioContext); + avcodec::av_free(av_io_context_); } - if ( m_buffer != nullptr ) + if (av_buffer_ != nullptr) { - avcodec::av_free(m_buffer); + avcodec::av_free(av_buffer_); } - if (m_pStreamCodec != nullptr) + if (av_stream_codec_ != nullptr) { - avcodec::avcodec_free_context(&m_pStreamCodec); + avcodec::avcodec_free_context(&av_stream_codec_); } - m_FrameBuffer.clear(); + frame_buffer_.clear(); } void MovieDecoder_FFMpeg::Init() { - m_iEOF = 0; - m_fTimestamp = 0; - m_iFrameNumber = 0; - m_totalFrames = 0; - m_fTimestampOffset = 0; - m_swsctx = nullptr; - m_avioContext = nullptr; - m_buffer = nullptr; + end_of_file_ = 0; + display_frame_num_ = 0; + total_frames_ = 0; + av_sws_context_ = nullptr; + av_io_context_ = nullptr; + av_buffer_ = nullptr; } float MovieDecoder_FFMpeg::GetTimestamp() const { // Always display the first frame. - if (m_iFrameNumber == 0) { + if (display_frame_num_ == 0) { return 0; } // In a logical situation, this means that display is outpacing decoding. - if (m_iFrameNumber >= static_cast(m_FrameBuffer.size())) { + if (display_frame_num_ >= static_cast(frame_buffer_.size())) { return 0; } - return m_FrameBuffer[m_iFrameNumber]->frameTimestamp; + return frame_buffer_[display_frame_num_]->frame_timestamp; } bool MovieDecoder_FFMpeg::IsCurrentFrameReady() { // We're displaying faster than decoding. Do not even try to display the frame. - if (m_iFrameNumber >= static_cast(m_FrameBuffer.size())) { + if (display_frame_num_ >= static_cast(frame_buffer_.size())) { return false; } // If the whole movie is decoded, then the frame is definitely ready. - if (m_iEOF) { + if (end_of_file_) { return true; } - std::lock_guard lock(m_FrameBuffer[m_iFrameNumber]->lock); - if (m_FrameBuffer[m_iFrameNumber]->skip) { - LOG->Info("Frame %i not decoded, skipping...", m_iFrameNumber); + std::lock_guard lock(frame_buffer_[display_frame_num_]->lock); + if (frame_buffer_[display_frame_num_]->skip) { + LOG->Info("Frame %i not decoded, skipping...", display_frame_num_); return true; } - if (!m_FrameBuffer[m_iFrameNumber]->decoded) { - LOG->Info("Frame %i not decoded and was not skipped, total frames: %i", m_iFrameNumber, m_totalFrames); + if (!frame_buffer_[display_frame_num_]->decoded) { + LOG->Info("Frame %i not decoded and was not skipped, total frames: %i", display_frame_num_, total_frames_); } - return m_FrameBuffer[m_iFrameNumber]->decoded; + return frame_buffer_[display_frame_num_]->decoded; } int MovieDecoder_FFMpeg::DecodeNextFrame() { // Add in a new FrameBuffer entry, and lock it immediately - m_FrameBuffer.emplace_back(std::make_unique()); - std::unique_lock lock(m_FrameBuffer.back()->lock); + frame_buffer_.emplace_back(std::make_unique()); + std::unique_lock lock(frame_buffer_.back()->lock); int status = SendPacketToBuffer(); if (status < 0) { return status; } - if (m_iEOF) { + if (end_of_file_) { // Release the mutex. lock.unlock(); - m_FrameBuffer.pop_back(); // Don't display an EoF frame. + frame_buffer_.pop_back(); // Don't display an EoF frame. // If we had to approximate the number of frames, set the actual // total number of frames. This is benign even if we did have an // accurate frame count at the start. - m_totalFrames = m_FrameBuffer.size(); + total_frames_ = frame_buffer_.size(); } status = DecodePacketInBuffer(); - if (firstFrame) { - firstFrame = false; + if (first_frame_) { + first_frame_ = false; } return status; } @@ -227,8 +224,8 @@ int MovieDecoder_FFMpeg::DecodeMovie() // The first frame expected to be decoded and drawn already, // that is handled by MovieTexture_Generic::Init(). - int frameNum = 0; - while (!m_iEOF) { + int frame_num = 0; + while (!end_of_file_) { // This wake up time could be tied to the RageTimer, but as it doesn't // need to sync with other parts of ITGm, using chrono is fine. // The 1ms time here is arbitrary, and means that the game will decode @@ -243,13 +240,13 @@ int MovieDecoder_FFMpeg::DecodeMovie() return status; } - frameNum++; + frame_num++; // This means when opening the file, less frames were detected than // there actually are. Increment to keep up so we don't end the video // early during display. - if (frameNum - 1 > m_totalFrames) { - m_totalFrames++; + if (frame_num - 1 > total_frames_) { + total_frames_++; } std::this_thread::sleep_until(wake_up); @@ -259,58 +256,58 @@ int MovieDecoder_FFMpeg::DecodeMovie() int MovieDecoder_FFMpeg::SendPacketToBuffer() { - if (cancel) { + if (cancel_) { return -2; } - if (m_iEOF > 0) { + if (end_of_file_ > 0) { return 0; } while (true) { - int ret = avcodec::av_read_frame(m_fctx, m_FrameBuffer.back()->packet); + int ret = avcodec::av_read_frame(av_format_context_, frame_buffer_.back()->packet); /* XXX: why is avformat returning AVERROR_NOMEM on EOF? */ if (ret < 0) { /* EOF. */ - m_iEOF = 1; + end_of_file_ = 1; return 0; } - if (m_FrameBuffer.back()->packet->stream_index == m_pStream->index) + if (frame_buffer_.back()->packet->stream_index == av_stream_->index) { - m_iCurrentPacketOffset = 0; + current_packet_offset_ = 0; return 1; } /* It's not for the video stream; ignore it. */ - avcodec::av_packet_unref(m_FrameBuffer.back()->packet); + avcodec::av_packet_unref(frame_buffer_.back()->packet); } } int MovieDecoder_FFMpeg::DecodePacketInBuffer() { - if (cancel) { + if (cancel_) { return -2; } - if (m_iEOF == 0 && m_iCurrentPacketOffset == -1) { + if (end_of_file_ == 0 && current_packet_offset_ == -1) { return 0; /* no packet */ } - while (m_iEOF == 0 && m_iCurrentPacketOffset <= m_FrameBuffer.back()->packet->size) + while (end_of_file_ == 0 && current_packet_offset_ <= frame_buffer_.back()->packet->size) { /* If we have no data on the first frame, just return EOF; passing an empty packet * to avcodec_decode_video in this case is crashing it. However, passing an empty * packet is normal with B-frames, to flush. This may be unnecessary in newer * versions of avcodec, but I'm waiting until a new stable release to upgrade. */ - if (m_FrameBuffer.back()->packet->size == 0 && firstFrame) { + if (frame_buffer_.back()->packet->size == 0 && first_frame_) { return 0; /* eof */ } /* Hack: we need to send size = 0 to flush frames at the end, but we have * to give it a buffer to read from since it tries to read anyway. */ - m_FrameBuffer.back()->packet->data = m_FrameBuffer.back()->packet->size ? m_FrameBuffer.back()->packet->data : nullptr; - int len = m_FrameBuffer.back()->packet->size; - avcodec::avcodec_send_packet(m_pStreamCodec, m_FrameBuffer.back()->packet); - int avcodec_return = avcodec::avcodec_receive_frame(m_pStreamCodec, m_FrameBuffer.back()->frame); + frame_buffer_.back()->packet->data = frame_buffer_.back()->packet->size ? frame_buffer_.back()->packet->data : nullptr; + int len = frame_buffer_.back()->packet->size; + avcodec::avcodec_send_packet(av_stream_codec_, frame_buffer_.back()->packet); + int avcodec_return = avcodec::avcodec_receive_frame(av_stream_codec_, frame_buffer_.back()->frame); if (len < 0) { @@ -318,38 +315,38 @@ int MovieDecoder_FFMpeg::DecodePacketInBuffer() { return -1; } - m_iCurrentPacketOffset += len; + current_packet_offset_ += len; if (avcodec_return != 0) { LOG->Warn( "Frame number %i not successfully decoded into buffer. avcodec_receive_frame status: %i", - static_cast(m_FrameBuffer.size() - 1), + static_cast(frame_buffer_.size() - 1), avcodec_return); continue; } - if (m_FrameBuffer.back()->frame->pkt_dts != AV_NOPTS_VALUE) + if (frame_buffer_.back()->frame->pkt_dts != AV_NOPTS_VALUE) { - m_FrameBuffer.back()->frameTimestamp = (float)(m_FrameBuffer.back()->frame->pkt_dts * av_q2d(m_pStream->time_base)); + frame_buffer_.back()->frame_timestamp = (float)(frame_buffer_.back()->frame->pkt_dts * av_q2d(av_stream_->time_base)); } else { /* If the timestamp is zero, this frame is to be played at the * time of the last frame plus the length of the last frame. */ - if (!firstFrame) { - m_FrameBuffer.back()->frameTimestamp += m_FrameBuffer[m_FrameBuffer.size() - 2]->frameDelay; + if (!first_frame_) { + frame_buffer_.back()->frame_timestamp += frame_buffer_[frame_buffer_.size() - 2]->frame_delay; } else { - m_FrameBuffer.back()->frameTimestamp = 0; + frame_buffer_.back()->frame_timestamp = 0; } } // Length of this frame, only used as a fallback for getting the frame // timestamp above. - m_FrameBuffer.back()->frameDelay = (float)av_q2d(m_pStream->time_base); - m_FrameBuffer.back()->frameDelay += m_FrameBuffer.back()->frame->repeat_pict * (m_FrameBuffer.back()->frameDelay * 0.5f); - m_FrameBuffer.back()->decoded = true; + frame_buffer_.back()->frame_delay = (float)av_q2d(av_stream_->time_base); + frame_buffer_.back()->frame_delay += frame_buffer_.back()->frame->repeat_pict * (frame_buffer_.back()->frame_delay * 0.5f); + frame_buffer_.back()->decoded = true; return 1; } @@ -357,19 +354,19 @@ int MovieDecoder_FFMpeg::DecodePacketInBuffer() { // This if statement means the packet did not decode correctly. This is not // necessarily fatal for video playback, but out of caution the frame should // be skipped. - if (!m_FrameBuffer.back()->decoded) { - m_FrameBuffer.back()->skip = true; + if (!frame_buffer_.back()->decoded) { + frame_buffer_.back()->skip = true; } return 0; /* packet done */ } bool MovieDecoder_FFMpeg::SkipNextFrame() { - if (m_iFrameNumber > (m_totalFrames - 1)) { + if (display_frame_num_ > (total_frames_ - 1)) { return true; } - if (m_FrameBuffer[m_iFrameNumber]->skip) { - m_iFrameNumber++; + if (frame_buffer_[display_frame_num_]->skip) { + display_frame_num_++; return true; } return false; @@ -385,40 +382,40 @@ bool MovieDecoder_FFMpeg::GetFrame(RageSurface* pSurface) * XXX 2: The problem of doing this in Open() is that m_AVTexfmt is not * already initialized with its correct value. */ - if (m_swsctx == nullptr) + if (av_sws_context_ == nullptr) { - m_swsctx = avcodec::sws_getCachedContext(m_swsctx, - GetWidth(), GetHeight(), m_pStreamCodec->pix_fmt, - GetWidth(), GetHeight(), m_AVTexfmt, - sws_flags, nullptr, nullptr, nullptr); - if (m_swsctx == nullptr) + av_sws_context_ = avcodec::sws_getCachedContext(av_sws_context_, + GetWidth(), GetHeight(), av_stream_codec_->pix_fmt, + GetWidth(), GetHeight(), av_pixel_format_, + kSwsFlags, nullptr, nullptr, nullptr); + if (av_sws_context_ == nullptr) { - LOG->Warn("Cannot initialize sws conversion context for (%d,%d) %d->%d", GetWidth(), GetHeight(), m_pStreamCodec->pix_fmt, m_AVTexfmt); + LOG->Warn("Cannot initialize sws conversion context for (%d,%d) %d->%d", GetWidth(), GetHeight(), av_stream_codec_->pix_fmt, av_pixel_format_); return false; } } - avcodec::sws_scale(m_swsctx, - m_FrameBuffer[m_iFrameNumber]->frame->data, m_FrameBuffer[m_iFrameNumber]->frame->linesize, 0, GetHeight(), + avcodec::sws_scale(av_sws_context_, + frame_buffer_[display_frame_num_]->frame->data, frame_buffer_[display_frame_num_]->frame->linesize, 0, GetHeight(), pict.data, pict.linesize); // Don't advance the frame number past the (potential) end of the buffer. // This can happen if display is outpacing decoding, or if we're at the // end of file. - if (m_iFrameNumber >= (m_totalFrames - 1)) { - return m_iEOF; + if (display_frame_num_ >= (total_frames_ - 1)) { + return end_of_file_; } - m_iFrameNumber++; + display_frame_num_++; return false; } -static RString averr_ssprintf( int err, const char *fmt, ... ) +static RString averr_ssprintf(int err, const char* fmt, ...) { - ASSERT( err < 0 ); + ASSERT(err < 0); va_list va; va_start(va, fmt); - RString s = vssprintf( fmt, va ); + RString s = vssprintf(fmt, va); va_end(va); std::size_t errbuf_size = 512; @@ -430,85 +427,85 @@ static RString averr_ssprintf( int err, const char *fmt, ... ) return s + " (" + Error + ")"; } -static int AVIORageFile_ReadPacket( void *opaque, std::uint8_t *buf, int buf_size ) +static int AVIORageFile_ReadPacket(void* opaque, std::uint8_t* buf, int buf_size) { - RageFile *f = (RageFile *)opaque; - int n = f->Read( buf, buf_size ); + RageFile* f = (RageFile*)opaque; + int n = f->Read(buf, buf_size); if (n == 0) return AVERROR_EOF; return n; } -static std::int64_t AVIORageFile_Seek( void *opaque, std::int64_t offset, int whence ) +static std::int64_t AVIORageFile_Seek(void* opaque, std::int64_t offset, int whence) { - RageFile *f = (RageFile *)opaque; - if( whence == AVSEEK_SIZE ) + RageFile* f = (RageFile*)opaque; + if (whence == AVSEEK_SIZE) return f->GetFileSize(); - if( whence != SEEK_SET && whence != SEEK_CUR && whence != SEEK_END ) + if (whence != SEEK_SET && whence != SEEK_CUR && whence != SEEK_END) { LOG->Trace("Error: unsupported seek whence: %d", whence); return -1; } - return f->Seek( (int) offset, whence ); + return f->Seek((int)offset, whence); } -RString MovieDecoder_FFMpeg::Open( RString sFile ) +RString MovieDecoder_FFMpeg::Open(RString sFile) { - m_fctx = avcodec::avformat_alloc_context(); - if( !m_fctx ) + av_format_context_ = avcodec::avformat_alloc_context(); + if (!av_format_context_) return "AVCodec: Couldn't allocate context"; - RageFile *f = new RageFile; + RageFile* f = new RageFile; - if( !f->Open(sFile, RageFile::READ) ) + if (!f->Open(sFile, RageFile::READ)) { RString errorMessage = f->GetError(); - RString error = ssprintf("MovieDecoder_FFMpeg: Error opening \"%s\": %s", sFile.c_str(), errorMessage.c_str() ); + RString error = ssprintf("MovieDecoder_FFMpeg: Error opening \"%s\": %s", sFile.c_str(), errorMessage.c_str()); delete f; return error; } - m_buffer = (unsigned char *)avcodec::av_malloc(STEPMANIA_FFMPEG_BUFFER_SIZE); - m_avioContext = avcodec::avio_alloc_context(m_buffer, STEPMANIA_FFMPEG_BUFFER_SIZE, 0, f, AVIORageFile_ReadPacket, nullptr, AVIORageFile_Seek); - m_fctx->pb = m_avioContext; - int ret = avcodec::avformat_open_input( &m_fctx, sFile.c_str(), nullptr, nullptr ); - if( ret < 0 ) - return RString( averr_ssprintf(ret, "AVCodec: Couldn't open \"%s\"", sFile.c_str()) ); + av_buffer_ = (unsigned char*)avcodec::av_malloc(STEPMANIA_FFMPEG_BUFFER_SIZE); + av_io_context_ = avcodec::avio_alloc_context(av_buffer_, STEPMANIA_FFMPEG_BUFFER_SIZE, 0, f, AVIORageFile_ReadPacket, nullptr, AVIORageFile_Seek); + av_format_context_->pb = av_io_context_; + int ret = avcodec::avformat_open_input(&av_format_context_, sFile.c_str(), nullptr, nullptr); + if (ret < 0) + return RString(averr_ssprintf(ret, "AVCodec: Couldn't open \"%s\"", sFile.c_str())); - ret = avcodec::avformat_find_stream_info( m_fctx, nullptr ); - if( ret < 0 ) - return RString( averr_ssprintf(ret, "AVCodec (%s): Couldn't find codec parameters", sFile.c_str()) ); + ret = avcodec::avformat_find_stream_info(av_format_context_, nullptr); + if (ret < 0) + return RString(averr_ssprintf(ret, "AVCodec (%s): Couldn't find codec parameters", sFile.c_str())); - int stream_idx = avcodec::av_find_best_stream( m_fctx, avcodec::AVMEDIA_TYPE_VIDEO, -1, -1, nullptr, 0 ); - if ( stream_idx < 0 || - static_cast(stream_idx) >= m_fctx->nb_streams || - m_fctx->streams[stream_idx] == nullptr ) + int stream_idx = avcodec::av_find_best_stream(av_format_context_, avcodec::AVMEDIA_TYPE_VIDEO, -1, -1, nullptr, 0); + if (stream_idx < 0 || + static_cast(stream_idx) >= av_format_context_->nb_streams || + av_format_context_->streams[stream_idx] == nullptr) return "Couldn't find any video streams"; - m_pStream = m_fctx->streams[stream_idx]; - m_pStreamCodec = avcodec::avcodec_alloc_context3(nullptr); - if (avcodec::avcodec_parameters_to_context(m_pStreamCodec, m_pStream->codecpar) < 0) + av_stream_ = av_format_context_->streams[stream_idx]; + av_stream_codec_ = avcodec::avcodec_alloc_context3(nullptr); + if (avcodec::avcodec_parameters_to_context(av_stream_codec_, av_stream_->codecpar) < 0) return ssprintf("Could not get context from parameters"); - if( m_pStreamCodec->codec_id == avcodec::AV_CODEC_ID_NONE ) - return ssprintf( "Unsupported codec %08x", m_pStreamCodec->codec_tag ); + if (av_stream_codec_->codec_id == avcodec::AV_CODEC_ID_NONE) + return ssprintf("Unsupported codec %08x", av_stream_codec_->codec_tag); RString sError = OpenCodec(); - if( !sError.empty() ) - return ssprintf( "AVCodec (%s): %s", sFile.c_str(), sError.c_str() ); + if (!sError.empty()) + return ssprintf("AVCodec (%s): %s", sFile.c_str(), sError.c_str()); - LOG->Trace("Bitrate: %i", static_cast(m_pStreamCodec->bit_rate)); - LOG->Trace("Codec pixel format: %s", avcodec::av_get_pix_fmt_name(m_pStreamCodec->pix_fmt)); - m_totalFrames = m_pStream->nb_frames; - if (m_totalFrames <= 0) { + LOG->Trace("Bitrate: %i", static_cast(av_stream_codec_->bit_rate)); + LOG->Trace("Codec pixel format: %s", avcodec::av_get_pix_fmt_name(av_stream_codec_->pix_fmt)); + total_frames_ = av_stream_->nb_frames; + if (total_frames_ <= 0) { // Sometimes we might not get a correct frame count. // In that case, approximate and fix it later. - m_totalFrames = m_fctx->duration // microseconds - * (m_pStream->avg_frame_rate.num) / (m_pStream->avg_frame_rate.den) / (1000000); + total_frames_ = av_format_context_->duration // microseconds + * (av_stream_->avg_frame_rate.num) / (av_stream_->avg_frame_rate.den) / (1000000); LOG->Trace("Number of frames provided is inaccurate, estimating."); } - LOG->Trace("Number of frames detected: %i", m_totalFrames); + LOG->Trace("Number of frames detected: %i", total_frames_); return RString(); } @@ -517,40 +514,40 @@ RString MovieDecoder_FFMpeg::OpenCodec() { Init(); - ASSERT( m_pStream != nullptr ); - if( m_pStreamCodec->codec ) - avcodec::avcodec_close( m_pStreamCodec ); + ASSERT(av_stream_ != nullptr); + if (av_stream_codec_->codec) + avcodec::avcodec_close(av_stream_codec_); - const avcodec::AVCodec *pCodec = avcodec::avcodec_find_decoder( m_pStreamCodec->codec_id ); - if( pCodec == nullptr ) - return ssprintf( "Couldn't find decoder %i", m_pStreamCodec->codec_id ); + const avcodec::AVCodec* pCodec = avcodec::avcodec_find_decoder(av_stream_codec_->codec_id); + if (pCodec == nullptr) + return ssprintf("Couldn't find decoder %i", av_stream_codec_->codec_id); - m_pStreamCodec->workaround_bugs = 1; - m_pStreamCodec->idct_algo = FF_IDCT_AUTO; - m_pStreamCodec->error_concealment = 3; + av_stream_codec_->workaround_bugs = 1; + av_stream_codec_->idct_algo = FF_IDCT_AUTO; + av_stream_codec_->error_concealment = 3; - LOG->Trace("Opening codec %s", pCodec->name ); + LOG->Trace("Opening codec %s", pCodec->name); - int ret = avcodec::avcodec_open2( m_pStreamCodec, pCodec, nullptr ); - if( ret < 0 ) - return RString( averr_ssprintf(ret, "Couldn't open codec \"%s\"", pCodec->name) ); - ASSERT( m_pStreamCodec->codec != nullptr ); + int ret = avcodec::avcodec_open2(av_stream_codec_, pCodec, nullptr); + if (ret < 0) + return RString(averr_ssprintf(ret, "Couldn't open codec \"%s\"", pCodec->name)); + ASSERT(av_stream_codec_->codec != nullptr); return RString(); } void MovieDecoder_FFMpeg::Close() { - if( m_pStream && m_pStreamCodec->codec ) + if (av_stream_ && av_stream_codec_->codec) { - avcodec::avcodec_close( m_pStreamCodec ); - m_pStream = nullptr; + avcodec::avcodec_close(av_stream_codec_); + av_stream_ = nullptr; } - if( m_fctx ) + if (av_format_context_) { - avcodec::avformat_close_input( &m_fctx ); - m_fctx = nullptr; + avcodec::avformat_close_input(&av_format_context_); + av_format_context_ = nullptr; } Init(); @@ -558,29 +555,29 @@ void MovieDecoder_FFMpeg::Close() void MovieDecoder_FFMpeg::Rewind() { - m_iFrameNumber = 0; + display_frame_num_ = 0; } -RageSurface *MovieDecoder_FFMpeg::CreateCompatibleSurface( int iTextureWidth, int iTextureHeight, bool bPreferHighColor, MovieDecoderPixelFormatYCbCr &fmtout ) +RageSurface* MovieDecoder_FFMpeg::CreateCompatibleSurface(int iTextureWidth, int iTextureHeight, bool bPreferHighColor, MovieDecoderPixelFormatYCbCr& fmtout) { - return RageMovieTextureDriver_FFMpeg::AVCodecCreateCompatibleSurface( iTextureWidth, iTextureHeight, bPreferHighColor, *ConvertValue(&m_AVTexfmt), fmtout ); + return RageMovieTextureDriver_FFMpeg::AVCodecCreateCompatibleSurface(iTextureWidth, iTextureHeight, bPreferHighColor, *ConvertValue(&av_pixel_format_), fmtout); } -MovieTexture_FFMpeg::MovieTexture_FFMpeg( RageTextureID ID ): - MovieTexture_Generic( ID, new MovieDecoder_FFMpeg ) +MovieTexture_FFMpeg::MovieTexture_FFMpeg(RageTextureID ID) : + MovieTexture_Generic(ID, new MovieDecoder_FFMpeg) { } -RageMovieTexture *RageMovieTextureDriver_FFMpeg::Create( RageTextureID ID, RString &sError ) +RageMovieTexture* RageMovieTextureDriver_FFMpeg::Create(RageTextureID ID, RString& sError) { - MovieTexture_FFMpeg *pRet = new MovieTexture_FFMpeg( ID ); + MovieTexture_FFMpeg* pRet = new MovieTexture_FFMpeg(ID); sError = pRet->Init(); - if( !sError.empty() ) - SAFE_DELETE( pRet ); + if (!sError.empty()) + SAFE_DELETE(pRet); return pRet; } -REGISTER_MOVIE_TEXTURE_CLASS( FFMpeg ); +REGISTER_MOVIE_TEXTURE_CLASS(FFMpeg); /* * (c) 2003-2005 Glenn Maynard diff --git a/src/arch/MovieTexture/MovieTexture_FFMpeg.h b/src/arch/MovieTexture/MovieTexture_FFMpeg.h index e8d4dbe332..3766c34b57 100644 --- a/src/arch/MovieTexture/MovieTexture_FFMpeg.h +++ b/src/arch/MovieTexture/MovieTexture_FFMpeg.h @@ -14,21 +14,21 @@ namespace avcodec { extern "C" { - #include - #include - #include - #include +#include +#include +#include +#include } }; #define STEPMANIA_FFMPEG_BUFFER_SIZE 4096 -static const int sws_flags = SWS_BICUBIC; // XXX: Reasonable default? +static const int kSwsFlags = SWS_BICUBIC; // XXX: Reasonable default? struct FrameHolder { avcodec::AVFrame* frame = avcodec::av_frame_alloc(); avcodec::AVPacket* packet = avcodec::av_packet_alloc(); - float frameTimestamp = 0; - float frameDelay = 0; + float frame_timestamp = 0; + float frame_delay = 0; bool decoded = false; bool skip = false; std::mutex lock; // Protects the frame as it's being initialized. @@ -38,8 +38,8 @@ struct FrameHolder { FrameHolder(const FrameHolder& fh) { avcodec::av_frame_ref(frame, fh.frame); avcodec::av_packet_ref(packet, fh.packet); - frameTimestamp = fh.frameTimestamp; - frameDelay = fh.frameDelay; + frame_timestamp = fh.frame_timestamp; + frame_delay = fh.frame_delay; decoded = fh.decoded; skip = fh.skip; } @@ -54,35 +54,35 @@ struct FrameHolder { } }; -class MovieTexture_FFMpeg: public MovieTexture_Generic +class MovieTexture_FFMpeg : public MovieTexture_Generic { public: - MovieTexture_FFMpeg( RageTextureID ID ); + MovieTexture_FFMpeg(RageTextureID ID); - static RageSurface *AVCodecCreateCompatibleSurface( int iTextureWidth, int iTextureHeight, bool bPreferHighColor, int &iAVTexfmt, MovieDecoderPixelFormatYCbCr &fmtout ); + static RageSurface* AVCodecCreateCompatibleSurface(int iTextureWidth, int iTextureHeight, bool bPreferHighColor, int& iAVTexfmt, MovieDecoderPixelFormatYCbCr& fmtout); }; -class RageMovieTextureDriver_FFMpeg: public RageMovieTextureDriver +class RageMovieTextureDriver_FFMpeg : public RageMovieTextureDriver { public: - virtual RageMovieTexture *Create( RageTextureID ID, RString &sError ); - static RageSurface *AVCodecCreateCompatibleSurface( int iTextureWidth, int iTextureHeight, bool bPreferHighColor, int &iAVTexfmt, MovieDecoderPixelFormatYCbCr &fmtout ); + virtual RageMovieTexture* Create(RageTextureID ID, RString& sError); + static RageSurface* AVCodecCreateCompatibleSurface(int iTextureWidth, int iTextureHeight, bool bPreferHighColor, int& iAVTexfmt, MovieDecoderPixelFormatYCbCr& fmtout); }; -class MovieDecoder_FFMpeg: public MovieDecoder +class MovieDecoder_FFMpeg : public MovieDecoder { public: MovieDecoder_FFMpeg(); ~MovieDecoder_FFMpeg(); - RString Open( RString sFile ); + RString Open(RString sFile); void Close(); void Rewind(); // This draws a frame from the buffer onto the provided RageSurface. // Returns true if returning the last frame in the movie. bool GetFrame(RageSurface* pOut); - int DecodeFrame( float fTargetTime ); + int DecodeFrame(float fTargetTime); // Decode a single frame. Return -2 on cancel, -1 on error, 0 on EOF, 1 if we have a frame. int DecodeNextFrame(); @@ -101,14 +101,14 @@ public: int DecodeMovie(); bool IsCurrentFrameReady(); - int GetWidth() const { return m_pStreamCodec->width; } - int GetHeight() const { return m_pStreamCodec->height; } + int GetWidth() const { return av_stream_codec_->width; } + int GetHeight() const { return av_stream_codec_->height; } - RageSurface *CreateCompatibleSurface( int iTextureWidth, int iTextureHeight, bool bPreferHighColor, MovieDecoderPixelFormatYCbCr &fmtout ); + RageSurface* CreateCompatibleSurface(int iTextureWidth, int iTextureHeight, bool bPreferHighColor, MovieDecoderPixelFormatYCbCr& fmtout); float GetTimestamp() const; - void Cancel() { cancel = true; }; + void Cancel() { cancel_ = true; }; // If the next frame to display had an issue decoding, skip it. bool SkipNextFrame(); @@ -125,33 +125,30 @@ private: // Returns -2 on cancel, -1 on error, 0 if the packet is finished. int DecodePacketInBuffer(); - avcodec::AVStream *m_pStream; - avcodec::AVFrame *m_Frame; - avcodec::AVPixelFormat m_AVTexfmt; /* pixel format of output surface */ - avcodec::SwsContext *m_swsctx; - avcodec::AVCodecContext *m_pStreamCodec; + avcodec::AVStream* av_stream_; + avcodec::AVPixelFormat av_pixel_format_; /* pixel format of output surface */ + avcodec::SwsContext* av_sws_context_; + avcodec::AVCodecContext* av_stream_codec_; - avcodec::AVFormatContext *m_fctx; - float m_fTimestamp; - float m_fTimestampOffset; - int m_iFrameNumber; - int m_totalFrames; // Total number of frames in the movie. + avcodec::AVFormatContext* av_format_context_; + int display_frame_num_; + int total_frames_; // Total number of frames in the movie. - unsigned char *m_buffer; - avcodec::AVIOContext *m_avioContext; + unsigned char* av_buffer_; + avcodec::AVIOContext* av_io_context_; // The movie buffer. - std::vector> m_FrameBuffer; + std::vector> frame_buffer_; - int m_iCurrentPacketOffset; + int current_packet_offset_; // 0 = no EOF // 1 = EOF while decoding - int m_iEOF; + int end_of_file_; // If true, received a cancel signal from the MovieTexture. - bool cancel = false; - bool firstFrame = true; + bool cancel_ = false; + bool first_frame_ = true; }; static struct AVPixelFormat_t @@ -196,29 +193,6 @@ static struct AVPixelFormat_t true, PixelFormatYCbCr_Invalid, }, - /* - { - 32, - { 0x000000FF, - 0x0000FF00, - 0x00FF0000, - 0xFF000000 }, - avcodec::AV_PIX_FMT_ABGR, - true, - true, - PixelFormatYCbCr_Invalid, - }, - { - 32, - { 0xFF000000, - 0x00FF0000, - 0x0000FF00, - 0x000000FF }, - avcodec::AV_PIX_FMT_RGBA, - true, - true, - PixelFormatYCbCr_Invalid, - }, */ { 24, { 0xFF0000,