• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
15 static const char *const mapper_type_labels[] = {
16 	[MAPPER_TYPE_MUXER] = "muxer",
17 	[MAPPER_TYPE_DEMUXER] = "demuxer",
18 };
19 
20 static const char *const mapper_target_labels[] = {
21 	[MAPPER_TARGET_SINGLE] = "single",
22 	[MAPPER_TARGET_MULTIPLE] = "multiple",
23 };
24 
mapper_context_init(struct mapper_context * mapper,enum mapper_type type,unsigned int cntr_count,unsigned int verbose)25 int 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 
mapper_context_pre_process(struct mapper_context * mapper,snd_pcm_access_t access,unsigned int bytes_per_sample,unsigned int samples_per_frame,unsigned int frames_per_buffer,struct container_context * cntrs)71 int 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 
mapper_context_process_frames(struct mapper_context * mapper,void * frame_buffer,unsigned int * frame_count,struct container_context * cntrs)120 int 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 
mapper_context_post_process(struct mapper_context * mapper)135 void 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 
mapper_context_destroy(struct mapper_context * mapper)143 void 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