|
From: Scott F. J. <sc...@fl...> - 2000-05-01 07:17:26
|
API thoughts.
Quicktime4linux will be a natural place to include a libdv codec.
Quicktime supports dvc, and it appears that the 120000 bytes are
just stored on a per-frame basis.
With the quicktime4linux library, one can either read an entire
frame into a buffer, or get a file descriptor and read a frame
out of a quicktime file from a stream.
It would make sense for us to support two front-ends on our code
as well: buffer and stream. I realize for most uses, we will want to
focus
on the stream method, but if somebody buffers an image, we shouldn't
prevent them
from decoding it.
We should create two layers to the API, a decoding (and in the future
encoding)
layer, and a file/buffer layer that allows us to write front-ends for
raw DV files, DV AVI files, DV frames stored in quicktime files, etc.
Because of the nature of the unshuffling of blocks, there is no
efficiency in having "scanline" based routines.
We should support generalized output image format converters,
and we should initially supply both RGB and YUV methods.
For example, a "base class" dv_image_t could be:
typedef struct dv_image_s {
int (*init)(); // Fn to initialize converter
int (*from_ycrcb_411)(dv_image_t *self, dv_block_t *bl, int row, int
column);
int (*from_ycrcb_420)(dv_image_t *self, dv_block_t *bl, int row, int
column);
void *ClientData;
} dv_image_t;
And a skeletal RGBImage converter would include:
RGBImage_new()
{
dv_image_t *im = (dv_image_t *)malloc(sizeof(dv_image_t));
im->init = NULL;
im->fromycrcb411 = dv_ycrcb_411_block;
im->fromycrcb420 = dv_ycrcb_420_block;
im->ClientData = (guint8 *)malloc(sizeof(guint8)720*576*4);
return im;
}
RGBImage_del(dv_image_t *im)
{
free(im->ClientData);
free(im);
}
Use becomes something like:
dv_image_t *image = RGBimage_new(); // Object to hold output data.
// Contains pointer to RGB
converter fn.
FILE *fp = fopen("my.dv", "r");
while(status = dv_read_frame(image, fp)) {
// Do something with image
}
RGBimage_del(image);
If we find we have a lot of "state" variables, we can
create a "decoder" object, pass the stream to this object,
and store the "state" variables in it:
dv_t *dv = dv_new();
FILE *fp = fopen("my.dv", "r");
dv_set_fp(dv, fp);
dv_set_quality(dv, DV_QUALITY_HIGH);
dv_set_voutput(dv, DV_VIDEO_OUTPUT_RGB); // vs. DV_VIDEO_OUTPUT_YUV
dv_set_aoutput(dv, DV_AUDIO_OUTPUT_NONE);
dv_read_frame(dv);
isPAL = dv_isPAL(dv);
At the higher level, we can write wrappers around DV stream, AVI,
quicktime, etc.
At this level, we may want to be able to seek to a specific frame,
or rewind, or play backwards, etc. When the lower level routines
are called, they should just operate on the buffer as given.
The higher level for raw dv streams is pretty simple, and we may
want to include it in our library. The one for quicktime should probably
be written within quicktime4linux, rather than within libdv.
|