aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/sound.hpp2
-rw-r--r--project.conf1
-rw-r--r--src/main.cpp114
-rw-r--r--src/sound.cpp2
4 files changed, 80 insertions, 39 deletions
diff --git a/include/sound.hpp b/include/sound.hpp
index 41dd043..2b07254 100644
--- a/include/sound.hpp
+++ b/include/sound.hpp
@@ -16,7 +16,7 @@ typedef struct {
*/
int sound_device_get_by_name(SoundDevice *device, const char *name = "default", unsigned int num_channels = 1, unsigned int period_frame_size = 32);
-int sound_device_close(SoundDevice *device);
+void sound_device_close(SoundDevice *device);
/*
Returns the next chunk of audio into @buffer.
diff --git a/project.conf b/project.conf
index f7a8e64..5187ddb 100644
--- a/project.conf
+++ b/project.conf
@@ -15,7 +15,6 @@ glx = ">=1"
libavcodec = ">=58"
libavformat = ">=58"
libavutil = ">=56.2"
-OpenCL = ">=2"
x11 = ">=1"
xcomposite = ">=0.2"
xdamage = "1"
diff --git a/src/main.cpp b/src/main.cpp
index 6936a8f..a8adfd8 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -27,7 +27,7 @@ extern "C" {
#include <libavutil/hwcontext.h>
}
-#include <CL/cl.h>
+//#include <CL/cl.h>
struct ScopedGLXFBConfig {
~ScopedGLXFBConfig() {
@@ -294,7 +294,12 @@ static void receive_frames(AVCodecContext *av_codec_context, AVStream *stream, A
//av_packet_unref(&av_packet);
}
#else
-static void receive_frames(AVCodecContext *av_codec_context, AVStream *stream, AVFormatContext *av_format_context) {
+static int64_t rescale_ts(AVStream *stream, int64_t val) {
+ return av_rescale_q_rnd(val,
+ stream->codec->time_base, stream->time_base, (AVRounding)(AV_ROUND_NEAR_INF | AV_ROUND_PASS_MINMAX));
+}
+
+static void receive_frames(AVCodecContext *av_codec_context, AVStream *stream, AVFormatContext *av_format_context, int fps) {
AVPacket av_packet;
av_init_packet(&av_packet);
for( ; ; ) {
@@ -310,8 +315,13 @@ static void receive_frames(AVCodecContext *av_codec_context, AVStream *stream, A
//av_packet.dts = av_rescale_q_rnd(av_packet.dts, av_codec_context->time_base, stream->time_base, (AVRounding)(AV_ROUND_NEAR_INF|AV_ROUND_PASS_MINMAX));
//av_packet.duration = 60;//av_rescale_q(av_packet->duration, av_codec_context->time_base, stream->time_base);
av_packet_rescale_ts(&av_packet, av_codec_context->time_base, stream->time_base);
- //av_packet.pts /= 2;
- //av_packet.dts /= 2;
+ //double timescale = ((double)fps / 60.0);
+ //av_packet.pts *= timescale;
+ //av_packet.dts *= timescale;
+ //stream->codec->time_base.num = 1;
+ //stream->codec->time_base.den = fps;
+ //av_packet.pts = rescale_ts(stream, av_packet.pts);
+ //av_packet.pts = rescale_ts(stream, av_packet.dts);
av_packet.stream_index = stream->index;
//av_packet->stream_index = 0;
@@ -345,7 +355,10 @@ static AVStream* add_stream(AVFormatContext *av_format_context, AVCodec **codec,
//*codec = avcodec_find_encoder(codec_id);
*codec = avcodec_find_encoder_by_name("h264_nvenc");
if(!*codec) {
- fprintf(stderr, "Error: Could not find encoder for '%s'\n", avcodec_get_name(codec_id));
+ *codec = avcodec_find_encoder_by_name("nvenc_h264");
+ }
+ if(!*codec) {
+ fprintf(stderr, "Error: Could not find h264_nvenc or nvenc_h264 encoder for %s\n", avcodec_get_name(codec_id));
exit(1);
}
@@ -376,8 +389,8 @@ static AVStream* add_stream(AVFormatContext *av_format_context, AVCodec **codec,
// timebase should be 1/framerate and timestamp increments should be identical to 1
codec_context->time_base.num = 1;
codec_context->time_base.den = 60;
- codec_context->framerate.num = 60;
- codec_context->framerate.den = 1;
+ //codec_context->framerate.num = 60;
+ //codec_context->framerate.den = 1;
codec_context->sample_aspect_ratio.num = 1;
codec_context->sample_aspect_ratio.den = 1;
codec_context->gop_size = 12; // Emit one intra frame every twelve frames at most
@@ -465,6 +478,7 @@ static void open_video(AVCodec *codec, AVStream *stream, WindowPixmap &window_pi
res = cuCtxPopCurrent(&old_ctx);
res = cuCtxPushCurrent(*cuda_context);
res = cuGraphicsGLRegisterImage(cuda_graphics_resource, window_pixmap.target_texture_id, GL_TEXTURE_2D, CU_GRAPHICS_REGISTER_FLAGS_READ_ONLY);
+ //cuGraphicsUnregisterResource(*cuda_graphics_resource);
if(res != CUDA_SUCCESS) {
fprintf(stderr, "Error: cuGraphicsGLRegisterImage failed, error %d, texture id: %u\n", res, window_pixmap.target_texture_id);
exit(1);
@@ -628,46 +642,74 @@ int main(int argc, char **argv) {
exit(1);
}
- //double start_time = glfwGetTime();
+ double start_time = glfwGetTime();
+ int fps = 0;
+ int current_fps = 30;
+ XEvent e;
while(!glfwWindowShouldClose(window)) {
glClear(GL_COLOR_BUFFER_BIT);
glfwSwapBuffers(window);
glfwPollEvents();
- // TODO: Use a framebuffer instead. glCopyImageSubData requires opengl 4.2
- glCopyImageSubData(
- window_pixmap.texture_id, GL_TEXTURE_2D, 0, 0, 0, 0,
- window_pixmap.target_texture_id, GL_TEXTURE_2D, 0, 0, 0, 0,
- window_pixmap.texture_width, window_pixmap.texture_height, 1);
- //int err = glGetError();
- //printf("error: %d\n", err);
-
- CUDA_MEMCPY2D memcpy_struct;
- memcpy_struct.srcXInBytes = 0;
- memcpy_struct.srcY = 0;
- memcpy_struct.srcMemoryType = CUmemorytype::CU_MEMORYTYPE_ARRAY;
-
- memcpy_struct.dstXInBytes = 0;
- memcpy_struct.dstY = 0;
- memcpy_struct.dstMemoryType = CUmemorytype::CU_MEMORYTYPE_DEVICE;
-
- memcpy_struct.srcArray = mapped_array;
- memcpy_struct.dstDevice = (CUdeviceptr)frame->data[0];
- memcpy_struct.dstPitch = frame->linesize[0];
- memcpy_struct.WidthInBytes = frame->width * 4;
- memcpy_struct.Height = frame->height;
- cuMemcpy2D(&memcpy_struct);
- //res = cuCtxPopCurrent(&old_ctx);
-
- //double time_now = glfwGetTime();
+ double time_now = glfwGetTime();
+ if(time_now - start_time >= 1.0) {
+ printf("fps: %d\n", fps);
+ start_time = time_now;
+ current_fps = fps;
+ fps = 0;
+ }
+
+ if (XCheckTypedEvent(dpy, ConfigureNotify, &e)) {
+ // Window resize
+ printf("Resize window!\n");
+ recreate_window_pixmap(dpy, src_window_id, window_pixmap);
+ }
+
+ if (XCheckTypedEvent(dpy, damage_event + XDamageNotify, &e)) {
+ //printf("Redraw!\n");
+ XDamageNotifyEvent *de = (XDamageNotifyEvent*)&e;
+ // de->drawable is the window ID of the damaged window
+ XserverRegion region = XFixesCreateRegion(dpy, nullptr, 0);
+ // Subtract all the damage, repairing the window
+ XDamageSubtract(dpy, de->damage, None, region);
+ XFixesDestroyRegion(dpy, region);
+
+ // TODO: Use a framebuffer instead. glCopyImageSubData requires opengl 4.2
+ glCopyImageSubData(
+ window_pixmap.texture_id, GL_TEXTURE_2D, 0, 0, 0, 0,
+ window_pixmap.target_texture_id, GL_TEXTURE_2D, 0, 0, 0, 0,
+ window_pixmap.texture_width, window_pixmap.texture_height, 1);
+ //int err = glGetError();
+ //printf("error: %d\n", err);
+
+ CUDA_MEMCPY2D memcpy_struct;
+ memcpy_struct.srcXInBytes = 0;
+ memcpy_struct.srcY = 0;
+ memcpy_struct.srcMemoryType = CUmemorytype::CU_MEMORYTYPE_ARRAY;
+
+ memcpy_struct.dstXInBytes = 0;
+ memcpy_struct.dstY = 0;
+ memcpy_struct.dstMemoryType = CUmemorytype::CU_MEMORYTYPE_DEVICE;
+
+ memcpy_struct.srcArray = mapped_array;
+ memcpy_struct.dstDevice = (CUdeviceptr)frame->data[0];
+ memcpy_struct.dstPitch = frame->linesize[0];
+ memcpy_struct.WidthInBytes = frame->width * 4;
+ memcpy_struct.Height = frame->height;
+ cuMemcpy2D(&memcpy_struct);
+ //res = cuCtxPopCurrent(&old_ctx);
+ }
+
+ ++fps;
//int frame_cc = (time_now - start_time) * 0.66666;
//printf("elapsed time: %d\n", frame_cc);
- frame->pts = frame_count++;
+ frame->pts = frame_count;
+ frame_count += 1;
if(avcodec_send_frame(video_stream->codec, frame) < 0) {
fprintf(stderr, "Error: avcodec_send_frame failed\n");
}
- receive_frames(video_stream->codec, video_stream, av_format_context);
+ receive_frames(video_stream->codec, video_stream, av_format_context, current_fps);
}
#if 0
diff --git a/src/sound.cpp b/src/sound.cpp
index fcfa7ae..9eec833 100644
--- a/src/sound.cpp
+++ b/src/sound.cpp
@@ -59,7 +59,7 @@ int sound_device_get_by_name(SoundDevice *device, const char *name, unsigned int
return 0;
}
-int sound_device_close(SoundDevice *device) {
+void sound_device_close(SoundDevice *device) {
/* TODO: Is this also needed in @sound_device_get_by_name on failure? */
snd_pcm_drain((snd_pcm_t*)device->handle);
snd_pcm_close((snd_pcm_t*)device->handle);