📄 gstsbcenc.c
字号:
if (!gst_structure_get_int(structure, "rate", &rate)) goto error; if (!gst_structure_get_int(structure, "channels", &channels)) goto error; enc->rate = rate; enc->channels = channels; src_caps = sbc_enc_get_fixed_srcpad_caps(enc); if (!src_caps) goto error; res = gst_pad_set_caps(enc->srcpad, src_caps); gst_caps_unref(src_caps); return res;error: GST_ERROR_OBJECT (enc, "invalid input caps"); return FALSE;}gboolean gst_sbc_enc_fill_sbc_params(GstSbcEnc *enc, GstCaps *caps){ GstStructure *structure; gint rate, channels, subbands, blocks, bitpool; const gchar* mode; const gchar* allocation; g_assert(gst_caps_is_fixed(caps)); structure = gst_caps_get_structure(caps, 0); if (!gst_structure_get_int(structure, "rate", &rate)) return FALSE; if (!gst_structure_get_int(structure, "channels", &channels)) return FALSE; if (!gst_structure_get_int(structure, "subbands", &subbands)) return FALSE; if (!gst_structure_get_int(structure, "blocks", &blocks)) return FALSE; if (!gst_structure_get_int(structure, "bitpool", &bitpool)) return FALSE; if (!(mode = gst_structure_get_string(structure, "mode"))) return FALSE; if (!(allocation = gst_structure_get_string(structure, "allocation"))) return FALSE; enc->rate = enc->sbc.rate = rate; enc->channels = enc->sbc.channels = channels; enc->blocks = enc->sbc.blocks = blocks; enc->subbands = enc->sbc.subbands = subbands; enc->sbc.bitpool = bitpool; enc->mode = enc->sbc.joint = gst_sbc_get_mode_int(mode); enc->allocation = enc->sbc.allocation = gst_sbc_get_allocation_mode_int(allocation); enc->codesize = sbc_get_codesize(&enc->sbc); enc->frame_length = sbc_get_frame_length(&enc->sbc); enc->frame_duration = sbc_get_frame_duration(&enc->sbc); GST_DEBUG("codesize: %d, frame_length: %d, frame_duration: %d", enc->codesize, enc->frame_length, enc->frame_duration); return TRUE;}static GstFlowReturn sbc_enc_chain(GstPad *pad, GstBuffer *buffer){ GstSbcEnc *enc = GST_SBC_ENC(gst_pad_get_parent(pad)); GstAdapter *adapter = enc->adapter; GstFlowReturn res = GST_FLOW_OK; gst_adapter_push(adapter, buffer); while (gst_adapter_available(adapter) >= enc->codesize && res == GST_FLOW_OK) { GstBuffer *output; GstCaps *caps; const guint8 *data; int consumed; caps = GST_PAD_CAPS(enc->srcpad); res = gst_pad_alloc_buffer_and_set_caps(enc->srcpad, GST_BUFFER_OFFSET_NONE, enc->frame_length, caps, &output); if (res != GST_FLOW_OK) goto done; data = gst_adapter_peek(adapter, enc->codesize); consumed = sbc_encode(&enc->sbc, (gpointer) data, enc->codesize, GST_BUFFER_DATA(output), GST_BUFFER_SIZE(output), NULL); if (consumed <= 0) { GST_ERROR ("comsumed < 0, codesize: %d", enc->codesize); break; } gst_adapter_flush(adapter, consumed); GST_BUFFER_TIMESTAMP(output) = GST_BUFFER_TIMESTAMP(buffer); res = gst_pad_push(enc->srcpad, output); if (res != GST_FLOW_OK) goto done; }done: gst_object_unref(enc); return res;}static GstStateChangeReturn sbc_enc_change_state(GstElement *element, GstStateChange transition){ GstSbcEnc *enc = GST_SBC_ENC(element); switch (transition) { case GST_STATE_CHANGE_READY_TO_PAUSED: GST_DEBUG("Setup subband codec"); sbc_init(&enc->sbc, 0); break; case GST_STATE_CHANGE_PAUSED_TO_READY: GST_DEBUG("Finish subband codec"); sbc_finish(&enc->sbc); break; default: break; } return parent_class->change_state(element, transition);}static void gst_sbc_enc_dispose(GObject *object){ GstSbcEnc *enc = GST_SBC_ENC(object); if (enc->adapter != NULL) g_object_unref (G_OBJECT (enc->adapter)); enc->adapter = NULL;}static void gst_sbc_enc_base_init(gpointer g_class){ GstElementClass *element_class = GST_ELEMENT_CLASS(g_class); gst_element_class_add_pad_template(element_class, gst_static_pad_template_get(&sbc_enc_sink_factory)); gst_element_class_add_pad_template(element_class, gst_static_pad_template_get(&sbc_enc_src_factory)); gst_element_class_set_details(element_class, &sbc_enc_details);}static gboolean sbc_enc_set_blocks(GstSbcEnc *enc, gint value){ if (value != 4 && value != 8 && value != 12 && value != 16 && value != 0) return FALSE; enc->blocks = value; return TRUE;}static gboolean sbc_enc_set_subbands(GstSbcEnc *enc, gint value){ if (value != 4 && value != 8 && value != 0) return FALSE; enc->subbands = value; return TRUE;}static void gst_sbc_enc_set_property(GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec){ GstSbcEnc *enc = GST_SBC_ENC(object); /* changes to those properties will only happen on the next caps * negotiation */ switch (prop_id) { case PROP_MODE: enc->mode = g_value_get_enum(value); break; case PROP_ALLOCATION: enc->allocation = g_value_get_enum(value); break; case PROP_BLOCKS: if (!sbc_enc_set_blocks(enc, g_value_get_int(value))) GST_WARNING_OBJECT(enc, "invalid value %d for " "blocks property", g_value_get_int(value)); break; case PROP_SUBBANDS: if (!sbc_enc_set_subbands(enc, g_value_get_int(value))) GST_WARNING_OBJECT(enc, "invalid value %d for " "subbands property", g_value_get_int(value)); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); break; }}static void gst_sbc_enc_get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec){ GstSbcEnc *enc = GST_SBC_ENC(object); switch (prop_id) { case PROP_MODE: g_value_set_enum(value, enc->mode); break; case PROP_ALLOCATION: g_value_set_enum(value, enc->allocation); break; case PROP_BLOCKS: g_value_set_int(value, enc->blocks); break; case PROP_SUBBANDS: g_value_set_int(value, enc->subbands); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); break; }}static void gst_sbc_enc_class_init(GstSbcEncClass *klass){ GObjectClass *object_class = G_OBJECT_CLASS(klass); GstElementClass *element_class = GST_ELEMENT_CLASS(klass); parent_class = g_type_class_peek_parent(klass); object_class->set_property = GST_DEBUG_FUNCPTR(gst_sbc_enc_set_property); object_class->get_property = GST_DEBUG_FUNCPTR(gst_sbc_enc_get_property); object_class->dispose = GST_DEBUG_FUNCPTR(gst_sbc_enc_dispose); element_class->change_state = GST_DEBUG_FUNCPTR(sbc_enc_change_state); g_object_class_install_property(object_class, PROP_MODE, g_param_spec_enum("mode", "Mode", "Encoding mode", GST_TYPE_SBC_MODE, SBC_ENC_DEFAULT_MODE, G_PARAM_READWRITE)); g_object_class_install_property(object_class, PROP_ALLOCATION, g_param_spec_enum("allocation", "Allocation", "Allocation mode", GST_TYPE_SBC_ALLOCATION, SBC_ENC_DEFAULT_ALLOCATION, G_PARAM_READWRITE)); g_object_class_install_property(object_class, PROP_BLOCKS, g_param_spec_int("blocks", "Blocks", "Blocks", 0, G_MAXINT, SBC_ENC_DEFAULT_BLOCKS, G_PARAM_READWRITE)); g_object_class_install_property(object_class, PROP_SUBBANDS, g_param_spec_int("subbands", "Sub Bands", "Sub Bands", 0, G_MAXINT, SBC_ENC_DEFAULT_SUB_BANDS, G_PARAM_READWRITE)); GST_DEBUG_CATEGORY_INIT(sbc_enc_debug, "sbcenc", 0, "SBC encoding element");}static void gst_sbc_enc_init(GstSbcEnc *self, GstSbcEncClass *klass){ self->sinkpad = gst_pad_new_from_static_template(&sbc_enc_sink_factory, "sink"); gst_pad_set_setcaps_function (self->sinkpad, GST_DEBUG_FUNCPTR (sbc_enc_sink_setcaps)); gst_element_add_pad(GST_ELEMENT(self), self->sinkpad); self->srcpad = gst_pad_new_from_static_template(&sbc_enc_src_factory, "src"); gst_pad_set_getcaps_function(self->srcpad, GST_DEBUG_FUNCPTR(sbc_enc_src_getcaps)); gst_pad_set_setcaps_function(self->srcpad, GST_DEBUG_FUNCPTR(sbc_enc_src_setcaps)); gst_element_add_pad(GST_ELEMENT(self), self->srcpad); gst_pad_set_chain_function(self->sinkpad, GST_DEBUG_FUNCPTR(sbc_enc_chain)); self->subbands = SBC_ENC_DEFAULT_SUB_BANDS; self->blocks = SBC_ENC_DEFAULT_BLOCKS; self->mode = SBC_ENC_DEFAULT_MODE; self->allocation = SBC_ENC_DEFAULT_ALLOCATION; self->rate = SBC_ENC_DEFAULT_RATE; self->channels = SBC_ENC_DEFAULT_CHANNELS; self->adapter = gst_adapter_new();}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -