Commit 31e0a13e authored by Clément Stenac's avatar Clément Stenac

Show stats in interface (Refs:#473)

parent 56052322
...@@ -295,12 +295,18 @@ struct input_stats_t ...@@ -295,12 +295,18 @@ struct input_stats_t
/* Input */ /* Input */
int i_read_packets; int i_read_packets;
int i_read_bytes; int i_read_bytes;
float f_input_bitrate;
float f_average_input_bitrate;
float f_bitrate; /* Demux */
int i_demux_read_packets;
float f_average_bitrate; int i_demux_read_bytes;
float f_demux_bitrate;
float f_average_demux_bitrate;
/* Decoders */ /* Decoders */
int i_decoded_audio;
int i_decoded_video;
/* Vout */ /* Vout */
int i_displayed_pictures; int i_displayed_pictures;
......
...@@ -145,7 +145,7 @@ int vlc_getnameinfo (const struct sockaddr *, int, char *, int, int *, int); ...@@ -145,7 +145,7 @@ int vlc_getnameinfo (const struct sockaddr *, int, char *, int, int *, int);
int vlm_ExecuteCommand (vlm_t *, const char *, vlm_message_t **); int vlm_ExecuteCommand (vlm_t *, const char *, vlm_message_t **);
char * config_GetUserDir (void); char * config_GetUserDir (void);
httpd_stream_t * httpd_StreamNew (httpd_host_t *, const char *psz_url, const char *psz_mime, const char *psz_user, const char *psz_password, const vlc_acl_t *p_acl); httpd_stream_t * httpd_StreamNew (httpd_host_t *, const char *psz_url, const char *psz_mime, const char *psz_user, const char *psz_password, const vlc_acl_t *p_acl);
int __stats_CounterGet (vlc_object_t*, int, char *); counter_t* __stats_CounterGet (vlc_object_t*, int, char *);
int __config_GetType (vlc_object_t *, const char *); int __config_GetType (vlc_object_t *, const char *);
void __vlc_thread_ready (vlc_object_t *); void __vlc_thread_ready (vlc_object_t *);
int playlist_Export (playlist_t *, const char *, const char *); int playlist_Export (playlist_t *, const char *, const char *);
...@@ -882,7 +882,7 @@ struct module_symbols_t ...@@ -882,7 +882,7 @@ struct module_symbols_t
void (*stats_ComputeInputStats_inner) (input_thread_t*, input_stats_t*); void (*stats_ComputeInputStats_inner) (input_thread_t*, input_stats_t*);
void (*stats_DumpInputStats_inner) (input_stats_t *); void (*stats_DumpInputStats_inner) (input_stats_t *);
void (*stats_ReinitInputStats_inner) (input_stats_t *); void (*stats_ReinitInputStats_inner) (input_stats_t *);
int (*__stats_CounterGet_inner) (vlc_object_t*, int, char *); counter_t* (*__stats_CounterGet_inner) (vlc_object_t*, int, char *);
}; };
# if defined (__PLUGIN__) # if defined (__PLUGIN__)
# define aout_FiltersCreatePipeline (p_symbols)->aout_FiltersCreatePipeline_inner # define aout_FiltersCreatePipeline (p_symbols)->aout_FiltersCreatePipeline_inner
......
...@@ -18,6 +18,7 @@ SOURCES_wxwidgets = \ ...@@ -18,6 +18,7 @@ SOURCES_wxwidgets = \
dialogs/messages.cpp \ dialogs/messages.cpp \
dialogs/playlist.cpp \ dialogs/playlist.cpp \
dialogs/iteminfo.cpp \ dialogs/iteminfo.cpp \
dialogs/infopanels.cpp \
dialogs/preferences.cpp \ dialogs/preferences.cpp \
dialogs/preferences_widgets.cpp \ dialogs/preferences_widgets.cpp \
dialogs/preferences_widgets.h \ dialogs/preferences_widgets.h \
...@@ -57,6 +58,7 @@ EXTRA_DIST += \ ...@@ -57,6 +58,7 @@ EXTRA_DIST += \
dialogs/open.hpp \ dialogs/open.hpp \
dialogs/messages.hpp \ dialogs/messages.hpp \
dialogs/iteminfo.hpp \ dialogs/iteminfo.hpp \
dialogs/infopanels.hpp \
dialogs/subtitles.hpp \ dialogs/subtitles.hpp \
dialogs/streamout.hpp \ dialogs/streamout.hpp \
dialogs/updatevlc.hpp \ dialogs/updatevlc.hpp \
......
...@@ -272,7 +272,7 @@ void DialogsProvider::OnIdle( wxIdleEvent& WXUNUSED(event) ) ...@@ -272,7 +272,7 @@ void DialogsProvider::OnIdle( wxIdleEvent& WXUNUSED(event) )
/* Update the fileinfo windows */ /* Update the fileinfo windows */
if( p_fileinfo_dialog ) if( p_fileinfo_dialog )
p_fileinfo_dialog->UpdateFileInfo(); p_fileinfo_dialog->Update();
} }
void DialogsProvider::OnPlaylist( wxCommandEvent& WXUNUSED(event) ) void DialogsProvider::OnPlaylist( wxCommandEvent& WXUNUSED(event) )
......
...@@ -22,6 +22,7 @@ ...@@ -22,6 +22,7 @@
*****************************************************************************/ *****************************************************************************/
#include "dialogs/fileinfo.hpp" #include "dialogs/fileinfo.hpp"
#include "dialogs/infopanels.hpp"
/***************************************************************************** /*****************************************************************************
* Event Table. * Event Table.
...@@ -53,35 +54,36 @@ FileInfo::FileInfo( intf_thread_t *_p_intf, wxWindow *p_parent ): ...@@ -53,35 +54,36 @@ FileInfo::FileInfo( intf_thread_t *_p_intf, wxWindow *p_parent ):
wxFrame( p_parent, -1, wxU(_("Stream and media info")), wxDefaultPosition, wxFrame( p_parent, -1, wxU(_("Stream and media info")), wxDefaultPosition,
wxDefaultSize, wxDEFAULT_FRAME_STYLE ) wxDefaultSize, wxDEFAULT_FRAME_STYLE )
{ {
playlist_t *p_playlist; p_intf = _p_intf;
playlist_t *p_playlist = (playlist_t *)vlc_object_find( p_intf,
VLC_OBJECT_PLAYLIST,
FIND_ANYWHERE );
/* Initializations */ /* Initializations */
p_intf = _p_intf;
SetIcon( *p_intf->p_sys->p_icon ); SetIcon( *p_intf->p_sys->p_icon );
SetAutoLayout( TRUE ); SetAutoLayout( TRUE );
/* Create a panel to put everything in */ wxBoxSizer *panel_sizer = new wxBoxSizer( wxVERTICAL );
wxPanel *panel = new wxPanel( this, -1 );
panel->SetAutoLayout( TRUE ); wxNotebook *notebook = new wxNotebook( this, -1 );
#if (!wxCHECK_VERSION(2,5,2))
wxNotebookSizer *notebook_sizer = new wxNotebookSizer( notebook );
#endif
item_info = new ItemInfoPanel( p_intf, notebook, false );
stats_info = new InputStatsInfoPanel( p_intf, notebook );
fileinfo_tree = notebook->AddPage( item_info, wxU(_("General") ), true );
new wxTreeCtrl( panel, -1, wxDefaultPosition, wxSize( 350, 350 ), notebook->AddPage( stats_info, wxU(_("Statistics") ), false );
wxTR_HAS_BUTTONS | wxTR_HIDE_ROOT | wxSUNKEN_BORDER );
fileinfo_root_label = wxT(""); #if (!wxCHECK_VERSION(2,5,2))
panel_sizer->Add( notebook_sizer, 1, wxEXPAND | wxALL, 5 );
#else
panel_sizer->Add( notebook, 1, wxEXPAND | wxALL, 5 );
#endif
/* Place everything in sizers */
wxBoxSizer *main_sizer = new wxBoxSizer( wxVERTICAL );
wxBoxSizer *panel_sizer = new wxBoxSizer( wxVERTICAL );
panel_sizer->Add( fileinfo_tree, 1, wxEXPAND | wxALL, 5 );
panel_sizer->Layout(); panel_sizer->Layout();
panel->SetSizerAndFit( panel_sizer ); SetSizerAndFit( panel_sizer );
main_sizer->Add( panel, 1, wxEXPAND, 0 );
main_sizer->Layout();
SetSizerAndFit( main_sizer );
p_playlist = (playlist_t *)vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
FIND_ANYWHERE );
if( p_playlist ) if( p_playlist )
{ {
...@@ -89,76 +91,49 @@ FileInfo::FileInfo( intf_thread_t *_p_intf, wxWindow *p_parent ): ...@@ -89,76 +91,49 @@ FileInfo::FileInfo( intf_thread_t *_p_intf, wxWindow *p_parent ):
vlc_object_release( p_playlist ); vlc_object_release( p_playlist );
} }
last_update = 0L;
b_need_update = VLC_TRUE; b_need_update = VLC_TRUE;
UpdateFileInfo(); Update();
} }
void FileInfo::UpdateFileInfo() void FileInfo::Update()
{ {
if( mdate() - last_update < 400000L ) return;
last_update = mdate();
playlist_t *p_playlist = (playlist_t *)vlc_object_find( p_intf,
VLC_OBJECT_PLAYLIST,
FIND_ANYWHERE );
if( !p_playlist ) return;
input_thread_t *p_input = input_thread_t *p_input =
(input_thread_t *)vlc_object_find( p_intf, VLC_OBJECT_INPUT, (input_thread_t *)vlc_object_find( p_playlist, VLC_OBJECT_INPUT,
FIND_ANYWHERE ); FIND_CHILD );
if( !p_input || p_input->b_dead || !p_input->input.p_item->psz_name ) if( !p_input || p_input->b_dead || !p_input->input.p_item->psz_name )
{ {
if( fileinfo_root ) item_info->Clear();
{ stats_info->Clear();
fileinfo_root_label = wxT(""); if ( p_input )
fileinfo_tree->DeleteChildren( fileinfo_root );
}
if (p_input)
{ {
vlc_object_release(p_input); vlc_object_release(p_input);
} }
vlc_object_release( p_playlist );
return; return;
} }
if( !fileinfo_root )
{
/* On linux, the first argument of wxTreeCtrl::AddRoot() can be
* retrieved with the GetItemText() method, but it doesn't work on
* Windows when the wxTR_HIDE_ROOT style is set. That's why we need to
* use the fileinfo_root_label variable... */
fileinfo_root =
fileinfo_tree->AddRoot( wxL2U(p_input->input.p_item->psz_name) );
fileinfo_root_label = wxL2U(p_input->input.p_item->psz_name);
}
else if( fileinfo_root_label == wxL2U(p_input->input.p_item->psz_name) &&
b_need_update == VLC_FALSE )
{
vlc_object_release(p_input);
return;
}
/* We rebuild the tree from scratch */
fileinfo_tree->DeleteChildren( fileinfo_root );
fileinfo_root_label = wxL2U(p_input->input.p_item->psz_name);
vlc_mutex_lock( &p_input->input.p_item->lock ); vlc_mutex_lock( &p_input->input.p_item->lock );
for( int i = 0; i < p_input->input.p_item->i_categories; i++ ) if( b_need_update == VLC_TRUE )
{ {
info_category_t *p_cat = p_input->input.p_item->pp_categories[i]; item_info->Update( p_input->input.p_item );
wxTreeItemId cat = fileinfo_tree->AppendItem( fileinfo_root,
wxU(p_cat->psz_name) );
for( int j = 0; j < p_cat->i_infos; j++ )
{
info_t *p_info = p_cat->pp_infos[j];
if( p_info->psz_value[0] != 0 )
/* We only wanna show fields that have an actual value */
{
fileinfo_tree->AppendItem( cat, (wxString)wxU(p_info->psz_name)
+ wxT(": ") + wxU(p_info->psz_value) );
}
}
fileinfo_tree->Expand( cat );
} }
stats_info->Update( p_input->input.p_item );
vlc_mutex_unlock( &p_input->input.p_item->lock ); vlc_mutex_unlock( &p_input->input.p_item->lock );
b_need_update = VLC_FALSE;
vlc_object_release(p_input); vlc_object_release(p_input);
vlc_object_release( p_playlist );
b_need_update = VLC_FALSE;
return; return;
} }
......
...@@ -30,13 +30,15 @@ ...@@ -30,13 +30,15 @@
namespace wxvlc namespace wxvlc
{ {
class ItemInfoPanel;
class InputStatsInfoPanel;
class FileInfo: public wxFrame class FileInfo: public wxFrame
{ {
public: public:
/* Constructor */ /* Constructor */
FileInfo( intf_thread_t *p_intf, wxWindow *p_parent ); FileInfo( intf_thread_t *p_intf, wxWindow *p_parent );
virtual ~FileInfo(); virtual ~FileInfo();
void UpdateFileInfo(); void Update();
vlc_bool_t b_need_update; vlc_bool_t b_need_update;
...@@ -47,9 +49,11 @@ namespace wxvlc ...@@ -47,9 +49,11 @@ namespace wxvlc
DECLARE_EVENT_TABLE(); DECLARE_EVENT_TABLE();
intf_thread_t *p_intf; intf_thread_t *p_intf;
wxTreeCtrl *fileinfo_tree;
wxTreeItemId fileinfo_root; mtime_t last_update;
wxString fileinfo_root_label;
ItemInfoPanel *item_info;
InputStatsInfoPanel *stats_info;
}; };
}; };
......
/*****************************************************************************
* infopanels.cpp : Information panels (general info, stats, ...)
*****************************************************************************
* Copyright (C) 2000-2004 the VideoLAN team
* $Id: iteminfo.cpp 13905 2006-01-12 23:10:04Z dionoea $
*
* Authors: Clment Stenac <zorglub@videolan.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 of the License, 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 this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
#include "dialogs/infopanels.hpp"
#include <wx/combobox.h>
#include <wx/statline.h>
#ifndef wxRB_SINGLE
# define wxRB_SINGLE 0
#endif
/*****************************************************************************
* General info panel
*****************************************************************************/
BEGIN_EVENT_TABLE( ItemInfoPanel, wxPanel )
END_EVENT_TABLE()
ItemInfoPanel::ItemInfoPanel( intf_thread_t *_p_intf,
wxWindow* _p_parent,
bool _b_modifiable ):
wxPanel( _p_parent, -1 )
{
/* Initializations */
p_intf = _p_intf;
p_parent = _p_parent;
b_modifiable = _b_modifiable;
SetAutoLayout( TRUE );
wxBoxSizer *panel_sizer = new wxBoxSizer( wxVERTICAL );
wxFlexGridSizer *sizer = new wxFlexGridSizer(2,3,20);
/* URI Textbox */
wxStaticText *uri_static =
new wxStaticText( this, -1, wxU(_("URI")) );
sizer->Add( uri_static, 0 , wxALL , 5 );
uri_text = new wxTextCtrl( this, -1,
wxU(""), wxDefaultPosition, wxSize( 300, -1 ),
wxTE_PROCESS_ENTER );
sizer->Add( uri_text, 1 , wxALL , 5 );
/* Name Textbox */
wxStaticText *name_static =
new wxStaticText( this, -1, wxU(_("Name")) );
sizer->Add( name_static, 0 , wxALL , 5 );
name_text = new wxTextCtrl( this, -1,
wxU(""), wxDefaultPosition, wxSize( 300, -1 ),
wxTE_PROCESS_ENTER );
sizer->Add( name_text, 1 , wxALL , 5 );
/* Treeview */
info_tree = new wxTreeCtrl( this, -1, wxDefaultPosition,
wxSize(220,200),
wxSUNKEN_BORDER |wxTR_HAS_BUTTONS |
wxTR_HIDE_ROOT );
info_root = info_tree->AddRoot( wxU( "" ) );
sizer->Layout();
panel_sizer->Add( sizer, 0, wxEXPAND, 5 );
panel_sizer->Add( info_tree, 0, wxEXPAND, 5 );
panel_sizer->Layout();
SetSizerAndFit( panel_sizer );
}
ItemInfoPanel::~ItemInfoPanel()
{
}
void ItemInfoPanel::Update( input_item_t *p_item )
{
/* Rebuild the tree */
Clear();
uri_text->SetValue( wxU( p_item->psz_uri ) );
name_text->SetValue( wxU( p_item->psz_name ) );
for( int i = 0; i< p_item->i_categories ; i++)
{
wxTreeItemId cat = info_tree->AppendItem( info_root,
wxU( p_item->pp_categories[i]->psz_name) );
for( int j = 0 ; j < p_item->pp_categories[i]->i_infos ; j++ )
{
info_tree->AppendItem( cat , (wxString)
wxU(p_item->pp_categories[i]->pp_infos[j]->psz_name) +
wxT(": ") +
wxU(p_item->pp_categories[i]->pp_infos[j]->psz_value) );
}
info_tree->Expand( cat );
}
}
void ItemInfoPanel::Clear()
{
info_tree->DeleteChildren( info_root );
}
void ItemInfoPanel::OnOk( )
{
}
void ItemInfoPanel::OnCancel( )
{
}
/*****************************************************************************
* Statistics info panel
*****************************************************************************/
BEGIN_EVENT_TABLE( InputStatsInfoPanel, wxPanel )
END_EVENT_TABLE()
InputStatsInfoPanel::InputStatsInfoPanel( intf_thread_t *_p_intf,
wxWindow* _p_parent ):
wxPanel( _p_parent, -1 )
{
/* Initializations */
p_intf = _p_intf;
p_parent = _p_parent;
SetAutoLayout( TRUE );
wxBoxSizer *panel_sizer = new wxBoxSizer( wxVERTICAL );
wxFlexGridSizer *sizer = new wxFlexGridSizer( 2,2,20 );
/* Input */
wxStaticBox *input_box = new wxStaticBox( this, -1,
wxU( _("Input") ) );
wxStaticBoxSizer *input_bsizer = new wxStaticBoxSizer( input_box,
wxVERTICAL );
wxFlexGridSizer *input_sizer = new wxFlexGridSizer( 2,2, 20 );
#define INPUT_ADD(txt,widget,dflt) \
{ input_sizer->Add ( new wxStaticText( this, -1, wxU(_( txt ) ) ) ); \
widget = new wxStaticText( this, -1, wxU( dflt ) ); \
input_sizer->Add( widget ); \
}
INPUT_ADD( "Read at media", read_bytes_text, "0" );
INPUT_ADD( "Input bitrate", input_bitrate_text, "0" );
INPUT_ADD( "Demuxed", demux_bytes_text ,"0");
INPUT_ADD( "Stream bitrate", demux_bitrate_text, "0" );
input_sizer->Layout();
input_bsizer->Add( input_sizer, 0, wxALL | wxGROW, 5 );
input_bsizer->Layout();
sizer->Add( input_bsizer, 0, wxALL|wxGROW, 5 );
/* Vout */
wxStaticBox *video_box = new wxStaticBox( this, -1,
wxU( _("Video" ) ) );
wxStaticBoxSizer *video_bsizer = new wxStaticBoxSizer( video_box,
wxVERTICAL );
wxFlexGridSizer *video_sizer = new wxFlexGridSizer( 2,3, 20 );
#define VIDEO_ADD(txt,widget,dflt) \
{ video_sizer->Add ( new wxStaticText( this, -1, wxU(_( txt ) ) ) ); \
widget = new wxStaticText( this, -1, wxU( dflt ) ); \
video_sizer->Add( widget ); \
}
VIDEO_ADD( "Decoded blocks", video_decoded_text, "0" );
VIDEO_ADD( "Displayed frames", displayed_text, "0" );
VIDEO_ADD( "Lost frames", lost_frames_text, "0" );
video_sizer->Layout();
video_bsizer->Add( video_sizer, 0, wxALL | wxGROW, 5 );
video_bsizer->Layout();
sizer->Add( video_bsizer , 0, wxALL| wxGROW, 5 );
panel_sizer->Add( sizer, 0, wxEXPAND, 5 );
panel_sizer->Layout();
SetSizerAndFit( panel_sizer );
}
InputStatsInfoPanel::~InputStatsInfoPanel()
{
}
void InputStatsInfoPanel::Update( input_item_t *p_item )
{
vlc_mutex_lock( &p_item->p_stats->lock );
/* Input */
#define UPDATE( widget,format, calc... ) \
{ \
wxString formatted; \
formatted.Printf( wxString( wxT(format) ), ## calc ); \
widget->SetLabel( formatted ); \
}
UPDATE( read_bytes_text, "%.0f kB",(float)(p_item->p_stats->i_read_bytes)/1000 );
UPDATE( input_bitrate_text, "%.0f kB/s", (float)(p_item->p_stats->f_input_bitrate)*1000 );
UPDATE( demux_bytes_text, "%.0f kB", (float)(p_item->p_stats->i_demux_read_bytes)/1000 );
UPDATE( demux_bitrate_text, "%.0f kB/s", (float)(p_item->p_stats->f_demux_bitrate)*1000 );
/* Video */
UPDATE( video_decoded_text, "%i", p_item->p_stats->i_decoded_video );
UPDATE( displayed_text, "%i", p_item->p_stats->i_displayed_pictures );
UPDATE( lost_frames_text, "%i", p_item->p_stats->i_lost_pictures );
vlc_mutex_unlock( &p_item->p_stats->lock );
}
void InputStatsInfoPanel::Clear()
{}
void InputStatsInfoPanel::OnOk( )
{}
void InputStatsInfoPanel::OnCancel( )
{}
/*****************************************************************************
* infopanels.hpp: Information panels (statistics, general info, ...)
*****************************************************************************
* Copyright (C) 1999-2005 the VideoLAN team
* $Id: iteminfo.hpp 13905 2006-01-12 23:10:04Z dionoea $
*
* Authors: Clment Stenac <zorglub@videolan.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 of the License, 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 this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
#ifndef _WXVLC_INFOPANELS_H_
#define _WXVLC_INFOPANELS_H_
#include "wxwidgets.hpp"
#include <wx/treectrl.h>
namespace wxvlc
{
class ItemInfoPanel: public wxPanel
{
public:
/* Constructor */
ItemInfoPanel( intf_thread_t *p_intf, wxWindow *p_parent, bool );
virtual ~ItemInfoPanel();
void Update( input_item_t *);
void Clear();
void OnOk();
void OnCancel();
private:
DECLARE_EVENT_TABLE();
intf_thread_t *p_intf;
input_item_t *p_item;
wxWindow *p_parent;
wxTextCtrl *uri_text;
wxTextCtrl *name_text;
wxStaticText *uri_label;
wxStaticText *name_label;
wxTreeCtrl *info_tree;
wxTreeItemId info_root;
bool b_modifiable;
};
class InputStatsInfoPanel: public wxPanel
{
public:
/* Constructor */
InputStatsInfoPanel( intf_thread_t *p_intf,wxWindow *p_parent );
virtual ~InputStatsInfoPanel();
void Update( input_item_t *);
void Clear();
void OnOk();
void OnCancel();
private:
DECLARE_EVENT_TABLE();
intf_thread_t *p_intf;
input_item_t *p_item;
wxWindow *p_parent;
wxStaticText *read_bytes_text;
wxStaticText *input_bitrate_text;
wxStaticText *demux_bytes_text;
wxStaticText *demux_bitrate_text;
wxStaticText *video_decoded_text;
wxStaticText *displayed_text;
wxStaticText *lost_frames_text;
};
};
#endif
...@@ -384,11 +384,7 @@ static decoder_t * CreateDecoder( input_thread_t *p_input, ...@@ -384,11 +384,7 @@ static decoder_t * CreateDecoder( input_thread_t *p_input,
p_dec->pf_decode_sub = 0; p_dec->pf_decode_sub = 0;
p_dec->pf_packetize = 0; p_dec->pf_packetize = 0;
stats_Create( p_dec, "decoded_audio", VLC_VAR_INTEGER, STATS_COUNTER ); /* Initialize the decoder fifo */
stats_Create( p_dec, "decoded_video", VLC_VAR_INTEGER, STATS_COUNTER );
stats_Create( p_dec, "decoded_sub", VLC_VAR_INTEGER, STATS_COUNTER );
/* Initialize the decoder fifo */
p_dec->p_module = NULL; p_dec->p_module = NULL;
...@@ -433,6 +429,12 @@ static decoder_t * CreateDecoder( input_thread_t *p_input, ...@@ -433,6 +429,12 @@ static decoder_t * CreateDecoder( input_thread_t *p_input,
vlc_object_attach( p_dec, p_input ); vlc_object_attach( p_dec, p_input );
stats_Create( p_dec->p_parent, "decoded_audio",
VLC_VAR_INTEGER, STATS_COUNTER );
stats_Create( p_dec->p_parent, "decoded_video",
VLC_VAR_INTEGER, STATS_COUNTER );
stats_Create( p_dec->p_parent, "decoded_sub",
VLC_VAR_INTEGER, STATS_COUNTER );
/* Find a suitable decoder/packetizer module */ /* Find a suitable decoder/packetizer module */
if( i_object_type == VLC_OBJECT_DECODER ) if( i_object_type == VLC_OBJECT_DECODER )
p_dec->p_module = module_Need( p_dec, "decoder", "$codec", 0 ); p_dec->p_module = module_Need( p_dec, "decoder", "$codec", 0 );
...@@ -625,7 +627,7 @@ static int DecoderDecode( decoder_t *p_dec, block_t *p_block ) ...@@ -625,7 +627,7 @@ static int DecoderDecode( decoder_t *p_dec, block_t *p_block )
while( (p_aout_buf = p_dec->pf_decode_audio( p_dec, while( (p_aout_buf = p_dec->pf_decode_audio( p_dec,
&p_packetized_block )) ) &p_packetized_block )) )
{ {
stats_UpdateInteger( p_dec, "decoded_audio", 1 ); stats_UpdateInteger( p_dec->p_parent, "decoded_audio", 1 );
/* FIXME the best would be to handle the case start_date < preroll < end_date /* FIXME the best would be to handle the case start_date < preroll < end_date
* but that's not easy with non raw audio stream */ * but that's not easy with non raw audio stream */
if( p_dec->p_owner->i_preroll_end > 0 && if( p_dec->p_owner->i_preroll_end > 0 &&
...@@ -649,7 +651,7 @@ static int DecoderDecode( decoder_t *p_dec, block_t *p_block ) ...@@ -649,7 +651,7 @@ static int DecoderDecode( decoder_t *p_dec, block_t *p_block )
} }
else while( (p_aout_buf = p_dec->pf_decode_audio( p_dec, &p_block )) ) else while( (p_aout_buf = p_dec->pf_decode_audio( p_dec, &p_block )) )
{ {
stats_UpdateInteger( p_dec, "decoded_audio", 1 ); stats_UpdateInteger( p_dec->p_parent, "decoded_audio", 1 );
if( p_dec->p_owner->i_preroll_end > 0 && if( p_dec->p_owner->i_preroll_end > 0 &&
p_aout_buf->start_date < p_dec->p_owner->i_preroll_end ) p_aout_buf->start_date < p_dec->p_owner->i_preroll_end )
{ {
...@@ -695,7 +697,8 @@ static int DecoderDecode( decoder_t *p_dec, block_t *p_block ) ...@@ -695,7 +697,8 @@ static int DecoderDecode( decoder_t *p_dec, block_t *p_block )
while( (p_pic = p_dec->pf_decode_video( p_dec, while( (p_pic = p_dec->pf_decode_video( p_dec,
&p_packetized_block )) ) &p_packetized_block )) )
{ {
stats_UpdateInteger( p_dec, "decoded_video", 1 ); stats_UpdateInteger( p_dec->p_parent, "decoded_video",
1 );
if( p_dec->p_owner->i_preroll_end > 0 && if( p_dec->p_owner->i_preroll_end > 0 &&
p_pic->date < p_dec->p_owner->i_preroll_end ) p_pic->date < p_dec->p_owner->i_preroll_end )
{ {
...@@ -716,7 +719,7 @@ static int DecoderDecode( decoder_t *p_dec, block_t *p_block ) ...@@ -716,7 +719,7 @@ static int DecoderDecode( decoder_t *p_dec, block_t *p_block )
} }
else while( (p_pic = p_dec->pf_decode_video( p_dec, &p_block )) ) else while( (p_pic = p_dec->pf_decode_video( p_dec, &p_block )) )
{ {
stats_UpdateInteger( p_dec, "decoded_video", 1 ); stats_UpdateInteger( p_dec->p_parent, "decoded_video", 1 );
if( p_dec->p_owner->i_preroll_end > 0 && if( p_dec->p_owner->i_preroll_end > 0 &&
p_pic->date < p_dec->p_owner->i_preroll_end ) p_pic->date < p_dec->p_owner->i_preroll_end )
{ {
...@@ -736,7 +739,7 @@ static int DecoderDecode( decoder_t *p_dec, block_t *p_block ) ...@@ -736,7 +739,7 @@ static int DecoderDecode( decoder_t *p_dec, block_t *p_block )
subpicture_t *p_spu; subpicture_t *p_spu;
while( (p_spu = p_dec->pf_decode_sub( p_dec, &p_block ) ) ) while( (p_spu = p_dec->pf_decode_sub( p_dec, &p_block ) ) )
{ {
stats_UpdateInteger( p_dec, "decoded_sub", 1 ); stats_UpdateInteger( p_dec->p_parent, "decoded_sub", 1 );
if( p_dec->p_owner->i_preroll_end > 0 && if( p_dec->p_owner->i_preroll_end > 0 &&
p_spu->i_start < p_dec->p_owner->i_preroll_end && p_spu->i_start < p_dec->p_owner->i_preroll_end &&
( p_spu->i_stop <= 0 || p_spu->i_stop <= p_dec->p_owner->i_preroll_end ) ) ( p_spu->i_stop <= 0 || p_spu->i_stop <= p_dec->p_owner->i_preroll_end ) )
......
...@@ -1021,6 +1021,7 @@ static int EsOutSend( es_out_t *out, es_out_id_t *es, block_t *p_block ) ...@@ -1021,6 +1021,7 @@ static int EsOutSend( es_out_t *out, es_out_id_t *es, block_t *p_block )
input_thread_t *p_input = p_sys->p_input; input_thread_t *p_input = p_sys->p_input;
es_out_pgrm_t *p_pgrm = es->p_pgrm; es_out_pgrm_t *p_pgrm = es->p_pgrm;
int64_t i_delay; int64_t i_delay;
int i_total;
if( es->fmt.i_cat == AUDIO_ES ) if( es->fmt.i_cat == AUDIO_ES )
i_delay = p_sys->i_audio_delay; i_delay = p_sys->i_audio_delay;
...@@ -1029,6 +1030,11 @@ static int EsOutSend( es_out_t *out, es_out_id_t *es, block_t *p_block ) ...@@ -1029,6 +1030,11 @@ static int EsOutSend( es_out_t *out, es_out_id_t *es, block_t *p_block )
else else
i_delay = 0; i_delay = 0;
stats_UpdateInteger( p_input, "demux_read", p_block->i_buffer );
stats_GetInteger( p_input, p_input->i_object_id, "demux_read",
&i_total );
stats_UpdateFloat( p_input , "demux_bitrate", (float)i_total );
/* Mark preroll blocks */ /* Mark preroll blocks */
if( es->i_preroll_end >= 0 ) if( es->i_preroll_end >= 0 )
{ {
......
...@@ -677,8 +677,11 @@ static int Init( input_thread_t * p_input, vlc_bool_t b_quick ) ...@@ -677,8 +677,11 @@ static int Init( input_thread_t * p_input, vlc_bool_t b_quick )
counter_t *p_counter; counter_t *p_counter;
stats_Create( p_input, "read_bytes", VLC_VAR_INTEGER, STATS_COUNTER ); stats_Create( p_input, "read_bytes", VLC_VAR_INTEGER, STATS_COUNTER );
stats_Create( p_input, "read_packets", VLC_VAR_INTEGER, STATS_COUNTER ); stats_Create( p_input, "read_packets", VLC_VAR_INTEGER, STATS_COUNTER );
stats_Create( p_input, "demux_read", VLC_VAR_INTEGER, STATS_COUNTER );
stats_Create( p_input, "input_bitrate", VLC_VAR_FLOAT, stats_Create( p_input, "input_bitrate", VLC_VAR_FLOAT,
STATS_DERIVATIVE ); STATS_DERIVATIVE );
stats_Create( p_input, "demux_bitrate", VLC_VAR_FLOAT,
STATS_DERIVATIVE );
p_counter = stats_CounterGet( p_input, p_input->i_object_id, p_counter = stats_CounterGet( p_input, p_input->i_object_id,
"input_bitrate" ); "input_bitrate" );
if( p_counter ) p_counter->update_interval = 1000000; if( p_counter ) p_counter->update_interval = 1000000;
......
...@@ -166,6 +166,7 @@ int __stats_Get( vlc_object_t *p_this, int i_object_id, char *psz_name, vlc_valu ...@@ -166,6 +166,7 @@ int __stats_Get( vlc_object_t *p_this, int i_object_id, char *psz_name, vlc_valu
if( p_counter->i_samples == 0 ) if( p_counter->i_samples == 0 )
{ {
vlc_mutex_unlock( &p_handler->object_lock ); vlc_mutex_unlock( &p_handler->object_lock );
val->i_int = val->f_float = 0.0;
return VLC_EGENERIC; return VLC_EGENERIC;
} }
...@@ -244,22 +245,57 @@ counter_t *__stats_CounterGet( vlc_object_t *p_this, int i_object_id, ...@@ -244,22 +245,57 @@ counter_t *__stats_CounterGet( vlc_object_t *p_this, int i_object_id,
void stats_ComputeInputStats( input_thread_t *p_input, void stats_ComputeInputStats( input_thread_t *p_input,
input_stats_t *p_stats ) input_stats_t *p_stats )
{ {
vlc_object_t *p_obj;
vlc_list_t *p_list;
int i_index;
vlc_mutex_lock( &p_stats->lock ); vlc_mutex_lock( &p_stats->lock );
/* read_packets and read_bytes are common to all streams */
/* Input */
stats_GetInteger( p_input, p_input->i_object_id, "read_packets", stats_GetInteger( p_input, p_input->i_object_id, "read_packets",
&p_stats->i_read_packets ); &p_stats->i_read_packets );
stats_GetInteger( p_input, p_input->i_object_id, "read_bytes", stats_GetInteger( p_input, p_input->i_object_id, "read_bytes",
&p_stats->i_read_bytes ); &p_stats->i_read_bytes );
stats_GetFloat( p_input, p_input->i_object_id, "input_bitrate", stats_GetFloat( p_input, p_input->i_object_id, "input_bitrate",
&p_stats->f_bitrate ); &p_stats->f_input_bitrate );
stats_GetInteger( p_input, p_input->i_object_id, "demux_read",
&p_stats->i_demux_read_bytes );
stats_GetFloat( p_input, p_input->i_object_id, "demux_bitrate",
&p_stats->f_demux_bitrate );
stats_GetInteger( p_input, p_input->i_object_id, "decoded_video",
&p_stats->i_decoded_video );
stats_GetInteger( p_input, p_input->i_object_id, "decoded_audio",
&p_stats->i_decoded_audio );
/* Vouts */
p_list = vlc_list_find( p_input, VLC_OBJECT_VOUT, FIND_CHILD );
if( p_list )
{
p_stats->i_displayed_pictures = 0 ;
p_stats->i_lost_pictures = 0;
for( i_index = 0; i_index < p_list->i_count ; i_index ++ )
{
int i_displayed = 0, i_lost = 0;
p_obj = (vlc_object_t *)p_list->p_values[i_index].p_object;
stats_GetInteger( p_obj, p_obj->i_object_id, "displayed_pictures",
&i_displayed );
stats_GetInteger( p_obj, p_obj->i_object_id, "lost_pictures",
&i_lost );
p_stats->i_displayed_pictures += i_displayed;
p_stats->i_lost_pictures += i_lost;
}
vlc_list_release( p_list );
}
vlc_mutex_unlock( &p_stats->lock ); vlc_mutex_unlock( &p_stats->lock );
} }
void stats_ReinitInputStats( input_stats_t *p_stats ) void stats_ReinitInputStats( input_stats_t *p_stats )
{ {
p_stats->i_read_packets = p_stats->i_read_bytes = p_stats->i_read_packets = p_stats->i_read_bytes =
p_stats->f_bitrate = p_stats->f_average_bitrate = p_stats->f_input_bitrate = p_stats->f_average_input_bitrate =
p_stats->i_displayed_pictures = p_stats->i_lost_pictures = 0; p_stats->i_displayed_pictures = p_stats->i_lost_pictures =
p_stats->i_decoded_video = p_stats->i_decoded_audio = 0;
} }
void stats_DumpInputStats( input_stats_t *p_stats ) void stats_DumpInputStats( input_stats_t *p_stats )
...@@ -267,9 +303,10 @@ void stats_DumpInputStats( input_stats_t *p_stats ) ...@@ -267,9 +303,10 @@ void stats_DumpInputStats( input_stats_t *p_stats )
vlc_mutex_lock( &p_stats->lock ); vlc_mutex_lock( &p_stats->lock );
/* f_bitrate is in bytes / microsecond /* f_bitrate is in bytes / microsecond
* *1000 => bytes / millisecond => kbytes / seconds */ * *1000 => bytes / millisecond => kbytes / seconds */
fprintf( stderr, "Read packets : %i (%i bytes) - %f kB/s\n", fprintf( stderr, "Input : %i (%i bytes) - %f kB/s - Vout : %i/%i\n",
p_stats->i_read_packets, p_stats->i_read_bytes, p_stats->i_read_packets, p_stats->i_read_bytes,
p_stats->f_bitrate * 1000 ); p_stats->f_input_bitrate * 1000,
p_stats->i_displayed_pictures, p_stats->i_lost_pictures );
vlc_mutex_unlock( &p_stats->lock ); vlc_mutex_unlock( &p_stats->lock );
} }
...@@ -424,8 +461,6 @@ static counter_t *GetCounter( stats_handler_t *p_handler, int i_object_id, ...@@ -424,8 +461,6 @@ static counter_t *GetCounter( stats_handler_t *p_handler, int i_object_id,
} }
static stats_handler_t *stats_HandlerGet( vlc_object_t *p_this ) static stats_handler_t *stats_HandlerGet( vlc_object_t *p_this )
{ {
stats_handler_t *p_handler = (stats_handler_t*) stats_handler_t *p_handler = (stats_handler_t*)
...@@ -471,5 +506,3 @@ static stats_handler_t* stats_HandlerCreate( vlc_object_t *p_this ) ...@@ -471,5 +506,3 @@ static stats_handler_t* stats_HandlerCreate( vlc_object_t *p_this )
return p_handler; return p_handler;
} }
...@@ -625,8 +625,8 @@ static void RunThread ( playlist_t *p_playlist ) ...@@ -625,8 +625,8 @@ static void RunThread ( playlist_t *p_playlist )
{ {
stats_ComputeInputStats( p_playlist->p_input, stats_ComputeInputStats( p_playlist->p_input,
p_playlist->p_input->input.p_item->p_stats ); p_playlist->p_input->input.p_item->p_stats );
// stats_DumpInputStats( // stats_DumpInputStats(
// p_playlist->p_input->input.p_item->p_stats ); // p_playlist->p_input->input.p_item->p_stats );
} }
/* This input is dead. Remove it ! */ /* This input is dead. Remove it ! */
......
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