Boot Linux faster!

Check our new training course

Boot Linux faster!

Check our new training course
and Creative Commons CC-BY-SA
lecture and lab materials

Bootlin logo

Elixir Cross Referencer

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
/*
 * Broadcom BM2835 V4L2 driver
 *
 * Copyright © 2013 Raspberry Pi (Trading) Ltd.
 *
 * This file is subject to the terms and conditions of the GNU General Public
 * License.  See the file COPYING in the main directory of this archive
 * for more details.
 *
 * Authors: Vincent Sanders <vincent.sanders@collabora.co.uk>
 *          Dave Stevenson <dsteve@broadcom.com>
 *          Simon Mellor <simellor@broadcom.com>
 *          Luke Diamand <luked@broadcom.com>
 */

/* all the data structures which serialise the MMAL protocol. note
 * these are directly mapped onto the recived message data.
 *
 * BEWARE: They seem to *assume* pointers are u32 and that there is no
 * structure padding!
 *
 * NOTE: this implementation uses kernel types to ensure sizes. Rather
 * than assigning values to enums to force their size the
 * implementation uses fixed size types and not the enums (though the
 * comments have the actual enum type
 */

#define VC_MMAL_VER 15
#define VC_MMAL_MIN_VER 10
#define VC_MMAL_SERVER_NAME  MAKE_FOURCC("mmal")

/* max total message size is 512 bytes */
#define MMAL_MSG_MAX_SIZE 512
/* with six 32bit header elements max payload is therefore 488 bytes */
#define MMAL_MSG_MAX_PAYLOAD 488

#include "mmal-msg-common.h"
#include "mmal-msg-format.h"
#include "mmal-msg-port.h"

enum mmal_msg_type {
	MMAL_MSG_TYPE_QUIT = 1,
	MMAL_MSG_TYPE_SERVICE_CLOSED,
	MMAL_MSG_TYPE_GET_VERSION,
	MMAL_MSG_TYPE_COMPONENT_CREATE,
	MMAL_MSG_TYPE_COMPONENT_DESTROY, /* 5 */
	MMAL_MSG_TYPE_COMPONENT_ENABLE,
	MMAL_MSG_TYPE_COMPONENT_DISABLE,
	MMAL_MSG_TYPE_PORT_INFO_GET,
	MMAL_MSG_TYPE_PORT_INFO_SET,
	MMAL_MSG_TYPE_PORT_ACTION, /* 10 */
	MMAL_MSG_TYPE_BUFFER_FROM_HOST,
	MMAL_MSG_TYPE_BUFFER_TO_HOST,
	MMAL_MSG_TYPE_GET_STATS,
	MMAL_MSG_TYPE_PORT_PARAMETER_SET,
	MMAL_MSG_TYPE_PORT_PARAMETER_GET, /* 15 */
	MMAL_MSG_TYPE_EVENT_TO_HOST,
	MMAL_MSG_TYPE_GET_CORE_STATS_FOR_PORT,
	MMAL_MSG_TYPE_OPAQUE_ALLOCATOR,
	MMAL_MSG_TYPE_CONSUME_MEM,
	MMAL_MSG_TYPE_LMK, /* 20 */
	MMAL_MSG_TYPE_OPAQUE_ALLOCATOR_DESC,
	MMAL_MSG_TYPE_DRM_GET_LHS32,
	MMAL_MSG_TYPE_DRM_GET_TIME,
	MMAL_MSG_TYPE_BUFFER_FROM_HOST_ZEROLEN,
	MMAL_MSG_TYPE_PORT_FLUSH, /* 25 */
	MMAL_MSG_TYPE_HOST_LOG,
	MMAL_MSG_TYPE_MSG_LAST
};

/* port action request messages differ depending on the action type */
enum mmal_msg_port_action_type {
	MMAL_MSG_PORT_ACTION_TYPE_UNKNOWN = 0,      /* Unkown action */
	MMAL_MSG_PORT_ACTION_TYPE_ENABLE,           /* Enable a port */
	MMAL_MSG_PORT_ACTION_TYPE_DISABLE,          /* Disable a port */
	MMAL_MSG_PORT_ACTION_TYPE_FLUSH,            /* Flush a port */
	MMAL_MSG_PORT_ACTION_TYPE_CONNECT,          /* Connect ports */
	MMAL_MSG_PORT_ACTION_TYPE_DISCONNECT,       /* Disconnect ports */
	MMAL_MSG_PORT_ACTION_TYPE_SET_REQUIREMENTS, /* Set buffer requirements*/
};

struct mmal_msg_header {
	u32 magic;
	u32 type; /** enum mmal_msg_type */

	/* Opaque handle to the control service */
	struct mmal_control_service *control_service;

	struct mmal_msg_context *context; /** a u32 per message context */
	u32 status; /** The status of the vchiq operation */
	u32 padding;
};

/* Send from VC to host to report version */
struct mmal_msg_version {
	u32 flags;
	u32 major;
	u32 minor;
	u32 minimum;
};

/* request to VC to create component */
struct mmal_msg_component_create {
	void *client_component; /* component context */
	char name[128];
	u32 pid;                /* For debug */
};

/* reply from VC to component creation request */
struct mmal_msg_component_create_reply {
	u32 status; /** enum mmal_msg_status - how does this differ to
		     * the one in the header?
		     */
	u32 component_handle; /* VideoCore handle for component */
	u32 input_num;        /* Number of input ports */
	u32 output_num;       /* Number of output ports */
	u32 clock_num;        /* Number of clock ports */
};

/* request to VC to destroy a component */
struct mmal_msg_component_destroy {
	u32 component_handle;
};

struct mmal_msg_component_destroy_reply {
	u32 status; /** The component destruction status */
};


/* request and reply to VC to enable a component */
struct mmal_msg_component_enable {
	u32 component_handle;
};

struct mmal_msg_component_enable_reply {
	u32 status; /** The component enable status */
};


/* request and reply to VC to disable a component */
struct mmal_msg_component_disable {
	u32 component_handle;
};

struct mmal_msg_component_disable_reply {
	u32 status; /** The component disable status */
};

/* request to VC to get port information */
struct mmal_msg_port_info_get {
	u32 component_handle;  /* component handle port is associated with */
	u32 port_type;         /* enum mmal_msg_port_type */
	u32 index;             /* port index to query */
};

/* reply from VC to get port info request */
struct mmal_msg_port_info_get_reply {
	u32 status; /** enum mmal_msg_status */
	u32 component_handle;  /* component handle port is associated with */
	u32 port_type;         /* enum mmal_msg_port_type */
	u32 port_index;        /* port indexed in query */
	s32 found;             /* unused */
	u32 port_handle;               /**< Handle to use for this port */
	struct mmal_port port;
	struct mmal_es_format format; /* elementry stream format */
	union mmal_es_specific_format es; /* es type specific data */
	u8 extradata[MMAL_FORMAT_EXTRADATA_MAX_SIZE]; /* es extra data */
};

/* request to VC to set port information */
struct mmal_msg_port_info_set {
	u32 component_handle;
	u32 port_type;         /* enum mmal_msg_port_type */
	u32 port_index;           /* port indexed in query */
	struct mmal_port port;
	struct mmal_es_format format;
	union mmal_es_specific_format es;
	u8 extradata[MMAL_FORMAT_EXTRADATA_MAX_SIZE];
};

/* reply from VC to port info set request */
struct mmal_msg_port_info_set_reply {
	u32 status;
	u32 component_handle;  /* component handle port is associated with */
	u32 port_type;         /* enum mmal_msg_port_type */
	u32 index;             /* port indexed in query */
	s32 found;             /* unused */
	u32 port_handle;               /**< Handle to use for this port */
	struct mmal_port port;
	struct mmal_es_format format;
	union mmal_es_specific_format es;
	u8 extradata[MMAL_FORMAT_EXTRADATA_MAX_SIZE];
};


/* port action requests that take a mmal_port as a parameter */
struct mmal_msg_port_action_port {
	u32 component_handle;
	u32 port_handle;
	u32 action; /* enum mmal_msg_port_action_type */
	struct mmal_port port;
};

/* port action requests that take handles as a parameter */
struct mmal_msg_port_action_handle {
	u32 component_handle;
	u32 port_handle;
	u32 action; /* enum mmal_msg_port_action_type */
	u32 connect_component_handle;
	u32 connect_port_handle;
};

struct mmal_msg_port_action_reply {
	u32 status; /** The port action operation status */
};




/* MMAL buffer transfer */

/** Size of space reserved in a buffer message for short messages. */
#define MMAL_VC_SHORT_DATA 128

/** Signals that the current payload is the end of the stream of data */
#define MMAL_BUFFER_HEADER_FLAG_EOS                    (1<<0)
/** Signals that the start of the current payload starts a frame */
#define MMAL_BUFFER_HEADER_FLAG_FRAME_START            (1<<1)
/** Signals that the end of the current payload ends a frame */
#define MMAL_BUFFER_HEADER_FLAG_FRAME_END              (1<<2)
/** Signals that the current payload contains only complete frames (>1) */
#define MMAL_BUFFER_HEADER_FLAG_FRAME                  \
	(MMAL_BUFFER_HEADER_FLAG_FRAME_START|MMAL_BUFFER_HEADER_FLAG_FRAME_END)
/** Signals that the current payload is a keyframe (i.e. self decodable) */
#define MMAL_BUFFER_HEADER_FLAG_KEYFRAME               (1<<3)
/** Signals a discontinuity in the stream of data (e.g. after a seek).
 * Can be used for instance by a decoder to reset its state */
#define MMAL_BUFFER_HEADER_FLAG_DISCONTINUITY          (1<<4)
/** Signals a buffer containing some kind of config data for the component
 * (e.g. codec config data) */
#define MMAL_BUFFER_HEADER_FLAG_CONFIG                 (1<<5)
/** Signals an encrypted payload */
#define MMAL_BUFFER_HEADER_FLAG_ENCRYPTED              (1<<6)
/** Signals a buffer containing side information */
#define MMAL_BUFFER_HEADER_FLAG_CODECSIDEINFO          (1<<7)
/** Signals a buffer which is the snapshot/postview image from a stills
 * capture
 */
