Using Gstreamer, there occurs 'Segmentation fault' errors.,

56 views Asked by At

I'm trying to use Gstreamer API and I want to streaming internal buffer using rtsp with H.264 encoder. SO I made a code by searching but It doesn't works. I cannot find what is wrong with my code.

The code is composed that <bmp file read -> put in image buffer -> encode H.264 -> rtsp stream>

Here are my codes.

    FILE* f = NULL;
    unsigned char bmp_info[54];
    unsigned char* read_data;
    read_data = (unsigned char*)malloc(1280*720*3*sizeof(unsigned char));

    f = fopen("0005.bmp","rb");
    if(f==NULL)
    {
        APP_PRINTF("app_tidl: [ERROR] STREAMING FILE NOT EXIST!!!\n");
    }
    fread(bmp_info,sizeof(unsigned char),54,f);
    int bmp_width = *(int*)&bmp_info[18];
    int bmp_height = *(int*)&bmp_info[22];
    APP_PRINTF("app_tidl: FREAD BMP WIDTH : %d / HEIGHT : %d\n",bmp_width,bmp_height);
    int size = bmp_width*bmp_height*3;
    fread(read_data,sizeof(unsigned char),size,f);
    fclose(f);
    APP_PRINTF("app_tidl: FILE BMP READ FINISHED!!!\n");

    gst_cmd_params->input_data_camera = read_data;//obj->pDisplayBuf888;
    APP_PRINTF("copied bmp buffer to input_data of gstreamer\n");

    appCodecInit_usbCam(gst_cmd_params);

And Go to 'appCodecInit_usbCam', then

int32_t appGstInit_usbCam(app_codec_wrapper_params_t* params)
{
    int32_t status = 0;
    app_gst_wrapper_obj_t* p_gst_pipe_obj = &g_app_gst_wrapper_obj;

    p_gst_pipe_obj->input_file = (gchar *)params->input_data_camera;
    printf("gst_wrapper: inputdata transform!\n");

    p_gst_pipe_obj->m_pipeline = NULL;


        /* GStreamer INIT  */
        gst_init(NULL, NULL);
        printf("gst_wrapper: gst_init!\n");
        p_gst_pipe_obj->m_pipeline = gst_pipeline_new("pipeline");
        printf("gst_wrapper: new pipeline!\n");
        p_gst_pipe_obj->m_source = gst_element_factory_make("appsrc", "source");
        printf("gst_wrapper: appsrc!\n");
        p_gst_pipe_obj->m_converter = gst_element_factory_make("videoconvert", "conv");
        printf("gst_wrapper: videoconvert!\n");
        p_gst_pipe_obj->m_sink = gst_element_factory_make("udpsink", "videosink");
        p_gst_pipe_obj->m_encoder = gst_element_factory_make("x264enc", "encode_h264");
        p_gst_pipe_obj->m_payloader = gst_element_factory_make("rtph264pay", "rtph264pay");

        printf("gst_wrapper: gst_init parameter set!\n");

        if (!isValidIpAddress (IP_ADDRESS)) {
            printf ("gst_wrapper: IP is not valid\n");
            status = -1;
        }
        p_gst_pipe_obj->ip_address = IP_ADDRESS;

        
        if (setup_pipeline(p_gst_pipe_obj) !=TRUE)
        {
            printf("gst_wrapper: setup_pipeline failed!!!!!!!!!");
            gst_object_unref(p_gst_pipe_obj->m_pipeline);
            status = -1;
        }


        GstBus *bus;
        /* set element properties */
        printf("gst_wrapper: set_element_properties FINISHED!!!!\n");

        p_gst_pipe_obj->m_loop = g_main_loop_new(NULL,FALSE);
        printf("gst_wrapper: main loop make finished.\n");

        bus = gst_pipeline_get_bus(GST_PIPELINE(p_gst_pipe_obj->m_pipeline));
        printf("gst_wrapper: pipeline get bus finished.\n");
        gst_bus_add_watch(bus, bus_call, p_gst_pipe_obj->m_loop);
        gst_object_unref(bus);
        printf("gst_wrapper: bus added watch.\n");

        printf("gst_wrapper: Now Streaming Ready........\n");


    return status;
}

