mirror of
				https://gitlab.freedesktop.org/pipewire/pipewire.git
				synced 2025-10-29 05:40:27 -04:00 
			
		
		
		
	 934ab3036e
			
		
	
	
		934ab3036e
		
	
	
	
	
		
			
			SPDX tags make the licensing information easy to understand and clear, and they are machine parseable. See https://spdx.dev for more information.
		
			
				
	
	
		
			183 lines
		
	
	
	
		
			4.4 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			183 lines
		
	
	
	
		
			4.4 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /* PipeWire */
 | |
| /* SPDX-FileCopyrightText: Copyright © 2019 Wim Taymans */
 | |
| /* SPDX-License-Identifier: MIT */
 | |
| 
 | |
| #include <stdio.h>
 | |
| #include <unistd.h>
 | |
| #include <sys/mman.h>
 | |
| 
 | |
| #include <SDL2/SDL.h>
 | |
| 
 | |
| #include <jack/jack.h>
 | |
| #include <pipewire-jack-extensions.h>
 | |
| 
 | |
| #define MAX_BUFFERS	64
 | |
| 
 | |
| #define JACK_DEFAULT_VIDEO_TYPE "32 bit float RGBA video"
 | |
| 
 | |
| #define CLAMP(v,low,high)				\
 | |
| ({							\
 | |
| 	__typeof__(v) _v = (v);				\
 | |
| 	__typeof__(low) _low = (low);			\
 | |
| 	__typeof__(high) _high = (high);		\
 | |
| 	(_v < _low) ? _low : (_v > _high) ? _high : _v;	\
 | |
| })
 | |
| 
 | |
| struct pixel {
 | |
| 	float r, g, b, a;
 | |
| };
 | |
| 
 | |
| struct data {
 | |
| 	const char *path;
 | |
| 
 | |
| 	SDL_Renderer *renderer;
 | |
| 	SDL_Window *window;
 | |
| 	SDL_Texture *texture;
 | |
| 	SDL_Texture *cursor;
 | |
| 
 | |
| 	jack_client_t *client;
 | |
| 	const char *client_name;
 | |
| 	jack_port_t *in_port;
 | |
| 
 | |
| 	jack_image_size_t size;
 | |
| 
 | |
| 	int counter;
 | |
| 	SDL_Rect rect;
 | |
| 	SDL_Rect cursor_rect;
 | |
| };
 | |
| 
 | |
| static void handle_events(struct data *data)
 | |
| {
 | |
| 	SDL_Event event;
 | |
| 	while (SDL_PollEvent(&event)) {
 | |
| 		switch (event.type) {
 | |
| 		case SDL_QUIT:
 | |
| 			exit(0);
 | |
| 			break;
 | |
| 		}
 | |
| 	}
 | |
| }
 | |
| 
 | |
| static int
 | |
| process (jack_nframes_t nframes, void *arg)
 | |
| {
 | |
|         struct data *data = (struct data*)arg;
 | |
| 	void *sdata, *ddata;
 | |
| 	int sstride, dstride;
 | |
| 	uint32_t i, j;
 | |
| 	uint8_t *src, *dst;
 | |
| 
 | |
|         sdata = jack_port_get_buffer (data->in_port, nframes);
 | |
| 
 | |
| 	handle_events(data);
 | |
| 
 | |
| 	if (SDL_LockTexture(data->texture, NULL, &ddata, &dstride) < 0) {
 | |
| 		fprintf(stderr, "Couldn't lock texture: %s\n", SDL_GetError());
 | |
| 		goto done;
 | |
| 	}
 | |
| 
 | |
| 	/* copy video image in texture */
 | |
| 	sstride = data->size.stride;
 | |
| 
 | |
| 	src = sdata;
 | |
| 	dst = ddata;
 | |
| 
 | |
| 	for (i = 0; i < data->size.height; i++) {
 | |
| 		struct pixel *p = (struct pixel *) src;
 | |
| 		for (j = 0; j < data->size.width; j++) {
 | |
| 			dst[j * 4 + 0] = CLAMP(lrintf(p[j].r * 255.0f), 0, 255);
 | |
| 			dst[j * 4 + 1] = CLAMP(lrintf(p[j].g * 255.0f), 0, 255);
 | |
| 			dst[j * 4 + 2] = CLAMP(lrintf(p[j].b * 255.0f), 0, 255);
 | |
| 			dst[j * 4 + 3] = CLAMP(lrintf(p[j].a * 255.0f), 0, 255);
 | |
| 		}
 | |
| 		src += sstride;
 | |
| 		dst += dstride;
 | |
| 	}
 | |
| 	SDL_UnlockTexture(data->texture);
 | |
| 
 | |
| 	SDL_RenderClear(data->renderer);
 | |
| 	SDL_RenderCopy(data->renderer, data->texture, &data->rect, NULL);
 | |
| 	SDL_RenderPresent(data->renderer);
 | |
| 
 | |
|       done:
 | |
| 	return 0;
 | |
| }
 | |
