[vlc-devel] Re: access_demux versus access2 - trying to understand how to write a VCD plugin

R. Bernstein rocky at panix.com
Fri Dec 24 06:32:35 CET 2004


Thanks for the more high-level overview. It helps quite a bit,
although, alas, a full-feature VCD plugin is going to be a bit more
involved. (Even if it is cleaner and more doable than it was a year
ago).  Happy Holiday!

Laurent Aimar writes:
 > On Thu, Dec 23, 2004, R. Bernstein wrote:
 > > Since the first time I looked at videolan in to write a VCD plugin
 > > with playback control, a great deal seems to have changed. 
 > > 
 > > One thing that hasn't is the lack of developer information or
 > > documentation. So I look at close source code and the two things that
 > > seem the most relevant are dvdnav.c and v4l.c. 
 > > 
 > > The things that the VCD plugin needs to do (which it doesn't right
 > > now) is detect changes in streams between still-frame MPEGs and motion
 > > MPEGs which may have different aspect ratios. Also it needs to handle
 > > key events.
 > > 
 > > Looking at dvdnav.c and v4l.c I see neither uses
 > > set_capability("access2") like the VCD and CDDA plugins are, but
 > > set_capability("access_demux") instead. It seems like they provide
 > > both the input reading part ("access") as well as the some demuxing
 > > part at least to be able to signal the kinds of stream changes and
 > > input events mentioned above. 
 > 
 > 
 > The general(main) architecture of vlc input is
 > 
 >  access_t -> stream_t -> demux_t -> es_out_t
 > 
 > You have
 >  access_t : it does the reading part ('protocol' specific, like http, file).
 >  demux_t  : it understands a format of encapsulation (like AVI, MPEG-PS),
 >             it extracts the elementary stream(s), and it handles the seeking
 >             part.
 > 
 > The core provides:
 >  stream_t : it is the glue between access_t and demux_t (and add a layer
 >             of abstraction). It also adds a buffering system.
 >  es_out_t : it handles the ES selection, the packetization and decoding part.
 >             it converts PTS/DTS given by demuxer in nice system date, and
 >             it controls the speed of the input (es_out_Send() is blocking).
 > 
 >  This way work swell when a demuxer has a really simple relation with the
 > access. But some time, the access part (reading) and the demuxer part
 > (demuxing and seeking) are really tied together. For those cases, a
 > access_demux_t can be used instead:
 > 
 >  access_demux_t -> es_out_t
 > 
 >  (No more access and no more stream_t).
 >  The input core will see the access_demux_t as a demux_t except for a few
 > control (access_demux_t->pf_control).
 >  The field access_demux_t->s is NULL as it has to do the reading part itself.
 >  The access_demux_t should provide (as all demuxers):
 >   - pf_demux: it will read data, demux them and send them to es_out_t.
 >   - pf_control: various demuxer controls, that the input will call.
 >  A few DEMUX_* are mandatory (see include/vlc_demux.h)
 > 
 > > Lastly question is on es_out_Control (a static inline function which
 > > mostly calls out->pf_control) and the other es_out_* routines. How
 > > does one understand what do what they require or how to use, I guess
 > > specifically for MPEG streams. 
 > 
 > About es_out_t <-> demux_t the general case will be:
 >  es_format_t fmt;
 >  es_out_id_t *p_es;
 > 
 >  // First, declare the ES (at anytime, but the best for user/interface, is
 > the earlier)
 > 
 >  es_format_Init( &fmt, AUDIO_ES, VLC_FOURCC( 'm', 'p', 'g', 'a' ) );
 >  fmt.XXX = XXX;
 >  ...
 >  p_es = es_out_Add( p_demux->out, &fmt );
 > 
 > 
 > 
 >  // Now when demuxing:
 > 
 >  // If you know that you have a discontinuity (but no need after a seek, the
 >  input core takes care of that case) then reset the PCR
 >  if( i_have_detected_a_discontinuity )
 >      es_out_Control( p_demux->out, p_es, ES_CONTROL_RESET_PCR );
 > 
 >  // You have to send PCR (one a least before the first packet).
 >  if( i_have_a_new_pcr )
 >  {
 >     int64_t i_pcr = my_pcr_in_microsecond;
 >     es_out_Control( p_demux->out, p_es, ES_CONTROL_SET_PCR, i_pcr );
 >  }
 > 
 >  // Send data to the decoder (if no decoder, then the data will be discarded)
 >  // Fill the block_t with the right info before.
 >  block_t *p_data;
 >  p_data = block_New( p_demux, my_data_size );
 >  p_data->i_buffer = my_buffer_size; // (not mandatory, block_New does it).
 >  memcpy( p_data->p_buffer, my_data, my_data_size );
 >  if( i_have_a_new_dts )
 >      p_data->i_dts = my_dts_in_microsecond;
 >  if( i_have_a_new_pts )
 >      p_data->i_pts = my_pts_in_microsecond;
 >  if( is_video_trakc && i_know_the_data_frame_type )
 >  {
 >     if( is_i_frame )
 >         p_data->i_flags |= BLOCK_FALG_TYPE_I;
 >     else if( is_p_frame )
 >         p_data->i_flags |= BLOCK_FALG_TYPE_P;
 >     else if( is_b_frame )
 >         p_data->i_flags |= BLOCK_FALG_TYPE_B;
 >     else if( i_only_know_it_is_not_a_key_frame )
 >         p_data->i_flags |= BLOCK_FALG_TYPE_PB;
 > 
 >  }
 >  if( i_have_the_sample_length )
 >      p_data->i_length = my_length_in_microsecond;
 > 
 >  es_out_Send( p_demux->out, p_es, p_data );
 > 
 > 
 >  You can do a es_out_Del( p_demux->out, p_es ) to remove a specific ES
 >  before the end of the input stream.
 >  (The core will remove all remaining ES after unloading the demux/access_demux
 > at the end).
 > 
 > (All others ES_OUT_CONTROL_* are used by the core, and you don't need them).
 > Have a look at include/vlc_es_out.h).
 > 
 > 
 >  I hope this will help. If you have others questions, don't hesitate.
 > (but I won't be able to answer before january).
 > 
 > -- 
 > fenrir
 > 
 > -- 
 > This is the vlc-devel mailing-list, see http://www.videolan.org/vlc/
 > To unsubscribe, please read http://developers.videolan.org/lists.html

-- 
This is the vlc-devel mailing-list, see http://www.videolan.org/vlc/
To unsubscribe, please read http://developers.videolan.org/lists.html



More information about the vlc-devel mailing list