static void *aac_create(obs_data_t settings, obs_encoder_t encoder) { struct aac_encoder *enc; int bitrate = (int)obs_data_getint(settings, "bitrate"); audio_t audio = obs_encoder_audio(encoder); if (!bitrate) { aac_warn("aac_create", "Invalid bitrate specified"); return NULL; } avcodec_register_all(); enc = bzalloc(sizeof(struct aac_encoder)); enc->encoder = encoder; enc->aac = avcodec_find_encoder(AV_CODEC_ID_AAC); if (!enc->aac) { aac_warn("aac_create", "Couldn't find encoder"); goto fail; } blog(LOG_INFO, "Using ffmpeg \"%s\" aac encoder", enc->aac->name); enc->context = avcodec_alloc_context3(enc->aac); if (!enc->context) { aac_warn("aac_create", "Failed to create codec context"); goto fail; } enc->context->bit_rate = bitrate * 1000; enc->context->channels = (int)audio_output_channels(audio); enc->context->sample_rate = audio_output_samplerate(audio); enc->context->sample_fmt = enc->aac->sample_fmts ? enc->aac->sample_fmts[0] : AV_SAMPLE_FMT_FLTP; init_sizes(enc, audio); /* enable experimental FFmpeg encoder if the only one available */ enc->context->strict_std_compliance = -2; enc->context->flags = CODEC_FLAG_GLOBAL_HEADER; if (initialize_codec(enc)) return enc; fail: aac_destroy(enc); return NULL; }
static void update_monitor(struct monitor_capture *capture, obs_data_t settings) { struct monitor_info monitor = {0}; uint32_t width, height; monitor.desired_id = (int)obs_data_getint(settings, "monitor"); EnumDisplayMonitors(NULL, NULL, enum_monitor, (LPARAM)&monitor); capture->monitor = monitor.id; width = monitor.rect.right - monitor.rect.left; height = monitor.rect.bottom - monitor.rect.top; dc_capture_init(&capture->data, monitor.rect.left, monitor.rect.top, width, height, capture->capture_cursor, capture->compatibility); }
static bool rtmp_stream_start(void *data) { struct rtmp_stream *stream = data; obs_service_t service = obs_output_get_service(stream->output); obs_data_t settings; if (!obs_output_can_begin_data_capture(stream->output, 0)) return false; if (!obs_output_initialize_encoders(stream->output, 0)) return false; settings = obs_output_get_settings(stream->output); dstr_copy(&stream->path, obs_service_get_url(service)); dstr_copy(&stream->key, obs_service_get_key(service)); dstr_copy(&stream->username, obs_service_get_username(service)); dstr_copy(&stream->password, obs_service_get_password(service)); stream->drop_threshold_usec = (int64_t)obs_data_getint(settings, "drop_threshold"); obs_data_release(settings); return pthread_create(&stream->connect_thread, NULL, connect_thread, stream) == 0; }
void XCompcapMain::updateSettings(obs_data_t settings) { PLock lock(&p->lock); XErrorLock xlock; ObsGsContextHolder obsctx; blog(LOG_DEBUG, "Settings updating"); Window prevWin = p->win; xcc_cleanup(p); if (settings) { const char *windowName = obs_data_getstring(settings, "capture_window"); p->win = getWindowFromString(windowName); p->cut_top = obs_data_getint(settings, "cut_top"); p->cut_left = obs_data_getint(settings, "cut_left"); p->cut_right = obs_data_getint(settings, "cut_right"); p->cut_bot = obs_data_getint(settings, "cut_bot"); p->lockX = obs_data_getbool(settings, "lock_x"); p->swapRedBlue = obs_data_getbool(settings, "swap_redblue"); } else { p->win = prevWin; } xlock.resetError(); XCompositeRedirectWindow(xdisp, p->win, CompositeRedirectAutomatic); if (xlock.gotError()) { blog(LOG_ERROR, "XCompositeRedirectWindow failed: %s", xlock.getErrorText().c_str()); return; } XSelectInput(xdisp, p->win, StructureNotifyMask); XSync(xdisp, 0); XWindowAttributes attr; if (!XGetWindowAttributes(xdisp, p->win, &attr)) { p->win = 0; p->width = 0; p->height = 0; return; } gs_color_format cf = GS_RGBA; p->width = attr.width; p->height = attr.height; if (p->cut_top + p->cut_bot < (int)p->height) { p->cur_cut_top = p->cut_top; p->cur_cut_bot = p->cut_bot; } else { p->cur_cut_top = 0; p->cur_cut_bot = 0; } if (p->cut_left + p->cut_right < (int)p->width) { p->cur_cut_left = p->cut_left; p->cur_cut_right = p->cut_right; } else { p->cur_cut_left = 0; p->cur_cut_right = 0; } if (p->tex) texture_destroy(p->tex); uint8_t *texData = new uint8_t[width() * height() * 4]; for (unsigned int i = 0; i < width() * height() * 4; i += 4) { texData[i + 0] = p->swapRedBlue ? 0 : 0xFF; texData[i + 1] = 0; texData[i + 2] = p->swapRedBlue ? 0xFF : 0; texData[i + 3] = 0xFF; } const uint8_t* texDataArr[] = { texData, 0 }; p->tex = gs_create_texture(width(), height(), cf, 1, texDataArr, 0); delete[] texData; if (p->swapRedBlue) { GLuint tex = *(GLuint*)texture_getobj(p->tex); glBindTexture(GL_TEXTURE_2D, tex); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_B, GL_RED); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_R, GL_BLUE); glBindTexture(GL_TEXTURE_2D, 0); } const int attrs[] = { GLX_BIND_TO_TEXTURE_RGBA_EXT, GL_TRUE, GLX_DRAWABLE_TYPE, GLX_PIXMAP_BIT, GLX_BIND_TO_TEXTURE_TARGETS_EXT, GLX_TEXTURE_2D_BIT_EXT, GLX_DOUBLEBUFFER, GL_FALSE, None }; int nelem = 0; GLXFBConfig* configs = glXChooseFBConfig(xdisp, XCompcap::getRootWindowScreen(attr.root), attrs, &nelem); if (nelem <= 0) { blog(LOG_ERROR, "no matching fb config found"); p->win = 0; p->height = 0; p->width = 0; return; } glXGetFBConfigAttrib(xdisp, configs[0], GLX_Y_INVERTED_EXT, &nelem); p->inverted = nelem != 0; xlock.resetError(); p->pixmap = XCompositeNameWindowPixmap(xdisp, p->win); if (xlock.gotError()) { blog(LOG_ERROR, "XCompositeNameWindowPixmap failed: %s", xlock.getErrorText().c_str()); p->pixmap = 0; XFree(configs); return; } const int attribs[] = { GLX_TEXTURE_TARGET_EXT, GLX_TEXTURE_2D_EXT, GLX_TEXTURE_FORMAT_EXT, GLX_TEXTURE_FORMAT_RGBA_EXT, None }; p->glxpixmap = glXCreatePixmap(xdisp, configs[0], p->pixmap, attribs); if (xlock.gotError()) { blog(LOG_ERROR, "glXCreatePixmap failed: %s", xlock.getErrorText().c_str()); XFreePixmap(xdisp, p->pixmap); XFree(configs); p->pixmap = 0; p->glxpixmap = 0; return; } XFree(configs); p->gltex = gs_create_texture(p->width, p->height, cf, 1, 0, GS_GL_DUMMYTEX); GLuint gltex = *(GLuint*)texture_getobj(p->gltex); glBindTexture(GL_TEXTURE_2D, gltex); glXBindTexImageEXT(xdisp, p->glxpixmap, GLX_FRONT_LEFT_EXT, NULL); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); }
static void *libfdk_create(obs_data_t settings, obs_encoder_t encoder) { bool hasFdkHandle = false; libfdk_encoder_t *enc = 0; int bitrate = (int)obs_data_getint(settings, "bitrate") * 1000; int afterburner = obs_data_getbool(settings, "afterburner") ? 1 : 0; audio_t audio = obs_encoder_audio(encoder); int mode = 0; AACENC_ERROR err; if (!bitrate) { blog(LOG_ERROR, "Invalid bitrate"); return NULL; } enc = bzalloc(sizeof(libfdk_encoder_t)); enc->encoder = encoder; enc->channels = (int)audio_output_channels(audio); enc->sample_rate = audio_output_samplerate(audio); switch(enc->channels) { case 1: mode = MODE_1; break; case 2: mode = MODE_2; break; case 3: mode = MODE_1_2; break; case 4: mode = MODE_1_2_1; break; case 5: mode = MODE_1_2_2; break; case 6: mode = MODE_1_2_2_1; break; default: blog(LOG_ERROR, "Invalid channel count"); goto fail; } CHECK_LIBFDK(aacEncOpen(&enc->fdkhandle, 0, enc->channels)); hasFdkHandle = true; CHECK_LIBFDK(aacEncoder_SetParam(enc->fdkhandle, AACENC_AOT, 2)); // MPEG-4 AAC-LC CHECK_LIBFDK(aacEncoder_SetParam(enc->fdkhandle, AACENC_SAMPLERATE, enc->sample_rate)); CHECK_LIBFDK(aacEncoder_SetParam(enc->fdkhandle, AACENC_CHANNELMODE, mode)); CHECK_LIBFDK(aacEncoder_SetParam(enc->fdkhandle, AACENC_CHANNELORDER, 1)); CHECK_LIBFDK(aacEncoder_SetParam(enc->fdkhandle, AACENC_BITRATEMODE, 0)); CHECK_LIBFDK(aacEncoder_SetParam(enc->fdkhandle, AACENC_BITRATE, bitrate)); CHECK_LIBFDK(aacEncoder_SetParam(enc->fdkhandle, AACENC_TRANSMUX, 0)); CHECK_LIBFDK(aacEncoder_SetParam(enc->fdkhandle, AACENC_AFTERBURNER, afterburner)); CHECK_LIBFDK(aacEncEncode(enc->fdkhandle, NULL, NULL, NULL, NULL)); CHECK_LIBFDK(aacEncInfo(enc->fdkhandle, &enc->info)); enc->frame_size_bytes = enc->info.frameLength * 2 * enc->channels; enc->packet_buffer_size = enc->channels * 768; if(enc->packet_buffer_size < 8192) enc->packet_buffer_size = 8192; enc->packet_buffer = bmalloc(enc->packet_buffer_size); blog(LOG_INFO, "libfdk_aac encoder created"); return enc; fail: if(hasFdkHandle) aacEncClose(&enc->fdkhandle); if(enc->packet_buffer) bfree(enc->packet_buffer); if(enc) bfree(enc); blog(LOG_WARNING, "libfdk_aac encoder creation failed"); return 0; }