| 
 | |
| int main(int argc, char *argv[])
 | |
| {
 | |
| 	struct data data = { 0, };
 | |
| 	jack_options_t options = JackNullOption;
 | |
|         jack_status_t status;
 | |
| 	int res;
 | |
| 
 | |
| 	data.client = jack_client_open ("video-dsp-play", options, &status);
 | |
|         if (data.client == NULL) {
 | |
|                 fprintf (stderr, "jack_client_open() failed, "
 | |
|                          "status = 0x%2.0x\n", status);
 | |
|                 if (status & JackServerFailed) {
 | |
|                         fprintf (stderr, "Unable to connect to JACK server\n");
 | |
|                 }
 | |
|                 exit (1);
 | |
|         }
 | |
|         if (status & JackServerStarted) {
 | |
|                 fprintf (stderr, "JACK server started\n");
 | |
|         }
 | |
|         if (status & JackNameNotUnique) {
 | |
|                 data.client_name = jack_get_client_name(data.client);
 | |
|                 fprintf (stderr, "unique name `%s' assigned\n", data.client_name);
 | |
|         }
 | |
| 
 | |
|         jack_set_process_callback (data.client, process, &data);
 | |
| 
 | |
| 	if ((res = jack_get_video_image_size(data.client, &data.size)) < 0) {
 | |
| 		fprintf(stderr, "can't get video size: %d %s\n", res, strerror(-res));
 | |
| 		return -1;
 | |
| 	}
 | |
| 
 | |
| 	if (SDL_Init(SDL_INIT_VIDEO) < 0) {
 | |
| 		fprintf(stderr, "can't initialize SDL: %s\n", SDL_GetError());
 | |
| 		return -1;
 | |
| 	}
 | |
| 
 | |
| 	if (SDL_CreateWindowAndRenderer
 | |
| 	    (data.size.width, data.size.height, SDL_WINDOW_RESIZABLE, &data.window, &data.renderer)) {
 | |
| 		fprintf(stderr, "can't create window: %s\n", SDL_GetError());
 | |
| 		return -1;
 | |
| 	}
 | |
| 
 | |
| 	data.texture = SDL_CreateTexture(data.renderer,
 | |
| 					  SDL_PIXELFORMAT_RGBA32,
 | |
| 					  SDL_TEXTUREACCESS_STREAMING,
 | |
| 					  data.size.width,
 | |
| 					  data.size.height);
 | |
| 	data.rect.x = 0;
 | |
| 	data.rect.y = 0;
 | |
| 	data.rect.w = data.size.width;
 | |
| 	data.rect.h = data.size.height;
 | |
| 
 | |
| 	data.in_port = jack_port_register (data.client, "input",
 | |
|                                           JACK_DEFAULT_VIDEO_TYPE,
 | |
|                                           JackPortIsInput, 0);
 | |
| 
 | |
|        if (data.in_port == NULL) {
 | |
|                 fprintf(stderr, "no more JACK ports available\n");
 | |
|                 exit (1);
 | |
|         }
 | |
| 
 | |
|         if (jack_activate (data.client)) {
 | |
|                 fprintf (stderr, "cannot activate client");
 | |
|                 exit (1);
 | |
|         }
 | |
| 
 | |
| 	while (1) {
 | |
| 		sleep (1);
 | |
| 	}
 | |
| 
 | |
|         jack_client_close (data.client);
 | |
| 
 | |
| 	SDL_DestroyTexture(data.texture);
 | |
| 	SDL_DestroyRenderer(data.renderer);
 | |
| 	SDL_DestroyWindow(data.window);
 | |
| 
 | |
| 	return 0;
 | |
| }
 |