aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGeorge Yunaev <you@yourdomain.example.com>2011-12-17 02:14:02 -0800
committerGeorge Yunaev <you@yourdomain.example.com>2011-12-17 02:14:02 -0800
commite3589e5e29b8941951889c3c05197f8e044a2c6d (patch)
tree17ab17313a457a77a856358e886cad64fb385d57
parent5684e8ef15bc5a4ef2c407a4dafb33684e4afb95 (diff)
Reverted d1c5773a2736849616adda4013d1a8c5a56a84e6
-rw-r--r--xbmc/music/karaoke/karaokevideobackground.cpp406
-rw-r--r--xbmc/music/karaoke/karaokevideobackground.h103
2 files changed, 0 insertions, 509 deletions
diff --git a/xbmc/music/karaoke/karaokevideobackground.cpp b/xbmc/music/karaoke/karaokevideobackground.cpp
deleted file mode 100644
index 8c73ce2557..0000000000
--- a/xbmc/music/karaoke/karaokevideobackground.cpp
+++ /dev/null
@@ -1,406 +0,0 @@
-/*
- * Copyright (C) 2005-2010 Team XBMC
- * http://www.xbmc.org
- *
- * This Program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2, or (at your option)
- * any later version.
- *
- * This Program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with XBMC; see the file COPYING. If not, write to
- * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
- * http://www.gnu.org/copyleft/gpl.html
- *
- */
-
-#include "system.h"
-#include "guilib/Texture.h"
-#include "guilib/GUITexture.h"
-#include "settings/Settings.h"
-#include "Application.h"
-#include "utils/MathUtils.h"
-#include "filesystem/SpecialProtocol.h"
-#include "settings/AdvancedSettings.h"
-#include "karaokevideobackground.h"
-
-static bool PERSISTENT_OBJECT = 0;
-
-
-KaraokeVideoFFMpeg::KaraokeVideoFFMpeg()
-{
- pFormatCtx = 0;
- pCodecCtx = 0;
- pCodec = 0;
- pFrame = 0;
- pFrameRGB = 0;
- m_timeBase = 0;
- m_texture = 0;
-
- m_maxFrame = 0;
- m_currentFrameNumber = 0;
-}
-
-KaraokeVideoFFMpeg::~KaraokeVideoFFMpeg()
-{
- Dismiss();
-
- delete m_texture;
-}
-
-bool KaraokeVideoFFMpeg::Init()
-{
- if ( !m_dllAvUtil.Load() || !m_dllAvCodec.Load() || !m_dllSwScale.Load() || !m_dllAvFormat.Load() )
- {
- CLog::Log( LOGERROR, "Karaoke Video Background: failed to load FFMpeg libraries" );
- return false;
- }
-
- m_dllAvCodec.avcodec_register_all();
- m_dllAvFormat.av_register_all();
-
- CLog::Log( LOGDEBUG, "Karaoke Video Background: init succeed" );
- return true;
-}
-
-void KaraokeVideoFFMpeg::Dismiss()
-{
- closeVideoFile();
-
- m_dllAvCodec.Unload();
- m_dllAvUtil.Unload();
- m_dllSwScale.Unload();
- m_dllAvFormat.Unload();
-
- CLog::Log( LOGDEBUG, "Karaoke Video Background: dismiss succeed" );
-}
-
-bool KaraokeVideoFFMpeg::openVideoFile( const CStdString& filename )
-{
- // See http://dranger.com/ffmpeg/tutorial01.html
- closeVideoFile();
-
- CStdString realPath = CSpecialProtocol::TranslatePath( filename );
-
- // Open video file
- if ( m_dllAvFormat.av_open_input_file( &pFormatCtx, realPath.c_str(), NULL, 0, NULL ) < 0 )
- {
- CLog::Log( LOGERROR, "Karaoke Video Background: Could not open video file %s (%s)", filename.c_str(), realPath.c_str() );
- return false;
- }
-
- // Retrieve stream information
- if ( m_dllAvFormat.av_find_stream_info( pFormatCtx ) < 0 )
- {
- CLog::Log( LOGERROR, "Karaoke Video Background: Could not find stream information in the video file %s", filename.c_str() );
- return false;
- }
-
- // Find the first video stream
- videoStream = -1;
-
- for ( unsigned i = 0; i < pFormatCtx->nb_streams; i++ )
- {
- if ( pFormatCtx->streams[i]->codec->codec_type == CODEC_TYPE_VIDEO )
- {
- videoStream = i;
- break;
- }
- }
-
- if ( videoStream == -1 )
- {
- CLog::Log( LOGERROR, "Karaoke Video Background: Could not find playable video stream in the file %s", filename.c_str() );
- return false;
- }
-
- m_fps_den = pFormatCtx->streams[videoStream]->r_frame_rate.den;
- m_fps_num = pFormatCtx->streams[videoStream]->r_frame_rate.num;
-
- if ( m_fps_den == 60000 )
- m_fps_den = 30000;
-
- // Get a pointer to the codec context for the video stream
- pCodecCtx = pFormatCtx->streams[ videoStream ]->codec;
-
- // Find the decoder for the video stream
- pCodec = m_dllAvCodec.avcodec_find_decoder( pCodecCtx->codec_id );
-
- if ( pCodec == NULL )
- {
- CLog::Log( LOGERROR, "Karaoke Video Background: Could not find the video decoder for the file %s", filename.c_str() );
- return false;
- }
-
- // Open the codec
- if ( m_dllAvCodec.avcodec_open( pCodecCtx, pCodec ) < 0 )
- {
- CLog::Log( LOGERROR, "Karaoke Video Background: Could not open the video decoder for the file %s", filename.c_str() );
- return false;
- }
-
- // Allocate video frames
- pFrame = m_dllAvCodec.avcodec_alloc_frame();
-
- if ( !pFrame )
- {
- CLog::Log( LOGERROR, "Karaoke Video Background: Could not allocate memory for frame" );
- return false;
- }
-
- // Init the rest of params
- m_videoWidth = pCodecCtx->width;
- m_videoHeight = pCodecCtx->height;
- m_timeBase = 0;
- m_currentFrameNumber = 0;
- m_maxFrame = 0;
- m_curVideoFile = filename;
-
- // Find out the necessary aspect ratio for height (assuming fit by width) and width (assuming fit by height)
- RESOLUTION res = g_graphicsContext.GetVideoResolution();
- m_displayLeft = g_settings.m_ResInfo[res].Overscan.left;
- m_displayRight = g_settings.m_ResInfo[res].Overscan.right;
- m_displayTop = g_settings.m_ResInfo[res].Overscan.top;
- m_displayBottom = g_settings.m_ResInfo[res].Overscan.bottom;
-
- int screen_width = m_displayRight - m_displayLeft;
- int screen_height = m_displayBottom - m_displayTop;
-
- // Do we need to modify the output video size? This could happen in two cases:
- // 1. Either video dimension is larger than the screen - video needs to be downscaled
- // 2. Both video dimensions are smaller than the screen - video needs to be upscaled
- if ( (m_videoWidth > screen_width || m_videoHeight > screen_height )
- || ( m_videoWidth < screen_width && m_videoHeight < screen_height ) )
- {
- // Calculate the scale coefficients for width/height separately
- double scale_width = (double) screen_width / (double) m_videoWidth;
- double scale_height = (double) screen_height / (double) m_videoHeight;
-
- // And apply the smallest
- double scale = scale_width < scale_height ? scale_width : scale_height;
- m_videoWidth = (int) ((double) m_videoWidth * scale);
- m_videoHeight = (int) ((double) m_videoHeight * scale);
- }
-
- // Allocate the conversion frame and relevant picture
- pFrameRGB = (AVPicture*)m_dllAvUtil.av_mallocz(sizeof(AVPicture));
-
- if ( !pFrameRGB )
- {
- CLog::Log( LOGERROR, "Karaoke Video Background: Could not allocate memory for frame" );
- return false;
- }
-
- // Due to a bug in swsscale we need to allocate one extra line of data
- if ( m_dllAvCodec.avpicture_alloc( pFrameRGB, PIX_FMT_RGB32, m_videoWidth, m_videoHeight + 1 ) < 0 )
- {
- CLog::Log( LOGERROR, "Karaoke Video Background: Could not allocate memory for picture buf" );
- return false;
- }
-
- // Calculate the desktop dimensions to show the video
- if ( m_videoWidth < screen_width || m_videoHeight < screen_height )
- {
- m_displayLeft = (screen_width - m_videoWidth) / 2;
- m_displayRight -= m_displayLeft;
-
- m_displayTop = (screen_height - m_videoHeight) / 2;
- m_displayBottom -= m_displayTop;
- }
-
- CLog::Log( LOGDEBUG, "Karaoke Video Background: Video file %s (%dx%d) opened successfully, will be shown as %dx%d at (%d, %d - %d, %d) rectangle",
- filename.c_str(),
- pCodecCtx->width, pCodecCtx->height,
- m_videoWidth, m_videoHeight,
- m_displayLeft, m_displayTop, m_displayRight, m_displayBottom );
-
- return true;
-}
-
-void KaraokeVideoFFMpeg::closeVideoFile()
-{
- // Free the YUV frame
- if ( pFrame )
- m_dllAvUtil.av_free( pFrame );
-
- // Free the RGB frame
- if ( pFrameRGB )
- {
- m_dllAvCodec.avpicture_free( pFrameRGB );
- m_dllAvUtil.av_free( pFrameRGB );
- }
-
- // Close the codec
- if ( pCodecCtx )
- m_dllAvCodec.avcodec_close( pCodecCtx );
-
- // Close the video file
- if ( pFormatCtx )
- m_dllAvFormat.av_close_input_file( pFormatCtx );
-
- pFormatCtx = 0;
- pCodecCtx = 0;
- pCodec = 0;
- pFrame = 0;
- pFrameRGB = 0;
- m_curVideoFile.clear();
-}
-
-bool KaraokeVideoFFMpeg::readFrame( int frame )
-{
- AVPacket packet;
- int frameFinished;
-
- while ( m_currentFrameNumber < frame )
- {
- // Read a frame
- if ( m_dllAvFormat.av_read_frame( pFormatCtx, &packet ) < 0 )
- return false; // Frame read failed (e.g. end of stream)
-
- if ( packet.stream_index == videoStream )
- {
- // Is this a packet from the video stream -> decode video frame
- m_dllAvCodec.avcodec_decode_video2( pCodecCtx, pFrame, &frameFinished, &packet );
-
- // Did we get a video frame?
- if ( frameFinished )
- {
- m_currentFrameNumber++;
-
- if ( m_currentFrameNumber >= frame )
- {
- // convert the picture
- struct SwsContext * context = m_dllSwScale.sws_getContext( pCodecCtx->width, pCodecCtx->height, pCodecCtx->pix_fmt,
- m_videoWidth, m_videoHeight, PIX_FMT_RGB32, SWS_FAST_BILINEAR, NULL, NULL, NULL );
-
- m_dllSwScale.sws_scale( context, pFrame->data, pFrame->linesize, 0, pCodecCtx->height, pFrameRGB->data, pFrameRGB->linesize );
- m_dllSwScale.sws_freeContext( context );
- }
-
- m_dllAvCodec.av_free_packet( &packet );
- }
-
- return true;
- }
- }
-
- return false;
-}
-
-void KaraokeVideoFFMpeg::Render()
-{
- // Just in case
- if ( !m_texture )
- return;
-
- // Get the current song timing in ms.
- // This will only fit songs up to 71,000 hours, so if you got a larger one, change to int64
- unsigned int songTime = (unsigned int) MathUtils::round_int( g_application.GetTime() * 1000 );
- unsigned int videoTime = m_timeBase + songTime;
-
- // Which frame should we show?
- int frame_for_time = ((videoTime * m_fps_num) / m_fps_den) / 1000;
-
- if ( frame_for_time == 0 )
- frame_for_time = 1;
-
- // Loop if we know how many frames we have total
- if ( m_maxFrame > 0 )
- frame_for_time %= m_maxFrame;
-
- // Read a new frame if necessary
- while ( m_currentFrameNumber < frame_for_time )
- {
- if ( readFrame( frame_for_time ) )
- {
- // We have read a new frame.
- m_lastTimeFrame = videoTime;
- break;
- }
-
- // End of video; restart
- m_maxFrame = m_currentFrameNumber - 1;
- m_currentFrameNumber = 0;
- m_timeBase = 0;
-
- // Reset the frame
- frame_for_time = 0;
-
- if ( m_dllAvFormat.av_seek_frame( pFormatCtx, videoStream, 0, 0 ) < 0 )
- return;
-
- m_dllAvCodec.avcodec_flush_buffers( pCodecCtx );
- }
-
- // We got a frame. Draw it.
- m_texture->Update( m_videoWidth, m_videoHeight, m_videoWidth * 4, XB_FMT_A8R8G8B8, pFrameRGB->data[0], false );
- CRect vertCoords((float) m_displayLeft, (float) m_displayTop, (float) m_displayRight, (float) m_displayBottom );
- CGUITexture::DrawQuad(vertCoords, 0xffffffff, m_texture );
-}
-
-bool KaraokeVideoFFMpeg::Start( const CStdString& filename )
-{
- if ( !m_dllAvFormat.IsLoaded() )
- {
- if ( !Init() )
- return false;
- }
-
- if ( !filename.empty() )
- {
- if ( !openVideoFile( filename ) )
- return false;
-
- m_lastTimeFrame = 0;
- }
- else
- {
- // m_currentFrameNumber is set to 0 in openVideoFile
- unsigned int curframe = m_currentFrameNumber;
-
- if ( !openVideoFile( g_advancedSettings.m_karaokeDefaultBackgroundFilePath ) )
- return false;
-
- if ( curframe > 0 && m_dllAvFormat.av_seek_frame( pFormatCtx, videoStream, curframe, 0 ) >= 0 )
- {
- m_dllAvCodec.avcodec_flush_buffers( pCodecCtx );
- m_currentFrameNumber = curframe;
- }
- else
- m_lastTimeFrame = 0;
- }
-
- m_timeBase = m_lastTimeFrame;
- m_lastTimeFrame = 0;
-
- // Allocate the texture
- m_texture = new CTexture( m_videoWidth, m_videoHeight, XB_FMT_A8R8G8B8 );
-
- if ( !m_texture )
- {
- CLog::Log( LOGERROR, "Karaoke Video Background: Could not allocate texture" );
- return false;
- }
-
- return true;
-}
-
-void KaraokeVideoFFMpeg::Stop()
-{
- if ( !m_dllAvFormat.IsLoaded() )
- {
- CLog::Log( LOGERROR, "KaraokeVideoFFMpeg::Start: internal error, called on unitinialized object" );
- return;
- }
-
- delete m_texture;
- m_texture = 0;
-
- if ( !PERSISTENT_OBJECT )
- Dismiss();
-}
diff --git a/xbmc/music/karaoke/karaokevideobackground.h b/xbmc/music/karaoke/karaokevideobackground.h
deleted file mode 100644
index bc8f8dbb3b..0000000000
--- a/xbmc/music/karaoke/karaokevideobackground.h
+++ /dev/null
@@ -1,103 +0,0 @@
-#ifndef KARAOKEVIDEOFFMPEG_H
-#define KARAOKEVIDEOFFMPEG_H
-
-/*
- * Copyright (C) 2005-2010 Team XBMC
- * http://www.xbmc.org
- *
- * This Program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2, or (at your option)
- * any later version.
- *
- * This Program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with XBMC; see the file COPYING. If not, write to
- * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
- * http://www.gnu.org/copyleft/gpl.html
- *
- */
-
-#include "DllAvFormat.h"
-#include "DllAvCodec.h"
-#include "DllAvUtil.h"
-#include "DllSwScale.h"
-
-class CBaseTexture;
-
-// C++ Interface: karaokevideoffmpeg
-// Contact: oldnemesis
-//
-// FFMpeg-based background video decoder for Karaoke background.
-// We are not using DVDPlayer for this because:
-// 1. DVDPlayer was not designed to run at the same time when music is being played and other things (like lyrics) rendered.
-// While this setup works from time to time, it constantly gets broken. Some modes, like VDPAU, lead to crash right away.
-//
-// 2. We do not need to decode audio, hence we don't have to use extra CPU.
-//
-// 3. We do not really care about frame rate. Jerky video is fine for the background. Lyrics sync is much more important.
-//
-class KaraokeVideoFFMpeg
-{
-public:
- KaraokeVideoFFMpeg();
- ~KaraokeVideoFFMpeg();
-
- // Start playing the video. It is called each time a new song is being played. Should continue playing existing
- // video from the position it was paused. If it returns false, the video rendering is disabled and
- // KaraokeVideoFFMpeg object is deleted. Must write the reason for failure into the log file.
- bool Start( const CStdString& filename = "" );
-
- // Render the current frame into the screen. This function also must handle video loops and
- // switching to the next video when necessary. Hence it shouldn't take too long.
- void Render();
-
- // Stops playing the video. It is called once the song is finished and the Render() is not going to be called anymore.
- // The object, however, is kept and should keep its state because it must continue on next Start() call.
- void Stop();
-
-private:
- // Initialize the object. This function is called only once when the object is created or after it has been dismissed.
- // If it returns false, the video rendering is disabled and KaraokeVideoFFMpeg object is deleted
- bool Init();
-
- // Dismisses the object, freeing all the memory and unloading the libraries. The object must be inited before using again.
- void Dismiss();
-
- bool openVideoFile( const CStdString& filename );
- void closeVideoFile();
- bool readFrame( int frame );
-
- // FFMpeg objects
- DllAvFormat m_dllAvFormat;
- DllAvCodec m_dllAvCodec;
- DllAvUtil m_dllAvUtil;
- DllSwScale m_dllSwScale;
-
- CStdString m_curVideoFile;
- unsigned int skipFrames;
- AVFormatContext *pFormatCtx;
- int videoStream;
- AVCodecContext *pCodecCtx;
- AVCodec *pCodec;
- AVFrame *pFrame;
- AVPicture *pFrameRGB;
- int m_videoWidth; // shown video width, i.e. upscaled or downscaled as necessary
- int m_videoHeight; // shown video height, i.e. upscaled or downscaled as necessary
- int m_displayLeft, m_displayRight, m_displayTop, m_displayBottom; // Video as shown at the display
-
- int m_maxFrame;
- int m_fps_den;
- int m_fps_num;
- int m_currentFrameNumber;
- unsigned int m_lastTimeFrame;
- unsigned int m_timeBase;
-
- CBaseTexture *m_texture;
-};
-
-#endif