# GStreamer Camera Application Source: [https://docs.qualcomm.com/doc/80-70015-17/topic/gstreamer_camera_application.html](https://docs.qualcomm.com/doc/80-70015-17/topic/gstreamer_camera_application.html) GStreamer is an open source framework for creating streaming media applications. Examples illustrating how to develop camera applications using GStreamer and Qualcomm Camera are provided. ## Using gst-launch-1.0 Source: [https://docs.qualcomm.com/doc/80-70015-17/topic/gstreamer_camera_application.html](https://docs.qualcomm.com/doc/80-70015-17/topic/gstreamer_camera_application.html) Use gst-launch-1.0 command-line GStreamer utility to build and run a GStreamer pipeline. The pipeline is specified as a collection of elements with properties separated by `!`. ### Prerequisites To use [gst-launch-1.0](https://gstreamer.freedesktop.org/documentation/tools/gst-launch.html?gi-language=c) and GStreamer plugins, QIM-SDK (meta-qcom-qim-product-sdk) must be installed on the device. Refer to [Qualcomm Linux Build Guide](https://docs.qualcomm.com/bundle/publicresource/topics/80-70015-254/introduction.html) for QIM-SDK build and installation information. Note: Connect to the device console using SSH. See [How To SSH?](https://docs.qualcomm.com/bundle/publicresource/topics/80-70015-254/how_to.html#use-ssh) for instructions. Run the following commands in an SSH terminal: # mount -o rw,remount / # export XDG_RUNTIME_DIR=/dev/socket/weston # export WAYLAND_DISPLAY=wayland-1 Copy to clipboard ### Single camera stream start 1. Run the following command in the device terminal: gst-launch-1.0 -e qtiqmmfsrc name=camsrc ! 'video/x-raw(memory:GBM),format=NV12,\ width=1280,height=720,framerate=30/1' ! fakesink Copy to clipboard 2. This example shows how to start the camera with 720p@30 FPS configuration. The frame coming from the camera sensor is thrown away by fakesink. If the gst pipeline status is changed to “PLAYING” as shown below, this indicates that the camera is running. Since this command dumps camera frames to fakesink, nothing will be saved on the device. Refer to [Video encoding](https://docs.qualcomm.com/doc/80-70015-17/topic/gstreamer_camera_application.html#id_kfw_tg2_wcc__d7e83) and [Video encoding and snapshot](https://docs.qualcomm.com/doc/80-70015-17/topic/gstreamer_camera_application.html#id_kfw_tg2_wcc__d7e114) for information on operating the camera and saving the video file. gbm_create_device(187): Info: backend name is: msm_drm Setting pipeline to PAUSED ... Pipeline is live and does not need PREROLL ... Setting pipeline to PLAYING ... New clock: GstSystemClockCopy to clipboard To stop the camera, press CTRL+C. ### Video encoding 1. Run the following command in the device terminal: gst-launch-1.0 -e qtiqmmfsrc name=camsrc camera=0 ! \ video/x-raw\(memory:GBM\),format=NV12,width=1280,height=720,framerate=30/1,\ compression=ubwc,interlace-mode=progressive,colorimetry=bt601 ! v4l2h264enc \ capture-io-mode=5 output-io-mode=5 extra-controls="controls,video_bitrate=6000000,\ video_bitrate_mode=0;" ! h264parse ! mp4mux ! filesink location=/opt/mux_avc.mp4 Copy to clipboard This command starts the camera with 720p@30 FPS configuration and saves it as a video file after h264 video encoding. If the gst pipeline status is changed to “PLAYING”, this indicates the camera is running. To stop the camera, press CTRL+C. 2. /opt/mux\_avc.mp4 is generated on the device. The recorded content can be pulled from the device by running the following scp command on the host PC: $ scp -r root@[ip-addr]:/opt/mux_avc.mp4 .Copy to clipboard ### Video encoding and snapshot 1. Run the following command in the device terminal: gst-pipeline-app -e qtiqmmfsrc name=camsrc camera=0 ! \ video/x-raw\(memory:GBM\),format=NV12,width=1280,height=720,framerate=30/1,\ compression=ubwc,interlace-mode=progressive,colorimetry=bt601 ! v4l2h264enc \ capture-io-mode=5 output-io-mode=5 extra-controls="controls,video_bitrate=6000000,\ video_bitrate_mode=0;" ! h264parse ! mp4mux ! filesink location=/opt/mux_avc.mp4 \ camsrc.image_1 ! "image/jpeg,width=1280,height=720,framerate=30/1" \ ! multifilesink location=/opt/frame%d.jpg async=false sync=true Copy to clipboard 2. Press Enter. This command will print the following menu and wait for user input. ##################################### MENU ##################################### ============================== Pipeline Controls ============================== (0) NULL : Set the pipeline into NULL state (1) READY : Set the pipeline into READY state (2) PAUSED : Set the pipeline into PAUSED state (3) PLAYING : Set the pipeline into PLAYING state ==================================== Other ==================================== (p) Plugin Mode : Choose a plugin which to control (q) Quit : Exit the application Choose an option: Copy to clipboard 3. Use the following menu steps to take a snapshot while recording video. (1) ready -> (3) Playing -> (p)Plugin Mode : Select (8)camerasrc ->(36) capture-image -> (1): still – Snapshot ->(1) Snapshot count ('guint' value for arg1)Copy to clipboard 4. To stop the camera, press **Enter**, press **b** (back), and then press **q** (quit). The recorded video file and snapshot images are saved in /opt/. The recorded content can be pulled from the device by running the following scp command on the host PC: $ scp -r root@[ip-addr]:/opt/ .Copy to clipboard ## Writing source code Source: [https://docs.qualcomm.com/doc/80-70015-17/topic/gstreamer_camera_application.html](https://docs.qualcomm.com/doc/80-70015-17/topic/gstreamer_camera_application.html) Use case examples and source code examples enable developers to create a camera application using Qualcomm's qtiqmmfsrc GStreamer plug-in. The GStreamer community provides extensive [documentation](https://gstreamer.freedesktop.org/documentation/?gi-language=c) as a resource for developers. ### Single pipeline video recording The following is an example of a single pipeline video recording use case using Qualcomm's qtiqmmfsrc GStreamer plug-in. The qtiqmmfsrc plug-in provides various properties to control the camera subsystem which are explained in the [Qualcomm Linux Intelligent Multimedia Software Development Kit (QIM SDK) Reference](https://docs.qualcomm.com/bundle/publicresource/topics/80-70015-50/qtiqmmfsrc.html). #include #include #include #define DISABLE_BITRATE 0 #define VARIABLE_BITRATE 1 #define CONSTANT_BITRATE 2 #define FILE_SINK_LOCATION "/home/root/test_app_mux.mp4" typedef struct _AppContext { GstElement *pipeline; GstElement *qtiqmmfsrc; GstElement *x_raw; GstElement *v4l2h264enc; GstElement *enc_queue; GstElement *h264parse; GstElement *mp4mux; GstElement *mux_queue; GstElement *filesink; GMainLoop *mloop; /* Main application event loop */ } AppContext; /* Interreupt handler */ static gboolean handle_interrupt_signal (gpointer userdata) { AppContext *appctx = (AppContext *) userdata; GstState state = GST_STATE_VOID_PENDING; static gboolean waiting_eos = FALSE; g_print ("Received an interrupt signal!\n"); if (!gst_element_get_state (appctx->pipeline, &state, NULL, GST_CLOCK_TIME_NONE)) { gst_printerr ("Failed to get current state!\n"); gst_element_send_event (appctx->pipeline, gst_event_new_eos ()); //gst_element_set_state (appctx->pipeline, GST_STATE_NULL); //g_main_loop_quit (appctx->mloop); return TRUE; } g_printerr ("current state is %d\n", state); //update_pipeline_state (appctx->pipeline, appctx->messages, GST_STATE_NULL); g_printerr ("Sending EOS event\n"); gst_element_send_event (appctx->pipeline, gst_event_new_eos ()); return TRUE; } /* Handle state change transition */ static void state_changed_cb (GstBus * bus, GstMessage * message, gpointer userdata) { GstElement *pipeline = GST_ELEMENT (userdata); GstState old, new_st, pending; /* Handle pipeline state change only */ if (GST_MESSAGE_SRC (message) != GST_OBJECT_CAST (pipeline)) return; gst_message_parse_state_changed (message, &old, &new_st, &pending); g_print ("\nPipeline state changed from %s to %s, pending: %s\n", gst_element_state_get_name (old), gst_element_state_get_name (new_st), gst_element_state_get_name (pending)); } /* Error handler */ static void error_cb (GstBus *bus, GstMessage *msg, gpointer data) { AppContext *appctx = (AppContext *) data; GMainLoop *mloop = appctx->mloop; GError *error = NULL; gchar *debug = NULL; gst_message_parse_error (msg, &error, &debug); gst_object_default_error (GST_MESSAGE_SRC (msg), error, debug); g_free (debug); g_error_free (error); g_main_loop_quit (mloop); } /* EOS handler */ static void eos_cb (GstBus *bus, GstMessage *msg, gpointer userdata) { AppContext *appctx = (AppContext *) userdata; g_print ("Received EOS from '%s' ... \n", GST_MESSAGE_SRC_NAME (msg)); g_main_loop_quit (appctx->mloop); } static void destroy_pipeline (AppContext *appctx) { /* destroy pipeline */ gst_element_unlink_many (appctx->qtiqmmfsrc, appctx->x_raw, appctx->v4l2h264enc, appctx->enc_queue, appctx->h264parse, appctx->mp4mux, appctx->mux_queue, appctx->filesink, NULL); gst_bin_remove_many (GST_BIN(appctx->pipeline), appctx->qtiqmmfsrc, appctx->x_raw, appctx->v4l2h264enc, appctx->enc_queue, appctx->h264parse, appctx->mp4mux, appctx->mux_queue, appctx->filesink, NULL); gst_object_unref (appctx->pipeline); } int main(int argc, char *argv[]) { AppContext appctx; GstBus *bus; GstMessage *msg; GstCaps *filtercaps; guint interrupt_watch_id; /* Initilize GStreamer */ gst_init (&argc, &argv); /* Create all elements */ appctx.qtiqmmfsrc = gst_element_factory_make ("qtiqmmfsrc", "qtiqmmfsrc"); appctx.x_raw = gst_element_factory_make ("capsfilter", "x_raw"); appctx.v4l2h264enc = gst_element_factory_make ("v4l2h264enc", "v4l2h264enc"); appctx.enc_queue = gst_element_factory_make ("queue", "enc_queue"); appctx.h264parse = gst_element_factory_make ("h264parse", "h264parse"); appctx.mp4mux = gst_element_factory_make ("mp4mux", "mp4mux"); appctx.mux_queue = gst_element_factory_make ("queue", "mux_queue"); appctx.filesink = gst_element_factory_make ("filesink", "filesink"); /* Create the pipeline */ appctx.pipeline = gst_pipeline_new ("basic-recording"); if (!appctx.pipeline || !appctx.qtiqmmfsrc || !appctx.x_raw || !appctx.v4l2h264enc || !appctx.enc_queue || !appctx.h264parse || !appctx.mp4mux || !appctx.mux_queue || !appctx.filesink) { g_printerr ("Failed to create pipeline or elements.\n"); return -1; } /* Add the elements to the pipeline */ gst_bin_add_many (GST_BIN(appctx.pipeline), appctx.qtiqmmfsrc, appctx.x_raw, appctx.v4l2h264enc, appctx.enc_queue, appctx.h264parse, appctx.mp4mux, appctx.mux_queue, appctx.filesink, NULL); /* Configure stream caps */ filtercaps = gst_caps_new_simple ("video/x-raw", "format", G_TYPE_STRING, "NV12", "width", G_TYPE_INT, 1280, "height", G_TYPE_INT, 720, "framerate", GST_TYPE_FRACTION, 30, 1, "compression", G_TYPE_STRING, "ubwc", "interlace-mode", G_TYPE_STRING, "progressive", "colorimetry", G_TYPE_STRING, "bt601", NULL); gst_caps_set_features (filtercaps, 0, gst_caps_features_new ("memory:GBM", NULL)); g_object_set (G_OBJECT (appctx.x_raw), "caps", filtercaps, NULL); gst_caps_unref (filtercaps); /* Set v4l2h264enc */ g_object_set (G_OBJECT (appctx.v4l2h264enc), "capture-io-mode", 5, NULL); g_object_set (G_OBJECT (appctx.v4l2h264enc), "output-io-mode", 5, NULL); g_object_set (G_OBJECT (appctx.v4l2h264enc), "controls,video_bitrate", 5000000, NULL); g_object_set (G_OBJECT (appctx.v4l2h264enc), "video_bitrate_mode", 0, NULL); /* Set filesink */ g_object_set (G_OBJECT (appctx.filesink), "location", FILE_SINK_LOCATION, NULL); /* Link elements */ if (!gst_element_link_many (appctx.qtiqmmfsrc, appctx.x_raw, appctx.v4l2h264enc, appctx.enc_queue, appctx.h264parse, appctx.mp4mux, appctx.mux_queue, appctx.filesink, NULL)) { g_printerr ("Faile to link elements\n"); gst_bin_remove_many (GST_BIN(appctx.pipeline), appctx.qtiqmmfsrc, appctx.x_raw, appctx.v4l2h264enc, appctx.enc_queue, appctx.h264parse, appctx.mp4mux, appctx.mux_queue, appctx.filesink, NULL); gst_object_unref (appctx.pipeline); return -1; } /* Initialize main loop */ if ((appctx.mloop = g_main_loop_new (NULL, FALSE)) == NULL) { g_printerr ("ERROR: Failed to create Main loop!\n"); destroy_pipeline(&appctx); return -1; } /* Retrieve reference of the pipeline bus */ if ((bus = gst_pipeline_get_bus (GST_PIPELINE (appctx.pipeline))) == NULL) { g_printerr ("Failed to retrieve pipeline bus\n"); g_main_loop_unref (appctx.mloop); destroy_pipeline(&appctx); return -1; } /* Connect watcher to bus signal */ gst_bus_add_signal_watch (bus); g_signal_connect (bus, "message::state-changed", G_CALLBACK (state_changed_cb), appctx.pipeline); g_signal_connect (bus, "message::error", G_CALLBACK (error_cb), &appctx); g_signal_connect (bus, "message::eos", G_CALLBACK (eos_cb), &appctx); gst_object_unref (bus); /* Set pipeline state to PLAYING */ gst_element_set_state (appctx.pipeline, GST_STATE_PLAYING); /* Register interrupt handler for main_loop */ interrupt_watch_id = g_unix_signal_add (SIGINT, handle_interrupt_signal, &appctx); /* Run mainloop */ g_main_loop_run (appctx.mloop); /* Release/Free resources */ gst_element_set_state (appctx.pipeline, GST_STATE_NULL); g_main_loop_unref (appctx.mloop); /* destroy pipeline */ destroy_pipeline(&appctx); return 0; } Copy to clipboard Code can be compiled with the QIM Product SDK. The QIM SDK can be downloaded or created from a workspace. To install the QIM SDK: - [Download QIM Platform SDK](https://docs.qualcomm.com/bundle/publicresource/topics/80-70015-51/install-sdk.html) - To generate the platform SDK from a workspace, see the [Build Guide](https://docs.qualcomm.com/bundle/publicresource/topics/80-70015-254/introduction.html) and [How to generate eSDK](https://docs.qualcomm.com/bundle/publicresource/topics/80-70015-254/how_to.html). After installing the QIM SDK: 1. Save the above code to simple\_camera.c and run the following command to compile it: unset LD_LIBRARY_PATH source /environment-setup-armv8-2a-qcom-linux $CC -o simple_camera simple_camera.c `pkg-config --cflags --libs gstreamer-1.0 gstreamer-audio-1.0 gstreamer-pbutils-1.0` Copy to clipboard 2. Run the following command to push the `simple_camera` binary to the device: scp ./simple_camera root@[ip-addr]:/opt/simple_cameraCopy to clipboard 3. Use the following commands to run `simple_camera` in the device: cd /opt/ ./simple_camera Copy to clipboard ### Walkthrough The GStreamer pipeline contains the basic building blocks for a media pipeline using [GstElement](https://gstreamer.freedesktop.org/documentation/gstreamer/gstelement.html?gi-language=c). In this example, the `qtiqmmfsrc`, `capsfilter`, `v4l2h264enc`, `h264parse`, `mp4mux`, and `filesink` elements are used to create a single video recording pipeline. ![](data:image/png;base64,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) [gst_init](https://gstreamer.freedesktop.org/documentation/gstreamer/gst.html?gi-language=c#gst_init) must be the first GStreamer command. It initializes all internal GStreamer structures, checks what plug-ins are available, and executes any command line option. /* Initialize GStreamer */ gst_init (&argc, &argv); Copy to clipboard New elements can be created with [gst_element_factory_make](https://gstreamer.freedesktop.org/documentation/gstreamer/gstelementfactory.html?gi-language=c#gst_element_factory_make). The first parameter is the type of element to create and the second parameter is the name to give this instance. /* Create all elements */ appctx.qtiqmmfsrc = gst_element_factory_make ("qtiqmmfsrc", "qtiqmmfsrc"); appctx.x_raw = gst_element_factory_make ("capsfilter", "x_raw"); appctx.v4l2h264enc = gst_element_factory_make ("v4l2h264enc", "v4l2h264enc"); appctx.enc_queue = gst_element_factory_make ("queue", "enc_queue"); appctx.h264parse = gst_element_factory_make ("h264parse", "h264parse"); appctx.mp4mux = gst_element_factory_make ("mp4mux", "mp4mux"); appctx.mux_queue = gst_element_factory_make ("queue", "mux_queue"); appctx.filesink = gst_element_factory_make ("filesink", "filesink"); Copy to clipboard The pipeline can be created with [gst_pipeline_new](https://gstreamer.freedesktop.org/documentation/gstreamer/gstpipeline.html?gi-language=c#gst_pipeline_new). Created elements can then be added to the pipeline using [gst_bin_add_many](https://gstreamer.freedesktop.org/documentation/gstreamer/gstbin.html?gi-language=c#gst_bin_add_many). /* Create the pipeline */ appctx.pipeline = gst_pipeline_new ("basic-recording"); if (!appctx.pipeline || !appctx.qtiqmmfsrc || !appctx.x_raw || !appctx.v4l2h264enc || !appctx.enc_queue || !appctx.h264parse || !appctx.mp4mux || !appctx.mux_queue || !appctx.filesink) { g_printerr ("Failed to create pipeline or elements.\n"); return -1; } /* Add the elements to the pipeline */ gst_bin_add_many (GST_BIN(appctx.pipeline), appctx.qtiqmmfsrc, appctx.x_raw, appctx.v4l2h264enc, appctx.enc_queue, appctx.h264parse, appctx.mp4mux, appctx.mux_queue, appctx.filesink, NULL); Copy to clipboard Caps (capabilities) are object describing media types. Here, a new [GstCaps](https://gstreamer.freedesktop.org/documentation/gstreamer/gstcaps.html?gi-language=c#GstCaps) (filtercaps) is created using [gst_caps_new_simple](https://gstreamer.freedesktop.org/documentation/gstreamer/gstcaps.html?gi-language=c#gst_caps_new_simple). This filtercaps describes the [qtiqmmfsrc pad configuration](https://docs.qualcomm.com/bundle/publicresource/topics/80-70015-50/qtiqmmfsrc.html). /* Configure stream caps */ filtercaps = gst_caps_new_simple ("video/x-raw", "format", G_TYPE_STRING, "NV12", "width", G_TYPE_INT, 1280, "height", G_TYPE_INT, 720, "framerate", GST_TYPE_FRACTION, 30, 1, "compression", G_TYPE_STRING, "ubwc", "interlace-mode", G_TYPE_STRING, "progressive", "colorimetry", G_TYPE_STRING, "bt601", NULL); gst_caps_set_features (filtercaps, 0, gst_caps_features_new ("memory:GBM", NULL)); g_object_set (G_OBJECT (appctx.x_raw), "caps", filtercaps, NULL); gst_caps_unref (filtercaps); Copy to clipboard GStreamer elements are all a kind of [GObject](https://docs.gtk.org/gobject/#GObject-struct). Object properties are written to with [g_object_set](https://docs.gtk.org/gobject/#g-object-set) and read from with [g_object_get](https://docs.gtk.org/gobject/#g-object-get). For more information on the following code snippet, see: - [v4l2h264enc properties](https://docs.qualcomm.com/bundle/publicresource/topics/80-70015-50/v4l2h264enc.html) - [filesink properties](https://gstreamer.freedesktop.org/documentation/coreelements/filesink.html?gi-language=c) /* Set v4l2h264enc */ g_object_set (G_OBJECT (appctx.v4l2h264enc), "capture-io-mode", 5, NULL); g_object_set (G_OBJECT (appctx.v4l2h264enc), "output-io-mode", 5, NULL); g_object_set (G_OBJECT (appctx.v4l2h264enc), "controls,video_bitrate", 5000000, NULL); g_object_set (G_OBJECT (appctx.v4l2h264enc), "video_bitrate_mode", 0, NULL); /* Set filesink */ g_object_set (G_OBJECT (appctx.filesink), "location", FILE_SINK_LOCATION, NULL); Copy to clipboard [gst_element_link_many](https://gstreamer.freedesktop.org/documentation/gstreamer/gstelement.html?gi-language=c#gst_element_link_many) links each element: /* Link elements */ if (!gst_element_link_many (appctx.qtiqmmfsrc, appctx.x_raw, appctx.v4l2h264enc, appctx.enc_queue, appctx.h264parse, appctx.mp4mux, appctx.mux_queue, appctx.filesink, NULL)) { g_printerr ("Faile to link elements\n"); gst_bin_remove_many (GST_BIN(appctx.pipeline), appctx.qtiqmmfsrc, appctx.x_raw, appctx.v4l2h264enc, appctx.enc_queue, appctx.h264parse, appctx.mp4mux, appctx.mux_queue, appctx.filesink, NULL); gst_object_unref (appctx.pipeline); return -1; } Copy to clipboard g\_main\_loop\_new() initializes the main loop. gst\_pipeline\_get\_bus() gets the bus reference and registers the callback function for particular bus messages. Here, the state\_changed\_cb, error\_cb, and eos\_cb functions are set for the `state_changed`, `error`, and `end-of-stream` (EoS) bus messages. The pipeline state is then set to `GST_STATE_PLAYING` and the camera stream starts. /* Initialize main loop */ if ((appctx.mloop = g_main_loop_new (NULL, FALSE)) == NULL) { g_printerr ("ERROR: Failed to create Main loop!\n"); destroy_pipeline(&appctx); return -1; } /* Retrieve reference of the pipeline bus */ if ((bus = gst_pipeline_get_bus (GST_PIPELINE (appctx.pipeline))) == NULL) { g_printerr ("Failed to retrieve pipeline bus\n"); g_main_loop_unref (appctx.mloop); destroy_pipeline(&appctx); return -1; } /* Connect watcher to bus signal */ gst_bus_add_signal_watch (bus); g_signal_connect (bus, "message::state-changed", G_CALLBACK (state_changed_cb), appctx.pipeline); g_signal_connect (bus, "message::error", G_CALLBACK (error_cb), &appctx); g_signal_connect (bus, "message::eos", G_CALLBACK (eos_cb), &appctx); gst_object_unref (bus); /* Set pipeline state to PLAYING */ gst_element_set_state (appctx.pipeline, GST_STATE_PLAYING); Copy to clipboard The handler function is registered using g\_unix\_signal\_add(). If the pipeline process gets a `SIGINT` signal, then handle\_interrupt\_signal() is called. `Main_loop` will continue until getting a Ctrl+C interrupt signal. After the interrupt signal is received, `main_loop` is exited, resources are released, and the pipeline is destroyed. /* Register interrupt handler for main_loop */ interrupt_watch_id = g_unix_signal_add (SIGINT, handle_interrupt_signal, &appctx); /* Run mainloop */ g_main_loop_run (appctx.mloop); /* Release/Free resources */ gst_element_set_state (appctx.pipeline, GST_STATE_NULL); g_main_loop_unref (appctx.mloop); /* destroy pipeline */ destroy_pipeline(&appctx); Copy to clipboard ## Samples Source: [https://docs.qualcomm.com/doc/80-70015-17/topic/gstreamer_camera_application.html](https://docs.qualcomm.com/doc/80-70015-17/topic/gstreamer_camera_application.html) Sample applications and use case examples demonstrate camera and multi-camera features. The QIM SDK includes [GStreamer sample applications for camera](https://docs.qualcomm.com/bundle/publicresource/topics/80-70015-50/camera-sample-applications.html) as well as sample applications for [AI/ML and other multimedia applications](https://docs.qualcomm.com/bundle/publicresource/topics/80-70015-50/example-applications.html). Note: Before using the sample applications, ensure that the installation prerequisites for gst-launch-1.0 and GStreamer plugins are met. The [Gstreamer use case examples](https://docs.qualcomm.com/bundle/publicresource/topics/80-70015-50/multimedia-use-cases.html) listed below use gst-launch-1.0. **Camera and video encode** | Example | Description | | --- | --- | | [One stream – 1080p AVC RTSP from
live source](https://docs.qualcomm.com/bundle/publicresource/topics/80-70015-50/one-stream-1080p-avc-rtsp-from-live-source.html) |

  • Single stream use case using single camera


  • One 1080P stream video encoding


  • 1080P network streaming using RTSP


| | [Three 1080p AVC streams from live
source](https://docs.qualcomm.com/bundle/publicresource/topics/80-70015-50/three-1080p-avc-streams-from-live-source.html) |

  • Three stream use case using single camera


  • Three 1080P streams video encoding


  • Video file save for each streams


| | [Three streams – 1080p AVC, 1080p
HEVC, and 1080p YUV from live source](https://docs.qualcomm.com/bundle/publicresource/topics/80-70015-50/three-streams_1080p-avc-1080p-hevc-and-1080p-yuv-from-live-source.html) |

  • Three stream use case using single camera


  • One 1080P stream video encoding in H264 format and video
    file save


  • One 1080P stream video encoding in HEVC format and video
    file save


  • One 1080P stream for display


| | [Three streams – 1080p AVC MP4,
1080p AVC MPEGTS, and 1080p AVC MP4 from live
source](https://docs.qualcomm.com/bundle/publicresource/topics/80-70015-50/three-streams-1080p-avc-mp4-1080p-avc-mpegts-and-1080p-avc-mp4-from-live-source.html) |

  • Three stream use case using single camera


  • One 1080P stream video encoding in H264 format and video
    file save


  • One 1080P stream video encoding in MPEGTS format and video
    file save


  • One 1080P stream video encoding in H265 format and video
    file save


| | [Three streams – 1080p AVC file
save, 1080p AVC RTSP, and 1080p YUV from live
source](https://docs.qualcomm.com/bundle/publicresource/topics/80-70015-50/three_streams-1080p-avc-file-save-1080p-avc-rtsp-and-1080p-yuv-from-live-source.html) |

  • Three stream use case using single camera


  • One 1080P stream video encoding in H264 format and video
    file save


  • 1080P network streaming using RTSP


  • One 1080P stream for display


| | [Three stream – 4k JPEG snapshot,
1080p AVC MP4, 1080p YUV from live source](https://docs.qualcomm.com/bundle/publicresource/topics/80-70015-50/three-stream_4k_jpeg_snapshot_1080p_avc_mp4_1080p_yuv_from_live_source.html) |

  • Three stream use case using single camera


  • One 1080P stream video encoding in H264 format and video
    file save


  • One 4k snapshot stream for JPEG encoding


  • One 1080P stream for display


| **Multi-camera/multi-client use cases** | Example | Description | | --- | --- | | [Two streams – both 720p—one from
each camera with side-by-side stitching sent to
display](https://docs.qualcomm.com/bundle/publicresource/topics/80-70015-50/two-streams-both-720p-one-from-each-camera-with-side-by-side-stitching-sent-to-display.html) |

  • Two streams from two cameras - one stream from each
    camera


  • Compose to single frame (side-by-side stitching) and sent to
    display


| | [Two streams – both 720p—one from
each camera with side-by-side stitching sent to encode for
filesave and RTSP streaming](https://docs.qualcomm.com/bundle/publicresource/topics/80-70015-50/two-streams-both-720p-one-from-each-camera-with-side-by-side-stitching-sent-to-encode-for-filesave-and-rtsp-streaming.html) |

  • Two streams from two cameras - one stream from each
    camera


  • Compose to single frame (side-by-side stitching)


  • Divert to two streams - one for video file save and the
    other for network streaming using RTSP


| | [Two streams – both 720p—one from
each camera with picture-in-picture composition and sent to
display](https://docs.qualcomm.com/bundle/publicresource/topics/80-70015-50/two-streams-both-720p-one-from-each-camera-with-picture-in-picture-composition-and-sent-to-display.html) |

  • Two streams from two cameras - one stream from each
    camera


  • Compose to single frame (picture-in-picture composition) and
    sent to display


| | [Two streams – both 720p—one from
each camera with picture-in-picture composition sent to encode
for filesave and RTSP streaming](https://docs.qualcomm.com/bundle/publicresource/topics/80-70015-50/two-streams-720p-one-camera-with-pip-composition-to-encode-filesave-rtsp-streaming.html) |

  • Two streams from two cameras - one stream from each
    camera


  • Compose to single frame (picture-in-picture
    composition)


  • Divert to two streams - one for video file save and the
    other for network streaming using RTSP


| | [1080p to 1080p – Rotate
(90/180/270)](https://docs.qualcomm.com/bundle/publicresource/topics/80-70015-50/1080p-to-1080p-rotate-90-180-270.html) |

  • Single stream use case using single camera


  • Rotates the frame by 180 degrees and sent to display


| Last Published: Oct 17, 2024 [Previous Topic V4L2 Interface](https://docs.qualcomm.com/bundle/publicresource/80-70015-17/topics/v4l2_interface.md) [Next Topic Advanced Camera Features](https://docs.qualcomm.com/bundle/publicresource/80-70015-17/topics/advanced_camera_features.md)