And in 'setup_pipeline',

int setup_pipeline (app_gst_wrapper_obj_t *data)
{
    /* set element properties */
    printf("gst_wrapper: set_element_properties start!!!!\n");    

    g_object_set (G_OBJECT (data->m_source),"stream-type",0,"is-live",TRUE,"format",GST_FORMAT_TIME, NULL);
    printf("gst_wrapper: setting types of [m_source]\n");

    g_object_set (G_OBJECT (data->m_source), "caps", gst_caps_new_simple("video/x-raw","format",G_TYPE_STRING,"RGB","width",G_TYPE_INT,1280,"height",G_TYPE_INT,720,"framerate",GST_TYPE_FRACTION,0,1,NULL), NULL);
    printf("gst_wrapper: setting properties of [m_source]\n");

    g_signal_connect_data(G_OBJECT(data->m_source), "need-data", G_CALLBACK(start_feed), &data, NULL, 0);
    g_signal_connect_data(G_OBJECT(data->m_source), "enough-data", G_CALLBACK(stop_feed), &data, NULL, 0);
    
    g_object_set (G_OBJECT (data->m_sink),"host","192.168.105.101","port",8887,NULL);
    printf("gst_wrapper: setting properties of [m_sink]\n");

    g_object_set (G_OBJECT (data->m_payloader), "config-interval", 60, NULL);
    printf("gst_wrapper: setting properties of [m_payloader]\n");

    /* Add the elements into the pipeline and link them together */
    gst_bin_add_many (GST_BIN (data->m_pipeline), data->m_source, data->m_converter, data->m_encoder, data->m_payloader, data->m_sink, NULL);
    printf("gst_wrapper: ADD bin GST FINISHED!!!!\n");
  
    if (gst_element_link_many (data->m_source, data->m_converter,  data->m_encoder, data->m_payloader, data->m_sink, NULL) != TRUE) {
        g_printerr ("Elements could not be linked.\n");
        return FALSE;
    }
  
  return TRUE;
}

In g_signal_connect_data, 'start_feed' & 'stop_feed' callbacks are composed like below.

static void start_feed (GstElement *source, guint size, app_gst_wrapper_obj_t *data) {
  if (data->sourceid == 0) {
    g_print ("Start feeding\n");
    data->sourceid = g_idle_add ((GSourceFunc) cb_need_data, data);
  }
}

static void stop_feed (GstElement *source, app_gst_wrapper_obj_t *data) {
  if (data->sourceid != 0) {
    g_print ("Stop feeding\n");
    g_source_remove (data->sourceid);
    data->sourceid = 0;
  }
}

And the 'cb_need_data' function is like below.

static void cb_need_data (app_gst_wrapper_obj_t *data)
{
  //static gboolean white = FALSE;
  static GstClockTime timestamp = 0;
  GstBuffer *buffer;
  guint size,height,width,channels;
  GstFlowReturn ret;
  guchar *data1;
  GstMapInfo map;

  height    = 720;  
  width     = 1280;
  channels  = 3;
  data1      = (guchar *)data->input_file;
  size = height*width*channels;

  buffer = gst_buffer_new_allocate (NULL, size, NULL);
  gst_buffer_map (buffer, &map, GST_MAP_READ);
  memcpy( (guchar *)map.data, data1,  size );
  
  gst_buffer_unmap(buffer, &map);


  GST_BUFFER_PTS (buffer) = timestamp;
  GST_BUFFER_DURATION (buffer) = gst_util_uint64_scale_int (1, GST_SECOND, 2);

  timestamp += GST_BUFFER_DURATION (buffer);

  g_signal_emit_by_name (data->m_source, "push-buffer", buffer, &ret);
  //ret = gst_app_src_push_buffer(GST_APP_SRC(appsrc),buffer);
  gst_buffer_unref(buffer);

  if (ret!=GST_FLOW_OK)
  {
    printf("source push buffer has somthing WRONG [ %d ]@@@@ \n",ret);
  }

}
0

There are 0 answers