All pastes #43357 Raw Edit

Untitled

public c v1 · immutable
#43357 ·published 2006-02-27 16:41 UTC
rendered paste body
#include <unistd.h>#include <stdlib.h>#include <stdio.h>#include <string.h>/************************************************************************/#include <gst/gst.h>static GstStaticPadTemplate srctemplate =GST_STATIC_PAD_TEMPLATE (  "src",  GST_PAD_SRC,  GST_PAD_ALWAYS,  GST_STATIC_CAPS(	  "audio/x-raw-int, "	  "width = (int) 16, "	  "depth = (int) 16, "	  "endianness = (int) BYTE_ORDER, "	  "channels = (int) 1, "	  "rate = (int) 8000, "	  "signed = (boolean) true"));typedef struct _AstAudioSrc AstAudioSrc;typedef struct _AstAudioSrcClass AstAudioSrcClass;/** * AstAudioSrc: * * Opaque #AstAudioSrc data structure */struct _AstAudioSrc {	GstElement element;		GstPad *srcpad;	gboolean push;	gboolean playing;};struct _AstAudioSrcClass {	GstElementClass parent_class;};/* Standard macros for defining types for this element.  */#define GST_TYPE_AST_AUDIO_SRC \  (ast_audio_src_get_type())#define AST_AUDIO_SRC(obj)						\  (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_AST_AUDIO_SRC,AstAudioSrc))#define AST_AUDIO_SRC_CLASS(klass)					\  (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_AST_AUDIO_SRC,AstAudioSrcClass))#define GST_IS_AST_AUDIO_SRC(obj) \  (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_AST_AUDIO_SRC))#define GST_IS_AST_AUDIO_SRC_CLASS(obj) \  (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_AST_AUDIO_SRC))/* Standard function returning type information. */GType ast_audio_src_get_type(void);GST_BOILERPLATE(AstAudioSrc, ast_audio_src, GstElement, GST_TYPE_ELEMENT);static GstElementDetails ast_audio_src_details =	GST_ELEMENT_DETAILS("Asterisk Channel Audio",			    "Blah",			    "Blah Blah",			    "Jeffrey C. Ollie <jeff@ocjtech.us>");static void ast_audio_src_base_init (gpointer g_class){	GstElementClass *gstelement_class = GST_ELEMENT_CLASS (g_class);	gst_element_class_add_pad_template(gstelement_class,					   gst_static_pad_template_get(&srctemplate));	gst_element_class_set_details(gstelement_class, &ast_audio_src_details);}static GstStateChangeReturn ast_audio_src_change_state (GstElement *element, GstStateChange transition){	GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS;	AstAudioSrc *aasrc = AST_AUDIO_SRC(element);	switch (transition) {	case GST_STATE_CHANGE_NULL_TO_READY:		fprintf(stderr, "AstAudioSrc transitioning to READY...\n");		break;	case GST_STATE_CHANGE_READY_TO_PAUSED:		fprintf(stderr, "AstAudioSrc transitioning to PAUSED...\n");		fprintf(stderr, "Sending new segment event...\n");		if (!gst_pad_push_event(aasrc->srcpad, gst_event_new_new_segment(FALSE,										 1.0,										 GST_FORMAT_TIME,										 0, -1, 0))) {		  fprintf(stderr, "Unable to send new segment event...\n");		}		break;	case GST_STATE_CHANGE_PAUSED_TO_PLAYING:		fprintf(stderr, "AstAudioSrc transitioning to PLAYING...\n");		aasrc->playing = TRUE;		break;	default:		break;	}		ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);		switch (transition) {	case GST_STATE_CHANGE_PLAYING_TO_PAUSED:		fprintf(stderr, "AstAudioSrc transitioning to PAUSED...\n");		aasrc->playing = FALSE;		break;	case GST_STATE_CHANGE_PAUSED_TO_READY:		fprintf(stderr, "AstAudioSrc transitioning to PAUSED...\n");		break;	case GST_STATE_CHANGE_READY_TO_NULL:		fprintf(stderr, "AstAudioSrc transitioning to NULL...\n");		break;	default:		break;	}	if (ret == GST_STATE_CHANGE_SUCCESS && GST_STATE_CHANGE_READY_TO_PAUSED) {		ret = GST_STATE_CHANGE_NO_PREROLL;	}	return ret;}static void ast_audio_src_class_init(AstAudioSrcClass *klass){	GObjectClass *gobject_class;	GstElementClass *gstelement_class;		gobject_class = G_OBJECT_CLASS (klass);	gstelement_class = GST_ELEMENT_CLASS (klass);	gstelement_class->change_state = ast_audio_src_change_state;}static gboolean ast_audio_src_activatepush(GstPad *pad, gboolean active){	GstElement *e;	AstAudioSrc *a;	if (active)		fprintf(stderr, "Activating push on pad...\n");	else		fprintf(stderr, "Deactivating push on pad...\n");	e = gst_pad_get_parent_element(pad);	a = AST_AUDIO_SRC(e);	a->push = active;	return TRUE;}static void ast_audio_src_init (AstAudioSrc *aasrc, AstAudioSrcClass *klass){	aasrc->srcpad = gst_pad_new_from_template(gst_element_class_get_pad_template(GST_ELEMENT_CLASS(klass), "src"), "src");	aasrc->push = FALSE;	aasrc->playing = FALSE;	gst_pad_set_activatepush_function(aasrc->srcpad, ast_audio_src_activatepush);	gst_element_add_pad(GST_ELEMENT(aasrc), aasrc->srcpad);}static gboolean register_elements (GstPlugin *plugin){	return gst_element_register(plugin, "ast_audio_src", GST_RANK_NONE, GST_TYPE_AST_AUDIO_SRC);}static GstPluginDesc plugin_desc = {	GST_VERSION_MAJOR,	GST_VERSION_MINOR,	"format_gstreamer_plugins",	"Private elements of format_gstreamer",	register_elements,	"0.0.1",	"GPL",	"format_gstreamer",	"format_gstreamer",	"http://www.asterisk.org/",	GST_PADDING_INIT};/************************************************************************/struct filestream {	FILE *f;	GstElement *pipeline;	GstElement *audio;	guint64 offset;	GstClockTime timestamp;};static void *write_runner(void *data) {	struct filestream *fs;	GstBus *bus;	GstMessage *message;	fprintf(stderr, "Write runner started...\n");	fs = (struct filestream *) data;		bus = gst_pipeline_get_bus(GST_PIPELINE(fs->pipeline));	while(1) {		message = gst_bus_poll(bus, GST_MESSAGE_EOS, -1);		switch(GST_MESSAGE_TYPE(message)) {		case GST_MESSAGE_EOS: {			fprintf(stderr, "EOS message received, shutting down...\n");						/* shut down pipeline here */			gst_element_set_state(fs->pipeline, GST_STATE_NULL);						fprintf(stderr, "Pipeline state set to NULL.\n");						fprintf(stderr, "Unreferencing pipeline...\n");			gst_object_unref(GST_OBJECT(fs->pipeline));			fprintf(stderr, "Unreferencing pipeline... finished\n");						fprintf(stderr, "Closing file...\n");			fclose(fs->f);			fprintf(stderr, "Freeing filestream...\n");			free(fs);			fprintf(stderr, "Freeing filestream... finished.\n");			fs = NULL;			return NULL;			break;		}		default: {			break;		}		}	}		fprintf(stderr, "Write runner finished...\n");	return NULL;}static struct filestream *gstreamer_rewrite(FILE *f){	struct filestream *tmp;	static pthread_t runner;	GstElement *fdsink;	GstElement *subpipeline;	GError *error;	GstElement *audio_input;	GstElement *video_input;	GstElement *output;	fprintf(stderr, "Opening new stream...\n");        if ((tmp = malloc(sizeof(struct filestream)))) {                memset(tmp, 0, sizeof(struct filestream));		tmp->f = f;		fprintf(stderr, "Creating pipeline...\n");		tmp->pipeline = gst_pipeline_new("format_gstreamer");		if (!tmp->pipeline) {			fprintf(stderr, "Unable to create pipeline...\n");			free(tmp);			return NULL;		}		fprintf(stderr, "Creating ast_audio_src...\n");		tmp->audio = gst_element_factory_make("ast_audio_src", "ast_audio_src");		if (!tmp->audio) {			fprintf(stderr, "Could not make ast_audio_src element!\n");			gst_object_unref(tmp->pipeline);			free(tmp);			return NULL;		}		gst_bin_add(GST_BIN(tmp->pipeline), tmp->audio);		fprintf(stderr, "Creating fdsink fd=%i...\n", fileno(tmp->f));		fdsink = gst_element_factory_make("fdsink", "fdsink");		if (!fdsink) { 			fprintf(stderr, "Unable to link queue and audioconvert!\n"); 			gst_object_unref(tmp->pipeline); 			free(tmp); 			return NULL; 		}					g_object_set(G_OBJECT(fdsink), "fd", fileno(tmp->f), NULL);				gst_bin_add(GST_BIN(tmp->pipeline), fdsink);		fprintf(stderr, "Creating sub-pipeline...\n");		error = NULL;		subpipeline = gst_parse_launch("queue name=audio_input ! audioconvert ! vorbisenc ! oggmux name=output", &error);		if (error) {			fprintf(stderr, "There was an error creating the sub pipeline: %s\n", error->message);			if (subpipeline)				gst_object_unref(subpipeline);			gst_object_unref(tmp->pipeline);			free(tmp);			return NULL;		}		gst_bin_add(GST_BIN(tmp->pipeline), subpipeline);		audio_input = gst_bin_get_by_name(GST_BIN(subpipeline), "audio_input");		if (!audio_input) {			fprintf(stderr, "Unable to find audio input element in pipeline!\n");			gst_object_unref(tmp->pipeline);			free(tmp);			return NULL;		}		if (!gst_element_link(tmp->audio, audio_input)) {			fprintf(stderr, "Unable to link audio input...\n");			gst_object_unref(tmp->pipeline);			free(tmp);			return NULL;		}		output = gst_bin_get_by_name(GST_BIN(subpipeline), "output");		if (!output) {			fprintf(stderr, "Unable to find output element in pipeline!\n");			gst_object_unref(tmp->pipeline);			free(tmp);			return NULL;		}		if (!gst_element_link(output, fdsink)) {			fprintf(stderr, "Unable to link output...\n");			gst_object_unref(tmp->pipeline);			free(tmp);			return NULL;		}				fprintf(stderr, "Setting pipeline to playing state...\n");		gst_element_set_state(tmp->pipeline, GST_STATE_PLAYING);				fprintf(stderr, "Starting thread...\n");		pthread_create(&runner, NULL, write_runner, tmp);	} else {		fprintf(stderr, "Out of memory...\n");	}	return tmp;}static void gstreamer_close(struct filestream *fs){	AstAudioSrc *a;	a = AST_AUDIO_SRC(fs->audio);	fprintf(stderr, "Close received, sending EOS.\n");	gst_pad_push_event(a->srcpad, gst_event_new_eos());}static int gstreamer_write(struct filestream *fs){	GstBuffer *buffer;	GstClockTime duration;	AstAudioSrc *a;	a = AST_AUDIO_SRC(fs->audio);	if (!(a->push)) {		fprintf(stderr, "Dropping frame because pad is not ready to push.\n");		return 0;	}	if (!(a->playing)) {		fprintf(stderr, "Dropping frame beause not playing yet...\n");		return 0;	}	duration = 160 * (1000000000 / 8000);	/*fprintf(stderr, "Creating buffer for frame (%i samples, duration %ld) ...\n", f->samples, (long int) duration);*/	/* create buffer and send it */	buffer = gst_buffer_new_and_alloc(160 *2);	gst_buffer_set_caps(buffer, gst_pad_get_caps(a->srcpad));	memset(GST_BUFFER_DATA(buffer), 0, 160 * 2);	GST_BUFFER_OFFSET(buffer) = fs->offset;	GST_BUFFER_SIZE(buffer) = 160 * 2;	GST_BUFFER_TIMESTAMP(buffer) = fs->timestamp;	GST_BUFFER_DURATION(buffer) = duration;	fs->offset += 160 * 2;	fs->timestamp += duration;	/*fprintf(stderr, "Pushing frame...\n");*/	gst_pad_push(a->srcpad, buffer);	return 0;}int main(int argc, char *argv[]){	struct filestream *fs;	FILE *f;	int i;	fprintf(stderr, "Gstreamer initialization starting...\n");	gst_init(NULL, NULL);	fprintf(stderr, "Gstreamer initialization finished...\n");	fprintf(stderr, "Enabling gstreamer debugging...\n");	gst_debug_set_colored(FALSE);	gst_debug_set_active(TRUE);	gst_debug_set_default_threshold(GST_LEVEL_WARNING);	fprintf(stderr, "Registering static plugins...\n");	_gst_plugin_register_static(&plugin_desc);	fprintf(stderr, "Registering static plugins... finished\n");		f = fopen("/tmp/t.ogg", "w");	fs = gstreamer_rewrite(f);	for (i = 0; i < 100; i++) {		usleep(20000); /* 20 ms */		gstreamer_write(fs);	}	gstreamer_close(fs);	usleep(10000000); /* 10 s */}