1
/*
2
 * Copyright (C) 2009-2010 Felipe Contreras
3
 *
4
 * Author: Felipe Contreras <felipe.contreras@gmail.com>
5
 *
6
 * This file may be used under the terms of the GNU Lesser General Public
7
 * License version 2.1, a copy of which is found in LICENSE included in the
8
 * packaging of this file.
9
 */
10
11
#ifndef GST_DSP_BASE_H
12
#define GST_DSP_BASE_H
13
14
#include <gst/gst.h>
15
16
G_BEGIN_DECLS
17
18
#define GST_DSP_BASE(obj) (GstDspBase *)(obj)
19
#define GST_DSP_BASE_TYPE (gst_dsp_base_get_type())
20
#define GST_DSP_BASE_CLASS(obj) (GstDspBaseClass *)(obj)
21
#define GST_DSP_BASE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), GST_DSP_BASE_TYPE, GstDspBaseClass))
22
23
/* #define TS_COUNT */
24
25
typedef struct _GstDspBase GstDspBase;
26
typedef struct _GstDspBaseClass GstDspBaseClass;
27
28
typedef struct du_port_t du_port_t;
29
30
#include "dmm_buffer.h"
31
#include "sem.h"
32
#include "async_queue.h"
33
34
struct td_buffer;
35
36
typedef void (*port_buffer_cb_t) (GstDspBase *base, struct td_buffer *tb);
37
38
struct td_buffer {
39
	struct du_port_t *port;
40
	dmm_buffer_t *data;
41
	dmm_buffer_t *comm;
42
	dmm_buffer_t *params;
43
	void *user_data;
44
	bool keyframe;
45
	bool pinned;
46
	bool clean;
47
};
48
49
struct du_port_t {
50
	int id;
51
	struct td_buffer *buffers;
52
	guint num_buffers;
53
	AsyncQueue *queue;
54
	port_buffer_cb_t send_cb;
55
	port_buffer_cb_t recv_cb;
56
	int dir;
57
};
58
59
struct td_codec {
60
	const struct dsp_uuid *uuid;
61
	const char *filename;
62
	void (*setup_params)(GstDspBase *base);
63
	void (*create_args)(GstDspBase *base, unsigned *profile_id, void **arg_data);
64
	bool (*handle_extra_data)(GstDspBase *base, GstBuffer *buf);
65
	void (*flush_buffer)(GstDspBase *base);
66
	void (*send_params)(GstDspBase *base, struct dsp_node *node);
67
	void (*update_params) (GstDspBase *base, struct dsp_node *node, uint32_t msg);
68
	unsigned (*get_latency)(GstDspBase *base, unsigned frame_duration);
69
};
70
71
struct ts_item {
72
	GstClockTime time;
73
	GstClockTime duration;
74
	GstEvent *event;
75
};
76
77
struct _GstDspBase {
78
	GstElement element;
79
80
	GstPad *sinkpad, *srcpad;
81
82
	struct td_codec *codec;
83
	int dsp_handle;
84
	void *proc;
85
	struct dsp_node *node;
86
	struct dsp_notification *events[3];
87
88
	GstFlowReturn status;
89
	unsigned long input_buffer_size;
90
	unsigned long output_buffer_size;
91
	GThread *dsp_thread, *out_thread;
92
	gboolean done;
93
	int deferred_eos;
94
	int eos;
95
96
	du_port_t *ports[2];
97
	dmm_buffer_t *alg_ctrl;
98
	struct ts_item ts_array[20];
99
	guint ts_in_pos, ts_out_pos, ts_push_pos;
100
	GMutex *ts_mutex;
101
	gulong ts_count;
102
	GstClockTime default_duration;
103
	GSem *flush;
104
	guint alg;
105
106
	gboolean use_pad_alloc; /**< Use pad_alloc for output buffers. */
107
	gboolean use_pinned; /**< Reuse output buffers. */
108
	guint dsp_error;
109
110
	void *(*create_node)(GstDspBase *base);
111
	bool (*parse_func)(GstDspBase *base, GstBuffer *buf);
112
	void (*pre_process_buffer)(GstDspBase *base, GstBuffer *buf);
113
	void (*reset)(GstDspBase *base);
114
	void (*flush_buffer)(GstDspBase *base);
115
	void (*got_message)(GstDspBase *self, struct dsp_msg *msg);
116
	bool (*send_buffer)(GstDspBase *self, struct td_buffer *tb);
117
	bool (*send_play_message)(GstDspBase *self);
118
	bool (*send_stop_message)(GstDspBase *self);
119
	GstCaps *tmp_caps;
120
121
	struct timespec eos_start;
122
	gint eos_timeout; /* how much to wait for the EOS from DSP (ms) */
123
124
	GstBuffer *codec_data;
125
	bool parsed;
126
127
	/* hacks */
128
	guint skip_hack; /* don't push x number of buffers */
129
	guint skip_hack_2; /* don't process x number of buffers */
130
};
131
132
struct _GstDspBaseClass {
133
	GstElementClass parent_class;
134
135
	gboolean (*sink_event)(GstDspBase *base, GstEvent *event);
136
	gboolean (*src_event)(GstDspBase *base, GstEvent *event);
137
};
138
139
GType gst_dsp_base_get_type(void);
140
141
du_port_t *du_port_new(int id, int dir);
142
void du_port_free(du_port_t *p);
143
void du_port_alloc_buffers(du_port_t *p, guint num_buffers);
144
145
gboolean gstdsp_start(GstDspBase *self);
146
gboolean gstdsp_send_codec_data(GstDspBase *self, GstBuffer *buf);
147
gboolean gstdsp_set_codec_data_caps(GstDspBase *base, GstBuffer *buf);
148
gboolean gstdsp_reinit(GstDspBase *base);
149
void gstdsp_got_error(GstDspBase *self, guint id, const char *message);
150
void gstdsp_post_error(GstDspBase *self, const char *message);
151
void gstdsp_send_alg_ctrl(GstDspBase *self, struct dsp_node *node, dmm_buffer_t *b);
152
void gstdsp_base_flush_buffer(GstDspBase *self);
153
154
typedef void (*gstdsp_setup_params_func)(GstDspBase *base, dmm_buffer_t *b);
155
156
static inline void gstdsp_port_setup_params(GstDspBase *self,
157
					    du_port_t *p,
158
					    size_t size,
159
					    gstdsp_setup_params_func func)