#define MMAL_BUFFER_HEADER_FLAGS_SNAPSHOT              (1<<8)
/** Signals a buffer which contains data known to be corrupted */
#define MMAL_BUFFER_HEADER_FLAG_CORRUPTED              (1<<9)
/** Signals that a buffer failed to be transmitted */
#define MMAL_BUFFER_HEADER_FLAG_TRANSMISSION_FAILED    (1<<10)

struct mmal_driver_buffer {
	u32 magic;
	u32 component_handle;
	u32 port_handle;
	void *client_context;
};

/* buffer header */
struct mmal_buffer_header {
	struct mmal_buffer_header *next; /* next header */
	void *priv; /* framework private data */
	u32 cmd;
	void *data;
	u32 alloc_size;
	u32 length;
	u32 offset;
	u32 flags;
	s64 pts;
	s64 dts;
	void *type;
	void *user_data;
};

struct mmal_buffer_header_type_specific {
	union {
		struct {
		u32 planes;
		u32 offset[4];
		u32 pitch[4];
		u32 flags;
		} video;
	} u;
};

struct mmal_msg_buffer_from_host {
	/* The front 32 bytes of the buffer header are copied
	 * back to us in the reply to allow for context. This
	 * area is used to store two mmal_driver_buffer structures to
	 * allow for multiple concurrent service users.
	 */
	/* control data */
	struct mmal_driver_buffer drvbuf;

	/* referenced control data for passthrough buffer management */
	struct mmal_driver_buffer drvbuf_ref;
	struct mmal_buffer_header buffer_header; /* buffer header itself */
	struct mmal_buffer_header_type_specific buffer_header_type_specific;
	s32 is_zero_copy;
	s32 has_reference;

	/** allows short data to be xfered in control message */
	u32 payload_in_message;
	u8 short_data[MMAL_VC_SHORT_DATA];
};


/* port parameter setting */

#define MMAL_WORKER_PORT_PARAMETER_SPACE      96

struct mmal_msg_port_parameter_set {
	u32 component_handle; /* component */
	u32 port_handle;      /* port */
	u32 id;     /* Parameter ID  */
	u32 size;      /* Parameter size */
	uint32_t value[MMAL_WORKER_PORT_PARAMETER_SPACE];
};

struct mmal_msg_port_parameter_set_reply {
	u32 status; /** enum mmal_msg_status todo: how does this
		     * differ to the one in the header?
		     */
};

/* port parameter getting */

struct mmal_msg_port_parameter_get {
	u32 component_handle; /* component */
	u32 port_handle;      /* port */
	u32 id;     /* Parameter ID  */
	u32 size;      /* Parameter size */
};

struct mmal_msg_port_parameter_get_reply {
	u32 status;           /* Status of mmal_port_parameter_get call */
	u32 id;     /* Parameter ID  */
	u32 size;      /* Parameter size */
	uint32_t value[MMAL_WORKER_PORT_PARAMETER_SPACE];
};

/* event messages */
#define MMAL_WORKER_EVENT_SPACE 256

struct mmal_msg_event_to_host {
	void *client_component; /* component context */

	u32 port_type;
	u32 port_num;

	u32 cmd;
	u32 length;
	u8 data[MMAL_WORKER_EVENT_SPACE];
	struct mmal_buffer_header *delayed_buffer;
};

/* all mmal messages are serialised through this structure */
struct mmal_msg {
	/* header */
	struct mmal_msg_header h;
	/* payload */
	union {
		struct mmal_msg_version version;

		struct mmal_msg_component_create component_create;
		struct mmal_msg_component_create_reply component_create_reply;

		struct mmal_msg_component_destroy component_destroy;
		struct mmal_msg_component_destroy_reply component_destroy_reply;

		struct mmal_msg_component_enable component_enable;
		struct mmal_msg_component_enable_reply component_enable_reply;

		struct mmal_msg_component_disable component_disable;
		struct mmal_msg_component_disable_reply component_disable_reply;

		struct mmal_msg_port_info_get port_info_get;
		struct mmal_msg_port_info_get_reply port_info_get_reply;

		struct mmal_msg_port_info_set port_info_set;
		struct mmal_msg_port_info_set_reply port_info_set_reply;

		struct mmal_msg_port_action_port port_action_port;
		struct mmal_msg_port_action_handle port_action_handle;
		struct mmal_msg_port_action_reply port_action_reply;

		struct mmal_msg_buffer_from_host buffer_from_host;

		struct mmal_msg_port_parameter_set port_parameter_set;
		struct mmal_msg_port_parameter_set_reply
			port_parameter_set_reply;
		struct mmal_msg_port_parameter_get
			port_parameter_get;
		struct mmal_msg_port_parameter_get_reply
			port_parameter_get_reply;

		struct mmal_msg_event_to_host event_to_host;

		u8 payload[MMAL_MSG_MAX_PAYLOAD];
	} u;
};