Skip to content

Instantly share code, notes, and snippets.

@hiccupzhu
Created November 15, 2012 09:20
Show Gist options
  • Save hiccupzhu/4077592 to your computer and use it in GitHub Desktop.
Save hiccupzhu/4077592 to your computer and use it in GitHub Desktop.
Using GStreamer gst_parse_bin_from_description
#include <gst/gst.h>
static const char* demux_cmd = "filesrc location=/mnt/hgfs/E/media/source/IceAgeTrailer.mpg ! mpegpsdemux";
#define DISABLE_MUX 1
#if DISABLE_MUX
static const char* enc_video_cmd = "queue ! ffdec_mpeg2video ! ffmpegcolorspace ! queue ! xvimagesink";
static const char* enc_audio_cmd = "queue ! mad ! queue ! audioconvert ! alsasink";
#else
static const char* enc_video_cmd = "queue ! ffdec_mpeg2video ! ffmpegcolorspace ! queue ! x264enc byte-stream=true ! queue";
//static const char* enc_audio_cmd = "queue ! mad ! audioconvert ! queue ! ffenc_aac ! queue";
static const char* enc_audio_cmd = "queue ! mad ! queue ! audioconvert ! alsasink";
static const char* mux_cmd = "mpegtsmux ! udpsink host=192.168.8.204 port=30000";
#endif
//static char* enc_video_cmd = "queue ! deinterlace method=0 fields=1 ! x264enc byte-stream=true pass=17 threads=2 bitrate=800 bframes=3 vbv-buf-capacity=3000 ! mpegtsmux name=muxer ! queue ! tcpserversink port=8000 queue ! mad ! audioconvert ! faac outputformat=1 profile=1 ! queue ! muxer.";
static void on_pad_added (GstElement* element, GstPad* pad, gpointer data){
GstPad* sinkpad;
GstElement* decoder = (GstElement*) data;
g_print ("%s::%s [linking] %s ", gst_pad_get_name(pad), gst_element_get_name(element), gst_element_get_name(decoder));
sinkpad = gst_element_get_static_pad (decoder, "sink");
GstPadLinkReturn ret = gst_pad_link (pad, sinkpad);
if(ret != GST_PAD_LINK_OK){
g_print(" failed [return code]:%d\n", ret);
}else{
g_print(" successful\n");
}
gst_object_unref (sinkpad);
}
static GMainLoop *loop;
static void ctrl_c_handler(int s){
printf("Caught signal %d\n", s);
g_main_loop_quit(loop);
}
int main (int argc, char *argv[]){
GstElement *dec_bin, *enc_video_bin, *enc_audio_bin, *mux_bin, *pipeline;
GError *err = NULL;
gchar *name;
gboolean ret;
__sighandler_t pre_handler = signal (SIGINT, ctrl_c_handler);
if(SIG_ERR == pre_handler){
g_print("captrue signal SIGINT failed\n");
}
/* init GStreamer */
gst_init (&argc, &argv);
g_print("%s::%d\n", __FUNCTION__, __LINE__);
loop = g_main_loop_new (NULL, FALSE);
if(loop == NULL){
GST_ERROR("create main loop failed\n");
return -1;
}
g_print("%s::%d\n", __FUNCTION__, __LINE__);
pipeline = gst_pipeline_new("my_pipeline");
if(pipeline == NULL){
GST_ERROR("create pipeline failed\n");
return -1;
}
GstElement* source = gst_element_factory_make ("filesrc", "source");
GstElement* demuxer = gst_element_factory_make ("mpegpsdemux", "demuxer");
g_object_set (G_OBJECT (source), "location", "/mnt/hgfs/E/media/source/IceAgeTrailer.mpg", NULL);
enc_video_bin = gst_parse_bin_from_description (enc_video_cmd, TRUE, &err);
if(dec_bin == NULL || err != NULL){
GST_ERROR("create enc_video_bin failed\n");
return -1;
}
g_object_set(enc_video_bin, "name", "video-encoder-bin");
g_print("enc_video_bin->numpads=%d enc_video_bin->numsinkpads=%d\n",
enc_video_bin->numpads,
enc_video_bin->numsinkpads);
enc_audio_bin = gst_parse_bin_from_description (enc_audio_cmd, TRUE, &err);
if(dec_bin == NULL || err != NULL){
GST_ERROR("create enc_audio_bin failed\n");
return -1;
}
g_object_set(enc_audio_bin, "name", "audio-encoder-bin");
g_print("enc_audio_bin->numpads=%d enc_audio_bin->numsinkpads=%d\n",
enc_audio_bin->numpads,
enc_audio_bin->numsinkpads);
#if !DISABLE_MUX
mux_bin = gst_parse_bin_from_description (mux_cmd, TRUE, &err);
if(mux_bin == NULL || err != NULL){
GST_ERROR("create mux_cmd failed\n");
return -1;
}
g_object_set(mux_bin, "name", "mux-bin");
g_print("mux_bin->numpads=%d mux_bin->numsinkpads=%d\n",
mux_bin->numpads,
mux_bin->numsinkpads);
g_print("%s::%d\n", __FUNCTION__, __LINE__);
gst_bin_add_many(GST_BIN(pipeline), source, demuxer, enc_video_bin, enc_audio_bin, mux_bin, NULL);
gst_element_link(enc_video_bin, mux_bin);
#else
gst_bin_add_many(GST_BIN(pipeline), source, demuxer, enc_video_bin, enc_audio_bin, NULL);
#endif
// gst_bin_add_many(GST_BIN(pipeline), dec_bin, enc_video_bin, NULL);
g_print("%s::%d\n", __FUNCTION__, __LINE__);
gst_element_link(source, demuxer);
g_signal_connect(demuxer, "pad-added", G_CALLBACK (on_pad_added), enc_video_bin);
g_signal_connect(demuxer, "pad-added", G_CALLBACK (on_pad_added), enc_audio_bin);
// g_signal_connect(enc_video_bin, "pad-added", G_CALLBACK (on_pad_added), mux_bin);
// g_signal_connect(enc_audio_bin, "pad-added", G_CALLBACK (on_pad_added), mux_bin);
// ret = gst_element_link(dec_bin, enc_video_bin);
// if(ret == FALSE){
// g_print("elemet link failed\n");
// return -1;
// }
g_print("%s::%d\n", __FUNCTION__, __LINE__);
GstStateChangeReturn res;
#if 1
res = gst_element_set_state(pipeline, GST_STATE_PLAYING);
if(res == GST_STATE_CHANGE_FAILURE){
g_print("gst_element_set_state failed\n");
return -1;
}
#else
res = gst_element_set_state(dec_bin, GST_STATE_PLAYING);
if(res == GST_STATE_CHANGE_FAILURE){
g_print("gst_element_set_state failed\n");
return -1;
}
res = gst_element_set_state(enc_video_bin, GST_STATE_PLAYING);
if(res == GST_STATE_CHANGE_FAILURE){
g_print("gst_element_set_state failed\n");
return -1;
}
#endif
g_print("%s::%d\n", __FUNCTION__, __LINE__);
g_main_loop_run (loop);
gst_element_set_state (pipeline, GST_STATE_NULL);
g_print ("Deleting pipeline\n");
gst_object_unref (GST_OBJECT (pipeline));
g_main_loop_unref (loop);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment