void obs_register_encoder_s(const struct obs_encoder_info *info, size_t size) { if (find_encoder(info->id)) { encoder_warn("Encoder id '%s' already exists! " "Duplicate library?", info->id); goto error; } #define CHECK_REQUIRED_VAL_(info, val, func) \ CHECK_REQUIRED_VAL(struct obs_encoder_info, info, val, func) CHECK_REQUIRED_VAL_(info, get_name, obs_register_encoder); CHECK_REQUIRED_VAL_(info, create, obs_register_encoder); CHECK_REQUIRED_VAL_(info, destroy, obs_register_encoder); CHECK_REQUIRED_VAL_(info, encode, obs_register_encoder); if (info->type == OBS_ENCODER_AUDIO) CHECK_REQUIRED_VAL_(info, get_frame_size, obs_register_encoder); #undef CHECK_REQUIRED_VAL_ REGISTER_OBS_DEF(size, obs_encoder_info, obs->encoder_types, info); return; error: HANDLE_ERROR(size, obs_encoder_info, info); }
static struct obs_encoder *create_encoder(const char *id, enum obs_encoder_type type, const char *name, obs_data_t *settings, size_t mixer_idx, obs_data_t *hotkey_data) { struct obs_encoder *encoder; struct obs_encoder_info *ei = find_encoder(id); bool success; if (!ei || ei->type != type) return NULL; encoder = bzalloc(sizeof(struct obs_encoder)); encoder->info = *ei; encoder->mixer_idx = mixer_idx; success = init_encoder(encoder, name, settings, hotkey_data); if (!success) { obs_encoder_destroy(encoder); encoder = NULL; } encoder->control = bzalloc(sizeof(obs_weak_encoder_t)); encoder->control->encoder = encoder; obs_context_data_insert(&encoder->context, &obs->data.encoders_mutex, &obs->data.first_encoder); blog(LOG_INFO, "encoder '%s' (%s) created", name, id); return encoder; }
obs_properties_t *obs_get_encoder_properties(const char *id) { const struct obs_encoder_info *ei = find_encoder(id); if (ei && ei->get_properties) { obs_data_t *defaults = get_defaults(ei); obs_properties_t *properties; properties = ei->get_properties(NULL); obs_properties_apply_settings(properties, defaults); obs_data_release(defaults); return properties; } return NULL; }
int lqt_gavl_add_video_track_compressed(quicktime_t * file, const gavl_video_format_t * format, const gavl_compression_info_t * ci) { lqt_codec_info_t ** infos; lqt_codec_info_t * info; lqt_compression_info_t lci; compression_info_gavl_2_lqt(ci, NULL, format, &lci); infos = lqt_query_registry(0, 1, 1, 0); info = find_encoder(infos, lci.id); lqt_add_video_track_compressed(file, &lci, info); lqt_destroy_codec_info(infos); return 1; }
void obs_register_encoder_s(const struct obs_encoder_info *info, size_t size) { if (find_encoder(info->id)) { blog(LOG_WARNING, "Encoder id '%s' already exists! " "Duplicate library?", info->id); return; } CHECK_REQUIRED_VAL(info, get_name, obs_register_encoder); CHECK_REQUIRED_VAL(info, create, obs_register_encoder); CHECK_REQUIRED_VAL(info, destroy, obs_register_encoder); CHECK_REQUIRED_VAL(info, encode, obs_register_encoder); if (info->type == OBS_ENCODER_AUDIO) CHECK_REQUIRED_VAL(info, get_frame_size, obs_register_encoder); REGISTER_OBS_DEF(size, obs_encoder_info, obs->encoder_types, info); }
static struct obs_encoder *create_encoder(const char *id, enum obs_encoder_type type, const char *name, obs_data_t *settings, size_t mixer_idx, obs_data_t *hotkey_data) { struct obs_encoder *encoder; struct obs_encoder_info *ei = find_encoder(id); bool success; if (ei && ei->type != type) return NULL; encoder = bzalloc(sizeof(struct obs_encoder)); encoder->mixer_idx = mixer_idx; if (!ei) { blog(LOG_ERROR, "Encoder ID '%s' not found", id); encoder->info.id = bstrdup(id); encoder->info.type = type; encoder->owns_info_id = true; } else { encoder->info = *ei; } success = init_encoder(encoder, name, settings, hotkey_data); if (!success) { blog(LOG_ERROR, "creating encoder '%s' (%s) failed", name, id); obs_encoder_destroy(encoder); return NULL; } encoder->control = bzalloc(sizeof(obs_weak_encoder_t)); encoder->control->encoder = encoder; obs_context_data_insert(&encoder->context, &obs->data.encoders_mutex, &obs->data.first_encoder); blog(LOG_INFO, "encoder '%s' (%s) created", name, id); return encoder; }
int lqt_gavl_writes_compressed_video(lqt_file_type_t type, const gavl_video_format_t * format, const gavl_compression_info_t * ci) { int ret = 0; lqt_compression_info_t lci; lqt_codec_info_t ** infos; lqt_codec_info_t * info; if(!compression_info_gavl_2_lqt(ci, NULL, format, &lci)) return 0; infos = lqt_query_registry(0, 1, 1, 0); info = find_encoder(infos, lci.id); if(info) ret = lqt_writes_compressed(type, &lci, info); lqt_destroy_codec_info(infos); return ret; }
enum obs_encoder_type obs_get_encoder_type(const char *id) { struct obs_encoder_info *info = find_encoder(id); return info ? info->type : OBS_ENCODER_AUDIO; }
const char *obs_get_encoder_codec(const char *id) { struct obs_encoder_info *info = find_encoder(id); return info ? info->codec : NULL; }
const char *obs_encoder_get_display_name(const char *id) { struct obs_encoder_info *ei = find_encoder(id); return ei ? ei->get_name() : NULL; }
obs_data_t *obs_encoder_defaults(const char *id) { const struct obs_encoder_info *info = find_encoder(id); return (info) ? get_defaults(info) : NULL; }
int nouveau_backlight_init(struct drm_connector *connector) { struct nouveau_drm *drm = nouveau_drm(connector->dev); struct nouveau_backlight *bl; struct nouveau_encoder *nv_encoder = NULL; struct nvif_device *device = &drm->client.device; char backlight_name[BL_NAME_SIZE]; struct backlight_properties props = {0}; const struct backlight_ops *ops; int ret; if (apple_gmux_present()) { NV_INFO_ONCE(drm, "Apple GMUX detected: not registering Nouveau backlight interface\n"); return 0; } if (connector->connector_type == DRM_MODE_CONNECTOR_LVDS) nv_encoder = find_encoder(connector, DCB_OUTPUT_LVDS); else if (connector->connector_type == DRM_MODE_CONNECTOR_eDP) nv_encoder = find_encoder(connector, DCB_OUTPUT_DP); else return 0; if (!nv_encoder) return 0; switch (device->info.family) { case NV_DEVICE_INFO_V0_CURIE: ret = nv40_backlight_init(nv_encoder, &props, &ops); break; case NV_DEVICE_INFO_V0_TESLA: case NV_DEVICE_INFO_V0_FERMI: case NV_DEVICE_INFO_V0_KEPLER: case NV_DEVICE_INFO_V0_MAXWELL: ret = nv50_backlight_init(nv_encoder, &props, &ops); break; default: return 0; } if (ret == -ENODEV) return 0; else if (ret) return ret; bl = kzalloc(sizeof(*bl), GFP_KERNEL); if (!bl) return -ENOMEM; if (!nouveau_get_backlight_name(backlight_name, bl)) { NV_ERROR(drm, "Failed to retrieve a unique name for the backlight interface\n"); goto fail_alloc; } bl->dev = backlight_device_register(backlight_name, connector->kdev, nv_encoder, ops, &props); if (IS_ERR(bl->dev)) { if (bl->id >= 0) ida_simple_remove(&bl_ida, bl->id); ret = PTR_ERR(bl->dev); goto fail_alloc; } nouveau_connector(connector)->backlight = bl; bl->dev->props.brightness = bl->dev->ops->get_brightness(bl->dev); backlight_update_status(bl->dev); return 0; fail_alloc: kfree(bl); return ret; }
uint32_t obs_get_encoder_caps(const char *encoder_id) { struct obs_encoder_info *info = find_encoder(encoder_id); return info ? info->caps : 0; }
SCM make_ffmpeg_output(SCM scm_file_name, SCM scm_format_name, SCM scm_video_parameters, SCM scm_have_video, SCM scm_audio_parameters, SCM scm_have_audio, SCM scm_debug) { SCM retval; struct ffmpeg_t *self; scm_dynwind_begin(0); const char *file_name = scm_to_locale_string(scm_file_name); scm_dynwind_free(file_name); self = (struct ffmpeg_t *)scm_gc_calloc(sizeof(struct ffmpeg_t), "ffmpeg"); self->video_stream_idx = -1; self->audio_stream_idx = -1; SCM_NEWSMOB(retval, ffmpeg_tag, self); int err; const char *format_name = NULL; if (!scm_is_false(scm_format_name)) { format_name = scm_to_locale_string(scm_symbol_to_string(scm_format_name)); scm_dynwind_free(format_name); }; #ifdef HAVE_AVFORMAT_ALLOC_OUTPUT_CONTEXT2 err = avformat_alloc_output_context2(&self->fmt_ctx, NULL, format_name, file_name); if (!self->fmt_ctx) { ffmpeg_destroy(retval); scm_misc_error("make-ffmpeg-output", "Error initializing output format for file '~a': ~a", scm_list_2(scm_file_name, get_error_text(err))); }; #else AVOutputFormat *format; if (format_name) format = av_guess_format(format_name, NULL, NULL); else format = av_guess_format(NULL, file_name, NULL); if (!format) { ffmpeg_destroy(retval); scm_misc_error("make-ffmpeg-output", "Unable to determine file format for file '~a'", scm_list_1(scm_file_name)); }; self->fmt_ctx = avformat_alloc_context(); if (!self->fmt_ctx) { ffmpeg_destroy(retval); scm_misc_error("make-ffmpeg-output", "Error initializing output format for file '~a'", scm_list_1(scm_file_name)); }; self->fmt_ctx->oformat = format; strncpy(self->fmt_ctx->filename, file_name, sizeof(self->fmt_ctx->filename)); #endif char have_video = scm_is_true(scm_have_video); if (have_video) { // Open codec and video stream enum AVCodecID video_codec_id = self->fmt_ctx->oformat->video_codec; AVCodec *video_encoder = find_encoder(retval, video_codec_id, "video"); AVStream *video_stream = open_output_stream(retval, video_encoder, &self->video_stream_idx, "video", scm_file_name); // Get video parameters SCM scm_shape = scm_car(scm_video_parameters); SCM scm_frame_rate = scm_cadr(scm_video_parameters); SCM scm_video_bit_rate = scm_caddr(scm_video_parameters); SCM scm_aspect_ratio = scm_cadddr(scm_video_parameters); // Configure the output video codec self->video_codec_ctx = configure_output_video_codec(video_stream, video_codec_id, scm_video_bit_rate, scm_shape, scm_frame_rate, scm_aspect_ratio); // Some formats want stream headers to be separate. if (self->fmt_ctx->oformat->flags & AVFMT_GLOBALHEADER) self->video_codec_ctx->flags |= AV_CODEC_FLAG_GLOBAL_HEADER; // Open output video codec open_codec(retval, self->video_codec_ctx, video_encoder, "video", scm_file_name); // Allocate frame self->video_target_frame = allocate_output_video_frame(retval, self->video_codec_ctx); }; char have_audio = scm_is_true(scm_have_audio); if (have_audio) { // Open audio codec and stream enum AVCodecID audio_codec_id = self->fmt_ctx->oformat->audio_codec; AVCodec *audio_encoder = find_encoder(retval, audio_codec_id, "audio"); AVStream *audio_stream = open_output_stream(retval, audio_encoder, &self->audio_stream_idx, "audio", scm_file_name); // Get audio parameters SCM scm_select_rate = scm_car(scm_audio_parameters); SCM scm_channels = scm_cadr(scm_audio_parameters); SCM scm_audio_bit_rate = scm_caddr(scm_audio_parameters); SCM scm_select_format = scm_cadddr(scm_audio_parameters); // Configure the output audio codec self->audio_codec_ctx = configure_output_audio_codec(retval, audio_stream, audio_codec_id, scm_select_rate, scm_channels, scm_audio_bit_rate, scm_select_format); // Some formats want stream headers to be separate. if (self->fmt_ctx->oformat->flags & AVFMT_GLOBALHEADER) self->audio_codec_ctx->flags |= AV_CODEC_FLAG_GLOBAL_HEADER; // Open output audio codec open_codec(retval, self->audio_codec_ctx, audio_encoder, "audio", scm_file_name); // Allocate audio frame self->audio_target_frame = allocate_output_audio_frame(retval, self->audio_codec_ctx, self->audio_codec_ctx->sample_fmt); self->audio_packed_frame = allocate_output_audio_frame(retval, self->audio_codec_ctx, av_get_packed_sample_fmt(self->audio_codec_ctx->sample_fmt)); // Initialise audio buffer ringbuffer_init(&self->audio_buffer, 1024); }; if (scm_is_true(scm_debug)) av_dump_format(self->fmt_ctx, 0, file_name, 1); // Open the output file if needed if (!(self->fmt_ctx->oformat->flags & AVFMT_NOFILE)) { int err = avio_open(&self->fmt_ctx->pb, file_name, AVIO_FLAG_WRITE); if (err < 0) { ffmpeg_destroy(retval); scm_misc_error("make-ffmpeg-output", "Could not open '~a': ~a", scm_list_2(scm_file_name, get_error_text(err))); } self->output_file = 1; } // Write video file header err = avformat_write_header(self->fmt_ctx, NULL); if (err < 0) { ffmpeg_destroy(retval); scm_misc_error("make-ffmpeg-output", "Error writing header of video '~a': ~a", scm_list_2(scm_file_name, get_error_text(err))); }; self->header_written = 1; scm_dynwind_end(); return retval; }