[Libburn] Reading procedure
Tiago Cogumbreiro
cogumbreiro at linus.uac.pt
Fri Oct 22 06:17:27 PDT 2004
On Wed, 2004-10-20 at 02:51, Derek Foreman wrote:
> 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.
Yes, my proposition is in a lower level. So my first question is where
should I start hacking on?
I've just bought a new DVD+-rw with dual layer support, I imagine this
feature is transparent to the user (libburn) and only alters the media
size. Bottom line is: I am interested in playing around with dvd burning
as well.
Maybe you could add one more link to the libburn webpage:
Linux udf project has a set of tools (udftools) which mess around with
drives too (for formating them, sending packets...)
http://cvs.sourceforge.net/viewcvs.py/linux-udf/
More information about the libburn
mailing list