Commit 32912a97 authored by Jean-Paul Saman's avatar Jean-Paul Saman

Merge branch 'master' of git.m2x.eu:vlc into debian

parents 0c432a22 4cb95a42
......@@ -105,7 +105,8 @@ AS_IF([test "${enable_static_modules}" = yes], [
enable_shared="no"
enable_static="yes"
VLC_DEFAULT_PLUGIN_TYPE="builtin"
echo "*** WARNING: Building modules as static. VLC will not work."
AS_IF([test "${enable_vlc}" != "no"],
[AC_MSG_WARN([Building modules as static. VLC will not work.])])
], [
VLC_DEFAULT_PLUGIN_TYPE="plugin"
])
......
......@@ -486,8 +486,20 @@ VLC_PUBLIC_API void *libvlc_media_get_user_data( libvlc_media_t *p_md );
/**
* Get media descriptor's elementary streams description
*
* Note, you need to call libvlc_media_parse() before calling this function.
* Not doing this will result in an empty array.
* Note, you need to play the media _one_ time with --sout="#description"
* Not doing this will result in an empty array, and doing it more than once
* will duplicate the entries in the array each time. Something like this:
*
* @begincode
* libvlc_media_player_t *player = libvlc_media_player_new_from_media(media);
* libvlc_media_add_option_flag(media, "sout=#description");
* libvlc_media_player_play(player);
* // ... wait until playing
* libvlc_media_player_release(player);
* @endcode
*
* This is very likely to change in next release, and be done at the parsing
* phase.
*
* \param p_md media descriptor object
* \param tracks address to store an allocated array of Elementary Streams
......
......@@ -60,7 +60,6 @@ typedef struct libvlc_log_iterator_t libvlc_log_iterator_t;
typedef struct libvlc_log_message_t
{
unsigned sizeof_msg; /* sizeof() of message structure, must be filled in by user */
int i_severity; /* 0=INFO, 1=ERR, 2=WARN, 3=DBG */
const char *psz_type; /* module type */
const char *psz_name; /* module name */
......
......@@ -267,6 +267,13 @@ VLC_EXPORT( char *, vlc_sdp_Start, ( vlc_object_t *obj, const char *cfgpref, con
VLC_EXPORT( char *, sdp_AddMedia, (char **sdp, const char *type, const char *protocol, int dport, unsigned pt, bool bw_indep, unsigned bw, const char *ptname, unsigned clockrate, unsigned channels, const char *fmtp) );
VLC_EXPORT( char *, sdp_AddAttribute, (char **sdp, const char *name, const char *fmt, ...) LIBVLC_FORMAT( 3, 4 ) );
/** Description module */
typedef struct sout_description_data_t
{
int i_es;
es_format_t **es;
vlc_sem_t *sem;
} sout_description_data_t;
#ifdef __cplusplus
}
......
......@@ -164,7 +164,7 @@ typedef struct
DWORD writer;
} vlc_rwlock_t;
typedef DWORD vlc_threadvar_t;
typedef struct vlc_threadvar *vlc_threadvar_t;
typedef struct vlc_timer *vlc_timer_t;
#endif
......
......@@ -96,22 +96,22 @@ vlc_module_begin ()
set_category( CAT_INPUT )
set_subcategory( SUBCAT_INPUT_ACCESS )
add_integer( "decklink-card-index", 0, NULL,
add_integer( "decklink-card-index", 0,
CARD_INDEX_TEXT, CARD_INDEX_LONGTEXT, true )
add_string( "decklink-mode", "pal ", NULL,
add_string( "decklink-mode", "pal ",
MODE_TEXT, MODE_LONGTEXT, true )
add_integer( "decklink-caching", DEFAULT_PTS_DELAY / 1000, NULL,
add_integer( "decklink-caching", DEFAULT_PTS_DELAY / 1000,
CACHING_TEXT, CACHING_LONGTEXT, true )
add_string( "decklink-audio-connection", 0, NULL,
add_string( "decklink-audio-connection", 0,
AUDIO_CONNECTION_TEXT, AUDIO_CONNECTION_LONGTEXT, true )
add_integer( "decklink-audio-rate", 48000, NULL,
add_integer( "decklink-audio-rate", 48000,
RATE_TEXT, RATE_LONGTEXT, true )
add_integer( "decklink-audio-channels", 2, NULL,
add_integer( "decklink-audio-channels", 2,
CHANNELS_TEXT, CHANNELS_LONGTEXT, true )
add_string( "decklink-video-connection", 0, NULL,
add_string( "decklink-video-connection", 0,
VIDEO_CONNECTION_TEXT, VIDEO_CONNECTION_LONGTEXT, true )
change_string_list( ppsz_videoconns, ppsz_videoconns_text, 0 )
add_string( "decklink-aspect-ratio", NULL, NULL,
add_string( "decklink-aspect-ratio", NULL,
ASPECT_RATIO_TEXT, ASPECT_RATIO_LONGTEXT, true )
add_shortcut( "decklink" )
......
......@@ -304,7 +304,7 @@ static block_t* GrabAudio( demux_t *p_demux )
if( !p_block )
{
msg_Warn( p_demux, "cannot get block" );
return 0;
return NULL;
}
p_sys->p_block = p_block;
......@@ -312,10 +312,10 @@ static block_t* GrabAudio( demux_t *p_demux )
i_read = read( p_sys->i_fd, p_block->p_buffer,
p_sys->i_max_frame_size );
if( i_read <= 0 ) return 0;
if( i_read <= 0 ) return NULL;
p_block->i_buffer = i_read;
p_sys->p_block = 0;
p_sys->p_block = NULL;
/* Correct the date because of kernel buffering */
i_correct = i_read;
......
......@@ -67,8 +67,8 @@ struct intf_sys_t
#define NONE 0
#define GESTURE( a, b, c, d ) (a | ( b << 4 ) | ( c << 8 ) | ( d << 12 ))
int Open ( vlc_object_t * );
void Close ( vlc_object_t * );
static int Open ( vlc_object_t * );
static void Close ( vlc_object_t * );
static int MouseEvent ( vlc_object_t *, char const *,
vlc_value_t, vlc_value_t, void * );
......@@ -114,7 +114,7 @@ vlc_module_end ()
/*****************************************************************************
* OpenIntf: initialize interface
*****************************************************************************/
int Open ( vlc_object_t *p_this )
static int Open ( vlc_object_t *p_this )
{
intf_thread_t *p_intf = (intf_thread_t *)p_this;
......@@ -159,7 +159,7 @@ static int gesture( int i_pattern, int i_num )
/*****************************************************************************
* CloseIntf: destroy dummy interface
*****************************************************************************/
void Close ( vlc_object_t *p_this )
static void Close ( vlc_object_t *p_this )
{
intf_thread_t *p_intf = (intf_thread_t *)p_this;
......
......@@ -28,6 +28,7 @@
# include "config.h"
#endif
#include "qt4.hpp"
#include "components/interface_widgets.hpp"
#include "dialogs_provider.hpp"
#include "util/customwidgets.hpp" // qtEventToVLCKey, QVLCStackedWidget
......@@ -211,7 +212,7 @@ void BackgroundWidget::updateArt( const QString& url )
}
else
{ /* Xmas joke */
if( QDate::currentDate().dayOfYear() >= 354 )
if( QDate::currentDate().dayOfYear() >= QT_CHRISTMAS_TROLL_DAY )
pixmapUrl = QString( ":/logo/vlc128-christmas.png" );
else
pixmapUrl = QString( ":/logo/vlc128.png" );
......
......@@ -26,6 +26,7 @@
# include "config.h"
#endif
#include "qt4.hpp"
#include "dialogs/help.hpp"
#include "util/qt_dirs.hpp"
......@@ -101,7 +102,7 @@ AboutDialog::AboutDialog( intf_thread_t *_p_intf)
ui.introduction->setText(
qtr( "VLC media player" ) + qfu( " " VERSION_MESSAGE ) );
if( QDate::currentDate().dayOfYear() >= 354 )
if( QDate::currentDate().dayOfYear() >= QT_CHRISTMAS_TROLL_DAY )
ui.iconVLC->setPixmap( QPixmap( ":/logo/vlc128-christmas.png" ) );
else
ui.iconVLC->setPixmap( QPixmap( ":/logo/vlc128.png" ) );
......
......@@ -935,7 +935,7 @@ void MainInterface::showBuffering( float f_cache )
void MainInterface::createSystray()
{
QIcon iconVLC;
if( QDate::currentDate().dayOfYear() >= 354 )
if( QDate::currentDate().dayOfYear() >= QT_CHRISTMAS_TROLL_DAY )
iconVLC = QIcon( ":/logo/vlc128-christmas.png" );
else
iconVLC = QIcon( ":/logo/vlc128.png" );
......
......@@ -446,7 +446,7 @@ static void *Thread( void *obj )
/* Icon setting, Mac uses icon from .icns */
#ifndef Q_WS_MAC
if( QDate::currentDate().dayOfYear() >= 352 ) /* One Week before Xmas */
if( QDate::currentDate().dayOfYear() >= QT_CHRISTMAS_TROLL_DAY )
app.setWindowIcon( QIcon(vlc_christmas_xpm) );
else
app.setWindowIcon( QIcon(vlc_xpm) );
......
......@@ -129,4 +129,12 @@ static inline QString QVLCUserDir( vlc_userdir_t type )
return res;
}
/* After this day of the year, the usual VLC cone is replaced by another cone
* wearing a Santa hat.
* Warning: can panic users (virus changed my icons!!), and cause religious
* trolls (VLC is a supporter of catholicism!!)
* Note, this icon doesn't represent an endorsment of Coca-Cola company
*/
#define QT_CHRISTMAS_TROLL_DAY 354
#endif
......@@ -132,6 +132,9 @@ void CtrlButton::draw( OSGraphics &rImage, int xDest, int yDest, int w, int h )
void CtrlButton::setImage( AnimBitmap *pImg )
{
if( pImg == m_pImg )
return;
AnimBitmap *pOldImg = m_pImg;
m_pImg = pImg;
......
......@@ -159,6 +159,9 @@ void CtrlCheckbox::draw( OSGraphics &rImage, int xDest, int yDest, int w, int h
void CtrlCheckbox::setImage( AnimBitmap *pImg )
{
if( pImg == m_pImgCurrent )
return;
AnimBitmap *pOldImg = m_pImgCurrent;
m_pImgCurrent = pImg;
......
......@@ -598,10 +598,12 @@ void Builder::addImage( const BuilderData::Image &rData )
// Compute the position of the control
const GenericRect *pRect;
int width = (rData.m_width > 0) ? rData.m_width : pBmp->getWidth();
int height = (rData.m_height > 0) ? rData.m_height : pBmp->getHeight();
GET_BOX( pRect, rData.m_panelId , pLayout);
const Position pos = makePosition( rData.m_leftTop, rData.m_rightBottom,
rData.m_xPos, rData.m_yPos,
pBmp->getWidth(), pBmp->getHeight(),
width, height,
*pRect, rData.m_xKeepRatio,
rData.m_yKeepRatio );
......
......@@ -6,12 +6,12 @@ Font id:string fontFile:string size:int
PopupMenu id:string
MenuItem label:string action:string pos:int popupId:string
MenuSeparator pos:int popupId:string
Window id:string xPos:int yPos:int visible:bool dragDrop:bool playOnDrop:bool
Window id:string xPos:int yPos:int position:string xOffset:string yOffset:string xMargin:string yMargin:string visible:bool dragDrop:bool playOnDrop:bool
Layout id:string width:int height:int minWidth:int maxWidth:int minHeight:int maxHeight:int windowId:string
Anchor xPos:int yPos:int leftTop:string range:int priority:int points:string layoutId:string
Button id:string xPos:int yPos:int leftTop:string rightBottom:string xKeepRatio:bool yKeepRatio:bool visible:string upId:string downId:string overId:string actionId:string tooltip:string help:string layer:int windowId:string layoutId:string panelId:string
Checkbox id:string xPos:int yPos:int leftTop:string rightBottom:string xKeepRatio:bool yKeepRatio:bool visible:string up1Id:string down1Id:string over1Id:string up2Id:string down2Id:string over2Id:string state:string action1:string action2:string tooltip1:string tooltip2:string help:string layer:int windowId:string layoutId:string panelId:string
Image id:string xPos:int yPos:int leftTop:string rightBottom:string xKeepRatio:bool yKeepRatio:bool visible:string bmpId:string actionId:string action2Id:string resize:string help:string art:bool layer:int windowId:string layoutId:string panelId:string
Image id:string xPos:int yPos:int width:int height:int leftTop:string rightBottom:string xKeepRatio:bool yKeepRatio:bool visible:string bmpId:string actionId:string action2Id:string resize:string help:string art:bool layer:int windowId:string layoutId:string panelId:string
IniFile id:string file:string
Panel id:string xPos:int yPos:int leftTop:string rightBottom:string xKeepRatio:bool yKeepRatio:bool width:int height:int layer:int windowId:string layoutId:string panelId:string
Text id:string xPos:int yPos:int visible:string fontId:string text:string width:int leftTop:string rightBottom:string xKeepRatio:bool yKeepRatio:bool color:uint32_t scrolling:string alignment:string help:string layer:int windowId:string layoutId:string panelId:string
......
......@@ -154,12 +154,17 @@ m_pos( pos ), m_popupId( popupId ) {}
/// Type definition
struct Window
{
Window( const string & id, int xPos, int yPos, bool visible, bool dragDrop, bool playOnDrop ):
m_id( id ), m_xPos( xPos ), m_yPos( yPos ), m_visible( visible ), m_dragDrop( dragDrop ), m_playOnDrop( playOnDrop ) {}
Window( const string & id, int xPos, int yPos, const string & position, const string & xOffset, const string & yOffset, const string & xMargin, const string & yMargin, bool visible, bool dragDrop, bool playOnDrop ):
m_id( id ), m_xPos( xPos ), m_yPos( yPos ), m_position( position ), m_xOffset( xOffset ), m_yOffset( yOffset ), m_xMargin( xMargin ), m_yMargin( yMargin ), m_visible( visible ), m_dragDrop( dragDrop ), m_playOnDrop( playOnDrop ) {}
string m_id;
int m_xPos;
int m_yPos;
string m_position;
string m_xOffset;
string m_yOffset;
string m_xMargin;
string m_yMargin;
bool m_visible;
bool m_dragDrop;
bool m_playOnDrop;
......@@ -267,12 +272,14 @@ m_id( id ), m_xPos( xPos ), m_yPos( yPos ), m_leftTop( leftTop ), m_rightBottom(
/// Type definition
struct Image
{
Image( const string & id, int xPos, int yPos, const string & leftTop, const string & rightBottom, bool xKeepRatio, bool yKeepRatio, const string & visible, const string & bmpId, const string & actionId, const string & action2Id, const string & resize, const string & help, bool art, int layer, const string & windowId, const string & layoutId, const string & panelId ):
m_id( id ), m_xPos( xPos ), m_yPos( yPos ), m_leftTop( leftTop ), m_rightBottom( rightBottom ), m_xKeepRatio( xKeepRatio ), m_yKeepRatio( yKeepRatio ), m_visible( visible ), m_bmpId( bmpId ), m_actionId( actionId ), m_action2Id( action2Id ), m_resize( resize ), m_help( help ), m_art( art ), m_layer( layer ), m_windowId( windowId ), m_layoutId( layoutId ), m_panelId( panelId ) {}
Image( const string & id, int xPos, int yPos, int width, int height, const string & leftTop, const string & rightBottom, bool xKeepRatio, bool yKeepRatio, const string & visible, const string & bmpId, const string & actionId, const string & action2Id, const string & resize, const string & help, bool art, int layer, const string & windowId, const string & layoutId, const string & panelId ):
m_id( id ), m_xPos( xPos ), m_yPos( yPos ), m_width( width ), m_height( height ), m_leftTop( leftTop ), m_rightBottom( rightBottom ), m_xKeepRatio( xKeepRatio ), m_yKeepRatio( yKeepRatio ), m_visible( visible ), m_bmpId( bmpId ), m_actionId( actionId ), m_action2Id( action2Id ), m_resize( resize ), m_help( help ), m_art( art ), m_layer( layer ), m_windowId( windowId ), m_layoutId( layoutId ), m_panelId( panelId ) {}
string m_id;
int m_xPos;
int m_yPos;
int m_width;
int m_height;
string m_leftTop;
string m_rightBottom;
bool m_xKeepRatio;
......@@ -283,7 +290,7 @@ m_id( id ), m_xPos( xPos ), m_yPos( yPos ), m_leftTop( leftTop ), m_rightBottom(
string m_action2Id;
string m_resize;
string m_help;
bool m_art;
bool m_art;
int m_layer;
string m_windowId;
string m_layoutId;
......
This diff is collapsed.
......@@ -33,6 +33,16 @@
class SkinParser: public XMLParser
{
public:
enum {
POS_UNDEF = 0,
POS_CENTER = 1,
POS_LEFT = 2,
POS_RIGHT = 4,
POS_TOP = 8,
POS_BOTTOM = 16,
};
SkinParser( intf_thread_t *pIntf, const string &rFileName,
const string &rPath, bool useDTD = true,
BuilderData *pData = NULL );
......@@ -88,6 +98,19 @@ private:
/// Check if the id is unique, and if not generate a new one
const string uniqueId( const string &id );
/// Management of relative positions
const int getRefWidth( bool toScreen );
const int getRefHeight( bool toScreen );
const int getDimension( string value, int refDimension );
const int getPosition( string value );
void updateWindowPos( int width, int height );
void convertPosition( string position,
string xOffset, string yOffset,
string xMargin, string yMargin,
int width, int height, int refWidth, int refHeight,
int* p_x, int* p_y );
/// Helper for handleBeginElement: Provide default attribute if missing.
static void DefaultAttr( AttrList_t &attr, const char *a, const char *b )
{
......
......@@ -236,7 +236,7 @@ void GenericLayout::refreshRect( int x, int y, int width, int height )
// first apply new shape to the window
pWindow->updateShape();
pWindow->refresh( x, y, width, height );
pWindow->invalidateRect( x, y, width, height );
}
}
......
......@@ -92,27 +92,30 @@ void GenericWindow::move( int left, int top )
m_left = left;
m_top = top;
m_pOsWindow->moveResize( left, top, m_width, m_height );
if( m_pOsWindow && isVisible() )
m_pOsWindow->moveResize( left, top, m_width, m_height );
}
void GenericWindow::resize( int width, int height )
{
// don't try when value is 0 (may crash)
if( !width || ! height )
if( !width || !height )
return;
// Update the window size
m_width = width;
m_height = height;
m_pOsWindow->moveResize( m_left, m_top, width, height );
if( m_pOsWindow && isVisible() )
m_pOsWindow->moveResize( m_left, m_top, width, height );
}
void GenericWindow::raise() const
{
m_pOsWindow->raise();
if( m_pOsWindow )
m_pOsWindow->raise();
}
......@@ -124,7 +127,8 @@ void GenericWindow::setOpacity( uint8_t value )
void GenericWindow::toggleOnTop( bool onTop ) const
{
m_pOsWindow->toggleOnTop( onTop );
if( m_pOsWindow )
m_pOsWindow->toggleOnTop( onTop );
}
......@@ -149,6 +153,7 @@ void GenericWindow::innerShow()
if( m_pOsWindow )
{
m_pOsWindow->show();
m_pOsWindow->moveResize( m_left, m_top, m_width, m_height );
}
}
......@@ -179,3 +184,18 @@ void GenericWindow::setParent( GenericWindow* pParent, int x, int y, int w, int
void* handle = pParent ? pParent->getOSHandle() : NULL;
m_pOsWindow->reparent( handle, m_left, m_top, m_width, m_height );
}
void GenericWindow::invalidateRect( int left, int top, int width, int height )
{
if( m_pOsWindow )
{
// tell the OS we invalidate a window client area
bool b_supported =
m_pOsWindow->invalidateRect( left, top, width, height );
// if not supported, directly refresh the area
if( !b_supported )
refresh( left, top, width, height );
}
}
......@@ -80,6 +80,9 @@ public:
/// Refresh an area of the window
virtual void refresh( int left, int top, int width, int height ) { }
/// Invalidate an area of the window
virtual void invalidateRect( int left, int top, int width, int height );
/// Get the coordinates of the window
int getLeft() const { return m_left; }
int getTop() const { return m_top; }
......@@ -131,6 +134,9 @@ protected:
/// Actually hide the window
virtual void innerHide();
///
bool isVisible() const { return m_pVarVisible->get(); }
private:
/// Window position and size
int m_left, m_top, m_width, m_height;
......
......@@ -62,6 +62,9 @@ public:
/// reparent the window
virtual void reparent( void* OSHandle, int x, int y, int w, int h ) = 0;
/// updateWindow (tell the OS we need to update the window)
virtual bool invalidateRect( int x, int y, int w, int h ) const = 0;
protected:
OSWindow( intf_thread_t *pIntf ): SkinObject( pIntf ) { }
};
......
......@@ -324,9 +324,6 @@ void TopWindow::innerShow()
// Show the window
GenericWindow::innerShow();
// place the top window on the screen (after show!)
move( getLeft(), getTop() );
}
......
......@@ -69,6 +69,8 @@ public:
}
virtual ~VoutMainWindow() { }
#ifdef WIN32
virtual void processEvent( EvtKey &rEvtKey )
{
// Only do the action when the key is down
......@@ -87,6 +89,8 @@ public:
var_SetInteger( getIntf()->p_libvlc, "key-pressed", i_vlck );
}
#endif
};
......
......@@ -33,13 +33,15 @@
WindowManager::WindowManager( intf_thread_t *pIntf ):
SkinObject( pIntf ), m_magnet( 0 ), m_direction( kNone ),
m_maximizeRect(0, 0, 50, 50),
m_pTooltip( NULL ), m_pPopup( NULL )
m_maximizeRect(0, 0, 50, 50), m_pTooltip( NULL ), m_pPopup( NULL ),
m_alpha( 255 ), m_moveAlpha( 255 ), m_OpacityEnabled( false )
{
// Create and register a variable for the "on top" status
VarManager *pVarManager = VarManager::instance( getIntf() );
m_cVarOnTop = VariablePtr( new VarBoolImpl( getIntf() ) );
pVarManager->registerVar( m_cVarOnTop, "vlc.isOnTop" );
m_OpacityEnabled = var_InheritBool( getIntf(), "skins2-transparency" );
}
......@@ -71,7 +73,7 @@ void WindowManager::startMove( TopWindow &rWindow )
m_movingWindows.clear();
buildDependSet( m_movingWindows, &rWindow );
if( var_InheritBool( getIntf(), "skins2-transparency" ) )
if( isOpacityNeeded() )
{
// Change the opacity of the moving windows
WinSet_t::const_iterator it;
......@@ -79,14 +81,6 @@ void WindowManager::startMove( TopWindow &rWindow )
{
(*it)->setOpacity( m_moveAlpha );
}
// FIXME: We need to refresh the windows, because if 2 windows overlap
// and one of them becomes transparent, the other one is not refreshed
// automatically. I don't know why... -- Ipkiss
for( it = m_allWindows.begin(); it != m_allWindows.end(); ++it )
{
(*it)->refresh( 0, 0, (*it)->getWidth(), (*it)->getHeight() );
}
}
}
......@@ -96,7 +90,7 @@ void WindowManager::stopMove()
WinSet_t::const_iterator itWin1, itWin2;
AncList_t::const_iterator itAnc1, itAnc2;
if( var_InheritBool( getIntf(), "skins2-transparency" ) )
if( isOpacityNeeded() )
{
// Restore the opacity of the moving windows
WinSet_t::const_iterator it;
......@@ -429,6 +423,15 @@ void WindowManager::showAll( bool firstTime ) const
}
void WindowManager::show( TopWindow &rWindow ) const
{
rWindow.show();
if( isOpacityNeeded() )
rWindow.setOpacity( m_alpha );
}
void WindowManager::hideAll() const
{
WinSet_t::const_iterator it;
......
......@@ -120,8 +120,7 @@ public:
void raise( TopWindow &rWindow ) const { rWindow.raise(); }
/// Show the given window
void show( TopWindow &rWindow ) const
{ rWindow.show(); rWindow.setOpacity( m_alpha); }
void show( TopWindow &rWindow ) const;
/// Hide the given window
void hide( TopWindow &rWindow ) const { rWindow.hide(); }
......@@ -163,6 +162,10 @@ public:
/// Return the active popup, or NULL if none is active
Popup * getActivePopup() const { return m_pPopup; }
/// getter to know whether opacity is needed
bool isOpacityNeeded() const
{ return (m_OpacityEnabled && (m_alpha != 255 || m_moveAlpha != 255 )); }
private:
/// Some useful typedefs for lazy people like me
typedef set<TopWindow*> WinSet_t;
......@@ -206,6 +209,8 @@ private:
int m_alpha;
/// Alpha value of the moving windows
int m_moveAlpha;
/// transparency set by user
bool m_OpacityEnabled;
/// Direction of the current resizing
Direction_t m_direction;
/// Rect of the last maximized window
......
......@@ -45,7 +45,8 @@
#define MY_WM_TRAYACTION (WM_APP + 1)
LRESULT CALLBACK Win32Proc( HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam )
LRESULT CALLBACK Win32Factory::Win32Proc( HWND hwnd, UINT uMsg,
WPARAM wParam, LPARAM lParam )
{
// Get pointer to thread info: should only work with the parent window
intf_thread_t *p_intf = (intf_thread_t *)GetWindowLongPtr( hwnd,
......@@ -58,6 +59,7 @@ LRESULT CALLBACK Win32Proc( HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam )
}
Win32Factory *pFactory = (Win32Factory*)Win32Factory::instance( p_intf );
GenericWindow *pWin = pFactory->m_windowMap[hwnd];
if( hwnd == pFactory->getParentWindow() )
{
......@@ -92,19 +94,29 @@ LRESULT CALLBACK Win32Proc( HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam )
p_intf->p_sys->p_theme->getWindowManager().raiseAll();
CmdDlgHidePopupMenu aCmdPopup( p_intf );
aCmdPopup.execute();
return 0;
}
else if( (UINT)lParam == WM_RBUTTONDOWN )
{
CmdDlgShowPopupMenu aCmdPopup( p_intf );
aCmdPopup.execute();
return 0;
}
else if( (UINT)lParam == WM_LBUTTONDBLCLK )
{
CmdRestore aCmdRestore( p_intf );
aCmdRestore.execute();
return 0;
}
}
}
else if( pWin )
{
Win32Loop* pLoop =
(Win32Loop*) OSFactory::instance( p_intf )->getOSLoop();
if( pLoop )
return pLoop->processEvent( hwnd, uMsg, wParam, lParam );
}
// If hwnd does not match any window or message not processed
return DefWindowProc( hwnd, uMsg, wParam, lParam );
......@@ -131,7 +143,7 @@ bool Win32Factory::init()
// Create window class
WNDCLASS skinWindowClass;
skinWindowClass.style = CS_DBLCLKS;
skinWindowClass.lpfnWndProc = (WNDPROC) Win32Proc;
skinWindowClass.lpfnWndProc = (WNDPROC)Win32Factory::Win32Proc;
skinWindowClass.lpszClassName = _T("SkinWindowClass");
skinWindowClass.lpszMenuName = NULL;
skinWindowClass.cbClsExtra = 0;
......@@ -325,7 +337,6 @@ OSPopup *Win32Factory::createOSPopup()
int Win32Factory::getScreenWidth() const
{
return GetSystemMetrics(SM_CXSCREEN);
}
......
......@@ -118,6 +118,10 @@ public:
HWND getParentWindow() { return m_hParentWindow; }
/// Callback function (Windows Procedure)
static LRESULT CALLBACK Win32Proc( HWND hwnd, UINT uMsg,
WPARAM wParam, LPARAM lParam );
private:
/// Handle of the instance
HINSTANCE m_hInst;
......
This diff is collapsed.
......@@ -48,6 +48,10 @@ public:
/// Exit the main loop
virtual void exit();
/// called by the window procedure callback
virtual LRESULT CALLBACK processEvent( HWND hwnd, UINT msg,
WPARAM wParam, LPARAM lParam );
private:
// Private because it is a singleton
Win32Loop( intf_thread_t *pIntf );
......
......@@ -69,8 +69,10 @@ Win32Window::Win32Window( intf_thread_t *pIntf, GenericWindow &rWindow,
m_hWnd = CreateWindowEx( WS_EX_APPWINDOW, "SkinWindowClass",
"default name", WS_POPUP | WS_CLIPCHILDREN,
0, 0, 0, 0, NULL, 0, hInst, NULL );
}
// Store with it a pointer to the interface thread
SetWindowLongPtr( m_hWnd, GWLP_USERDATA, (LONG_PTR)getIntf() );
}
else
{
// top-level window (owned by the root window)
......@@ -78,6 +80,9 @@ Win32Window::Win32Window( intf_thread_t *pIntf, GenericWindow &rWindow,
m_hWnd = CreateWindowEx( 0, "SkinWindowClass",
"default name", WS_POPUP | WS_CLIPCHILDREN,
0, 0, 0, 0, hWnd_owner, 0, hInst, NULL );
// Store with it a pointer to the interface thread
SetWindowLongPtr( m_hWnd, GWLP_USERDATA, (LONG_PTR)getIntf() );
}
if( !m_hWnd )
......@@ -130,7 +135,17 @@ void Win32Window::reparent( void* OSHandle, int x, int y, int w, int h )
}
SetParent( m_hWnd, (HWND)OSHandle );
MoveWindow( m_hWnd, x, y, w, h, true );
MoveWindow( m_hWnd, x, y, w, h, TRUE );
}
bool Win32Window::invalidateRect( int x, int y, int w, int h) const
{
RECT rect = { x, y, x + w , y + h };
InvalidateRect( m_hWnd, &rect, FALSE );
UpdateWindow( m_hWnd );
return true;
}
......@@ -160,7 +175,7 @@ void Win32Window::hide() const
void Win32Window::moveResize( int left, int top, int width, int height ) const
{
MoveWindow( m_hWnd, left, top, width, height, true );
MoveWindow( m_hWnd, left, top, width, height, TRUE );
}
......@@ -175,44 +190,17 @@ void Win32Window::setOpacity( uint8_t value ) const
{
Win32Factory *pFactory = (Win32Factory*)Win32Factory::instance( getIntf() );
if( value == 255 )
if( !m_isLayered )
{
// If the window is opaque, we remove the WS_EX_LAYERED attribute
// which slows down resizing for nothing
if( m_isLayered )
{
SetWindowLongPtr( m_hWnd, GWL_EXSTYLE,
GetWindowLongPtr( m_hWnd, GWL_EXSTYLE ) & ~WS_EX_LAYERED );
// add the WS_EX_LAYERED attribute.
SetWindowLongPtr( m_hWnd, GWL_EXSTYLE,
GetWindowLongPtr( m_hWnd, GWL_EXSTYLE ) | WS_EX_LAYERED );
// Redraw the window, otherwise we may end up with a grey rectangle
// for some strange reason
RedrawWindow(m_hWnd, NULL, NULL,
RDW_ERASE | RDW_INVALIDATE | RDW_FRAME | RDW_ALLCHILDREN);
m_isLayered = false;
}
m_isLayered = true;
}
else
{
if( ! m_isLayered )
{
// (Re)Add the WS_EX_LAYERED attribute.
// Resizing will be very slow, now :)
SetWindowLongPtr( m_hWnd, GWL_EXSTYLE,
GetWindowLongPtr( m_hWnd, GWL_EXSTYLE ) | WS_EX_LAYERED );
// Redraw the window, otherwise we may end up with a grey
// rectangle for some strange reason
RedrawWindow(m_hWnd, NULL, NULL,
RDW_ERASE | RDW_INVALIDATE | RDW_FRAME | RDW_ALLCHILDREN);
m_isLayered = true;
}
// Change the opacity
SetLayeredWindowAttributes(
m_hWnd, 0, value, LWA_ALPHA|LWA_COLORKEY );
}
// Change the opacity
SetLayeredWindowAttributes( m_hWnd, 0, value, LWA_ALPHA );
}
......
......@@ -68,6 +68,9 @@ public:
/// reparent the window
void reparent( void* OSHandle, int x, int y, int w, int h );
/// invalidate a window surface
bool invalidateRect( int x, int y, int w, int h ) const;
private:
/// Window handle
HWND m_hWnd;
......
......@@ -349,4 +349,11 @@ void X11Window::toggleOnTop( bool onTop ) const
}
}
bool X11Window::invalidateRect( int x, int y, int w, int h ) const
{
XClearArea( XDISPLAY, m_wnd, x, y, w, h, True );
return true;
}
#endif
......@@ -76,6 +76,9 @@ public:
/// reparent the window
void reparent( void* OSHandle, int x, int y, int w, int h );
/// invalidate a window surface
bool invalidateRect( int x, int y, int w, int h ) const;
void setFullscreen() const;
private:
......
This diff is collapsed.
......@@ -59,6 +59,7 @@ vlc_module_end ()
struct sout_stream_sys_t
{
sout_description_data_t *data;
mtime_t i_stream_start;
};
......@@ -79,6 +80,14 @@ static int Open( vlc_object_t *p_this )
p_stream->pf_send = Send;
p_sys = p_stream->p_sys = malloc(sizeof(sout_stream_sys_t));
p_sys->data = var_InheritAddress(p_stream, "sout-description-data");
if (p_sys->data == NULL)
{
msg_Err(p_stream, "Missing data: the description stream output is "
"not meant to be used without special setup from the core");
free(p_sys);
return VLC_EGENERIC;
}
p_sys->i_stream_start = 0;
return VLC_SUCCESS;
......@@ -102,22 +111,13 @@ static sout_stream_id_t *Add( sout_stream_t *p_stream, es_format_t *p_fmt )
sout_stream_sys_t *p_sys = p_stream->p_sys;
sout_stream_id_t *id;
es_format_t *p_fmt_copy;
input_item_t *p_item;
input_thread_t *p_input;
msg_Dbg( p_stream, "Adding a stream" );
p_input = vlc_object_find( p_stream, VLC_OBJECT_INPUT, FIND_PARENT );
assert( p_input );
p_item = input_GetItem(p_input);
p_fmt_copy = malloc(sizeof(es_format_t));
es_format_Copy( p_fmt_copy, p_fmt );
vlc_mutex_lock( &p_item->lock );
TAB_APPEND( p_item->i_es, p_item->es, p_fmt_copy );
vlc_mutex_unlock( &p_item->lock );
vlc_object_release( p_input );
TAB_APPEND( p_sys->data->i_es, p_sys->data->es, p_fmt_copy );
if( p_sys->i_stream_start <= 0 )
p_sys->i_stream_start = mdate();
......@@ -143,16 +143,7 @@ static int Send( sout_stream_t *p_stream, sout_stream_id_t *id,
block_ChainRelease( p_buffer );
if( p_sys->i_stream_start + 1500000 < mdate() )
{
input_thread_t *p_input;
p_input = vlc_object_find( p_stream, VLC_OBJECT_INPUT, FIND_PARENT );
if( p_input )
{
input_Stop( p_input, true );
vlc_object_release( p_input );
}
}
vlc_sem_post(p_sys->data->sem);
return VLC_SUCCESS;
}
<!DOCTYPE Theme PUBLIC "-//VideoLAN//DTD VLC Skins V2.0//EN" "skin.dtd">
<Theme version="2.0">
<Theme version="2.0" alpha="255" movealpha="200">
<ThemeInfo name="subX" author="Martin Poehlmann" email="" webpage="http://www.skinconsortium.com"/>
<!-- Created using the VLC Skin Editor 0.8.0.dev (http://www.videolan.org/vlc/skineditor.html)-->
......@@ -176,7 +176,7 @@
<SubBitmap id="item" x="16" y="0" height="8" width="8"/>
</Bitmap>
<Window id="main">
<Window id="main" position="Center">
<Layout id="normal" width="500" height="350" minwidth="500" maxwidth="99999" minheight="126" maxheight="99999">
<Panel id="main.normal.titlebar" width="0" height="24" rightbottom="righttop">
<Image id="main.normal.titlebar.left" image="main.png.titlebar.left" action="move" action2="main.maximize()"/>
......@@ -194,7 +194,7 @@
<Button up="sysbuttons.png.aot1.normal" down="sysbuttons.png.aot1.down" over="sysbuttons.png.aot1.hover" action="vlc.onTop()" id="main.normal.titlebar.aot1" x="26" y="3" visible="vlc.isOnTop" tooltiptext="Disable Always On Top"/>
</Panel>
<Panel id="main.normal.component" y="24" width="0" height="0" rightbottom="rightbottom">
<Image id="main.normal.component.background" image="main.png.background" resize="scale" rightbottom="rightbottom" />
<Image id="main.normal.component.background" image="main.png.background" resize="scale" rightbottom="rightbottom"/>
<Image id="main.normal.component.art" image="main.png.background" resize="scale2" rightbottom="rightbottom" art="true"/>
<Video id="main.normal.component.video" width="500" height="224" rightbottom="rightbottom" visible="vlc.hasVout"/>
</Panel>
......@@ -247,7 +247,7 @@
</Panel>
</Layout>
</Window>
<Window id="eqwin" visible="false">
<Window id="eqwin" visible="false" position="Center">
<Layout id="eqwin-main" width="330" height="171" minwidth="330" maxwidth="330" minheight="171" maxheight="171">
<Image id="eq.normal.eq" image="eq.png.bg" action="move"/>
<Button up="sysbuttons.png.menu.normal" down="sysbuttons.png.menu.down" over="sysbuttons.png.menu.hover" action="dialogs.popup()" id="eqwin.normal.titlebar.menu" x="6" y="3" tooltiptext="VLC Menu"/>
......@@ -267,7 +267,7 @@
<Checkbox state="equalizer.isEnabled" up1="eq.png.knob.normal" up2="eq.png.knob.normal" down1="eq.png.knob.down" down2="eq.png.knob.down" over1="eq.png.knob.hover" over2="eq.png.knob.hover" action1="equalizer.enable()" action2="equalizer.disable()" tooltiptext1="Enable Equalizer" tooltiptext2="Disable Equalizer" id="eq.onoff.lef2" x="18" y="86"/>
</Layout>
</Window>
<Window id="plwin" visible="false">
<Window id="plwin" position="Center" xoffset="5%" yoffset="5%" visible="false">
<Layout id="plwin-normal" width="500" height="350" minwidth="170" maxwidth="99999" minheight="200" maxheight="99999">
<Panel id="pl.normal.titlebar" width="0" height="24" rightbottom="righttop">
<Image id="pl.normal.titlebar.left" image="pl.png.titlebar.left" action="move"/>
......@@ -298,12 +298,12 @@
</Panel>
</Layout>
</Window>
<Window id="aboutwin" visible="false">
<Window id="aboutwin" visible="false" position="Center">
<Layout id="aboutwinwin-main" width="330" height="171" minwidth="330" maxwidth="330" minheight="171" maxheight="171">
<Image id="about.normal.eq" image="about.png" action="move" action2="aboutwin.hide()"/>
</Layout>
</Window>
<Window id="fullscreenController" x="30" y="30">
<Window id="fullscreenController" position="South" ymargin="3%">
<Layout id="plwin-fsc-normal" width="500" height="350" minwidth="170" maxwidth="99999" minheight="200" maxheight="99999">
<Panel id="fsc.pl.normal.titlebar" width="0" height="24" rightbottom="righttop">
<Image id="fsc.pl.normal.titlebar.left" image="pl.png.titlebar.left" action="move"/>
......@@ -351,7 +351,7 @@
<Checkbox state="equalizer.isEnabled" up1="eq.png.led.off" up2="eq.png.led.on" down1="none" down2="none" over1="none" over2="none" action1="equalizer.enable()" action2="equalizer.disable()" tooltiptext1="Enable Equalizer" tooltiptext2="Disable Equalizer" id="fsc.eq.onoff.lef1" x="29" y="72"/>
<Checkbox state="equalizer.isEnabled" up1="eq.png.knob.normal" up2="eq.png.knob.normal" down1="eq.png.knob.down" down2="eq.png.knob.down" over1="eq.png.knob.hover" over2="eq.png.knob.hover" action1="equalizer.enable()" action2="equalizer.disable()" tooltiptext1="Enable Equalizer" tooltiptext2="Disable Equalizer" id="fsc.eq.onoff.lef2" x="18" y="86"/>
</Layout>
<Layout id="fsc_normal" width="500" height="500" minwidth="500" maxwidth="500" minheight="500" maxheight="500">
<Layout id="fsc_normal" width="500" height="130" minwidth="500" maxwidth="500" minheight="130" maxheight="130">
<Panel id="fsc.normal.titlebar" width="0" height="24" rightbottom="righttop">
<Image id="fsc.normal.titlebar.left" image="main.png.titlebar.left" action="move"/>
<Image id="fsc.normal.titlebar.right" x="480" image="main.png.titlebar.right" action="move" lefttop="righttop" rightbottom="righttop"/>
......
......@@ -76,6 +76,11 @@
visible CDATA "true"
x CDATA "0"
y CDATA "0"
position CDATA "-1"
xoffset CDATA "0"
yoffset CDATA "0"
xmargin CDATA "0"
ymargin CDATA "0"
dragdrop CDATA "true"
playondrop CDATA "true"
>
......@@ -110,6 +115,11 @@
ykeepratio CDATA "false"
width CDATA #REQUIRED
height CDATA #REQUIRED
position CDATA "-1"
xoffset CDATA "0"
yoffset CDATA "0"
xmargin CDATA "0"
ymargin CDATA "0"
>
<!-- Anchors -->
......@@ -131,6 +141,8 @@
visible CDATA "true"
x CDATA "0"
y CDATA "0"
width CDATA "-1"
height CDATA "-1"
lefttop CDATA "lefttop"
rightbottom CDATA "lefttop"
xkeepratio CDATA "false"
......@@ -255,6 +267,11 @@
y CDATA "0"
width CDATA "0"
height CDATA "0"
position CDATA "-1"
xoffset CDATA "0"
yoffset CDATA "0"
xmargin CDATA "0"
ymargin CDATA "0"
lefttop CDATA "lefttop"
rightbottom CDATA "lefttop"
xkeepratio CDATA "false"
......@@ -276,6 +293,11 @@
y CDATA "0"
width CDATA "0"
height CDATA "0"
position CDATA "-1"
xoffset CDATA "0"
yoffset CDATA "0"
xmargin CDATA "0"
ymargin CDATA "0"
lefttop CDATA "lefttop"
rightbottom CDATA "lefttop"
xkeepratio CDATA "false"
......@@ -301,6 +323,11 @@
y CDATA "0"
width CDATA "0"
height CDATA "0"
position CDATA "-1"
xoffset CDATA "0"
yoffset CDATA "0"
xmargin CDATA "0"
ymargin CDATA "0"
lefttop CDATA "lefttop"
rightbottom CDATA "lefttop"
xkeepratio CDATA "false"
......
......@@ -5,6 +5,6 @@ Actions=open;
[Desktop Action open]
Name=Open with VLC media player
Exec=vlc cdda://
Exec=vlc cdda://%d
Icon=vlc
[Desktop Entry]
X-KDE-Solid-Predicate=[ StorageVolume.ignored == false AND OpticalDisc.availableContent & 'VideoDvd' ]
X-KDE-Solid-Predicate=[ StorageVolume.ignored == false AND OpticalDisc.availableContent == 'Data|VideoDvd' ]
Type=Service
Actions=open;
[Desktop Action open]
Name=Open with VLC media player
Exec=vlc dvd://
Exec=vlc dvd://%d
Icon=vlc
[Desktop Entry]
X-KDE-Solid-Predicate=[ StorageVolume.ignored == false AND OpticalDisc.availableContent & 'VideoCd|SuperVideoCd' ]
X-KDE-Solid-Predicate=[ StorageVolume.ignored == false AND OpticalDisc.availableContent == 'VideoCd|SuperVideoCd' ]
Type=Service
Actions=open;
[Desktop Action open]
Name=Open with VLC media player
Exec=vlc vcd://
Exec=vlc vcd://%d
Icon=vlc
......@@ -45,7 +45,6 @@
#include "es_out.h"
#include "event.h"
#include "info.h"
#include "item.h"
#include "../stream_output/stream_output.h"
......@@ -2856,8 +2855,6 @@ static void EsOutUpdateInfo( es_out_t *out, es_out_id_t *es, const es_format_t *
const es_format_t *p_fmt_es = &es->fmt;
lldiv_t div;
input_item_UpdateTracksInfo(input_GetItem(p_input), fmt);
/* Create category */
char psz_cat[128];
snprintf( psz_cat, sizeof(psz_cat),_("Stream %d"), es->i_meta_id );
......
......@@ -1050,35 +1050,3 @@ void input_item_node_PostAndDelete( input_item_node_t *p_root )
input_item_node_Delete( p_root );
}
/* Called by es_out when a new Elementary Stream is added or updated. */
void input_item_UpdateTracksInfo(input_item_t *item, const es_format_t *fmt)
{
int i;
es_format_t *fmt_copy = malloc(sizeof *fmt_copy);
if (!fmt_copy)
return;
es_format_Copy(fmt_copy, fmt);
/* XXX: we could free p_extra to save memory, we will likely not need
* the decoder specific data */
vlc_mutex_lock( &item->lock );
for( i = 0; i < item->i_es; i++ )
{
if (item->es[i]->i_id != fmt->i_id)
continue;
/* We've found the right ES, replace it */
es_format_Clean(item->es[i]);
free(item->es[i]);
item->es[i] = fmt_copy;
vlc_mutex_unlock( &item->lock );
return;
}
/* ES not found, insert it */
TAB_APPEND(item->i_es, item->es, fmt_copy);
vlc_mutex_unlock( &item->lock );
}
......@@ -27,6 +27,5 @@
#include "input_interface.h"
void input_item_SetErrorWhenReading( input_item_t *p_i, bool b_error );
void input_item_UpdateTracksInfo( input_item_t *item, const es_format_t *fmt );
#endif
......@@ -42,7 +42,7 @@ sout_instance_t *input_resource_RequestSout( input_resource_t *, sout_instance_t
aout_instance_t *input_resource_RequestAout( input_resource_t *, aout_instance_t * );
/**
* This function return the current aout if any.
* This function returns the current aout if any.
*
* You must call vlc_object_release on the value returned (if non NULL).
*/
......@@ -54,14 +54,14 @@ aout_instance_t *input_resource_HoldAout( input_resource_t *p_resource );
vout_thread_t *input_resource_RequestVout( input_resource_t *, vout_thread_t *, video_format_t *, unsigned dpb_size, bool b_recycle );
/**
* This function return one of the current vout if any.
* This function returns one of the current vout if any.
*
* You must call vlc_object_release on the value returned (if non NULL).
*/
vout_thread_t *input_resource_HoldVout( input_resource_t * );
/**
* This function return all current vouts if any.
* This function returns all current vouts if any.
*
* You must call vlc_object_release on all values returned (if non NULL).
*/
......
......@@ -70,15 +70,21 @@ static void vlm_Destructor( vlm_t *p_vlm );
static void* Manage( void * );
static int vlm_MediaVodControl( void *, vod_media_t *, const char *, int, va_list );
typedef struct preparse_data_t
{
vlc_sem_t *p_sem;
bool b_mux;
} preparse_data_t;
static int InputEventPreparse( vlc_object_t *p_this, char const *psz_cmd,
vlc_value_t oldval, vlc_value_t newval, void *p_data )
{
VLC_UNUSED(p_this); VLC_UNUSED(psz_cmd); VLC_UNUSED(oldval);
vlc_sem_t *p_sem_preparse = p_data;
preparse_data_t *p_pre = p_data;
if( newval.i_int == INPUT_EVENT_DEAD ||
newval.i_int == INPUT_EVENT_ITEM_META )
vlc_sem_post( p_sem_preparse );
( p_pre->b_mux && newval.i_int == INPUT_EVENT_ITEM_META ) )
vlc_sem_post( p_pre->p_sem );
return VLC_SUCCESS;
}
......@@ -615,28 +621,39 @@ static int vlm_OnMediaUpdate( vlm_t *p_vlm, vlm_media_sys_t *p_media )
if( asprintf( &psz_header, _("Media: %s"), p_cfg->psz_name ) == -1 )
psz_header = NULL;
sout_description_data_t data;
TAB_INIT(data.i_es, data.es);
p_input = input_Create( p_vlm->p_vod, p_media->vod.p_item, psz_header, NULL );
if( p_input )
{
vlc_sem_t sem_preparse;
vlc_sem_init( &sem_preparse, 0 );
var_AddCallback( p_input, "intf-event", InputEventPreparse, &sem_preparse );
preparse_data_t preparse = { .p_sem = &sem_preparse,
.b_mux = (p_cfg->vod.psz_mux != NULL) };
var_AddCallback( p_input, "intf-event", InputEventPreparse,
&preparse );
data.sem = &sem_preparse;
var_Create( p_input, "sout-description-data", VLC_VAR_ADDRESS );
var_SetAddress( p_input, "sout-description-data", &data );
if( !input_Start( p_input ) )
{
while( !p_input->b_dead && ( !p_cfg->vod.psz_mux || !input_item_IsPreparsed( p_media->vod.p_item ) ) )
vlc_sem_wait( &sem_preparse );
}
vlc_sem_wait( &sem_preparse );
var_DelCallback( p_input, "intf-event", InputEventPreparse, &sem_preparse );
vlc_sem_destroy( &sem_preparse );
var_DelCallback( p_input, "intf-event", InputEventPreparse,
&preparse );
input_Stop( p_input, true );
vlc_thread_join( p_input );
vlc_object_release( p_input );
vlc_sem_destroy( &sem_preparse );
}
free( psz_header );
/* XXX: Don't do it that way, but properly use a new input item ref. */
input_item_t item = *p_media->vod.p_item;;
if( p_cfg->vod.psz_mux )
{
const char *psz_mux;
......@@ -647,7 +664,6 @@ static int vlm_OnMediaUpdate( vlm_t *p_vlm, vlm_media_sys_t *p_media )
else
psz_mux = p_cfg->vod.psz_mux;
input_item_t item;
es_format_t es, *p_es = &es;
union { char text[5]; uint32_t value; } fourcc;
......@@ -657,20 +673,19 @@ static int vlm_OnMediaUpdate( vlm_t *p_vlm, vlm_media_sys_t *p_media )
fourcc.text[2] = tolower(fourcc.text[2]);
fourcc.text[3] = tolower(fourcc.text[3]);
/* XXX: Don't do it that way, but properly use a new input item ref. */
item = *p_media->vod.p_item;
item.i_es = 1;
item.es = &p_es;
es_format_Init( &es, VIDEO_ES, fourcc.value );
p_media->vod.p_media =
p_vlm->p_vod->pf_media_new( p_vlm->p_vod, p_cfg->psz_name, &item );
}
else
{
p_media->vod.p_media =
p_vlm->p_vod->pf_media_new( p_vlm->p_vod, p_cfg->psz_name, p_media->vod.p_item );
item.i_es = data.i_es;
item.es = data.es;
}
p_media->vod.p_media = p_vlm->p_vod->pf_media_new( p_vlm->p_vod,
p_cfg->psz_name, &item );
TAB_CLEAN(data.i_es, data.es);
}
}
else if ( p_cfg->b_vod )
......@@ -861,6 +876,8 @@ static vlm_media_instance_sys_t *vlm_MediaInstanceNew( vlm_t *p_vlm, const char
p_instance->i_index = 0;
p_instance->b_sout_keep = false;
p_instance->p_parent = vlc_object_create( p_vlm, sizeof (vlc_object_t) );
vlc_object_attach( p_instance->p_parent, p_vlm->p_libvlc );
p_instance->p_input = NULL;
p_instance->p_input_resource = NULL;
......@@ -884,6 +901,7 @@ static void vlm_MediaInstanceDelete( vlm_t *p_vlm, int64_t id, vlm_media_instanc
input_resource_Terminate( p_instance->p_input_resource );
input_resource_Release( p_instance->p_input_resource );
}
vlc_object_release( p_instance->p_parent );
TAB_REMOVE( p_media->i_instance, p_media->instance, p_instance );
vlc_gc_decref( p_instance->p_item );
......@@ -919,6 +937,15 @@ static int vlm_ControlMediaInstanceStart( vlm_t *p_vlm, int64_t id, const char *
if( !p_instance )
return VLC_ENOMEM;
if ( p_cfg->b_vod )
{
var_Create( p_instance->p_parent, "vod-media", VLC_VAR_ADDRESS );
var_SetAddress( p_instance->p_parent, "vod-media",
p_media->vod.p_media );
var_Create( p_instance->p_parent, "vod-session", VLC_VAR_STRING );
var_SetString( p_instance->p_parent, "vod-session", psz_id );
}
if( p_cfg->psz_output != NULL || psz_vod_output != NULL )
{
char *psz_buffer;
......@@ -979,21 +1006,15 @@ static int vlm_ControlMediaInstanceStart( vlm_t *p_vlm, int64_t id, const char *
if( asprintf( &psz_log, _("Media: %s"), p_media->cfg.psz_name ) != -1 )
{
vlc_object_t *p_parent = p_media->cfg.b_vod ?
VLC_OBJECT(p_vlm->p_vod) :
VLC_OBJECT(p_vlm->p_libvlc);
if( !p_instance->p_input_resource )
p_instance->p_input_resource = input_resource_New( VLC_OBJECT( p_vlm->p_libvlc ) );
p_instance->p_input = input_Create( p_parent, p_instance->p_item,
psz_log, p_instance->p_input_resource );
p_instance->p_input_resource = input_resource_New( p_instance->p_parent );
p_instance->p_input = input_Create( p_instance->p_parent,
p_instance->p_item, psz_log,
p_instance->p_input_resource );
if( p_instance->p_input )
{
var_AddCallback( p_instance->p_input, "intf-event", InputEvent, p_media );
var_Create( p_instance->p_input, "vod-media", VLC_VAR_ADDRESS );
var_SetAddress( p_instance->p_input, "vod-media",
p_media->vod.p_media );
var_Create( p_instance->p_input, "vod-session", VLC_VAR_STRING );
var_SetString( p_instance->p_input, "vod-session", psz_id );
if( input_Start( p_instance->p_input ) != VLC_SUCCESS )
{
......
......@@ -38,6 +38,7 @@ typedef struct
bool b_sout_keep;
vlc_object_t *p_parent;
input_item_t *p_item;
input_thread_t *p_input;
input_resource_t *p_input_resource;
......
......@@ -800,48 +800,59 @@ void vlc_control_cancel (int cmd, ...)
struct vlc_timer
{
vlc_thread_t thread;
vlc_cond_t reschedule;
vlc_mutex_t lock;
void (*func) (void *);
void *data;
mtime_t value, interval;
unsigned users;
vlc_atomic_t overruns;
};
static void *vlc_timer_thread (void *data)
{
struct vlc_timer *timer = data;
mtime_t value, interval;
vlc_mutex_lock (&timer->lock);
value = timer->value;
interval = timer->interval;
vlc_mutex_unlock (&timer->lock);
mutex_cleanup_push (&timer->lock);
for (;;)
{
mwait (value);
int canc = vlc_savecancel ();
timer->func (timer->data);
vlc_restorecancel (canc);
if (interval == 0)
return NULL;
mtime_t now = mdate ();
unsigned misses = (now - value) / interval;
/* Try to compensate for one miss (mwait() will return immediately)
* but no more. Otherwise, we might busy loop, after extended periods
* without scheduling (suspend, SIGSTOP, RT preemption, ...). */
if (misses > 1)
{
misses--;
vlc_atomic_add (&timer->overruns, misses);
value += misses * interval;
}
value += interval;
while (timer->value == 0)
vlc_cond_wait (&timer->reschedule, &timer->lock);
if (vlc_cond_timedwait (&timer->reschedule, &timer->lock,
timer->value) == 0)
continue;
if (timer->interval == 0)
timer->value = 0; /* disarm */
vlc_mutex_unlock (&timer->lock);
int canc = vlc_savecancel ();
timer->func (timer->data);
vlc_restorecancel (canc);
mtime_t now = mdate ();
unsigned misses;
vlc_mutex_lock (&timer->lock);
if (timer->interval == 0)
continue;
misses = (now - timer->value) / timer->interval;
timer->value += timer->interval;
/* Try to compensate for one miss (mwait() will return immediately)
* but no more. Otherwise, we might busy loop, after extended periods
* without scheduling (suspend, SIGSTOP, RT preemption, ...). */
if (misses > 1)
{
misses--;
timer->value += misses * timer->interval;
vlc_atomic_add (&timer->overruns, misses);
}
}
vlc_cleanup_pop ();
assert (0);
}
/**
......@@ -862,13 +873,23 @@ int vlc_timer_create (vlc_timer_t *id, void (*func) (void *), void *data)
if (unlikely(timer == NULL))
return ENOMEM;
vlc_mutex_init (&timer->lock);
vlc_cond_init (&timer->reschedule);
assert (func);
timer->func = func;
timer->data = data;
timer->value = 0;
timer->interval = 0;
timer->users = 0;
vlc_atomic_set(&timer->overruns, 0);
if (vlc_clone (&timer->thread, vlc_timer_thread, timer,
VLC_THREAD_PRIORITY_INPUT))
{
vlc_cond_destroy (&timer->reschedule);
vlc_mutex_destroy (&timer->lock);
free (timer);
return ENOMEM;
}
*id = timer;
return 0;
}
......@@ -884,7 +905,9 @@ int vlc_timer_create (vlc_timer_t *id, void (*func) (void *), void *data)
*/
void vlc_timer_destroy (vlc_timer_t timer)
{
vlc_timer_schedule (timer, false, 0, 0);
vlc_cancel (timer->thread);
vlc_join (timer->thread, NULL);
vlc_cond_destroy (&timer->reschedule);
vlc_mutex_destroy (&timer->lock);
free (timer);
}
......@@ -909,25 +932,13 @@ void vlc_timer_destroy (vlc_timer_t timer)
void vlc_timer_schedule (vlc_timer_t timer, bool absolute,
mtime_t value, mtime_t interval)
{
vlc_mutex_lock (&timer->lock);
while (timer->value)
{
vlc_thread_t thread = timer->thread;
if (!absolute && value != 0)
value += mdate();
timer->value = 0;
vlc_mutex_unlock (&timer->lock);
vlc_cancel (thread);
/* cannot keep the lock during vlc_join X( */
vlc_join (thread, NULL);
vlc_mutex_lock (&timer->lock);
}
if ((value != 0)
&& (vlc_clone (&timer->thread, vlc_timer_thread, timer,
VLC_THREAD_PRIORITY_INPUT) == 0))
{
timer->value = (absolute ? 0 : mdate ()) + value;
timer->interval = interval;
}
vlc_mutex_lock (&timer->lock);
timer->value = value;
timer->interval = interval;
vlc_cond_signal (&timer->reschedule);
vlc_mutex_unlock (&timer->lock);
}
......
......@@ -358,6 +358,7 @@ void var_DestroyAll( vlc_object_t *obj )
vlc_object_internals_t *priv = vlc_internals( obj );
tdestroy( priv->var_root, CleanupVar );
priv->var_root = NULL;
}
#undef var_Change
......
......@@ -70,23 +70,37 @@ int vlc_poll (struct pollfd *fds, unsigned nfds, int timeout)
(void)fds; (void)nfds; (void)timeout;
abort ();
}
#else /* !HAVE_POLL */
#elif defined (WIN32)
#include <string.h>
#include <errno.h>
int vlc_poll (struct pollfd *fds, unsigned nfds, int timeout)
{
fd_set rdset, wrset, exset;
size_t setsize = sizeof (fd_set) + (nfds - FD_SETSIZE) * sizeof (SOCKET);
fd_set *rdset = malloc (setsize);
fd_set *wrset = malloc (setsize);
fd_set *exset = malloc (setsize);
struct timeval tv = { 0, 0 };
int val;
if (unlikely(rdset == NULL || wrset == NULL || exset == NULL))
{
free (rdset);
free (wrset);
free (exset);
errno = ENOMEM;
return -1;
}
resume:
val = -1;
vlc_testcancel ();
FD_ZERO (&rdset);
FD_ZERO (&wrset);
FD_ZERO (&exset);
FD_ZERO (rdset);
FD_ZERO (wrset);
FD_ZERO (exset);
for (unsigned i = 0; i < nfds; i++)
{
int fd = fds[i].fd;
......@@ -94,29 +108,28 @@ resume:
val = fd;
/* With POSIX, FD_SET & FD_ISSET are not defined if fd is negative or
* bigger or equal than FD_SETSIZE. That is one of the reasons why VLC
* uses poll() rather than select(). Most POSIX systems implement
* fd_set has a bit field with no sanity checks. This is especially bad
* on systems (such as BSD) that have no process open files limit by
* default, such that it is quite feasible to get fd >= FD_SETSIZE.
* The next instructions will result in a buffer overflow if run on
* a POSIX system, and the later FD_ISSET will do undefined memory
* access.
*
* With Winsock, fd_set is a table of integers. This is awfully slow.
* However, FD_SET and FD_ISSET silently and safely discard
* overflows. If it happens we will loose socket events. Note that
* most (if not all) Winsock SOCKET handles are actually bigger than
* FD_SETSIZE in terms of absolute value - they are not POSIX file
* descriptors. From Vista, there is a much nicer WSAPoll(), but Mingw
* is yet to support it.
*/
* bigger or equal than FD_SETSIZE. That is one of the reasons why VLC
* uses poll() rather than select(). Most POSIX systems implement
* fd_set has a bit field with no sanity checks. This is especially bad
* on systems (such as BSD) that have no process open files limit by
* default, such that it is quite feasible to get fd >= FD_SETSIZE.
* The next instructions will result in a buffer overflow if run on
* a POSIX system, and the later FD_ISSET would perform an undefined
* memory read.
*
* With Winsock, fd_set is a table of integers. This is awfully slow.
* However, FD_SET and FD_ISSET silently and safely discard excess
* entries. Here, overflow cannot happen anyway: fd_set of adequate
* size are allocated.
* Note that Vista has a much nicer WSAPoll(), but Mingw does not
* support it yet.
*/
if (fds[i].events & POLLIN)
FD_SET (fd, &rdset);
FD_SET ((SOCKET)fd, rdset);
if (fds[i].events & POLLOUT)
FD_SET (fd, &wrset);
FD_SET ((SOCKET)fd, wrset);
if (fds[i].events & POLLPRI)
FD_SET (fd, &exset);
FD_SET ((SOCKET)fd, exset);
}
#ifndef HAVE_ALERTABLE_SELECT
......@@ -135,7 +148,7 @@ resume:
tv.tv_usec = d.rem * 1000;
}
val = select (val + 1, &rdset, &wrset, &exset,
val = select (val + 1, rdset, wrset, exset,
/*(timeout >= 0) ?*/ &tv /*: NULL*/);
#ifndef HAVE_ALERTABLE_SELECT
......@@ -154,10 +167,16 @@ resume:
for (unsigned i = 0; i < nfds; i++)
{
int fd = fds[i].fd;
fds[i].revents = (FD_ISSET (fd, &rdset) ? POLLIN : 0)
| (FD_ISSET (fd, &wrset) ? POLLOUT : 0)
| (FD_ISSET (fd, &exset) ? POLLPRI : 0);
fds[i].revents = (FD_ISSET (fd, rdset) ? POLLIN : 0)
| (FD_ISSET (fd, wrset) ? POLLOUT : 0)
| (FD_ISSET (fd, exset) ? POLLPRI : 0);
}
free (exset);
free (wrset);
free (rdset);
return val;
}
#endif /* !HAVE_POLL */
#else
# error poll() not implemented!
#endif
......@@ -153,7 +153,7 @@ BOOL WINAPI DllMain (HINSTANCE hinstDll, DWORD fdwReason, LPVOID lpvReserved)
case DLL_PROCESS_ATTACH:
vlc_mutex_init (&super_mutex);
vlc_cond_init (&super_variable);
vlc_threadvar_create (&cancel_key, free);
vlc_threadvar_create (&cancel_key, NULL);
break;
case DLL_PROCESS_DETACH:
......@@ -458,40 +458,83 @@ void vlc_rwlock_unlock (vlc_rwlock_t *lock)
}
/*** Thread-specific variables (TLS) ***/
struct vlc_threadvar
{
DWORD id;
void (*destroy) (void *);
struct vlc_threadvar *prev;
struct vlc_threadvar *next;
} *vlc_threadvar_last = NULL;
int vlc_threadvar_create (vlc_threadvar_t *p_tls, void (*destr) (void *))
{
#warning FIXME: use destr() callback and stop leaking!
VLC_UNUSED( destr );
struct vlc_threadvar *var = malloc (sizeof (*var));
if (unlikely(var == NULL))
return errno;
*p_tls = TlsAlloc();
return (*p_tls == TLS_OUT_OF_INDEXES) ? EAGAIN : 0;
var->id = TlsAlloc();
if (var->id == TLS_OUT_OF_INDEXES)
{
free (var);
return EAGAIN;
}
var->destroy = destr;
var->next = NULL;
*p_tls = var;
vlc_mutex_lock (&super_mutex);
var->prev = vlc_threadvar_last;
vlc_threadvar_last = var;
vlc_mutex_unlock (&super_mutex);
return 0;
}
void vlc_threadvar_delete (vlc_threadvar_t *p_tls)
{
TlsFree (*p_tls);
struct vlc_threadvar *var = *p_tls;
vlc_mutex_lock (&super_mutex);
if (var->prev != NULL)
var->prev->next = var->next;
else
vlc_threadvar_last = var->next;
if (var->next != NULL)
var->next->prev = var->prev;
vlc_mutex_unlock (&super_mutex);
TlsFree (var->id);
free (var);
}
/**
* Sets a thread-local variable.
* @param key thread-local variable key (created with vlc_threadvar_create())
* @param value new value for the variable for the calling thread
* @return 0 on success, a system error code otherwise.
*/
int vlc_threadvar_set (vlc_threadvar_t key, void *value)
{
return TlsSetValue (key, value) ? ENOMEM : 0;
return TlsSetValue (key->id, value) ? ENOMEM : 0;
}
/**
* Gets the value of a thread-local variable for the calling thread.
* This function cannot fail.
* @return the value associated with the given variable for the calling
* or NULL if there is no value.
*/
void *vlc_threadvar_get (vlc_threadvar_t key)
{
return TlsGetValue (key);
return TlsGetValue (key->id);
}
static void vlc_threadvar_cleanup (void)
{
vlc_threadvar_t key;
retry:
/* TODO: use RW lock or something similar */
vlc_mutex_lock (&super_mutex);
for (key = vlc_threadvar_last; key != NULL; key = key->prev)
{
void *value = vlc_threadvar_get (key);
if (value != NULL)
{
vlc_mutex_unlock (&super_mutex);
vlc_threadvar_set (key, NULL);
key->destroy (value);
goto retry;
}
}
vlc_mutex_unlock (&super_mutex);
}
......@@ -524,6 +567,7 @@ static unsigned __stdcall vlc_entry (void *p)
vlc_threadvar_set (cancel_key, &cancel_data);
vlc_sem_post (&entry->ready);
func (data);
vlc_threadvar_cleanup ();
return 0;
}
......@@ -689,6 +733,7 @@ void vlc_testcancel (void)
{
for (vlc_cleanup_t *p = nfo->cleaners; p != NULL; p = p->next)
p->proc (p->data);
vlc_threadvar_cleanup ();
#ifndef UNDER_CE
_endthreadex(0);
#else
......
#!/bin/sh
# Copyright (C) 2010 VideoLAN
# License: GPLv2
#----------------------------------------------------------------------------
# Traffic shaping for HTTP Live Streaming client tests.
#----------------------------------------------------------------------------
# Requires: iproute2
#----------------------------------------------------------------------------
#qdisc pfifo_fast 0: root refcnt 2 bands 3 priomap 1 2 2 2 1 2 0 0 1 1 1 1 1 1 1 1
#
TC=tc
INTF="eth0"
RATE="500kbit"
BURST="20kbit"
PEAK="520kbit"
MTU="1500"
set +e
# Shaping
function traffic_shaping() {
${TC} qdisc add \
dev ${INTF} \
root \
tbf \
rate ${RATE} \
burst ${BURST} \
latency 70ms \
peakrate ${PEAK} \
mtu ${MTU}
RESULT=$?
}
# tc qdisc add dev eth2 root tbf rate 50kbit burst 2kbit latency 70ms peakrate 52kbit mtu 1500
traffic_shaping
if ! test "${RESULT}" = "0"; then
exit 1
fi
exit 0
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment