Largely simplify format handlers (for file copy etc.)

collecting common functions in a single place and removing
them from the individual handlers.
The full description is on mantis,
http://bugs.digium.com/view.php?id=6375
and only the ogg_vorbis handler needs to be converted to
the new structure.

As a result of this change, format_au.c and format_pcm_alaw.c
should go away (in a separate commit) as their functionality
(trivial) has been merged in another file.



git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@17243 65c4cc65-6c06-0410-ace0-fbb531ad65f3
This commit is contained in:
Luigi Rizzo
2006-04-04 12:59:25 +00:00
parent ec67c650ad
commit 4beb6deeaa
18 changed files with 1748 additions and 2790 deletions

View File

@@ -40,28 +40,109 @@ extern "C" {
#define AST_DIGIT_ANY "0123456789#*ABCD"
#define AST_DIGIT_ANYNUM "0123456789"
/*! structure used for lock and refcount of format handlers.
* Should not be here, but this is a temporary workaround
* until we implement a more general mechanism.
* The format handler should include a pointer to
* this structure.
* As a trick, if usecnt is initialized with -1,
* ast_format_register will init the mutex for you.
*/
struct ast_format_lock {
ast_mutex_t lock;
int usecnt; /* number of active clients */
};
/*!
* Each supported file format is described by the following fields.
* Not all are necessary, the support routine implement default
* values for some of them.
* A handler typically fills a structure initializing the desired
* fields, and then calls ast_format_register() with the (readonly)
* structure as an argument.
*/
struct ast_format {
char name[80]; /*! Name of format */
char exts[80]; /*! Extensions (separated by | if more than one)
this format can read. First is assumed for writing (e.g. .mp3) */
int format; /*! Format of frames it uses/provides (one only) */
/*! Prepare an input stream for playback. Return 0 on success, -1 on error.
* The FILE is already open (in s->f) so this function only needs to perform
* any applicable validity checks on the file. If none is required, the
* function can be omitted.
*/
int (*open)(struct ast_filestream *s);
/*! Prepare a stream for output, and comment it appropriately if applicable.
* Return 0 on success, -1 on error. Same as the open, the FILE is already
* open so the function just needs to prepare any header and other fields,
* if any. The function can be omitted if nothing is needed.
*/
int (*rewrite)(struct ast_filestream *s, const char *comment);
/*! Write a frame to a channel */
int (*write)(struct ast_filestream *, struct ast_frame *);
/*! seek num samples into file, whence - like a normal seek but with offset in samples */
int (*seek)(struct ast_filestream *, off_t, int);
int (*trunc)(struct ast_filestream *fs); /*! trunc file to current position */
off_t (*tell)(struct ast_filestream *fs); /*! tell current position */
/*! Read the next frame from the filestream (if available) and report
* when to get next frame (in samples)
*/
struct ast_frame * (*read)(struct ast_filestream *, int *whennext);
/*! Do any closing actions, if any. The descriptor and structure are closed
* and destroyed by the generic routines, so they must not be done here. */
void (*close)(struct ast_filestream *);
char * (*getcomment)(struct ast_filestream *); /*! Retrieve file comment */
AST_LIST_ENTRY(ast_format) list; /*! Link */
/*!
* If the handler needs a buffer (for read, typically)
* and/or a private descriptor, put here the
* required size (in bytes) and the support routine will allocate them
* for you, pointed by s->buf and s->private, respectively.
* When allocating a buffer, remember to leave AST_FRIENDLY_OFFSET
* spare bytes at the bginning.
*/
int buf_size; /*! size of frame buffer, if any, aligned to 8 bytes. */
int desc_size; /*! size of private descriptor, if any */
struct ast_format_lock *lockp;
};
/*
* This structure is allocated by file.c in one chunk,
* together with buf_size and desc_size bytes of memory
* to be used for private purposes (e.g. buffers etc.)
*/
struct ast_filestream {
/*! Everybody reserves a block of AST_RESERVED_POINTERS pointers for us */
struct ast_format *fmt; /* need to write to the lock and usecnt */
int flags;
mode_t mode;
char *filename;
char *realfilename;
/*! Video file stream */
struct ast_filestream *vfs;
/*! Transparently translate from another format -- just once */
struct ast_trans_pvt *trans;
struct ast_tranlator_pvt *tr;
int lastwriteformat;
int lasttimeout;
struct ast_channel *owner;
FILE *f;
struct ast_frame fr; /* frame produced by read, typically */
char *buf; /* buffer pointed to by ast_frame; */
void *private; /* pointer to private buffer */
};
#define SEEK_FORCECUR 10
/* Defined by individual formats. First item MUST be a
pointer for use by the stream manager */
struct ast_filestream;
/*! Registers a new file format */
/*! Register a new file format capability
* Adds a format to asterisk's format abilities. Fill in the fields, and it will work. For examples, look at some of the various format code.
* Adds a format to asterisk's format abilities.
* returns 0 on success, -1 on failure
*/
int ast_format_register(const char *name, const char *exts, int format,
struct ast_filestream * (*open)(FILE *f),
struct ast_filestream * (*rewrite)(FILE *f, const char *comment),
int (*write)(struct ast_filestream *, struct ast_frame *),
int (*seek)(struct ast_filestream *, off_t offset, int whence),
int (*trunc)(struct ast_filestream *),
off_t (*tell)(struct ast_filestream *),
struct ast_frame * (*read)(struct ast_filestream *, int *timetonext),
void (*close)(struct ast_filestream *),
char * (*getcomment)(struct ast_filestream *));
int ast_format_register(const struct ast_format *f);
/*! Unregisters a file format */
/*!
* \param name the name of the format you wish to unregister