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
/* Input */
int i_read_packets;
int i_read_bytes;
float f_input_bitrate;
float f_average_input_bitrate;
float f_bitrate;
float f_average_bitrate;
/* Demux */
int i_demux_read_packets;
int i_demux_read_bytes;
float f_demux_bitrate;
float f_average_demux_bitrate;
/* Decoders */
int i_decoded_audio;
int i_decoded_video;
/* Vout */
int i_displayed_pictures;
......
......@@ -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 **);
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);
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 *);
void __vlc_thread_ready (vlc_object_t *);
int playlist_Export (playlist_t *, const char *, const char *);
......@@ -882,7 +882,7 @@ struct module_symbols_t
void (*stats_ComputeInputStats_inner) (input_thread_t*, input_stats_t*);
void (*stats_DumpInputStats_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__)
# define aout_FiltersCreatePipeline (p_symbols)->aout_FiltersCreatePipeline_inner
......
......@@ -18,6 +18,7 @@ SOURCES_wxwidgets = \
dialogs/messages.cpp \
dialogs/playlist.cpp \
dialogs/iteminfo.cpp \
dialogs/infopanels.cpp \
dialogs/preferences.cpp \
dialogs/preferences_widgets.cpp \
dialogs/preferences_widgets.h \
......@@ -57,6 +58,7 @@ EXTRA_DIST += \
dialogs/open.hpp \
dialogs/messages.hpp \
dialogs/iteminfo.hpp \
dialogs/infopanels.hpp \
dialogs/subtitles.hpp \
dialogs/streamout.hpp \
dialogs/updatevlc.hpp \
......
......@@ -272,7 +272,7 @@ void DialogsProvider::OnIdle( wxIdleEvent& WXUNUSED(event) )
/* Update the fileinfo windows */
if( p_fileinfo_dialog )
p_fileinfo_dialog->UpdateFileInfo();
p_fileinfo_dialog->Update();
}
void DialogsProvider::OnPlaylist( wxCommandEvent& WXUNUSED(event) )
......
......@@ -22,6 +22,7 @@
*****************************************************************************/
#include "dialogs/fileinfo.hpp"
#include "dialogs/infopanels.hpp"
/*****************************************************************************
* Event Table.
......@@ -53,35 +54,36 @@ FileInfo::FileInfo( intf_thread_t *_p_intf, wxWindow *p_parent ):
wxFrame( p_parent, -1, wxU(_("Stream and media info")), wxDefaultPosition,
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 */
p_intf = _p_intf;
SetIcon( *p_intf->p_sys->p_icon );
SetAutoLayout( TRUE );
/* Create a panel to put everything in */
wxPanel *panel = new wxPanel( this, -1 );
panel->SetAutoLayout( TRUE );
wxBoxSizer *panel_sizer = new wxBoxSizer( wxVERTICAL );
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 =
new wxTreeCtrl( panel, -1, wxDefaultPosition, wxSize( 350, 350 ),
wxTR_HAS_BUTTONS | wxTR_HIDE_ROOT | wxSUNKEN_BORDER );
notebook->AddPage( item_info, wxU(_("General") ), true );
notebook->AddPage( stats_info, wxU(_("Statistics") ), false );
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->SetSizerAndFit( panel_sizer );
main_sizer->Add( panel, 1, wxEXPAND, 0 );
main_sizer->Layout();
SetSizerAndFit( main_sizer );
SetSizerAndFit( panel_sizer );
p_playlist = (playlist_t *)vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
FIND_ANYWHERE );
if( p_playlist )
{
......@@ -89,76 +91,49 @@ FileInfo::FileInfo( intf_thread_t *_p_intf, wxWindow *p_parent ):
vlc_object_release( p_playlist );
}
last_update = 0L;
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 *)vlc_object_find( p_intf, VLC_OBJECT_INPUT,
FIND_ANYWHERE );
(input_thread_t *)vlc_object_find( p_playlist, VLC_OBJECT_INPUT,
FIND_CHILD );
if( !p_input || p_input->b_dead || !p_input->input.p_item->psz_name )
{
if( fileinfo_root )
{
fileinfo_root_label = wxT("");
fileinfo_tree->DeleteChildren( fileinfo_root );
}
if (p_input)
item_info->Clear();
stats_info->Clear();
if ( p_input )
{
vlc_object_release(p_input);
}
vlc_object_release( p_playlist );
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 );
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];
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 );
item_info->Update( p_input->input.p_item );
}
stats_info->Update( p_input->input.p_item );
vlc_mutex_unlock( &p_input->input.p_item->lock );
b_need_update = VLC_FALSE;
vlc_object_release(p_input);
vlc_object_release( p_playlist );
b_need_update = VLC_FALSE;
return;
}
......
......@@ -30,13 +30,15 @@
namespace wxvlc
{
class ItemInfoPanel;
class InputStatsInfoPanel;
class FileInfo: public wxFrame
{
public:
/* Constructor */
FileInfo( intf_thread_t *p_intf, wxWindow *p_parent );
virtual ~FileInfo();
void UpdateFileInfo();
void Update();
vlc_bool_t b_need_update;
......@@ -47,9 +49,11 @@ namespace wxvlc
DECLARE_EVENT_TABLE();
intf_thread_t *p_intf;
wxTreeCtrl *fileinfo_tree;
wxTreeItemId fileinfo_root;
wxString fileinfo_root_label;
mtime_t last_update;
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,
p_dec->pf_decode_sub = 0;
p_dec->pf_packetize = 0;
stats_Create( p_dec, "decoded_audio", VLC_VAR_INTEGER, STATS_COUNTER );
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 */
/* Initialize the decoder fifo */
p_dec->p_module = NULL;
......@@ -433,6 +429,12 @@ static decoder_t * CreateDecoder( input_thread_t *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 */
if( i_object_type == VLC_OBJECT_DECODER )
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 )
while( (p_aout_buf = p_dec->pf_decode_audio( p_dec,
&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
* but that's not easy with non raw audio stream */
if( p_dec->p_owner->i_preroll_end > 0 &&
......@@ -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 )) )
{
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 &&
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 )
while( (p_pic = p_dec->pf_decode_video( p_dec,
&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 &&
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 )
}
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 &&
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 )
subpicture_t *p_spu;
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 &&
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 ) )
......
......@@ -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;
es_out_pgrm_t *p_pgrm = es->p_pgrm;
int64_t i_delay;
int i_total;
if( es->fmt.i_cat == AUDIO_ES )
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 )
else
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 */
if( es->i_preroll_end >= 0 )
{
......
......@@ -677,8 +677,11 @@ static int Init( input_thread_t * p_input, vlc_bool_t b_quick )
counter_t *p_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, "demux_read", VLC_VAR_INTEGER, STATS_COUNTER );
stats_Create( p_input, "input_bitrate", VLC_VAR_FLOAT,
STATS_DERIVATIVE );
stats_Create( p_input, "demux_bitrate", VLC_VAR_FLOAT,
STATS_DERIVATIVE );
p_counter = stats_CounterGet( p_input, p_input->i_object_id,
"input_bitrate" );
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
if( p_counter->i_samples == 0 )
{
vlc_mutex_unlock( &p_handler->object_lock );
val->i_int = val->f_float = 0.0;
return VLC_EGENERIC;
}
......@@ -244,22 +245,57 @@ counter_t *__stats_CounterGet( vlc_object_t *p_this, int i_object_id,