编码器
obs-encoder.h
主要包含
3个结构体定义:输入编码器数据;编码后数据;编码器定义
1个对外输出的注册编码器函数
输入编码器数据
/** Encoder input frame */
struct encoder_frame {
/** Data for the frame/audio */
uint8_t *data[MAX_AV_PLANES];
/** size of each plane */
uint32_t linesize[MAX_AV_PLANES];
/** Number of frames (audio only) */
uint32_t frames;
/** Presentation timestamp */
int64_t pts;
};
编码器输出数据
/** Encoder output packet */
struct encoder_packet {
uint8_t *data; /**< Packet data */
size_t size; /**< Packet size */
int64_t pts; /**< Presentation timestamp */
int64_t dts; /**< Decode timestamp */
int32_t timebase_num; /**< Timebase numerator */
int32_t timebase_den; /**< Timebase denominator */
enum obs_encoder_type type; /**< Encoder type */
bool keyframe; /**< Is a keyframe */
/* ---------------------------------------------------------------- */
/* Internal video variables (will be parsed automatically) */
/* DTS in microseconds */
int64_t dts_usec;
/* System DTS in microseconds */
int64_t sys_dts_usec;
/**
* Packet priority
*
* This is generally use by video encoders to specify the priority
* of the packet.
*/
int priority;
/**
* Dropped packet priority
*
* If this packet needs to be dropped, the next packet must be of this
* priority or higher to continue transmission.
*/
int drop_priority;
/** Audio track index (used with outputs) */
size_t track_idx;
/** Encoder from which the track originated from */
obs_encoder_t *encoder;
};
编码器接口定义
/**
* Encoder interface
*
* Encoders have a limited usage with OBS. You are not generally supposed to
* implement every encoder out there. Generally, these are limited or specific
* encoders for h264/aac for streaming and recording. It doesn't have to be
* *just* h264 or aac of course, but generally those are the expected encoders.
*
* That being said, other encoders will be kept in mind for future use.
*/
struct obs_encoder_info {
/* ----------------------------------------------------------------- */
/* Required implementation*/
/** Specifies the named identifier of this encoder */
const char *id;
/** Specifies the encoder type (video or audio) */
enum obs_encoder_type type;
/** Specifies the codec */
const char *codec;
/**
* Gets the full translated name of this encoder
*
* @param type_data The type_data variable of this structure
* @return Translated name of the encoder
*/
const char *(*get_name)(void *type_data);
/**
* Creates the encoder with the specified settings
*
* @param settings Settings for the encoder
* @param encoder OBS encoder context
* @return Data associated with this encoder context, or
* NULL if initialization failed.
*/
void *(*create)(obs_data_t *settings, obs_encoder_t *encoder);
/**
* Destroys the encoder data
*
* @param data Data associated with this encoder context
*/
void (*destroy)(void *data);
/**
* Encodes frame(s), and outputs encoded packets as they become
* available.
*
* @param data Data associated with this encoder
* context
* @param[in] frame Raw audio/video data to encode
* @param[out] packet Encoder packet output, if any
* @param[out] received_packet Set to true if a packet was received,
* false otherwise
* @return true if successful, false otherwise.
*/
bool (*encode)(void *data, struct encoder_frame *frame,
struct encoder_packet *packet, bool *received_packet);
/** Audio encoder only: Returns the frame size for this encoder */
size_t (*get_frame_size)(void *data);
/* ----------------------------------------------------------------- */
/* Optional implementation */
/**
* Gets the default settings for this encoder
*
* @param[out] settings Data to assign default settings to
*/
void (*get_defaults)(obs_data_t *settings);
/**
* Gets the property information of this encoder
*
* @return The properties data
*/
obs_properties_t *(*get_properties)(void *data);
/**
* Updates the settings for this encoder (usually used for things like
* changing bitrate while active)
*
* @param data Data associated with this encoder context
* @param settings New settings for this encoder
* @return true if successful, false otherwise
*/
bool (*update)(void *data, obs_data_t *settings);
/**
* Returns extra data associated with this encoder (usually header)
*
* @param data Data associated with this encoder context
* @param[out] extra_data Pointer to receive the extra data
* @param[out] size Pointer to receive the size of the extra
* data
* @return true if extra data available, false
* otherwise
*/
bool (*get_extra_data)(void *data, uint8_t **extra_data, size_t *size);
/**
* Gets the SEI data, if any
*
* @param data Data associated with this encoder context
* @param[out] sei_data Pointer to receive the SEI data
* @param[out] size Pointer to receive the SEI data size
* @return true if SEI data available, false otherwise
*/
bool (*get_sei_data)(void *data, uint8_t **sei_data, size_t *size);
/**
* Returns desired audio format and sample information
*
* @param data Data associated with this encoder context
* @param[in/out] info Audio format information
*/
void (*get_audio_info)(void *data, struct audio_convert_info *info);
/**
* Returns desired video format information
*
* @param data Data associated with this encoder context
* @param[in/out] info Video format information
*/
void (*get_video_info)(void *data, struct video_scale_info *info);
void *type_data;
void (*free_type_data)(void *type_data);
uint32_t caps;
/**
* Gets the default settings for this encoder
*
* If get_defaults is also defined both will be called, and the first
* call will be to get_defaults, then to get_defaults2.
*
* @param[out] settings Data to assign default settings to
* @param[in] typedata Type Data
*/
void (*get_defaults2)(obs_data_t *settings, void *type_data);
/**
* Gets the property information of this encoder
*
* @param[in] data Pointer from create (or null)
* @param[in] typedata Type Data
* @return The properties data
*/
obs_properties_t *(*get_properties2)(void *data, void *type_data);
bool (*encode_texture)(void *data, uint32_t handle, int64_t pts,
uint64_t lock_key, uint64_t *next_key,
struct encoder_packet *packet,
bool *received_packet);
};
对外输出的注册编码器函数
EXPORT void obs_register_encoder_s(const struct obs_encoder_info *info,
size_t size);
/**
* Register an encoder definition to the current obs context. This should be
* used in obs_module_load.
*
* @param info Pointer to the source definition structure.
*/
#define obs_register_encoder(info) \
obs_register_encoder_s(info, sizeof(struct obs_encoder_info))
obs-encoder.c
P.S. 函数声明在 obs.h 中
obs.h 中关于编码器的输出函数声明
/* ------------------------------------------------------------------------- */
/* Encoders */
EXPORT const char *obs_encoder_get_display_name(const char *id);
/**
* Creates a video encoder context
*
* @param id Video encoder ID
* @param name Name to assign to this context
* @param settings Settings
* @return The video encoder context, or NULL if failed or not found.
*/
EXPORT obs_encoder_t *obs_video_encoder_create(const char *id, const char *name,
obs_data_t *settings,
obs_data_t *hotkey_data);
/**
* Creates an audio encoder context
*
* @param id Audio Encoder ID
* @param name Name to assign to this context
* @param settings Settings
* @param mixer_idx Index of the mixer to use for this audio encoder
* @return The video encoder context, or NULL if failed or not found.
*/
EXPORT obs_encoder_t *obs_audio_encoder_create(const char *id, const char *name,
obs_data_t *settings,
size_t mixer_idx,
obs_data_t *hotkey_data);
/**
* Adds/releases a reference to an encoder. When the last reference is
* released, the encoder is destroyed.
*/
OBS_EXTERNAL_DEPRECATED EXPORT void obs_encoder_addref(obs_encoder_t *encoder);
EXPORT void obs_encoder_release(obs_encoder_t *encoder);
EXPORT void obs_weak_encoder_addref(obs_weak_encoder_t *weak);
EXPORT void obs_weak_encoder_release(obs_weak_encoder_t *weak);
EXPORT obs_encoder_t *obs_encoder_get_ref(obs_encoder_t *encoder);
EXPORT obs_weak_encoder_t *obs_encoder_get_weak_encoder(obs_encoder_t *encoder);
EXPORT obs_encoder_t *obs_weak_encoder_get_encoder(obs_weak_encoder_t *weak);
EXPORT bool obs_weak_encoder_references_encoder(obs_weak_encoder_t *weak,
obs_encoder_t *encoder);
EXPORT void obs_encoder_set_name(obs_encoder_t *encoder, const char *name);
EXPORT const char *obs_encoder_get_name(const obs_encoder_t *encoder);
/** Returns the codec of an encoder by the id */
EXPORT const char *obs_get_encoder_codec(const char *id);
/** Returns the type of an encoder by the id */
EXPORT enum obs_encoder_type obs_get_encoder_type(const char *id);
/** Returns the codec of the encoder */
EXPORT const char *obs_encoder_get_codec(const obs_encoder_t *encoder);
/** Returns the type of an encoder */
EXPORT enum obs_encoder_type obs_encoder_get_type(const obs_encoder_t *encoder);
/**
* Sets the scaled resolution for a video encoder. Set width and height to 0
* to disable scaling. If the encoder is active, this function will trigger
* a warning, and do nothing.
*/
EXPORT void obs_encoder_set_scaled_size(obs_encoder_t *encoder, uint32_t width,
uint32_t height);
/** For video encoders, returns true if pre-encode scaling is enabled */
EXPORT bool obs_encoder_scaling_enabled(const obs_encoder_t *encoder);
/** For video encoders, returns the width of the encoded image */
EXPORT uint32_t obs_encoder_get_width(const obs_encoder_t *encoder);
/** For video encoders, returns the height of the encoded image */
EXPORT uint32_t obs_encoder_get_height(const obs_encoder_t *encoder);
/** For audio encoders, returns the sample rate of the audio */
EXPORT uint32_t obs_encoder_get_sample_rate(const obs_encoder_t *encoder);
/** For audio encoders, returns the frame size of the audio packet */
EXPORT size_t obs_encoder_get_frame_size(const obs_encoder_t *encoder);
/**
* Sets the preferred video format for a video encoder. If the encoder can use
* the format specified, it will force a conversion to that format if the
* obs output format does not match the preferred format.
*
* If the format is set to VIDEO_FORMAT_NONE, will revert to the default
* functionality of converting only when absolutely necessary.
*/
EXPORT void obs_encoder_set_preferred_video_format(obs_encoder_t *encoder,
enum video_format format);
EXPORT enum video_format
obs_encoder_get_preferred_video_format(const obs_encoder_t *encoder);
/** Gets the default settings for an encoder type */
EXPORT obs_data_t *obs_encoder_defaults(const char *id);
EXPORT obs_data_t *obs_encoder_get_defaults(const obs_encoder_t *encoder);
/** Returns the property list, if any. Free with obs_properties_destroy */
EXPORT obs_properties_t *obs_get_encoder_properties(const char *id);
/**
* Returns the property list of an existing encoder, if any. Free with
* obs_properties_destroy
*/
EXPORT obs_properties_t *obs_encoder_properties(const obs_encoder_t *encoder);
/**
* Updates the settings of the encoder context. Usually used for changing
* bitrate while active
*/
EXPORT void obs_encoder_update(obs_encoder_t *encoder, obs_data_t *settings);
/** Gets extra data (headers) associated with this context */
EXPORT bool obs_encoder_get_extra_data(const obs_encoder_t *encoder,
uint8_t **extra_data, size_t *size);
/** Returns the current settings for this encoder */
EXPORT obs_data_t *obs_encoder_get_settings(const obs_encoder_t *encoder);
/** Sets the video output context to be used with this encoder */
EXPORT void obs_encoder_set_video(obs_encoder_t *encoder, video_t *video);
/** Sets the audio output context to be used with this encoder */
EXPORT void obs_encoder_set_audio(obs_encoder_t *encoder, audio_t *audio);
/**
* Returns the video output context used with this encoder, or NULL if not
* a video context
*/
EXPORT video_t *obs_encoder_video(const obs_encoder_t *encoder);
/**
* Returns the audio output context used with this encoder, or NULL if not
* a audio context
*/
EXPORT audio_t *obs_encoder_audio(const obs_encoder_t *encoder);
/** Returns true if encoder is active, false otherwise */
EXPORT bool obs_encoder_active(const obs_encoder_t *encoder);
EXPORT void *obs_encoder_get_type_data(obs_encoder_t *encoder);
EXPORT const char *obs_encoder_get_id(const obs_encoder_t *encoder);
EXPORT uint32_t obs_get_encoder_caps(const char *encoder_id);
EXPORT uint32_t obs_encoder_get_caps(const obs_encoder_t *encoder);
#ifndef SWIG
/** Duplicates an encoder packet */
OBS_DEPRECATED
EXPORT void obs_duplicate_encoder_packet(struct encoder_packet *dst,
const struct encoder_packet *src);
OBS_DEPRECATED
EXPORT void obs_free_encoder_packet(struct encoder_packet *packet);
#endif
EXPORT void obs_encoder_packet_ref(struct encoder_packet *dst,
struct encoder_packet *src);
EXPORT void obs_encoder_packet_release(struct encoder_packet *packet);
EXPORT void *obs_encoder_create_rerouted(obs_encoder_t *encoder,
const char *reroute_id);
/** Returns whether encoder is paused */
EXPORT bool obs_encoder_paused(const obs_encoder_t *output);
EXPORT const char *obs_encoder_get_last_error(obs_encoder_t *encoder);
EXPORT void obs_encoder_set_last_error(obs_encoder_t *encoder,
const char *message);
EXPORT uint64_t obs_encoder_get_pause_offset(const obs_encoder_t *encoder);
/* ------------------------------------------------------------------------- */
obs-internal.h 中内部使用的函数和结构体
/* encoders */
struct obs_weak_encoder {
struct obs_weak_ref ref;
struct obs_encoder *encoder;
};
struct encoder_callback {
bool sent_first_packet;
void (*new_packet)(void *param, struct encoder_packet *packet);
void *param;
};
struct obs_encoder {
struct obs_context_data context;
struct obs_encoder_info info;
/* allows re-routing to another encoder */
struct obs_encoder_info orig_info;
pthread_mutex_t init_mutex;
uint32_t samplerate;
size_t planes;
size_t blocksize;
size_t framesize;
size_t framesize_bytes;
size_t mixer_idx;
uint32_t scaled_width;
uint32_t scaled_height;
enum video_format preferred_format;
volatile bool active;
volatile bool paused;
bool initialized;
/* indicates ownership of the info.id buffer */
bool owns_info_id;
uint32_t timebase_num;
uint32_t timebase_den;
int64_t cur_pts;
struct circlebuf audio_input_buffer[MAX_AV_PLANES];
uint8_t *audio_output_buffer[MAX_AV_PLANES];
/* if a video encoder is paired with an audio encoder, make it start
* up at the specific timestamp. if this is the audio encoder,
* wait_for_video makes it wait until it's ready to sync up with
* video */
bool wait_for_video;
bool first_received;
struct obs_encoder *paired_encoder;
int64_t offset_usec;
uint64_t first_raw_ts;
uint64_t start_ts;
pthread_mutex_t outputs_mutex;
DARRAY(obs_output_t *) outputs;
bool destroy_on_stop;
/* stores the video/audio media output pointer. video_t *or audio_t **/
void *media;
pthread_mutex_t callbacks_mutex;
DARRAY(struct encoder_callback) callbacks;
struct pause_data pause;
const char *profile_encoder_encode_name;
char *last_error_message;
/* reconfigure encoder at next possible opportunity */
bool reconfigure_requested;
};
extern struct obs_encoder_info *find_encoder(const char *id);
extern bool obs_encoder_initialize(obs_encoder_t *encoder);
extern void obs_encoder_shutdown(obs_encoder_t *encoder);
extern void obs_encoder_start(obs_encoder_t *encoder,
void (*new_packet)(void *param,
struct encoder_packet *packet),
void *param);
extern void obs_encoder_stop(obs_encoder_t *encoder,
void (*new_packet)(void *param,
struct encoder_packet *packet),
void *param);
extern void obs_encoder_add_output(struct obs_encoder *encoder,
struct obs_output *output);
extern void obs_encoder_remove_output(struct obs_encoder *encoder,
struct obs_output *output);
extern bool start_gpu_encode(obs_encoder_t *encoder);
extern void stop_gpu_encode(obs_encoder_t *encoder);
extern bool do_encode(struct obs_encoder *encoder, struct encoder_frame *frame);
extern void send_off_encoder_packet(obs_encoder_t *encoder, bool success,
bool received, struct encoder_packet *pkt); // 把编码后数据发送到 output 中
void obs_encoder_destroy(obs_encoder_t *encoder);
DARRAY(struct obs_encoder_info) encoder_types; 表示当前注册的编码器
struct obs_core {
struct obs_module *first_module;
DARRAY(struct obs_module_path) module_paths;
DARRAY(struct obs_source_info) source_types;
DARRAY(struct obs_source_info) input_types;
DARRAY(struct obs_source_info) filter_types;
DARRAY(struct obs_source_info) transition_types;
DARRAY(struct obs_output_info) output_types;
DARRAY(struct obs_encoder_info) encoder_types;
DARRAY(struct obs_service_info) service_types;
DARRAY(struct obs_modal_ui) modal_ui_callbacks;
DARRAY(