Blame axfer/mapper.c

Packit Service a9274b
// SPDX-License-Identifier: GPL-2.0
Packit Service a9274b
//
Packit Service a9274b
// mapper.c - an interface of muxer/demuxer between buffer with data frames and
Packit Service a9274b
// 	      formatted files.
Packit Service a9274b
//
Packit Service a9274b
// Copyright (c) 2018 Takashi Sakamoto <o-takashi@sakamocchi.jp>
Packit Service a9274b
//
Packit Service a9274b
// Licensed under the terms of the GNU General Public License, version 2.
Packit Service a9274b
Packit Service a9274b
#include "mapper.h"
Packit Service a9274b
#include "misc.h"
Packit Service a9274b
Packit Service a9274b
#include <stdio.h>
Packit Service a9274b
Packit Service a9274b
static const char *const mapper_type_labels[] = {
Packit Service a9274b
	[MAPPER_TYPE_MUXER] = "muxer",
Packit Service a9274b
	[MAPPER_TYPE_DEMUXER] = "demuxer",
Packit Service a9274b
};
Packit Service a9274b
Packit Service a9274b
static const char *const mapper_target_labels[] = {
Packit Service a9274b
	[MAPPER_TARGET_SINGLE] = "single",
Packit Service a9274b
	[MAPPER_TARGET_MULTIPLE] = "multiple",
Packit Service a9274b
};
Packit Service a9274b
Packit Service a9274b
int mapper_context_init(struct mapper_context *mapper,
Packit Service a9274b
			enum mapper_type type, unsigned int cntr_count,
Packit Service a9274b
			unsigned int verbose)
Packit Service a9274b
{
Packit Service a9274b
	const struct mapper_data *data = NULL;
Packit Service a9274b
Packit Service a9274b
	assert(mapper);
Packit Service a9274b
	assert(cntr_count > 0);
Packit Service a9274b
Packit Service a9274b
	// Detect forgotten to destruct.
Packit Service a9274b
	assert(mapper->private_data == NULL);
Packit Service a9274b
Packit Service a9274b
	memset(mapper, 0, sizeof(*mapper));
Packit Service a9274b
Packit Service a9274b
	if (type == MAPPER_TYPE_MUXER) {
Packit Service a9274b
		if (cntr_count == 1) {
Packit Service a9274b
			data = &mapper_muxer_single;
Packit Service a9274b
			mapper->target = MAPPER_TARGET_SINGLE;
Packit Service a9274b
		} else {
Packit Service a9274b
			data = &mapper_muxer_multiple;
Packit Service a9274b
			mapper->target = MAPPER_TARGET_MULTIPLE;
Packit Service a9274b
		}
Packit Service a9274b
	} else {
Packit Service a9274b
		if (cntr_count == 1) {
Packit Service a9274b
			data = &mapper_demuxer_single;
Packit Service a9274b
			mapper->target = MAPPER_TARGET_SINGLE;
Packit Service a9274b
		} else {
Packit Service a9274b
			data = &mapper_demuxer_multiple;
Packit Service a9274b
			mapper->target = MAPPER_TARGET_MULTIPLE;
Packit Service a9274b
		}
Packit Service a9274b
	}
Packit Service a9274b
Packit Service a9274b
	mapper->ops = &data->ops;
Packit Service a9274b
	mapper->type = type;
Packit Service a9274b
Packit Service a9274b
	mapper->private_data = malloc(data->private_size);
Packit Service a9274b
	if (mapper->private_data == NULL)
Packit Service a9274b
		return -ENOMEM;
Packit Service a9274b
	memset(mapper->private_data, 0, data->private_size);
Packit Service a9274b
Packit Service a9274b
	mapper->cntr_count = cntr_count;
Packit Service a9274b
	mapper->verbose = verbose;
Packit Service a9274b
Packit Service a9274b
	return 0;
Packit Service a9274b
}
Packit Service a9274b
Packit Service a9274b
int mapper_context_pre_process(struct mapper_context *mapper,
Packit Service a9274b
			       snd_pcm_access_t access,
Packit Service a9274b
			       unsigned int bytes_per_sample,
Packit Service a9274b
			       unsigned int samples_per_frame,
Packit Service a9274b
			       unsigned int frames_per_buffer,
Packit Service a9274b
			       struct container_context *cntrs)
