[asterisk-commits] dvossel: branch dvossel/fixtheworld_phase1_step3 r300878 - in /team/dvossel/f...
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Thu Jan 6 20:40:37 UTC 2011
Author: dvossel
Date: Thu Jan 6 14:40:32 2011
New Revision: 300878
URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=300878
Log:
update file.c for ast_format conversion
Modified:
team/dvossel/fixtheworld_phase1_step3/include/asterisk/file.h
team/dvossel/fixtheworld_phase1_step3/main/file.c
team/dvossel/fixtheworld_phase1_step3/main/format_cap.c
Modified: team/dvossel/fixtheworld_phase1_step3/include/asterisk/file.h
URL: http://svnview.digium.com/svn/asterisk/team/dvossel/fixtheworld_phase1_step3/include/asterisk/file.h?view=diff&rev=300878&r1=300877&r2=300878
==============================================================================
--- team/dvossel/fixtheworld_phase1_step3/include/asterisk/file.h (original)
+++ team/dvossel/fixtheworld_phase1_step3/include/asterisk/file.h Thu Jan 6 14:40:32 2011
@@ -90,7 +90,8 @@
* \param fmt the format you wish to check (the extension)
* \param preflang (the preferred language you wisht to find the file in)
* See if a given file exists in a given format. If fmt is NULL, any format is accepted.
- * \return 0 if file does not exist, non-zero positive otherwise.
+ * \retval 0, false. The file does not exist
+ * \retval 1, true. The file does exist.
*/
int ast_fileexists(const char *filename, const char *fmt, const char *preflang);
Modified: team/dvossel/fixtheworld_phase1_step3/main/file.c
URL: http://svnview.digium.com/svn/asterisk/team/dvossel/fixtheworld_phase1_step3/main/file.c?view=diff&rev=300878&r1=300877&r2=300878
==============================================================================
--- team/dvossel/fixtheworld_phase1_step3/main/file.c (original)
+++ team/dvossel/fixtheworld_phase1_step3/main/file.c Thu Jan 6 14:40:32 2011
@@ -400,18 +400,20 @@
};
/*!
+ * \internal
* \brief perform various actions on a file. Second argument
- * arg2 depends on the command:
- * unused for EXISTS and DELETE
+ * \note arg2 depends on the command:
+ * unused for DELETE
+ * optional ast_cap holding all the formats found for a file, for EXISTS.
* destination file name (const char *) for COPY and RENAME
* struct ast_channel * for OPEN
* if fmt is NULL, OPEN will return the first matching entry,
* whereas other functions will run on all matching entries.
*/
-static format_t ast_filehelper(const char *filename, const void *arg2, const char *fmt, const enum file_action action)
+static int filehelper(const char *filename, const void *arg2, const char *fmt, const enum file_action action)
{
struct ast_format_def *f;
- format_t res = (action == ACTION_EXISTS) ? 0 : -1;
+ int res = (action == ACTION_EXISTS) ? 0 : -1;
AST_RWLIST_RDLOCK(&formats);
/* Check for a specific format */
@@ -445,9 +447,9 @@
FILE *bfile;
struct ast_filestream *s;
- if ( !(chan->writeformat & f->format) &&
- !((f->format & AST_FORMAT_AUDIO_MASK && fmt) ||
- (f->format & AST_FORMAT_VIDEO_MASK && fmt))) {
+ if ((ast_format_cmp(&chan->writeformat, &f->format) == AST_FORMAT_CMP_NOT_EQUAL) &&
+ !(((AST_FORMAT_GET_TYPE(f->format.id) == AST_FORMAT_TYPE_AUDIO) && fmt) ||
+ ((AST_FORMAT_GET_TYPE(f->format.id) == AST_FORMAT_TYPE_VIDEO) && fmt))) {
ast_free(fn);
continue; /* not a supported format */
}
@@ -475,7 +477,7 @@
s->fmt = f;
s->trans = NULL;
s->filename = NULL;
- if (s->fmt->format & AST_FORMAT_AUDIO_MASK) {
+ if (AST_FORMAT_GET_TYPE(s->fmt->format.id) == AST_FORMAT_TYPE_AUDIO) {
if (chan->stream)
ast_closestream(chan->stream);
chan->stream = s;
@@ -492,7 +494,12 @@
break; /* will never get here */
case ACTION_EXISTS: /* return the matching format */
- res |= f->format;
+ /* if arg2 is present, it is a format capabilities structure.
+ * Add this format to the set of formats this file can be played in */
+ if (arg2) {
+ ast_cap_add((struct ast_cap *) arg2, &f->format);
+ }
+ res = 1; /* file does exist and format it exists in is returned in arg2 */
break;
case ACTION_DELETE:
@@ -531,11 +538,17 @@
return filename[0] == '/';
}
-static format_t fileexists_test(const char *filename, const char *fmt, const char *lang,
- char *buf, int buflen)
+/*!
+ * \brief test if a file exists for a given format.
+ * \note result_cap is OPTIONAL
+ * \retval 1, true and result_cap represents format capabilities file exists in.
+ * \retval 0, false
+ */
+static int fileexists_test(const char *filename, const char *fmt, const char *lang,
+ char *buf, int buflen, struct ast_cap *result_cap)
{
if (buf == NULL) {
- return -1;
+ return 0;
}
if (ast_language_is_prefix && !is_absolute_path(filename)) { /* new layout */
@@ -554,25 +567,36 @@
}
}
- return ast_filehelper(buf, NULL, fmt, ACTION_EXISTS);
+ return filehelper(buf, result_cap, fmt, ACTION_EXISTS);
}
/*!
* \brief helper routine to locate a file with a given format
* and language preference.
- * Try preflang, preflang with stripped '_' suffices, or NULL.
+ *
+ * \note Try preflang, preflang with stripped '_' suffices, or NULL.
*
- * The last parameter(s) point to a buffer of sufficient size,
+ * \note The last parameter(s) point to a buffer of sufficient size,
* which on success is filled with the matching filename.
+ *
+ * \param filename, name of the file.
+ * \param fmt, format to look for the file in. OPTIONAL
+ * \param preflang, the perfered language
+ * \param buf, returns the matching filename
+ * \param buflen, size of the buf
+ * \param result_cap, OPTIONAL format capabilities result structure
+ * returns what formats the file was found in.
+ *
+ * \retval 1, true. file exists and result format is set
+ * \retval 0, false. file does not exist.
*/
-static format_t fileexists_core(const char *filename, const char *fmt, const char *preflang,
- char *buf, int buflen)
-{
- format_t res = -1;
+static int fileexists_core(const char *filename, const char *fmt, const char *preflang,
+ char *buf, int buflen, struct ast_cap *result_cap)
+{
char *lang;
if (buf == NULL) {
- return -1;
+ return 0;
}
/* We try languages in the following order:
@@ -588,8 +612,8 @@
while (!ast_strlen_zero(lang)) {
char *end;
- if ((res = fileexists_test(filename, fmt, lang, buf, buflen)) > 0) {
- return res;
+ if (fileexists_test(filename, fmt, lang, buf, buflen, result_cap)) {
+ return 1;
}
if ((end = strrchr(lang, '_')) != NULL) {
@@ -601,14 +625,14 @@
}
/* Try without any language */
- if ((res = fileexists_test(filename, fmt, NULL, buf, buflen)) > 0) {
- return res;
+ if (fileexists_test(filename, fmt, NULL, buf, buflen, result_cap)) {
+ return 1;
}
/* Finally try the default language unless it was already tried before */
if ((ast_strlen_zero(preflang) || strcmp(preflang, DEFAULT_LANGUAGE)) && (ast_strlen_zero(lang) || strcmp(lang, DEFAULT_LANGUAGE))) {
- if ((res = fileexists_test(filename, fmt, DEFAULT_LANGUAGE, buf, buflen)) > 0) {
- return res;
+ if ((fileexists_test(filename, fmt, DEFAULT_LANGUAGE, buf, buflen, result_cap)) > 0) {
+ return 1;
}
}
@@ -627,7 +651,8 @@
* language and format, set up a suitable translator,
* and open the stream.
*/
- format_t fmts, res;
+ struct ast_cap *file_fmt_cap;
+ int res;
int buflen;
char *buf;
@@ -643,20 +668,29 @@
buf = alloca(buflen);
if (buf == NULL)
return NULL;
- fmts = fileexists_core(filename, NULL, preflang, buf, buflen);
- if (fmts > 0)
- fmts &= AST_FORMAT_AUDIO_MASK;
- if (fmts < 1) {
+
+ if (!(file_fmt_cap = ast_cap_alloc())) {
+ return NULL;
+ }
+ if (!fileexists_core(filename, NULL, preflang, buf, buflen, file_fmt_cap) ||
+ ast_cap_has_type(file_fmt_cap, AST_FORMAT_TYPE_AUDIO)) {
+
ast_log(LOG_WARNING, "File %s does not exist in any format\n", filename);
+ file_fmt_cap = ast_cap_destroy(file_fmt_cap);
return NULL;
}
- chan->oldwriteformat = chan->writeformat;
- /* Set the channel to a format we can work with */
- res = ast_set_write_format(chan, fmts);
+
+ /* Set the channel to a format we can work with and save off the previous format. */
+ ast_format_copy(&chan->writeformat, &chan->oldwriteformat);
+ /* Set the channel to the best format that exists for the file. */
+ res = ast_set_write_format_from_cap(chan, file_fmt_cap);
+ /* don't need this anymore now that the channel's write format is set. */
+ file_fmt_cap = ast_cap_destroy(file_fmt_cap);
+
if (res == -1) { /* No format available that works with this channel */
return NULL;
}
- res = ast_filehelper(buf, chan, NULL, ACTION_OPEN);
+ res = filehelper(buf, chan, NULL, ACTION_OPEN);
if (res >= 0)
return chan->stream;
return NULL;
@@ -667,9 +701,12 @@
/* As above, but for video. But here we don't have translators
* so we must enforce a format.
*/
- format_t format;
+ struct ast_format tmp_fmt;
+ struct ast_cap *tmp_cap;
char *buf;
int buflen;
+ const char *fmt;
+ int fd;
if (preflang == NULL)
preflang = "";
@@ -678,20 +715,42 @@
if (buf == NULL)
return NULL;
- for (format = AST_FORMAT_AUDIO_MASK + 1; format <= AST_FORMAT_VIDEO_MASK; format = format << 1) {
- int fd;
- const char *fmt;
-
- if (!(chan->nativeformats & format))
+ /* is the channel capable of video without translation ?*/
+ if (!ast_cap_has_type(chan->nativeformats, AST_FORMAT_TYPE_VIDEO)) {
+ ast_log(LOG_WARNING, "Channel %s unable to play video file %s. Video not supported.\n", chan->name, filename);
+ return NULL;
+ }
+
+ if (!(tmp_cap = ast_cap_alloc())) {
+ return NULL;
+ }
+
+ /* Video is supported, so see what video formats exist for this file */
+ if (!fileexists_core(filename, NULL, preflang, buf, buflen, tmp_cap)) {
+ tmp_cap = ast_cap_destroy(tmp_cap);
+ return NULL;
+ }
+
+ /* iterate over file formats and pick the first one compatible with the channel's native formats */
+ ast_cap_iter_start(tmp_cap);
+ while (!ast_cap_iter_next(tmp_cap, &tmp_fmt)) {
+ fmt = ast_getformatname(&tmp_fmt);
+ if ((AST_FORMAT_GET_TYPE(tmp_fmt.id) != AST_FORMAT_TYPE_VIDEO) ||
+ !ast_cap_iscompatible(chan->nativeformats, &tmp_fmt)) {
continue;
- fmt = ast_getformatname(format);
- if ( fileexists_core(filename, fmt, preflang, buf, buflen) < 1) /* no valid format */
- continue;
- fd = ast_filehelper(buf, chan, fmt, ACTION_OPEN);
- if (fd >= 0)
+ }
+
+ fd = filehelper(buf, chan, fmt, ACTION_OPEN);
+ if (fd >= 0) {
+ ast_cap_iter_end(tmp_cap);
+ tmp_cap = ast_cap_destroy(tmp_cap);
return chan->vstream;
+ }
ast_log(LOG_WARNING, "File %s has video but couldn't be opened\n", filename);
}
+ ast_cap_iter_end(tmp_cap);
+ tmp_cap = ast_cap_destroy(tmp_cap);
+
return NULL;
}
@@ -763,7 +822,7 @@
if (whennext != s->lasttimeout) {
if (s->owner->timingfd > -1) {
- float samp_rate = (float) ast_format_rate(s->fmt->format);
+ float samp_rate = (float) ast_format_rate(&s->fmt->format);
unsigned int rate;
rate = (unsigned int) roundf(samp_rate / ((float) whennext));
@@ -771,7 +830,7 @@
ast_settimeout(s->owner, rate, ast_fsread_audio, s);
} else {
s->owner->streamid = ast_sched_add(s->owner->sched,
- whennext / (ast_format_rate(s->fmt->format) / 1000), ast_fsread_audio, s);
+ whennext / (ast_format_rate(&s->fmt->format) / 1000), ast_fsread_audio, s);
}
s->lasttimeout = whennext;
return FSREAD_SUCCESS_NOSCHED;
@@ -822,7 +881,7 @@
if (whennext != s->lasttimeout) {
s->owner->vstreamid = ast_sched_add(s->owner->sched,
- whennext / (ast_format_rate(s->fmt->format) / 1000),
+ whennext / (ast_format_rate(&s->fmt->format) / 1000),
ast_fsread_video, s);
s->lasttimeout = whennext;
return FSREAD_SUCCESS_NOSCHED;
@@ -854,7 +913,7 @@
{
enum fsread_res res;
- if (s->fmt->format & AST_FORMAT_AUDIO_MASK)
+ if (AST_FORMAT_GET_TYPE(s->fmt->format.id) == AST_FORMAT_TYPE_AUDIO)
res = ast_readaudio_callback(s);
else
res = ast_readvideo_callback(s);
@@ -896,7 +955,7 @@
/* Stop a running stream if there is one */
if (f->owner) {
- if (f->fmt->format < AST_FORMAT_AUDIO_MASK) {
+ if (AST_FORMAT_GET_TYPE(f->fmt->format.id) == AST_FORMAT_TYPE_AUDIO) {
f->owner->stream = NULL;
AST_SCHED_DEL(f->owner->sched, f->owner->streamid);
ast_settimeout(f->owner, 0, NULL, NULL);
@@ -925,22 +984,22 @@
buf = alloca(buflen);
if (buf == NULL)
return 0;
- return fileexists_core(filename, fmt, preflang, buf, buflen);
+ return fileexists_core(filename, fmt, preflang, buf, buflen, NULL) ? 1 : 0;
}
int ast_filedelete(const char *filename, const char *fmt)
{
- return ast_filehelper(filename, NULL, fmt, ACTION_DELETE);
+ return filehelper(filename, NULL, fmt, ACTION_DELETE);
}
int ast_filerename(const char *filename, const char *filename2, const char *fmt)
{
- return ast_filehelper(filename, filename2, fmt, ACTION_RENAME);
+ return filehelper(filename, filename2, fmt, ACTION_RENAME);
}
int ast_filecopy(const char *filename, const char *filename2, const char *fmt)
{
- return ast_filehelper(filename, filename2, fmt, ACTION_COPY);
+ return filehelper(filename, filename2, fmt, ACTION_COPY);
}
int ast_streamfile(struct ast_channel *chan, const char *filename, const char *preflang)
@@ -970,7 +1029,7 @@
vfs = ast_openvstream(chan, filename, preflang);
if (vfs) {
- ast_debug(1, "Ooh, found a video stream, too, format %s\n", ast_getformatname(vfs->fmt->format));
+ ast_debug(1, "Ooh, found a video stream, too, format %s\n", ast_getformatname(&vfs->fmt->format));
}
if (ast_test_flag(chan, AST_FLAG_MASQ_NOSTREAM))
@@ -982,7 +1041,7 @@
res = ast_playstream(fs);
if (!res && vfs)
res = ast_playstream(vfs);
- ast_verb(3, "<%s> Playing '%s.%s' (language '%s')\n", chan->name, filename, ast_getformatname(chan->writeformat), preflang ? preflang : "default");
+ ast_verb(3, "<%s> Playing '%s.%s' (language '%s')\n", chan->name, filename, ast_getformatname(&chan->writeformat), preflang ? preflang : "default");
return res;
}
@@ -1463,7 +1522,7 @@
AST_RWLIST_RDLOCK(&formats);
AST_RWLIST_TRAVERSE(&formats, f, list) {
- ast_cli(a->fd, FORMAT2, ast_getformatname(f->format), f->name, f->exts);
+ ast_cli(a->fd, FORMAT2, ast_getformatname(&f->format), f->name, f->exts);
count_fmt++;
}
AST_RWLIST_UNLOCK(&formats);
Modified: team/dvossel/fixtheworld_phase1_step3/main/format_cap.c
URL: http://svnview.digium.com/svn/asterisk/team/dvossel/fixtheworld_phase1_step3/main/format_cap.c?view=diff&rev=300878&r1=300877&r2=300878
==============================================================================
--- team/dvossel/fixtheworld_phase1_step3/main/format_cap.c (original)
+++ team/dvossel/fixtheworld_phase1_step3/main/format_cap.c Thu Jan 6 14:40:32 2011
@@ -222,7 +222,7 @@
it = ao2_iterator_init(cap->formats, 0);
while ((tmp = ao2_iterator_next(&it))) {
if (AST_FORMAT_GET_TYPE(tmp->id) == type) {
- ao2_unlink(cap, tmp);
+ ao2_unlink(cap->formats, tmp);
}
ao2_ref(tmp, -1);
}
@@ -295,7 +295,7 @@
}
ao2_iterator_destroy(&it);
- return data->joint_found ? 1 : 0;
+ return data.joint_found ? 1 : 0;
}
int ast_cap_identical(struct ast_cap *cap1, struct ast_cap *cap2)
@@ -303,13 +303,13 @@
struct ao2_iterator it;
struct ast_format *tmp;
- if (ao2_count(ca1->formats) != ao2_count(cap2->formats)) {
+ if (ao2_container_count(cap1->formats) != ao2_container_count(cap2->formats)) {
return 0; /* if they are not the same size, they are not identical */
}
it = ao2_iterator_init(cap1->formats, 0);
while ((tmp = ao2_iterator_next(&it))) {
- if (!ast_cap_iscompatible(cap, &tmp)) {
+ if (!ast_cap_iscompatible(cap2, tmp)) {
ao2_ref(tmp, -1);
ao2_iterator_destroy(&it);
return 0;
@@ -366,7 +366,7 @@
* compatible with cap2. If so copy it to the result */
it = ao2_iterator_init(cap->formats, 0);
while ((tmp = ao2_iterator_next(&it))) {
- if (AST_FORMATNEW_GET_TYPE(tmp->id) == ftype) {
+ if (AST_FORMAT_GET_TYPE(tmp->id) == ftype) {
/* copy format */
ast_cap_add(result, tmp);
}
@@ -392,7 +392,7 @@
it = ao2_iterator_init(cap->formats, 0);
while ((tmp = ao2_iterator_next(&it))) {
- if (AST_FORMATNEW_GET_TYPE(tmp->id) == ftype) {
+ if (AST_FORMAT_GET_TYPE(tmp->id) == type) {
ao2_ref(tmp, -1);
ao2_iterator_destroy(&it);
return 1;
More information about the asterisk-commits
mailing list