[Libburn] Reading procedure

Derek Foreman manmower at signalmarketing.com
Tue Oct 19 19:51:51 PDT 2004


On Fri, 15 Oct 2004, Tiago Cogumbreiro wrote:

> Hi list,
>
> I've been thinking about how the reading procedure should be visible to
> the user.
>
> Derek told me the source will be an abstraction layer. One of the
> sources will be the real cd drive, the others I assume are cd images, is
> this it?

I'm sorry, I was unclear.  The abstraction defines where the data will be 
put after it is read from a cd.

> My proposition is that optical media, aka CD's, DVD's and all, should be
> presented to the user as an array of data streams, a stream is like C's
> FILE struct. It is an array because there are multitracked optical media
> and the user needs to destinguish them, for example when extracting
> audio tracks from a CD. But we also want to enhance the library with the
> possibility for the user to implement it's own error recovery
> technology, while reading the streams, this is the simple Strategy
> pattern[1].

Interesting.  This isn't quite how I'd planned to expose the CD to a 
regular app.

> Let's call the strategy the 'data filter' (DF). What is the DF? It's
> basically a hook function that we need to send a certain number of
> arguments in order to provide a way to let the user correct the read
> errors.
>
> Most of you might not know, but my interest on libburn began because I
> had my own cdrecording library[2] and thought it was a duplicate effort
> to work on it when there was already libburn (which is more advanced).
>
>
>
> 1. The filter
>
> In that project I implemented what I am talking about, and the handler
> was designed as [3]:
> /* translated to C, since it was made in Java
> * @source - the data source
> * @read - the structure responsible by reading the data from the
> optical media
> * @sector - the sector you want to read from the CD
> * @ret_buff - the returned buffer
> * @ret_buff_len - the size of the returned buffer
> */
> int read_frame (burn_read_source *source, read_operation *read, int
> sector, char **ret_buff, int *ret_buff_len);
>
> This type of callbacks assumes there is someone controlling which lba to
> read next. Is this what we want? Is this enough flexibility for what we
> need? This will open on the API a function for getting the data from a
> given sector, which is READ_CD (0xBE).
>
> 2. The manager
>
> Another way to make it extendable would be to let the user define how to
> divide the media in streams. For example, an audio source being treated
> as a single stream, or each session being represented as a stream, or
> the user data being represented as a stream and the subs as another. In
> this case the hook function would have to define how the data is
> represented. This will still need the READ_CD op as public. And is
> somewhat compatible with the extendability explained beforehand.
>
> 3. Usage
>
> The usage would be something like this.
>
> BurnReadSource *source;
> source = burn_read_source_new (burn_read_media_new(),
> burn_read_manager_new(), burn_read_filter_new());
> BurnStream *streams[];
> int i, streams_len, buff_len;
> char buff[1024];
>
> burn_read_get_streams (source, &streams, &streams_len);
>
> for (i = 0; i < streams_len; i++)
> 	for (buff_len = burn_stream_read (streams[i], buff, 1024); buff_len >
> 0; buff_len = burn_stream_read (streams[i], buff, 1024))
> 		write (out, buff, 1024);
>
> What are your impressions on this?

I'd only really thought about the interface at the highest level...

You register a "burn_sink" with the lib.  The "file sink" would be 
provided by libburn, the same way a file source is now.  More advanced 
sinks would have to be written by the developer.

A burn_sink would define a target for data.  libburn itself would read 
sectors from the disc, and pass the data to the burn_sink callback 
function.

The libburn read functions would operate on the disc/session/track 
structures only after a sink has been registered.

So to read a track, you'd do something like

sink = burn_file_sink_new("filename.img", "filename.sub");
disc = burn_drive_get_disc(whatever);
burn_read_disc(drive, disc, sink);

And libburn would dump the disc to a file.

A more advanced data sink would be able to feed sectors into something 
like gstreamer for on the fly mp3 encoding, use C2 error information to 
discard "corrupt" sound, or read sections of the disc backwards to find 
"hidden" data.

A basic app probably shouldn't have to deal with sectors at all, and 
should stay in the realm of discs, sessions, and tracks.

I'm thinking what you propose should go in the mid layer, and be how sinks 
operate internally.  They'll pull from the drive in sectors, and push to 
the app through callbacks.


More information about the libburn mailing list