160
{
161
	unsigned i;
162
	for (i = 0; i < p->num_buffers; i++) {
163
		dmm_buffer_t *b;
164
		b = dmm_buffer_calloc(self->dsp_handle,
165
				      self->proc, size, DMA_BIDIRECTIONAL);
166
		if (func)
167
			func(self, b);
168
		dmm_buffer_map(b);
169
		p->buffers[i].params = b;
170
	}
171
}
172
173
/* this is saner than gst_pad_set_caps() */
174
static inline bool gst_pad_take_caps(GstPad *pad, GstCaps *caps)
175
{
176
	bool ret;
177
	ret = gst_pad_set_caps(pad, caps);
178
	gst_caps_unref(caps);
179
	return ret;
180
}
181
182
extern struct td_codec td_mp4vdec_codec;
183
extern struct td_codec td_h264dec_codec;
184
extern struct td_codec td_wmvdec_codec;
185
extern struct td_codec td_jpegdec_codec;
186
187
extern struct td_codec td_mp4venc_codec;
188
extern struct td_codec td_jpegenc_codec;
189
extern struct td_codec td_h264enc_codec;
190
191
extern struct td_codec td_vpp_codec;
192
extern struct td_codec td_aacdec_codec;
193
194
G_END_DECLS
195
196
#endif /* GST_DSP_BASE_H */