【Gstreamer 系列 5.5】ubuntu下的Gstreamer工程代码 5 - 摄像头视频流存储为mp4/yuv在本地

1.回调函数sourceFun

static void cb_need_data(GstElement *appsrc, guint unused_size, gpointer user_data)
{
    static int index = 0;
    //static GstClockTime timestamp = 0;
    GstBuffer *buffer;
    guint size;
    GstFlowReturn ret;

    unsigned char *image = getUsbCameraImage(&size);
    if(image == NULL)
    {
        g_HKCameraStatus.stopPush = true;
    }
    else
    {
        buffer = gst_buffer_new_allocate(NULL, size, NULL);

        /* cp image to buffer */
        gst_buffer_fill(buffer, 0, image, size);

        /* Push the buffer into the appsrc */
        g_signal_emit_by_name(appsrc, "push-buffer", buffer, &ret);

        /* Free the buffer now that we are done with it */
        gst_buffer_unref(buffer);

        index ++;
    }

    if(g_HKCameraStatus.stopPush == true)
    {
        printf("end-of-stream video all frame number = [%d]\n", index);
        index = 0;
        g_signal_emit_by_name (appsrc, "end-of-stream", NULL);
    }
}

2.将摄像头数据流打包为mp4保存在本地

/**
  * @brief video to xx.mp4
  * @param *source: app
  * @param *sink:   mp4 file address, example "./sink.mp4"
  * @return bool
  */
bool videoEncode_pushToLolcal(void *sourceFun, char *sink, unsigned int outPutWidth, unsigned int outPutHeight, unsigned int bitrate)
{
    GstBus *bus;

    GstElement *pipeline, *et_source, *et_sink, *et_videoparse, *et_omxh264enc, *et_queue, *et_h264parse, *et_mp4mux, *et_videoconvert;

    /* create loop */
    GMainLoop *myloop = g_main_loop_new(NULL, FALSE);

    /* create pipe */
    pipeline = gst_pipeline_new("video-encode");

    /* create source-link element */
    et_source = gst_element_factory_make("appsrc", "source");
    et_sink = gst_element_factory_make("filesink", "file-sink");

    /* create videoparse element */
    et_videoparse = gst_element_factory_make("videoparse", "work-videoparse");

    /* create videoparse element */
    et_videoconvert = gst_element_factory_make("videoconvert", "work-videoconvert");

    /* create encode element */
    et_omxh264enc = gst_element_factory_make("x264enc", "work-omxh264enc");
    et_queue = gst_element_factory_make("queue", "work-queue");
    et_h264parse = gst_element_factory_make("h264parse", "work-h264parse");
    et_mp4mux = gst_element_factory_make("mp4mux", "work-mp4mux");

    if(!et_source || !et_sink ||
       !et_videoparse ||
       !et_videoconvert ||
       !et_omxh264enc || !et_queue || !et_h264parse || !et_mp4mux)
    {
        printf("error One element could not be created\n");
        return false;
    }

    g_object_set(G_OBJECT(et_sink), "location", sink, NULL);

    /* set videoparse */
    g_object_set(et_videoparse, "format", 4, "width", outPutWidth, "height", outPutHeight, "framerate", "byte-stream", NULL);// "nv12" = 23, yuy2 = 4 ,

    /* set videoparse todo*/
    g_object_set(et_omxh264enc, "bitrate", bitrate, NULL);

    /* get bus */
    bus = gst_pipeline_get_bus(GST_PIPELINE(pipeline));
    gst_bus_add_watch(bus, bus_call, myloop);
    gst_object_unref(bus);

    /* put all elements in a bin */
    gst_bin_add_many(GST_BIN(pipeline), et_source, et_videoparse, et_queue, et_videoconvert, et_omxh264enc, et_h264parse, et_mp4mux, et_sink, NULL);

    /* link element */
    gst_element_link_many(et_source, et_videoparse, et_queue, et_videoconvert, et_omxh264enc, et_h264parse, et_mp4mux, et_sink, NULL);

    /* setup appsrc */
    g_object_set (G_OBJECT (et_source),
          "stream-type", 0,NULL);
    g_signal_connect(et_source, "need-data", G_CALLBACK(sourceFun), NULL);

    /* Now set to playing and iterate. */
    gst_element_set_state(pipeline, GST_STATE_PLAYING);
    g_main_loop_run(myloop);

    /* clean up nicely */
    gst_element_set_state(pipeline, GST_STATE_NULL);
    gst_object_unref(GST_OBJECT(pipeline));

    return true;
}

3.将摄像头数据流打包为yuv保存在本地

/**
  * @brief video to xx.yuv
  * @param *source: app
  * @param *sink:   mp4 file address, example "./sink.yuv"
  * @return bool
  */
bool video_pushToLolcal(void *sourceFun, char *sink)
{
    GstBus *bus;

    GstElement *pipeline, *et_source, *et_sink, *et_queue;

    /* create loop */
    GMainLoop *myloop = g_main_loop_new(NULL, FALSE);

    /* create pipe */
    pipeline = gst_pipeline_new("video-encode");

    /* create source-link element */
    et_source = gst_element_factory_make("appsrc", "source");
    et_sink = gst_element_factory_make("filesink", "file-sink");
    et_queue = gst_element_factory_make("queue", "work-queue");
    if(!et_source || !et_sink || !et_queue)
    {
        printf("error One element could not be created\n");
        return false;
    }

    g_object_set(G_OBJECT(et_sink), "location", sink, NULL);

    /* get bus */
    bus = gst_pipeline_get_bus(GST_PIPELINE(pipeline));
    gst_bus_add_watch(bus, bus_call, myloop);
    gst_object_unref(bus);

    /* put all elements in a bin */
    gst_bin_add_many(GST_BIN(pipeline), et_source, et_queue, et_sink, NULL);

    /* link element */
    gst_element_link_many(et_source, et_queue, et_sink, NULL);

    /* setup appsrc */
    g_object_set (G_OBJECT (et_source),
          "stream-type", 0,NULL);
    g_signal_connect(et_source, "need-data", G_CALLBACK(sourceFun), NULL);

    /* Now set to playing and iterate. */
    gst_element_set_state(pipeline, GST_STATE_PLAYING);
    g_main_loop_run(myloop);

    /* clean up nicely */
    gst_element_set_state(pipeline, GST_STATE_NULL);
    gst_object_unref(GST_OBJECT(pipeline));

    return true;
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值