Packit Service a9274b
{
Packit Service a9274b
	int err;
Packit Service a9274b
Packit Service a9274b
	assert(mapper);
Packit Service a9274b
	assert(access >= SND_PCM_ACCESS_MMAP_INTERLEAVED);
Packit Service a9274b
	assert(access <= SND_PCM_ACCESS_RW_NONINTERLEAVED);
Packit Service a9274b
	assert(bytes_per_sample > 0);
Packit Service a9274b
	assert(samples_per_frame > 0);
Packit Service a9274b
	assert(cntrs);
Packit Service a9274b
Packit Service a9274b
	// The purpose of multiple target is to mux/demux each channels to/from
Packit Service a9274b
	// containers.
Packit Service a9274b
	if (mapper->target == MAPPER_TARGET_MULTIPLE &&
Packit Service a9274b
	    samples_per_frame != mapper->cntr_count)
Packit Service a9274b
		return -EINVAL;
Packit Service a9274b
Packit Service a9274b
	mapper->access = access;
Packit Service a9274b
	mapper->bytes_per_sample = bytes_per_sample;
Packit Service a9274b
	mapper->samples_per_frame = samples_per_frame;
Packit Service a9274b
	mapper->frames_per_buffer = frames_per_buffer;
Packit Service a9274b
Packit Service a9274b
	err = mapper->ops->pre_process(mapper, cntrs, mapper->cntr_count);
Packit Service a9274b
	if (err < 0)
Packit Service a9274b
		return err;
Packit Service a9274b
Packit Service a9274b
	if (mapper->verbose > 0) {
Packit Service a9274b
		fprintf(stderr, "Mapper: %s\n",
Packit Service a9274b
		       mapper_type_labels[mapper->type]);
Packit Service a9274b
		fprintf(stderr, "  target: %s\n",
Packit Service a9274b
		       mapper_target_labels[mapper->target]);
Packit Service a9274b
		fprintf(stderr, "  access: %s\n",
Packit Service a9274b
		       snd_pcm_access_name(mapper->access));
Packit Service a9274b
		fprintf(stderr, "  bytes/sample: %u\n",
Packit Service a9274b
			mapper->bytes_per_sample);
Packit Service a9274b
		fprintf(stderr, "  samples/frame: %u\n",
Packit Service a9274b
			mapper->samples_per_frame);
Packit Service a9274b
		fprintf(stderr, "  frames/buffer: %lu\n",
Packit Service a9274b
			mapper->frames_per_buffer);
Packit Service a9274b
	}
Packit Service a9274b
Packit Service a9274b
	return 0;
Packit Service a9274b
}
Packit Service a9274b
Packit Service a9274b
int mapper_context_process_frames(struct mapper_context *mapper,
Packit Service a9274b
				  void *frame_buffer,
Packit Service a9274b
				  unsigned int *frame_count,
Packit Service a9274b
				  struct container_context *cntrs)
Packit Service a9274b
{
Packit Service a9274b
	assert(mapper);
Packit Service a9274b
	assert(frame_buffer);
Packit Service a9274b
	assert(frame_count);
Packit Service a9274b
	assert(*frame_count <= mapper->frames_per_buffer);
Packit Service a9274b
	assert(cntrs);
Packit Service a9274b
Packit Service a9274b
	return mapper->ops->process_frames(mapper, frame_buffer, frame_count,
Packit Service a9274b
					    cntrs, mapper->cntr_count);
Packit Service a9274b
}
Packit Service a9274b
Packit Service a9274b
void mapper_context_post_process(struct mapper_context *mapper)
Packit Service a9274b
{
Packit Service a9274b
	assert(mapper);
Packit Service a9274b
Packit Service a9274b
	if (mapper->ops && mapper->ops->post_process)
Packit Service a9274b
		mapper->ops->post_process(mapper);
Packit Service a9274b
}
Packit Service a9274b
Packit Service a9274b
void mapper_context_destroy(struct mapper_context *mapper)
Packit Service a9274b
{
Packit Service a9274b
	assert(mapper);
Packit Service a9274b
Packit Service a9274b
	if (mapper->private_data)
Packit Service a9274b
		free(mapper->private_data);
Packit Service a9274b
	mapper->private_data = NULL;
Packit Service a9274b
}