/*
 * OpenMRCP - Open Source Media Resource Control Protocol Stack
 * Copyright (C) 2007, Cepstral LLC
 *
 * Version: MPL 1.1
 *
 * The contents of this file are subject to the Mozilla Public License Version
 * 1.1 (the "License"); you may not use this file except in compliance with
 * the License. You may obtain a copy of the License at
 * http://www.mozilla.org/MPL/
 *
 * Software distributed under the License is distributed on an "AS IS" basis,
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 * for the specific language governing rights and limitations under the
 * License.
 *
 * Author(s):
 * Arsen Chaloyan <achaloyan@yahoo.com>
 *
 * Contributor(s):
 *
 */

#include "codec_manager.h"

#define MAX_CODEC_COUNT 10

typedef struct codec_slot_t codec_slot_t;

struct codec_slot_t {
	codec_descriptor_t  *codec_descriptor;
	codec_manipulator_t *codec_manipulator;
};

struct codec_manager_t {
	apr_pool_t *pool;

	codec_slot_t codecs[MAX_CODEC_COUNT];
	apr_size_t codec_count;
};

codec_manager_t* codec_manager_create(apr_pool_t *pool)
{
	size_t i;
	codec_manager_t *codec_manager = apr_palloc(pool,sizeof(codec_manager_t));
	codec_manager->pool = pool;
	codec_manager->codec_count = 0;
	for(i=0; i<MAX_CODEC_COUNT; i++) {
		codec_manager->codecs[i].codec_descriptor = NULL;
		codec_manager->codecs[i].codec_manipulator = NULL;
	}

	return codec_manager;
}

void codec_manager_destroy(codec_manager_t *codec_manager)
{
}

apr_status_t codec_manager_codec_register(codec_manager_t *codec_manager, codec_descriptor_t *descriptor, codec_manipulator_t *manipulator)
{
	if(codec_manager->codec_count >= MAX_CODEC_COUNT) {
		return APR_OS_START_USERERR;
	}

	codec_manager->codecs[codec_manager->codec_count].codec_descriptor = descriptor;
	codec_manager->codecs[codec_manager->codec_count].codec_manipulator = manipulator;
	codec_manager->codec_count++;
	return APR_SUCCESS;
}

const codec_manipulator_t* codec_manager_codec_get(codec_manager_t *codec_manager, codec_descriptor_t *descriptor)
{
	size_t i;
	if(!descriptor) {
		return NULL;
	}

	for(i=0; i<codec_manager->codec_count; i++) {
		if(!codec_manager->codecs[i].codec_descriptor) {
			continue;
		}
		if(descriptor->payload_type < 96) {
			if(codec_manager->codecs[i].codec_descriptor->payload_type == descriptor->payload_type) {
				descriptor->name = codec_manager->codecs[i].codec_descriptor->name;
				descriptor->sampling_rate = codec_manager->codecs[i].codec_descriptor->sampling_rate;
				break;
			}
		}
		else {
			if(codec_manager->codecs[i].codec_descriptor->name) {
				if(strcmp(codec_manager->codecs[i].codec_descriptor->name,descriptor->name) == 0) {
					break;
				}
			}
		}
	}
	if(i == codec_manager->codec_count) {
		return NULL;
	}

	return codec_manager->codecs[i].codec_manipulator;
}

apr_size_t codec_manager_codec_list_get(codec_manager_t *codec_manager, codec_descriptor_t **codec_list, apr_size_t max_count, apr_pool_t *pool)
{
	codec_descriptor_t *descriptor;
	apr_size_t i;
	apr_size_t count = codec_manager->codec_count;
	if(count > max_count) {
		count = max_count;
	}
	for(i=0; i<count; i++) {
		if(!codec_manager->codecs[i].codec_descriptor) {
			continue;
		}
		descriptor = apr_palloc(pool,sizeof(codec_descriptor_t));
		*descriptor = *codec_manager->codecs[i].codec_descriptor;
		codec_list[i] = descriptor;
	}
	return count;
}
