1// SPDX-License-Identifier: GPL-2.0 2// 3// mapper.c - an interface of muxer/demuxer between buffer with data frames and 4// formatted files. 5// 6// Copyright (c) 2018 Takashi Sakamoto <o-takashi@sakamocchi.jp> 7// 8// Licensed under the terms of the GNU General Public License, version 2. 9 10#include "mapper.h" 11#include "misc.h" 12 13#include <stdio.h> 14 15static const char *const mapper_type_labels[] = { 16 [MAPPER_TYPE_MUXER] = "muxer", 17 [MAPPER_TYPE_DEMUXER] = "demuxer", 18}; 19 20static const char *const mapper_target_labels[] = { 21 [MAPPER_TARGET_SINGLE] = "single", 22 [MAPPER_TARGET_MULTIPLE] = "multiple", 23}; 24 25int mapper_context_init(struct mapper_context *mapper, 26 enum mapper_type type, unsigned int cntr_count, 27 unsigned int verbose) 28{ 29 const struct mapper_data *data = NULL; 30 31 assert(mapper); 32 assert(cntr_count > 0); 33 34 // Detect forgotten to destruct. 35 assert(mapper->private_data == NULL); 36 37 memset(mapper, 0, sizeof(*mapper)); 38 39 if (type == MAPPER_TYPE_MUXER) { 40 if (cntr_count == 1) { 41 data = &mapper_muxer_single; 42 mapper->target = MAPPER_TARGET_SINGLE; 43 } else { 44 data = &mapper_muxer_multiple; 45 mapper->target = MAPPER_TARGET_MULTIPLE; 46 } 47 } else { 48 if (cntr_count == 1) { 49 data = &mapper_demuxer_single; 50 mapper->target = MAPPER_TARGET_SINGLE; 51 } else { 52 data = &mapper_demuxer_multiple; 53 mapper->target = MAPPER_TARGET_MULTIPLE; 54 } 55 } 56 57 mapper->ops = &data->ops; 58 mapper->type = type; 59 60 mapper->private_data = malloc(data->private_size); 61 if (mapper->private_data == NULL) 62 return -ENOMEM; 63 memset(mapper->private_data, 0, data->private_size); 64 65 mapper->cntr_count = cntr_count; 66 mapper->verbose = verbose; 67 68 return 0; 69} 70 71int mapper_context_pre_process(struct mapper_context *mapper, 72 snd_pcm_access_t access, 73 unsigned int bytes_per_sample, 74 unsigned int samples_per_frame, 75 unsigned int frames_per_buffer, 76 struct container_context *cntrs) 77{ 78 int err; 79 80 assert(mapper); 81 assert(access >= SND_PCM_ACCESS_MMAP_INTERLEAVED); 82 assert(access <= SND_PCM_ACCESS_RW_NONINTERLEAVED); 83 assert(bytes_per_sample > 0); 84 assert(samples_per_frame > 0); 85 assert(cntrs); 86 87 // The purpose of multiple target is to mux/demux each channels to/from 88 // containers. 89 if (mapper->target == MAPPER_TARGET_MULTIPLE && 90 samples_per_frame != mapper->cntr_count) 91 return -EINVAL; 92 93 mapper->access = access; 94 mapper->bytes_per_sample = bytes_per_sample; 95 mapper->samples_per_frame = samples_per_frame; 96 mapper->frames_per_buffer = frames_per_buffer; 97 98 err = mapper->ops->pre_process(mapper, cntrs, mapper->cntr_count); 99 if (err < 0) 100 return err; 101 102 if (mapper->verbose > 0) { 103 fprintf(stderr, "Mapper: %s\n", 104 mapper_type_labels[mapper->type]); 105 fprintf(stderr, " target: %s\n", 106 mapper_target_labels[mapper->target]); 107 fprintf(stderr, " access: %s\n", 108 snd_pcm_access_name(mapper->access)); 109 fprintf(stderr, " bytes/sample: %u\n", 110 mapper->bytes_per_sample); 111 fprintf(stderr, " samples/frame: %u\n", 112 mapper->samples_per_frame); 113 fprintf(stderr, " frames/buffer: %lu\n", 114 mapper->frames_per_buffer); 115 } 116 117 return 0; 118} 119 120int mapper_context_process_frames(struct mapper_context *mapper, 121 void *frame_buffer, 122 unsigned int *frame_count, 123 struct container_context *cntrs) 124{ 125 assert(mapper); 126 assert(frame_buffer); 127 assert(frame_count); 128 assert(*frame_count <= mapper->frames_per_buffer); 129 assert(cntrs); 130 131 return mapper->ops->process_frames(mapper, frame_buffer, frame_count, 132 cntrs, mapper->cntr_count); 133} 134 135void mapper_context_post_process(struct mapper_context *mapper) 136{ 137 assert(mapper); 138 139 if (mapper->ops && mapper->ops->post_process) 140 mapper->ops->post_process(mapper); 141} 142 143void mapper_context_destroy(struct mapper_context *mapper) 144{ 145 assert(mapper); 146 147 if (mapper->private_data) 148 free(mapper->private_data); 149 mapper->private_data = NULL; 150} 151