* Video with XANIM is working on Multimedia Board (I must improve the window

sizing, ...): it shows me movies.
* Fixed a major bug in sndcpcm: we must divide by 2 the length of the
  sound block because we work in 16 bits mode
* Support for Video in wxMultimediaBoard
* Other fixes


git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@6090 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Guilhem Lavaux
2000-02-16 20:20:11 +00:00
parent 3da93aae50
commit d73dd2b2fc
16 changed files with 295 additions and 103 deletions

View File

@@ -30,7 +30,7 @@
#include "wx/wx.h"
#endif
// Personnal headers
// Personal headers
#include "wx/stream.h"
#include "wx/wfstream.h"
@@ -51,6 +51,15 @@
#include "sndwin.h"
#endif
#include "vidbase.h"
#ifdef __UNIX__
#include "vidxanm.h"
#endif
#ifdef __WIN32__
#include "vidwin.h"
#endif
#include "mmboard.h"
#include "mmbman.h"
@@ -89,12 +98,45 @@ protected:
wxSoundFileStream *m_file_stream;
MMBoardTime m_length;
wxUint8 m_file_type;
};
class MMBoardVideoFile: public MMBoardFile {
public:
MMBoardVideoFile(const wxString& filename);
~MMBoardVideoFile();
bool NeedWindow();
void SetWindow(wxWindow *window);
void Play();
void Pause();
void Resume();
void Stop();
MMBoardTime GetPosition();
MMBoardTime GetLength();
bool IsStopped();
bool IsPaused();
wxString GetStringType();
wxString GetStringInformation();
protected:
wxWindow *m_output_window;
wxInputStream *m_input_stream;
wxVideoBaseDriver *m_video_driver;
};
// ----------------------------------------------------------------------------
// Implementation
// ----------------------------------------------------------------------------
#define MMBoard_UNKNOWNTYPE 0
#define MMBoard_WAVE 1
#define MMBoard_AIFF 2
// ----------------------------------------------------------------------------
// MMBoardSoundFile
@@ -107,9 +149,11 @@ MMBoardSoundFile::MMBoardSoundFile(const wxString& filename)
m_file_stream = GetDecoder();
if (!m_file_stream)
if (!m_file_stream) {
SetError(MMBoard_UnknownFile);
return;
}
// Compute length
wxUint32 length, seconds;
@@ -122,7 +166,8 @@ MMBoardSoundFile::MMBoardSoundFile(const wxString& filename)
MMBoardSoundFile::~MMBoardSoundFile()
{
delete m_file_stream;
if (m_file_stream)
delete m_file_stream;
MMBoardManager::UnrefSoundStream(m_output_stream);
delete m_input_stream;
}
@@ -133,16 +178,20 @@ wxSoundFileStream *MMBoardSoundFile::GetDecoder()
// First, we try a Wave decoder
f_stream = new wxSoundWave(*m_input_stream, *m_output_stream);
m_file_type = MMBoard_WAVE;
if (f_stream->CanRead())
return f_stream;
delete f_stream;
// Then, a AIFF decoder
f_stream = new wxSoundAiff(*m_input_stream, *m_output_stream);
m_file_type = MMBoard_AIFF;
if (f_stream->CanRead())
return f_stream;
delete f_stream;
m_file_type = MMBoard_UNKNOWNTYPE;
// TODO: automate
return NULL;
@@ -212,7 +261,17 @@ void MMBoardSoundFile::Stop()
wxString MMBoardSoundFile::GetStringType()
{
return wxString("WAVE file");
switch (m_file_type) {
case MMBoard_WAVE:
return wxString("WAVE file");
break;
case MMBoard_AIFF:
return wxString("AIFF file");
break;
default:
return wxString("Unknown file");
break;
}
}
wxString MMBoardSoundFile::GetStringInformation()
@@ -253,6 +312,101 @@ wxString MMBoardSoundFile::GetStringInformation()
// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
// MMBoardVideoFile
MMBoardVideoFile::MMBoardVideoFile(const wxString& filename)
{
m_output_window = NULL;
m_input_stream = new wxFileInputStream(filename);
#if defined(__UNIX__)
m_video_driver = new wxVideoXANIM(*m_input_stream);
#elif defined(__WIN32__)
m_video_driver = new wxVideoWindows(m_input_stream);
#else
m_video_driver = NULL;
SetError(MMBoard_UnknownFile);
#endif
}
MMBoardVideoFile::~MMBoardVideoFile()
{
if (m_video_driver)
delete m_video_driver;
delete m_input_stream;
}
bool MMBoardVideoFile::NeedWindow()
{
return TRUE;
}
void MMBoardVideoFile::SetWindow(wxWindow *window)
{
m_output_window = window;
m_video_driver->AttachOutput(*window);
}
void MMBoardVideoFile::Play()
{
m_video_driver->Play();
}
void MMBoardVideoFile::Pause()
{
m_video_driver->Pause();
}
void MMBoardVideoFile::Resume()
{
m_video_driver->Resume();
}
void MMBoardVideoFile::Stop()
{
m_video_driver->Stop();
}
MMBoardTime MMBoardVideoFile::GetPosition()
{
MMBoardTime btime;
btime.seconds = btime.minutes = btime.hours = 0;
return btime;
}
MMBoardTime MMBoardVideoFile::GetLength()
{
MMBoardTime btime;
btime.seconds = btime.minutes = btime.hours = 1;
return btime;
}
bool MMBoardVideoFile::IsStopped()
{
return FALSE;
}
bool MMBoardVideoFile::IsPaused()
{
return FALSE;
}
wxString MMBoardVideoFile::GetStringType()
{
return wxString("Video XANIM");
}
wxString MMBoardVideoFile::GetStringInformation()
{
return wxString("No info");
}
// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
// MMBoardFile
@@ -275,12 +429,20 @@ MMBoardFile *MMBoardManager::Open(const wxString& filename)
{
MMBoardFile *file;
// Test the audio codec
file = new MMBoardSoundFile(filename);
if (file->GetError()) {
delete file;
return NULL;
}
return file;
if (!file->GetError())
return file;
delete file;
// Test the video codec
file = new MMBoardVideoFile(filename);
if (!file->GetError())
return file;
delete file;
// Arrrgh, we just could not see what is that file ...
return NULL;
}
DECLARE_APP(MMBoardApp)

