[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