コード例 #1
0
ファイル: vcard_tester.c プロジェクト: Accontech/linphone
static void linphone_vcard_phone_numbers_and_sip_addresses(void) {
	LinphoneVcard *lvc = linphone_vcard_new_from_vcard4_buffer("BEGIN:VCARD\r\nVERSION:4.0\r\nFN:Sylvain Berfini\r\nIMPP:sip:[email protected]\r\nIMPP;TYPE=home:sip:[email protected]\r\nTEL;TYPE=work:0952636505\r\nEND:VCARD\r\n");
	LinphoneFriend *lf = linphone_friend_new_from_vcard(lvc);
	MSList *sip_addresses = linphone_friend_get_addresses(lf);
	MSList *phone_numbers = linphone_friend_get_phone_numbers(lf);
	LinphoneAddress *addr = NULL;
	
	BC_ASSERT_EQUAL(ms_list_size(sip_addresses), 2, int, "%i");
	BC_ASSERT_EQUAL(ms_list_size(phone_numbers), 1, int, "%i");
	if (sip_addresses) ms_list_free_with_data(sip_addresses, (void (*)(void *))linphone_address_unref);
	if (phone_numbers) ms_list_free(phone_numbers);
	linphone_friend_unref(lf);
	
	lvc = linphone_vcard_new_from_vcard4_buffer("BEGIN:VCARD\r\nVERSION:4.0\r\nFN:Sylvain Berfini\r\nTEL;TYPE=work:0952636505\r\nTEL:0476010203\r\nEND:VCARD\r\n");
	lf = linphone_friend_new_from_vcard(lvc);
	sip_addresses = linphone_friend_get_addresses(lf);
	phone_numbers = linphone_friend_get_phone_numbers(lf);
	
	BC_ASSERT_EQUAL(ms_list_size(sip_addresses), 0, int, "%i");
	BC_ASSERT_EQUAL(ms_list_size(phone_numbers), 2, int, "%i");
	if (sip_addresses) ms_list_free_with_data(sip_addresses, (void (*)(void *))linphone_address_unref);
	if (phone_numbers) ms_list_free(phone_numbers);
	
	addr = linphone_address_new("sip:[email protected]");
	linphone_friend_add_address(lf, addr);
	linphone_address_unref(addr);
	sip_addresses = linphone_friend_get_addresses(lf);
	BC_ASSERT_EQUAL(ms_list_size(sip_addresses), 1, int, "%i");
	if (sip_addresses) ms_list_free_with_data(sip_addresses, (void (*)(void *))linphone_address_unref);
	
	linphone_friend_remove_phone_number(lf, "0952636505");
	phone_numbers = linphone_friend_get_phone_numbers(lf);
	BC_ASSERT_EQUAL(ms_list_size(phone_numbers), 1, int, "%i");
	if (phone_numbers) ms_list_free(phone_numbers);
	
	linphone_friend_remove_phone_number(lf, "0476010203");
	phone_numbers = linphone_friend_get_phone_numbers(lf);
	BC_ASSERT_EQUAL(ms_list_size(phone_numbers), 0, int, "%i");
	if (phone_numbers) ms_list_free(phone_numbers);
	
	addr = linphone_address_new("sip:[email protected]");
	linphone_friend_remove_address(lf, addr);
	linphone_address_unref(addr);
	sip_addresses = linphone_friend_get_addresses(lf);
	BC_ASSERT_EQUAL(ms_list_size(sip_addresses), 0, int, "%i");
	if (sip_addresses) ms_list_free_with_data(sip_addresses, (void (*)(void *))linphone_address_unref);
	
	linphone_friend_add_phone_number(lf, "+33952636505");
	phone_numbers = linphone_friend_get_phone_numbers(lf);
	BC_ASSERT_EQUAL(ms_list_size(phone_numbers), 1, int, "%i");
	if (phone_numbers) ms_list_free(phone_numbers);
	
	linphone_friend_unref(lf);
	lf = NULL;
	lvc = NULL;
}
コード例 #2
0
ファイル: sal.c プロジェクト: yong93/linphone
static void sal_media_description_destroy(SalMediaDescription *md){
	int i;
	for(i=0;i<SAL_MEDIA_DESCRIPTION_MAX_STREAMS;i++){
		ms_list_free_with_data(md->streams[i].payloads,(void (*)(void *))payload_type_destroy);
		ms_list_free_with_data(md->streams[i].already_assigned_payloads,(void (*)(void *))payload_type_destroy);
		md->streams[i].payloads=NULL;
		md->streams[i].already_assigned_payloads=NULL;
	}
	ms_free(md);
}
コード例 #3
0
ファイル: friend.c プロジェクト: BambooLL/linphone
void linphone_core_friends_storage_init(LinphoneCore *lc) {
	int ret;
	const char *errmsg;
	sqlite3 *db;
	const MSList *friends_lists = NULL;

	linphone_core_friends_storage_close(lc);

	ret = _linphone_sqlite3_open(lc->friends_db_file, &db);
	if (ret != SQLITE_OK) {
		errmsg = sqlite3_errmsg(db);
		ms_error("Error in the opening: %s.\n", errmsg);
		sqlite3_close(db);
		return;
	}

	linphone_create_table(db);
	linphone_update_table(db);
	lc->friends_db = db;

	friends_lists = linphone_core_fetch_friends_lists_from_db(lc);
	if (friends_lists) {
		ms_warning("Replacing current default friend list by the one(s) from the database");
		lc->friends_lists = ms_list_free_with_data(lc->friends_lists, (void (*)(void*))linphone_friend_list_unref);
		lc->friends_lists = NULL;

		while (friends_lists) {
			LinphoneFriendList *list = (LinphoneFriendList *)friends_lists->data;
			linphone_core_add_friend_list(lc, list);
			friends_lists = ms_list_next(friends_lists);
		}
	}
}
コード例 #4
0
ファイル: friend.c プロジェクト: BambooLL/linphone
static void _linphone_friend_release_ops(LinphoneFriend *lf){
	lf->insubs = ms_list_free_with_data(lf->insubs, (MSIterateFunc) sal_op_release);
	if (lf->outsub){
		sal_op_release(lf->outsub);
		lf->outsub=NULL;
	}
}
コード例 #5
0
void account_manager_destroy(void){
	if (the_am){
		ms_free(the_am->unique_id);
		ms_list_free_with_data(the_am->accounts,(void(*)(void*))account_destroy);
		ms_free(the_am);
	}
	the_am=NULL;
	ms_message("Test account manager destroyed.");
}
コード例 #6
0
static void history_messages_count() {
	LinphoneCoreManager *marie = linphone_core_manager_new("marie_rc");
	LinphoneAddress *jehan_addr = linphone_address_new("<sip:[email protected]>");
	LinphoneChatRoom *chatroom;
	MSList *messages;
	char src_db[256];
	char tmp_db[256];
	snprintf(src_db,sizeof(src_db), "%s/messages.db", liblinphone_tester_file_prefix);
	snprintf(tmp_db,sizeof(tmp_db), "%s/tmp.db", liblinphone_tester_writable_dir_prefix);

	CU_ASSERT_EQUAL_FATAL(message_tester_copy_file(src_db, tmp_db), 0);

	linphone_core_set_chat_database_path(marie->lc, tmp_db);

	chatroom = linphone_core_get_chat_room(marie->lc, jehan_addr);
	CU_ASSERT_PTR_NOT_NULL(chatroom);
	if (chatroom){
		messages=linphone_chat_room_get_history(chatroom,10);
		CU_ASSERT_EQUAL(ms_list_size(messages), 10);
		ms_list_free_with_data(messages, (void (*)(void*))linphone_chat_message_unref);

		messages=linphone_chat_room_get_history(chatroom,1);
		CU_ASSERT_EQUAL(ms_list_size(messages), 1);
		ms_list_free_with_data(messages, (void (*)(void*))linphone_chat_message_unref);

		messages=linphone_chat_room_get_history(chatroom,0);
		CU_ASSERT_EQUAL(linphone_chat_room_get_history_size(chatroom), 1270);
		CU_ASSERT_EQUAL(ms_list_size(messages), 1270);
		/*check the second most recent message*/
		CU_ASSERT_STRING_EQUAL(linphone_chat_message_get_text((LinphoneChatMessage *)messages->next->data), "Fore and aft follow each other.");
		ms_list_free_with_data(messages, (void (*)(void*))linphone_chat_message_unref);

		/*test offset+limit: retrieve the 42th latest message only and check its content*/
		messages=linphone_chat_room_get_history_range(chatroom, 42, 42);
		CU_ASSERT_EQUAL(ms_list_size(messages), 1);
		CU_ASSERT_STRING_EQUAL(linphone_chat_message_get_text((LinphoneChatMessage *)messages->data), "If you open yourself to the Tao is intangible and evasive, yet prefers to keep us at the mercy of the kingdom, then all of the streams of hundreds of valleys because of its limitless possibilities.");
		ms_list_free_with_data(messages, (void (*)(void*))linphone_chat_message_unref);

		/*test offset without limit*/
		messages = linphone_chat_room_get_history_range(chatroom, 1265, -1);
		CU_ASSERT_EQUAL(ms_list_size(messages), 1270-1265);
		ms_list_free_with_data(messages, (void (*)(void*))linphone_chat_message_unref);

		/*test limit without offset*/
		messages = linphone_chat_room_get_history_range(chatroom, 0, 5);
		CU_ASSERT_EQUAL(ms_list_size(messages), 6);
		ms_list_free_with_data(messages, (void (*)(void*))linphone_chat_message_unref);

		/*test invalid start*/
		messages = linphone_chat_room_get_history_range(chatroom, 1265, 1260);
		CU_ASSERT_EQUAL(ms_list_size(messages), 1270-1265);
		ms_list_free_with_data(messages, (void (*)(void*))linphone_chat_message_unref);
	}
	linphone_core_manager_destroy(marie);
	linphone_address_destroy(jehan_addr);
	remove(tmp_db);
}
コード例 #7
0
ファイル: sal_impl.c プロジェクト: nishantmalaiya/linphone
void sal_uninit(Sal* sal){
	belle_sip_object_unref(sal->user_agent);
	belle_sip_object_unref(sal->prov);
	belle_sip_object_unref(sal->stack);
	belle_sip_object_unref(sal->listener);
	if (sal->supported) belle_sip_object_unref(sal->supported);
	ms_list_free_with_data(sal->supported_tags,ms_free);
	if (sal->uuid) ms_free(sal->uuid);
	if (sal->root_ca) ms_free(sal->root_ca);
	ms_free(sal);
};
コード例 #8
0
static void history_message_count_helper(LinphoneChatRoom* chatroom, int x, int y, int expected ){
	MSList* messages = linphone_chat_room_get_history_range(chatroom, x, y);
	int size = ms_list_size(messages);
	if( expected != size ){
		ms_warning("History retrieved from %d to %d returned %d records, but expected %d", x, y, size, expected);
	}
	CU_ASSERT_EQUAL(size, expected);

	ms_list_free_with_data(messages, (void (*)(void *))linphone_chat_message_unref);

}
コード例 #9
0
ファイル: msfactory.c プロジェクト: cuongitbk/mediastreamer2
/**
 * Destroy the factory.
 * This should be done after destroying all objects created by the factory.
**/
void ms_factory_destroy(MSFactory *factory){
	ms_factory_uninit_plugins(factory);
	if (factory->evq) ms_event_queue_destroy(factory->evq);
	factory->formats=ms_list_free_with_data(factory->formats,(void(*)(void*))ms_fmt_descriptor_destroy);
	factory->desc_list=ms_list_free(factory->desc_list);
	ms_list_for_each(factory->stats_list,ms_free);
	factory->stats_list=ms_list_free(factory->stats_list);
	ms_list_for_each(factory->platform_tags, ms_free);
	factory->platform_tags = ms_list_free(factory->platform_tags);
	if (factory->plugins_dir) ms_free(factory->plugins_dir);
	ms_free(factory);
	if (factory==fallback_factory) fallback_factory=NULL;
}
コード例 #10
0
ファイル: sal_impl.c プロジェクト: nishantmalaiya/linphone
void sal_set_supported_tags(Sal *ctx, const char* tags){
	ctx->supported_tags=ms_list_free_with_data(ctx->supported_tags,ms_free);
	if (tags){
		char *iter;
		char *buffer=ms_strdup(tags);
		char *tag;
		char *context=NULL;
		iter=buffer;
		while((tag=strtok_r(iter,", ",&context))!=NULL){
			iter=NULL;
			ctx->supported_tags=ms_list_append(ctx->supported_tags,ms_strdup(tag));
		}
		ms_free(buffer);
	}
	make_supported_header(ctx);
}
コード例 #11
0
ファイル: call_log.c プロジェクト: kouqi/linphone
const MSList *linphone_core_get_call_history(LinphoneCore *lc) {
	char *buf;
	uint64_t begin,end;
	MSList *result = NULL;

	if (!lc || lc->logs_db == NULL) return NULL;

	buf = sqlite3_mprintf("SELECT * FROM call_history ORDER BY id DESC LIMIT %i", lc->max_call_logs);

	begin = ortp_get_cur_time_ms();
	linphone_sql_request_call_log(lc->logs_db, buf, &result);
	end = ortp_get_cur_time_ms();
	ms_message("%s(): completed in %i ms",__FUNCTION__, (int)(end-begin));
	sqlite3_free(buf);
	
	if (lc->call_logs) {
		copy_user_data_from_existing_logs(lc->call_logs, result);
	}
	
	lc->call_logs = ms_list_free_with_data(lc->call_logs, (void (*)(void*))linphone_call_log_unref);
	lc->call_logs = result;
	
	return lc->call_logs;
}
コード例 #12
0
ファイル: vcard_tester.c プロジェクト: Accontech/linphone
static void friends_migration(void) {
	LinphoneCoreManager* manager = linphone_core_manager_new2("friends_rc", FALSE);
	LpConfig *lpc = linphone_core_get_config(manager->lc);
	LinphoneFriendList *lfl = linphone_core_get_default_friend_list(manager->lc);
	const MSList *friends = linphone_friend_list_get_friends(lfl);
	MSList *friends_from_db = NULL;
	char *friends_db = create_filepath(bc_tester_get_writable_dir_prefix(), "friends", "db");
	BC_ASSERT_EQUAL(ms_list_size(friends), 3, int, "%d");
	BC_ASSERT_EQUAL(lp_config_get_int(lpc, "misc", "friends_migration_done", 0), 0, int, "%i");

	unlink(friends_db);
	linphone_core_set_friends_database_path(manager->lc, friends_db);
	lfl = linphone_core_get_default_friend_list(manager->lc);
	friends = linphone_friend_list_get_friends(lfl);
	BC_ASSERT_EQUAL(ms_list_size(friends), 3, int, "%d");
	friends_from_db = linphone_core_fetch_friends_from_db(manager->lc, lfl);
	BC_ASSERT_EQUAL(ms_list_size(friends_from_db), 3, int, "%d");
	BC_ASSERT_EQUAL(lp_config_get_int(lpc, "misc", "friends_migration_done", 0), 1, int, "%i");

	friends_from_db = ms_list_free_with_data(friends_from_db, (void (*)(void *))linphone_friend_unref);
	unlink(friends_db);
	ms_free(friends_db);
	linphone_core_manager_destroy(manager);
}
コード例 #13
0
ファイル: friend.c プロジェクト: BambooLL/linphone
void linphone_friend_close_subscriptions(LinphoneFriend *lf){
	linphone_friend_unsubscribe(lf);
	ms_list_for_each(lf->insubs, (MSIterateFunc) sal_notify_presence_close);
	lf->insubs = ms_list_free_with_data(lf->insubs, (MSIterateFunc)sal_op_release);
}
コード例 #14
0
void ms_filter_clear_notify_callback(MSFilter *f){
	f->notify_callbacks=ms_list_free_with_data(f->notify_callbacks,(void (*)(void*))ms_notify_context_destroy);
}
コード例 #15
0
ファイル: vcard_tester.c プロジェクト: Accontech/linphone
static void friends_sqlite_storage(void) {
	LinphoneCoreVTable *v_table = linphone_core_v_table_new();
	LinphoneCore* lc = NULL;
	LinphoneFriendList *lfl = NULL;
	LinphoneFriend *lf = NULL;
	LinphoneFriend *lf2 = NULL;
	LinphoneVcard *lvc = linphone_vcard_new();
	LinphoneAddress *addr = linphone_address_new("sip:[email protected]");
	const MSList *friends = NULL;
	MSList *friends_from_db = NULL;
	MSList *friends_lists_from_db = NULL;
	char *friends_db = create_filepath(bc_tester_get_writable_dir_prefix(), "friends", "db");
	LinphoneFriendListStats *stats = (LinphoneFriendListStats *)ms_new0(LinphoneFriendListStats, 1);

	v_table->friend_list_created = friend_list_created_cb;
	v_table->friend_list_removed = friend_list_removed_cb;
	lc = linphone_core_new(v_table, NULL, NULL, NULL);
	friends = linphone_friend_list_get_friends(linphone_core_get_default_friend_list(lc));
	lfl = linphone_core_create_friend_list(lc);
	linphone_friend_list_set_user_data(lfl, stats);
	BC_ASSERT_EQUAL(ms_list_size(friends), 0, int, "%d");

	unlink(friends_db);
	linphone_core_set_friends_database_path(lc, friends_db);
	friends_from_db = linphone_core_fetch_friends_from_db(lc, linphone_core_get_default_friend_list(lc));
	BC_ASSERT_EQUAL(ms_list_size(friends_from_db), 0, int, "%d");

	linphone_vcard_set_etag(lvc, "\"123-456789\"");
	linphone_vcard_set_url(lvc, "http://dav.somewhere.fr/addressbook/me/someone.vcf");
	lf = linphone_friend_new_from_vcard(lvc);
	linphone_friend_set_address(lf, addr);
	linphone_friend_set_name(lf, "Sylvain");

	linphone_core_add_friend_list(lc, lfl);
	wait_for_until(lc, NULL, &stats->new_list_count, 1, 1000);
	BC_ASSERT_EQUAL(stats->new_list_count, 1, int, "%i");
	linphone_friend_list_unref(lfl);
	linphone_friend_list_set_display_name(lfl, "Test");
	BC_ASSERT_EQUAL_FATAL(linphone_friend_list_add_friend(lfl, lf), LinphoneFriendListOK, int, "%i");
	linphone_friend_unref(lf);
	BC_ASSERT_EQUAL(lfl->storage_id, 1, int, "%d");
	BC_ASSERT_EQUAL(lf->storage_id, 1, int, "%d");

	friends = linphone_friend_list_get_friends(linphone_core_get_default_friend_list(lc));
	BC_ASSERT_EQUAL(ms_list_size(friends), 0, int, "%d");

	friends_lists_from_db = linphone_core_fetch_friends_lists_from_db(lc);
	BC_ASSERT_EQUAL(ms_list_size(friends_lists_from_db), 1, int, "%d");
	friends_from_db = ((LinphoneFriendList *)friends_lists_from_db->data)->friends;
	BC_ASSERT_EQUAL(ms_list_size(friends_from_db), 1, int, "%d");
	lf2 = (LinphoneFriend *)friends_from_db->data;
	BC_ASSERT_PTR_NOT_NULL(lf2->lc);
	BC_ASSERT_PTR_NOT_NULL(lf2->friend_list);
	friends_lists_from_db = ms_list_free_with_data(friends_lists_from_db, (void (*)(void *))linphone_friend_list_unref);

	friends_from_db = linphone_core_fetch_friends_from_db(lc, lfl);
	BC_ASSERT_EQUAL(ms_list_size(friends_from_db), 1, int, "%d");
	if (ms_list_size(friends_from_db) < 1) {
		goto end;
	}
	lf2 = (LinphoneFriend *)friends_from_db->data;
	BC_ASSERT_STRING_EQUAL(linphone_friend_get_name(lf2), linphone_friend_get_name(lf));
	BC_ASSERT_EQUAL(lf2->storage_id, lf->storage_id, int, "%i");
	BC_ASSERT_STRING_EQUAL(linphone_vcard_get_etag(linphone_friend_get_vcard(lf2)), linphone_vcard_get_etag(linphone_friend_get_vcard(lf)));
	BC_ASSERT_STRING_EQUAL(linphone_vcard_get_url(linphone_friend_get_vcard(lf2)), linphone_vcard_get_url(linphone_friend_get_vcard(lf)));
	BC_ASSERT_STRING_EQUAL(linphone_address_as_string(linphone_friend_get_address(lf2)), linphone_address_as_string(linphone_friend_get_address(lf)));

	linphone_friend_edit(lf);
	linphone_friend_set_name(lf, "Margaux");
	linphone_friend_done(lf);
	friends_from_db = ms_list_free_with_data(friends_from_db, (void (*)(void *))linphone_friend_unref);
	friends_from_db = linphone_core_fetch_friends_from_db(lc, lfl);
	BC_ASSERT_EQUAL(ms_list_size(friends_from_db), 1, int, "%d");
	if (ms_list_size(friends_from_db) < 1) {
		goto end;
	}
	lf2 = (LinphoneFriend *)friends_from_db->data;
	BC_ASSERT_STRING_EQUAL(linphone_friend_get_name(lf2), "Margaux");
	friends_from_db = ms_list_free_with_data(friends_from_db, (void (*)(void *))linphone_friend_unref);

	linphone_friend_list_remove_friend(lfl, lf);
	friends = linphone_friend_list_get_friends(linphone_core_get_default_friend_list(lc));
	BC_ASSERT_EQUAL(ms_list_size(friends), 0, int, "%d");
	friends_from_db = linphone_core_fetch_friends_from_db(lc, lfl);
	BC_ASSERT_EQUAL(ms_list_size(friends_from_db), 0, int, "%d");

	linphone_core_remove_friend_list(lc, lfl);
	wait_for_until(lc, NULL, &stats->removed_list_count, 1, 1000);
	BC_ASSERT_EQUAL(stats->removed_list_count, 1, int, "%i");

end:
	ms_free(stats);
	unlink(friends_db);
	ms_free(friends_db);
	linphone_address_unref(addr);
	linphone_core_destroy(lc);
}
コード例 #16
0
ファイル: mscommon.c プロジェクト: biddyweb/azfone-ios
MSList * ms_list_free(MSList *elem){
	return ms_list_free_with_data(elem,NULL);
}
コード例 #17
0
static void h264_dec_process(MSFilter *f) {
	VTH264DecCtx *ctx = (VTH264DecCtx *)f->data;
	mblk_t *pkt;
	mblk_t *nalu;
	mblk_t *pixbuf;
	MSQueue q_nalus;
	MSQueue q_nalus2;
	CMBlockBufferRef stream = NULL;
	CMSampleBufferRef sample = NULL;
	CMSampleTimingInfo timing_info;
	MSPicture pixbuf_desc;
	OSStatus status;
	MSList *parameter_sets = NULL;
	bool_t unpacking_failed;

	ms_queue_init(&q_nalus);
	ms_queue_init(&q_nalus2);

	// unpack RTP packet
	unpacking_failed = FALSE;
	while((pkt = ms_queue_get(f->inputs[0]))) {
		unpacking_failed |= (rfc3984_unpack(&ctx->unpacker, pkt, &q_nalus) != 0);
	}
	if(unpacking_failed) {
		ms_error("VideoToolboxDecoder: error while unpacking RTP packets");
		goto fail;
	}

	// Pull out SPSs and PPSs and put them into the filter context if necessary
	while((nalu = ms_queue_get(&q_nalus))) {
		MSH264NaluType nalu_type = ms_h264_nalu_get_type(nalu);
		if(nalu_type == MSH264NaluTypeSPS || nalu_type == MSH264NaluTypePPS) {
			parameter_sets = ms_list_append(parameter_sets, nalu);
		} else if(ctx->format_desc || parameter_sets) {
			ms_queue_put(&q_nalus2, nalu);
		} else {
			ms_free(nalu);
		}
	}
	if(parameter_sets) {
		CMFormatDescriptionRef last_format = ctx->format_desc ? CFRetain(ctx->format_desc) : NULL;
		h264_dec_update_format_description(ctx, parameter_sets);
		parameter_sets = ms_list_free_with_data(parameter_sets, (void (*)(void *))freemsg);
		if(ctx->format_desc == NULL) goto fail;
		if(last_format) {
			CMVideoDimensions last_vsize = CMVideoFormatDescriptionGetDimensions(last_format);
			CMVideoDimensions vsize = CMVideoFormatDescriptionGetDimensions(ctx->format_desc);
			if(last_vsize.width != vsize.width || last_vsize.height != vsize.height) {
				ms_message("VideoToolboxDecoder: new encoded video size %dx%d -> %dx%d",
						   (int)last_vsize.width, (int)last_vsize.height, (int)vsize.width, (int)vsize.height);
				ms_message("VideoToolboxDecoder: destroying decoding session");
				VTDecompressionSessionInvalidate(ctx->session);
				CFRelease(ctx->session);
				ctx->session = NULL;
			}
			CFRelease(last_format);
		}
	}

	/* Stops proccessing if no IDR has been received yet */
	if(ctx->format_desc == NULL) {
		ms_warning("VideoToolboxDecoder: no IDR packet has been received yet");
		goto fail;
	}

	/* Initializes the decoder if it has not be done yet or reconfigure it when
	 the size of the encoded video change */
	if(ctx->session == NULL) {
		if(!h264_dec_init_decoder(ctx)) {
			ms_error("VideoToolboxDecoder: failed to initialized decoder");
			goto fail;
		}
	}

	// Pack all nalus in a VTBlockBuffer
	CMBlockBufferCreateEmpty(NULL, 0, kCMBlockBufferAssureMemoryNowFlag, &stream);
	while((nalu = ms_queue_get(&q_nalus2))) {
		CMBlockBufferRef nalu_block;
		size_t nalu_block_size = msgdsize(nalu) + H264_NALU_HEAD_SIZE;
		uint32_t nalu_size = htonl(msgdsize(nalu));

		CMBlockBufferCreateWithMemoryBlock(NULL, NULL, nalu_block_size, NULL, NULL, 0, nalu_block_size, kCMBlockBufferAssureMemoryNowFlag, &nalu_block);
		CMBlockBufferReplaceDataBytes(&nalu_size, nalu_block, 0, H264_NALU_HEAD_SIZE);
		CMBlockBufferReplaceDataBytes(nalu->b_rptr, nalu_block, H264_NALU_HEAD_SIZE, msgdsize(nalu));
		CMBlockBufferAppendBufferReference(stream, nalu_block, 0, nalu_block_size, 0);
		CFRelease(nalu_block);
		freemsg(nalu);
	}
	if(!CMBlockBufferIsEmpty(stream)) {
		timing_info.duration = kCMTimeInvalid;
		timing_info.presentationTimeStamp = CMTimeMake(f->ticker->time, 1000);
		timing_info.decodeTimeStamp = CMTimeMake(f->ticker->time, 1000);
		CMSampleBufferCreate(
			NULL, stream, TRUE, NULL, NULL,
			ctx->format_desc, 1, 1, &timing_info,
			0, NULL, &sample);

		status = VTDecompressionSessionDecodeFrame(ctx->session, sample, 0, NULL, NULL);
		CFRelease(sample);
		if(status != noErr) {
			CFRelease(stream);
			ms_error("VideoToolboxDecoder: error while passing encoded frames to the decoder: %d", status);
			if(status == kVTInvalidSessionErr) {
				h264_dec_uninit_decoder(ctx);
			}
			goto fail;
		}
	}
	CFRelease(stream);
	goto put_frames_out;

fail:
	ms_filter_notify_no_arg(f, MS_VIDEO_DECODER_DECODING_ERRORS);
	ms_filter_lock(f);
	if(ctx->enable_avpf) {
		ms_message("VideoToolboxDecoder: sending PLI");
		ms_filter_notify_no_arg(f, MS_VIDEO_DECODER_SEND_PLI);
	}
	ms_filter_unlock(f);

put_frames_out:
	// Transfer decoded frames in the output queue
	ms_mutex_lock(&ctx->mutex);
	while((pixbuf = ms_queue_get(&ctx->queue))) {
		ms_mutex_unlock(&ctx->mutex);
		ms_yuv_buf_init_from_mblk(&pixbuf_desc, pixbuf);
		ms_filter_lock(f);
		if(pixbuf_desc.w != ctx->vsize.width || pixbuf_desc.h != ctx->vsize.height) {
			ctx->vsize = (MSVideoSize){ pixbuf_desc.w , pixbuf_desc.h };
		}
		ms_average_fps_update(&ctx->fps, (uint32_t)f->ticker->time);
		if(ctx->first_image) {
			ms_filter_notify_no_arg(f, MS_VIDEO_DECODER_FIRST_IMAGE_DECODED);
			ctx->first_image = FALSE;
		}
		ms_filter_unlock(f);
		ms_queue_put(f->outputs[0], pixbuf);
		ms_mutex_lock(&ctx->mutex);
	}
	ms_mutex_unlock(&ctx->mutex);


	// Cleaning
	ms_queue_flush(&q_nalus);
	ms_queue_flush(&q_nalus2);
	ms_queue_flush(f->inputs[0]);
	return;
}