View File

@@ -85,6 +85,9 @@ public:
void OnPause(wxCommandEvent& event);
void OnRefreshInfo(wxEvent& event);
void OpenVideoWindow();
void CloseVideoWindow();
private:
// any class wishing to process wxWindows events must use this macro
DECLARE_EVENT_TABLE()
@@ -98,8 +101,13 @@ private:
wxSlider *m_positionSlider;
wxBitmapButton *m_playButton, *m_pauseButton, *m_stopButton, *m_ejectButton;
wxStaticText *m_fileType, *m_infoText;
wxWindow *m_video_window;
wxPanel *m_panel;
wxSizer *m_sizer;
wxTimer *m_refreshTimer;
};
// ----------------------------------------------------------------------------
@@ -260,16 +268,16 @@ MMBoardFrame::MMBoardFrame(const wxString& title, const wxPoint& pos, const wxSi
// Misc variables
m_opened_file = NULL;
wxPanel *panel = new wxPanel(this, -1);
m_panel = new wxPanel(this, -1);
// Initialize main slider
m_positionSlider = new wxSlider( panel, MMBoard_PositionSlider, 0, 0, 60,
m_positionSlider = new wxSlider( m_panel, MMBoard_PositionSlider, 0, 0, 60,
wxDefaultPosition, wxSize(300, -1),
wxSL_HORIZONTAL | wxSL_AUTOTICKS);
m_positionSlider->SetPageSize(60); // 60 secs
// Initialize info panel
wxPanel *infoPanel = new wxPanel( panel, -1);
wxPanel *infoPanel = new wxPanel( m_panel, -1);
infoPanel->SetBackgroundColour(*wxBLACK);
infoPanel->SetForegroundColour(*wxWHITE);
@@ -296,13 +304,13 @@ MMBoardFrame::MMBoardFrame(const wxString& title, const wxPoint& pos, const wxSi
wxBitmap *eject_bmp = new wxBitmap(eject_xpm);
wxBitmap *pause_bmp = new wxBitmap(pause_xpm);
m_playButton = new wxBitmapButton(panel, MMBoard_PlayButton, *play_bmp);
m_playButton = new wxBitmapButton(m_panel, MMBoard_PlayButton, *play_bmp);
m_playButton->Enable(FALSE);
m_pauseButton = new wxBitmapButton(panel, MMBoard_PauseButton, *pause_bmp);
m_pauseButton = new wxBitmapButton(m_panel, MMBoard_PauseButton, *pause_bmp);
m_pauseButton->Enable(FALSE);
m_stopButton = new wxBitmapButton(panel, MMBoard_StopButton, *stop_bmp);
m_stopButton = new wxBitmapButton(m_panel, MMBoard_StopButton, *stop_bmp);
m_stopButton->Enable(FALSE);
m_ejectButton = new wxBitmapButton(panel, MMBoard_EjectButton, *eject_bmp);
m_ejectButton = new wxBitmapButton(m_panel, MMBoard_EjectButton, *eject_bmp);
m_ejectButton->Enable(FALSE);
buttonSizer->Add(m_playButton, 0, wxALL, 2);
@@ -311,21 +319,27 @@ MMBoardFrame::MMBoardFrame(const wxString& title, const wxPoint& pos, const wxSi
buttonSizer->Add(m_ejectButton, 0, wxALL, 2);
// Top sizer
wxBoxSizer *sizer = new wxBoxSizer(wxVERTICAL);
sizer->Add(new wxStaticLine(panel, -1), 0, wxGROW | wxCENTRE, 0);
sizer->Add(m_positionSlider, 0, wxCENTRE | wxGROW | wxALL, 2);
sizer->Add(new wxStaticLine(panel, -1), 0, wxGROW | wxCENTRE, 0);
sizer->Add(buttonSizer, 0, wxALL, 0);
sizer->Add(new wxStaticLine(panel, -1), 0, wxGROW | wxCENTRE, 0);
sizer->Add(infoPanel, 1, wxCENTRE | wxGROW, 0);
m_sizer = new wxBoxSizer(wxVERTICAL);
m_sizer->Add(new wxStaticLine(m_panel, -1), 0, wxGROW | wxCENTRE, 0);
m_sizer->Add(m_positionSlider, 0, wxCENTRE | wxGROW | wxALL, 2);
m_sizer->Add(new wxStaticLine(m_panel, -1), 0, wxGROW | wxCENTRE, 0);
m_sizer->Add(buttonSizer, 0, wxALL, 0);
m_sizer->Add(new wxStaticLine(m_panel, -1), 0, wxGROW | wxCENTRE, 0);
m_sizer->Add(infoPanel, 1, wxCENTRE | wxGROW, 0);
panel->SetSizer(sizer);
panel->SetAutoLayout(TRUE);
sizer->Fit(this);
sizer->SetSizeHints(this);
m_panel->SetSizer(m_sizer);
m_panel->SetAutoLayout(TRUE);
m_sizer->Fit(this);
m_sizer->SetSizeHints(this);
// Timer
m_refreshTimer = new wxTimer(this, MMBoard_RefreshInfo);
// Video window
m_video_window = NULL;
// Multimedia file
m_opened_file = NULL;
}
MMBoardFrame::~MMBoardFrame()
@@ -336,6 +350,30 @@ MMBoardFrame::~MMBoardFrame()
delete m_refreshTimer;
}
void MMBoardFrame::OpenVideoWindow()
{
if (m_video_window)
return;
m_video_window = new wxWindow(m_panel, -1, wxDefaultPosition, wxSize(400, 400));
m_video_window->SetBackgroundColour(*wxBLACK);
m_sizer->Prepend(m_video_window, 0, wxCENTRE, 0);
m_sizer->Fit(this);
}
void MMBoardFrame::CloseVideoWindow()
{
if (!m_video_window)
return;
m_sizer->Remove(m_video_window);
delete m_video_window;
m_video_window = NULL;
m_sizer->Fit(this);
}
// event handlers
void MMBoardFrame::OnQuit(wxCommandEvent& WXUNUSED(event))
@@ -358,6 +396,14 @@ void MMBoardFrame::OnOpen(wxCommandEvent& WXUNUSED(event))
{
wxString selected_file;
if (m_opened_file) {
if (!m_opened_file->IsStopped()) {
wxCommandEvent event2;
OnStop(event2);
}
delete m_opened_file;
}
// select a file to be opened
selected_file = wxLoadFileSelector("multimedia", "*", NULL, this);
if (selected_file.IsNull())
@@ -382,6 +428,12 @@ void MMBoardFrame::OnOpen(wxCommandEvent& WXUNUSED(event))
// Enable a few buttons
m_playButton->Enable(TRUE);
m_ejectButton->Enable(TRUE);
if (m_opened_file->NeedWindow()) {
OpenVideoWindow();
m_opened_file->SetWindow(m_video_window);
} else
CloseVideoWindow();
}
void MMBoardFrame::UpdateInfoText()

View File

@@ -1,3 +1,5 @@
#include <stdio.h>
#define DEFINE_CONV(name, input_type, output_type, convert) \
static void Convert_##name##(const char *buf_in, char *buf_out, wxUint32 len) \
{\
@@ -8,7 +10,7 @@ static void Convert_##name##(const char *buf_in, char *buf_out, wxUint32 len) \
while (len > 0) { \
src = *t_buf_in++; \
*t_buf_out++ = convert; \
len--; \
len -= sizeof(input_type); \
} \
}

View File

@@ -141,7 +141,7 @@ bool wxSoundAiff::PrepareToPlay()
// m_input->SeekI(4, wxFromCurrent); // Pass an INT32
// m_input->SeekI(len-4, wxFromCurrent); // Pass the rest
m_input->SeekI(ssnd + 4, wxFromCurrent);
FinishPreparation(len - 4);
FinishPreparation(len - 8);
end_headers = TRUE;
break;
}

View File

@@ -137,9 +137,6 @@ class wxSoundStream {
// Sets the event handler: if it is non-null, all events are routed to it.
void SetEventHandler(wxSoundStream *handler) { m_handler = handler; }
// Initializes the full duplex mode.
virtual void SetDuplexMode(bool duplex) = 0;
wxSoundError GetError() const { return m_snderror; }
wxUint32 GetLastAccess() const { return m_lastcount; }

View File

@@ -32,11 +32,6 @@ bool wxSoundStreamCodec::StopProduction()
return m_sndio->StopProduction();
}
void wxSoundStreamCodec::SetDuplexMode(bool duplex)
{
m_sndio->SetDuplexMode(duplex);
}
wxUint32 wxSoundStreamCodec::GetBestSize() const
{
return m_sndio->GetBestSize();

View File

@@ -22,7 +22,6 @@ class wxSoundStreamCodec: public wxSoundStream {
bool StartProduction(int evt);
bool StopProduction();
void SetDuplexMode(bool duplex);
wxUint32 GetBestSize() const;
protected:

View File

@@ -33,8 +33,6 @@ class wxSoundStreamESD : public wxSoundStream {
bool StartProduction(int evt);
bool StopProduction();
void SetDuplexMode(bool duplex) {}
// You should not call this.
void WakeUpEvt(int evt);

View File

@@ -2,7 +2,7 @@
// Name: sndfile.cpp
// Purpose:
// Date: 08/11/1999
// Author: Guilhem Lavaux <lavaux@easynet.fr> (C) 1999
// Author: Guilhem Lavaux <lavaux@easynet.fr> (C) 1999, 2000
// CVSID: $Id$
// --------------------------------------------------------------------------
#include <wx/wxprec.h>
@@ -296,10 +296,6 @@ wxSoundStream& wxSoundFileStream::Write(const void *buffer, wxUint32 len)
return *this;
}
void wxSoundFileStream::SetDuplexMode(bool duplex)
{
}
bool wxSoundFileStream::StartProduction(int evt)
{
m_sndio->SetEventHandler(this);
@@ -337,6 +333,23 @@ wxUint32 wxSoundFileStream::GetPosition()
return m_length-m_bytes_left;
}
wxUint32 wxSoundFileStream::SetPosition(wxUint32 new_position)
{
if (!m_prepared && m_input != NULL && GetError() == wxSOUND_NOERR)
PrepareToPlay();
if (!m_prepared)
return 0;
if (new_position >= m_length) {
m_bytes_left = 0;
return m_length;
}
m_bytes_left = m_length-new_position;
return new_position;
}
void wxSoundFileStream::OnSoundEvent(int evt)
{
wxUint32 len = m_codec.GetBestSize();

View File

@@ -56,28 +56,42 @@ class wxSoundFileStream: public wxSoundStream {
wxSoundFileStream(wxOutputStream& stream, wxSoundStream& io_sound);
~wxSoundFileStream();
// Usual sound file calls (Play, Stop, ...)
bool Play();
bool Record(unsigned long time);
bool Stop();
bool Pause();
bool Resume();
// Functions which return the current state
bool IsStopped() const { return m_state == wxSOUND_FILE_STOPPED; }
bool IsPaused() const { return m_state == wxSOUND_FILE_PAUSED; }
// A user should not call these two functions. Several things must be done before calling them.
// Users should use Play(), ...
bool StartProduction(int evt);
bool StopProduction();
// These three functions deals with the length, the position in the sound file.
// All the values are expressed in bytes. If you need the values expressed in terms of
// time, you have to use GetSoundFormat().GetTimeFromBytes(...)
wxUint32 GetLength();
wxUint32 GetPosition();
wxUint32 SetPosition(wxUint32 new_position);
// These two functions use the sound format specified by GetSoundFormat(). All samples
// must be encoded in that format.
wxSoundStream& Read(void *buffer, wxUint32 len);
wxSoundStream& Write(const void *buffer, wxUint32 len);
void SetDuplexMode(bool duplex);
// This function set the sound format of the file. !! It must be used only when you are
// in output mode (concerning the file) !! If you are in input mode (concerning the file)
// You can't use this function to modify the format of the samples returned by Read() !
// For this action, you must use wxSoundRouterStream applied to wxSoundFileStream.
bool SetSoundFormat(const wxSoundFormatBase& format);
// You should use this function to test whether this file codec can read the stream you passed
// to it.
virtual bool CanRead() { return FALSE; }
protected:

View File

@@ -34,7 +34,6 @@ class wxSoundStreamOSS : public wxSoundStream {
bool StartProduction(int evt);
bool StopProduction();
void SetDuplexMode(bool duplex) {}
bool QueueFilled() const;
// You should not call this.

View File

@@ -23,7 +23,6 @@ class WXDLLEXPORT wxSoundStreamWin : public wxSoundStream {
wxSoundStream& Read(void *buffer, wxUint32 len);
bool SetSoundFormat(wxSoundFormatBase& base);
void SetDuplexMode(bool on) {}
bool StartProduction(int evt);
bool StopProduction();

View File

@@ -25,27 +25,8 @@
#endif
IMPLEMENT_ABSTRACT_CLASS(wxVideoBaseDriver, wxObject)
IMPLEMENT_DYNAMIC_CLASS(wxVideoOutput, wxWindow)
wxVideoOutput::wxVideoOutput()
: wxWindow()
{
m_dyn_size = TRUE;
}
wxVideoOutput::wxVideoOutput(wxWindow *parent, const wxWindowID id, const wxPoint& position,
const wxSize& size, const long style,
const wxString& name)
: wxWindow(parent, id, position, size, style, name)
{
m_dyn_size = TRUE;
}
///
wxVideoOutput::~wxVideoOutput()
{
}
wxVideoBaseDriver::wxVideoBaseDriver()
{
m_video_output = NULL;
@@ -60,7 +41,7 @@ wxVideoBaseDriver::~wxVideoBaseDriver()
{
}
bool wxVideoBaseDriver::AttachOutput(wxVideoOutput& output)
bool wxVideoBaseDriver::AttachOutput(wxWindow& output)
{
m_video_output = &output;
return TRUE;
@@ -76,9 +57,8 @@ void wxVideoBaseDriver::DetachOutput()
wxFrame *wxVideoCreateFrame(wxVideoBaseDriver *vid_drv)
{
wxFrame *frame = new wxFrame(NULL, -1, "Video Output", wxDefaultPosition, wxSize(100, 100));
wxVideoOutput *vid_out = new wxVideoOutput(frame, -1, wxPoint(0, 0), wxSize(300, 300));
wxWindow *vid_out = new wxWindow(frame, -1, wxPoint(0, 0), wxSize(300, 300));
vid_out->DynamicSize(TRUE);
frame->Layout();
frame->Show(TRUE);

View File

@@ -36,37 +36,14 @@ typedef enum {
///
class wxVideoBaseDriver;
class wxVideoOutput : public wxWindow {
///
DECLARE_DYNAMIC_CLASS(wxVideoOutput)
protected:
bool m_dyn_size;
public:
///
wxVideoOutput();
///
wxVideoOutput(wxWindow *parent, const wxWindowID id,
const wxPoint& pos = wxDefaultPosition,
const wxSize& size = wxDefaultSize, const long style = 0,
const wxString& name = "video_output");
///
virtual ~wxVideoOutput();
///
bool DynamicSize() { return m_dyn_size; }
///
void DynamicSize(bool dyn) { m_dyn_size = dyn; }
};
///
class wxVideoBaseDriver : public wxObject {
///
DECLARE_ABSTRACT_CLASS(wxVideoBaseDriver)
protected:
wxVideoOutput *m_video_output;
wxWindow *m_video_output;
public:
friend class wxVideoOutput;
//
wxVideoBaseDriver();
//
@@ -74,7 +51,6 @@ public:
//
virtual ~wxVideoBaseDriver();
//
virtual bool Play() = 0;
//
@@ -98,7 +74,7 @@ public:
virtual void OnFinished() {}
//
virtual bool AttachOutput(wxVideoOutput& output);
virtual bool AttachOutput(wxWindow& output);
//
virtual void DetachOutput();
};

View File

@@ -15,6 +15,10 @@
#else
#include <wx/wx.h>
#endif
// Pizza !
#include <wx/gtk/win_gtk.h>
#include <X11/Xlib.h>
#include <X11/Intrinsic.h>
#ifdef __WXGTK__
@@ -144,7 +148,7 @@ bool wxVideoXANIM::IsCapable(wxVideoType v_type)
return FALSE;
}
bool wxVideoXANIM::AttachOutput(wxVideoOutput& out)
bool wxVideoXANIM::AttachOutput(wxWindow& out)
{
if (!wxVideoBaseDriver::AttachOutput(out))
return FALSE;
@@ -202,14 +206,16 @@ bool wxVideoXANIM::RestartXANIM()
return FALSE;
// Check if we can change the size of the window dynamicly
xanim_chg_size = m_video_output->DynamicSize();
xanim_chg_size = TRUE;
// Get current display
#ifdef __WXGTK__
m_internal->xanim_dpy = gdk_display;
// We absolutely need the window to be realized.
gtk_widget_realize(m_video_output->m_wxwindow);
GtkPizza *pizza = GTK_PIZZA( m_video_output->m_wxwindow );
GdkWindow *window = pizza->bin_window;
m_internal->xanim_window =
((GdkWindowPrivate *)m_video_output->m_wxwindow->window)->xwindow;
((GdkWindowPrivate *)window)->xwindow;
#endif
// Get the XANIM atom
m_internal->xanim_atom = XInternAtom(m_internal->xanim_dpy,

View File

@@ -56,7 +56,7 @@ public:
bool IsCapable(wxVideoType v_type);
bool AttachOutput(wxVideoOutput& output);
bool AttachOutput(wxWindow& output);
void DetachOutput();
protected: