OpenMediaLib User and Development Guide
- OpenMediaLib User Development Guide
- Introduction
- High Level Use
- Reverse Polish Notation
- Applying RPN to Video/Audio
- Clip Modifications
- Compositing
- Playlists
- Stack Manipulations
- Advanced Stack Usage
- Aspect Ratio Considerations
- The Encoding Filter Graph
- Compositing Revisited
- Really, Really Advanced Stack Usage
- General Audio Issues
- Python
- Interpolation
- Threading
Putting it All Together
It is acknowledged that the above is rather abstract, so let's continue by making it a bit more concrete. We'll take a traditional video editor as our application and model it into the RPN filter graph system:
track 1: +------------------------+ +------------------+
| input1 | |input3 |
+------------------------+ +------------------+
| filter | |filter |
+------------------------+ +------------------+
track 2: +----------------------------------+
| input2 |
+----------------------------------+
We interpret it as 4 filter graphs:
/--- FG0 ---//--- FG1 ---//------- FG2 ---------//------ FG3 -------/
We also typically composite the results on to a background or canvas (typically, this is just a black image – you can picture this as being introduced as track 0 and it'll stretch for the duration of the longest track [track 1 in this case]).
Internally, we hook up our graphs as follows:
FG0: bg input1 filter:filter filter:composite
FG1: bg input1 filter:filter input2 filter:composite filter:composite
FG2: bg input2 filter:composite
FG3: bg input3 filter:filter filter:composite
Notes:
1) the FGs need to be constructed on demand (ie: when you cross from one section to the next) 2) in order to satisfy 1, we need to be able to construct and deconstruct the graphs to reuse the same objects 3) the objects in the multitrack are not the physical nodes - they're proxies which allow the identification of the node
Interfaces:
input_type:
// Property object
pcos::property_container properties( )
// Basic information
virtual const openpluginlib::wstring get_uri( ) const = 0;
virtual const openpluginlib::wstring get_mime_type( ) const = 0;
virtual bool has_video( ) const = 0;
virtual bool has_audio( ) const = 0;
// Audio/Visual
virtual int get_frames( ) const = 0;
virtual bool is_seekable( ) const = 0;
// Visual
virtual int get_video_streams( ) const = 0;
// Audio
virtual int get_audio_streams( ) const = 0;
// Set video and audio streams
virtual bool set_video_stream( const int ) { return false; }
virtual bool set_audio_stream( const int ) { return false; }
void set_process_flags( int flags )
int get_process_flags( )
// Default seek functionality
virtual void seek( const int position, const bool relative = false )
virtual int get_position( ) const
// Virtual frame fetch method
virtual frame_type_ptr fetch( ) = 0;
// Allow the app to refresh a cached frame
virtual void refresh_cache( frame_type_ptr ) { }
store_type: // Property object pcos::property_container properties( ) // Initialise method virtual bool init( ) // Push a frame to the store virtual bool push( frame_type_ptr ) = 0; // Tell the store to flush all pending frames, while returning the // one that was pending. The default implementation applies when // the store doesn't queue frames. virtual frame_type_ptr flush( ) // Playout all queued frames and return when done. The default // implementation applies when the store doesn't queue frames. virtual void complete( ) // Allows the store to dictate when it is running empty (ie: any // realtime store such as an audio player or device feed needs more // frames in order to provide smooth playout) virtual bool empty( )
filter_type:
