Permalink
Browse files

Merge branch 'rewrite'

  • Loading branch information...
wereHamster committed Mar 18, 2012
2 parents 4bd3a97 + 2ab6f6a commit c9ba909893caff83da30ff07c59c9f96272b647b
View
@@ -0,0 +1,11 @@
+config.make
+sysconf
+
+*.o
+
+libGL.so
+libX11.so
+yukon-core-lib
+
+filter
+stat
View
@@ -3,27 +3,43 @@ DESTDIR =
PREFIX = /usr/local
LIBDIR = lib
+ARCH = C
+
CC = gcc
-CFLAGS = -Iinclude -Wall -std=c99 -O3
+ASM = yasm
+
+CFLAGS = -Iinclude -I$(PREFIX)/include -Wall -std=c99 -O3
+LDFLAGS = -L$(PREFIX)/lib
-OBJS = src/core/conf.o src/core/glue.o src/core/log.o
+OBJS = src/core/conf.o src/core/log.o src/stream/stream.o src/core/engine.o \
+ src/core/opengl.o src/stream/buffer.o \
+ src/glue/glue.o src/core/audio.o src/stream/arch/$(ARCH)/frame.o
LIBS = libX11.so libGL.so
-include config.make
.PHONY: all clean install
-all: $(LIBS) yukon-core-lib sysconf
+all: $(LIBS) yukon-core-lib filter sysconf
+
+%.o: %.asm
+ $(ASM) -m $(ARCH) -f elf -o $@ $<
%.o: %.c
$(CC) $(CFLAGS) -fPIC -c -o $@ $<
-
+
$(LIBS):
$(CC) -shared -o $@.native -Wl,-soname,$@.native
$(CC) $(CFLAGS) -fPIC -shared -o $@ src/libs/$(@:%.so=%.c) $@.native
rm -f $@.native
yukon-core-lib: $(OBJS)
- $(CC) -shared -o $@ $(OBJS) -lseom
+ $(CC) -shared -o $@ $(OBJS) $(LDFLAGS) -lasound -lseom
+
+filter: src/filter/main.c src/filter/wav.c src/filter/y4m.c
+ $(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS) -lasound -lseom
+
+stat: src/tools/stat.c
+ $(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS) -lseom
sysconf:
echo 'LDPATH="$(PREFIX)/$(LIBDIR)/yukon"' > $@
@@ -38,7 +54,7 @@ install: $(LIBS) yukon-core-lib
$(foreach lib,$(LIBS),install -m 755 $(lib) $(DESTDIR)$(PREFIX)/$(LIBDIR)/yukon/$(call soname,$(lib));)
clean:
- rm -f $(OBJS) $(LIBS) yukon-core-lib sysconf
+ rm -f $(OBJS) $(LIBS) filter yukon-core-lib sysconf
mrproper: clean
rm -f config.make
View
@@ -0,0 +1,4 @@
+#!/bin/sh
+
+./filter --audio "$1" | lame - audio.mp3
+./filter --video "$1" | mencoder -vf scale=1280:720 -ovc xvid -xvidencopts bitrate=1800 -oac copy -audiofile audio.mp3 -o video.avi -
View
@@ -14,6 +14,7 @@
#define glue(name, ...) ({ \
if (__builtin_expect(core == NULL, 0)) { \
void *handle = dlopen("yukon-core-lib", RTLD_LAZY); \
+ dlerror(); \
if (handle) \
core = (__typeof__(core)) dlsym(handle, name); \
} (*core)(__VA_ARGS__); }) \
View
@@ -0,0 +1,45 @@
+
+#ifndef __YUKON_STREAM__
+#define __YUKON_STREAM__
+
+#define _FILE_OFFSET_BITS 64
+#define _LARGEFILE_SOURCE
+
+#include <pthread.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+#include <seom/stream.h>
+
+struct yukonBuffer {
+ pthread_mutex_t mutex;
+ pthread_cond_t cond;
+
+ unsigned long size, head, tail;
+ struct seomPacket *array[0];
+};
+
+struct yukonStream {
+ int fileDescriptor;
+ seomStream *stream;
+ pthread_t multiplexerThread;
+ struct yukonBuffer *buffer;
+};
+
+struct yukonBuffer *yukonBufferCreate(unsigned long size);
+void yukonBufferPut(struct yukonBuffer *buffer, struct seomPacket *packet);
+struct seomPacket *yukonBufferGet(struct yukonBuffer *buffer);
+unsigned long yukonBufferCount(struct yukonBuffer *buffer);
+void yukonBufferDestroy(struct yukonBuffer *buffer);
+
+struct yukonStream *yukonStreamCreate(const char *spec, unsigned long size);
+unsigned long yukonStreamStatus(struct yukonStream *stream);
+void yukonStreamPut(struct yukonStream *stream, struct seomPacket *packet);
+void yukonStreamDestroy(struct yukonStream *stream);
+
+#endif /* __YUKON_STREAM__ */
View
@@ -2,34 +2,63 @@
#ifndef __YUKON_H__
#define __YUKON_H__
+#define _FILE_OFFSET_BITS 64
+#define _LARGEFILE_SOURCE
+
+#include <stdarg.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <dlfcn.h>
+#include <string.h>
+#include <stdio.h>
#include <stdarg.h>
+#include <stdlib.h>
+#include <stdint.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+
#include <linux/limits.h>
-#include <seom/seom.h>
+#include <pthread.h>
#include <X11/Xlib.h>
#include <X11/keysym.h>
+#define GL_GLEXT_PROTOTYPES
#include <GL/gl.h>
#include <GL/glext.h>
#include <GL/glx.h>
+#include <stream.h>
+
void logMessage(unsigned long level, const char *fmt, ...);
void updateConfiguration(void);
-void yukonCoreCapture(Display *dpy, GLXDrawable drawable);
-void yukonCoreEvent(Display *dpy, XEvent *event);
-
typedef struct {
unsigned long logLevel;
KeySym hotkey;
- unsigned int insets[4];
unsigned int scale;
double fps;
- char output[PATH_MAX];
+ char output[PATH_MAX];
} yukonGlobalData;
extern yukonGlobalData yukonGlobal;
+struct yukonEngine {
+ struct yukonStream *stream;
+ unsigned long size[2];
+
+ pthread_mutex_t audioMutex;
+ unsigned long audioRunning;
+ pthread_t audioThread;
+};
+
+struct yukonEngine *yukonEngineCreate(const char *spec, unsigned long scale, unsigned long size[2]);
+void yukonEngineCapture(struct yukonEngine *engine);
+struct yukonEngine *yukonEngineDestroy(struct yukonEngine *engine);
+
+void *audioThreadCallback(void *data);
+
#endif /* __YUKON_H__ */
View
@@ -0,0 +1,4 @@
+#!/bin/sh
+
+./filter --video "$1" | mplayer - &>/dev/null &
+./filter --audio "$1" | mplayer -demuxer 35 - &>/dev/null
View
@@ -0,0 +1,195 @@
+
+#include <alsa/asoundlib.h>
+#include <yukon.h>
+#include <alloca.h>
+
+static int xrun(snd_pcm_t *handle, int err)
+{
+ if (err == -EPIPE) { /* xrun */
+ return snd_pcm_prepare(handle);
+ } else if (err == -ESTRPIPE) {
+ while ((err = snd_pcm_resume(handle)) == -EAGAIN)
+ sleep(1); /* wait until the suspend flag is released */
+ if (err < 0)
+ return snd_pcm_prepare(handle);
+ return 0;
+ } else {
+ return err;
+ }
+}
+
+snd_pcm_hw_params_t *getParams(snd_pcm_t *pcm)
+{
+ snd_pcm_hw_params_t *params;
+ snd_pcm_hw_params_malloc(&params);
+ snd_pcm_hw_params_any(pcm, params);
+
+ logMessage(3, "params: access\n");
+ if (snd_pcm_hw_params_set_access(pcm, params, SND_PCM_ACCESS_RW_INTERLEAVED) < 0)
+ goto failed;
+
+ snd_pcm_format_mask_t *formats = alloca(snd_pcm_format_mask_sizeof());
+ snd_pcm_format_mask_none(formats);
+ snd_pcm_format_mask_set(formats, SND_PCM_FORMAT_S16_LE);
+ snd_pcm_format_mask_set(formats, SND_PCM_FORMAT_S24_LE);
+ snd_pcm_format_mask_set(formats, SND_PCM_FORMAT_S32_LE);
+
+ logMessage(3, "params: format\n");
+ if (snd_pcm_hw_params_set_format_mask(pcm, params, formats) < 0)
+ goto failed;
+ logMessage(3, "params: channels\n");
+ if (snd_pcm_hw_params_set_channels(pcm, params, 2) < 0)
+ goto failed;
+ logMessage(3, "params: rate\n");
+ if (snd_pcm_hw_params_set_rate(pcm, params, 48000, 0) < 0)
+ goto failed;
+
+ snd_pcm_uframes_t size;
+ if (snd_pcm_hw_params_get_buffer_size_max(params, &size) < 0)
+ goto failed;
+ logMessage(3, "params: buffer size\n");
+ if (snd_pcm_hw_params_set_buffer_size(pcm, params, size) < 0)
+ goto failed;
+
+ int dir;
+ unsigned int periods;
+ if (snd_pcm_hw_params_get_periods_min(params, &periods, &dir) < 0)
+ goto failed;
+ logMessage(3, "params: periods\n");
+ if (snd_pcm_hw_params_set_periods(pcm, params, periods < 2 ? 2 : periods, dir) < 0)
+ goto failed;
+
+ return params;
+
+failed:
+ logMessage(3, "failed to set PCM parameters\n");
+ snd_pcm_hw_params_free(params);
+ return NULL;
+}
+
+snd_pcm_t *openAudioDevice(const char *device, snd_pcm_uframes_t *period)
+{
+ snd_pcm_t *pcm = NULL;
+
+ int err = snd_pcm_open(&pcm, device, SND_PCM_STREAM_CAPTURE, 0);
+ if (err < 0) {
+ logMessage(3, "failed to open PCM device: %s\n", snd_strerror(err));
+ return NULL;
+ }
+
+ snd_pcm_hw_params_t *params = getParams(pcm);
+ if (params == NULL)
+ goto failed;
+
+ if (snd_pcm_hw_params(pcm, params) < 0)
+ goto failed;
+
+ snd_pcm_hw_params_get_period_size(params, period, NULL);
+ snd_pcm_hw_params_free(params);
+
+ snd_output_t *output= NULL;
+ snd_output_stdio_attach(&output, stdout, 0);
+ snd_pcm_dump(pcm, output);
+
+ return pcm;
+
+failed:
+ snd_pcm_hw_params_free(params);
+ snd_pcm_close(pcm);
+
+ return NULL;
+}
+
+static int wait(snd_pcm_t *pcm, struct pollfd *ufds, unsigned int count)
+{
+ for (;;) {
+ poll(ufds, count, -1);
+
+ unsigned short revents;
+ snd_pcm_poll_descriptors_revents(pcm, ufds, count, &revents);
+
+ if (revents & POLLERR)
+ return -EIO;
+ else if (revents & POLLIN)
+ return 0;
+ }
+}
+
+void *audioThreadCallback(void *data)
+{
+ struct yukonEngine *engine = data;
+
+ snd_pcm_uframes_t period;
+ snd_pcm_t *pcm = openAudioDevice("hw:0", &period);
+ if (pcm == NULL) {
+ logMessage(3, "failed to set up audio capturing device, no sound will be captured!\n");
+ return NULL;
+ }
+
+ logMessage(4, "Audio capturing device is set up (period: %u)\n", period);
+
+ int count = snd_pcm_poll_descriptors_count(pcm);
+ struct pollfd ufds[count];
+
+ snd_pcm_poll_descriptors(pcm, ufds, count);
+
+ uint32_t header[1] = { snd_pcm_frames_to_bytes(pcm, 1) / 2 };
+ struct seomPacket *pkt = seomPacketCreate(0x02, sizeof(header));
+ memcpy(seomPacketPayload(pkt), &header, sizeof(header));
+ yukonStreamPut(engine->stream, pkt);
+
+ for (;;) {
+ if (snd_pcm_state(pcm) == SND_PCM_STATE_PREPARED)
+ snd_pcm_start(pcm);
+
+ pthread_mutex_lock(&engine->audioMutex);
+ if (engine->audioRunning == 0)
+ break;
+ pthread_mutex_unlock(&engine->audioMutex);
+
+ int err = xrun(pcm, wait(pcm, ufds, count));
+ if (err < 0)
+ continue;
+
+ struct seomPacket *packet = seomPacketCreate(0x03, snd_pcm_frames_to_bytes(pcm, period));
+ if (packet == NULL)
+ continue;
+
+ snd_pcm_sframes_t delay;
+ snd_pcm_delay(pcm, &delay);
+ packet->time -= 1000000 / 48000 * delay;
+
+ snd_pcm_sframes_t ret = snd_pcm_readi(pcm, seomPacketPayload(packet), period);
+ if (ret < 0) {
+ logMessage(2, "overrun!\n");
+ ret = xrun(pcm, ret);
+ }
+
+ yukonStreamPut(engine->stream, packet);
+ }
+
+ pthread_mutex_unlock(&engine->audioMutex);
+
+ snd_pcm_drain(pcm);
+ snd_pcm_uframes_t left = snd_pcm_avail_update(pcm);
+ if (left > 0) {
+ struct seomPacket *packet = seomPacketCreate(0x03, snd_pcm_frames_to_bytes(pcm, left));
+ if (packet) {
+ snd_pcm_sframes_t delay;
+ snd_pcm_delay(pcm, &delay);
+ packet->time -= 1000000 / 48000 * delay;
+
+ snd_pcm_sframes_t ret = snd_pcm_readi(pcm, seomPacketPayload(packet), left);
+ if (ret < 0) {
+ logMessage(2, "overrun (%d)!\n", ret);
+ ret = xrun(pcm, ret);
+ }
+
+ yukonStreamPut(engine->stream, packet);
+ }
+ }
+
+ snd_pcm_close(pcm);
+
+ return NULL;
+}
Oops, something went wrong.

0 comments on commit c9ba909

Please sign in to comment.