> ## Documentation Index
> Fetch the complete documentation index at: https://imsdkdocs.qualcomm.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Daisy Chaining

> Daisy Chaining AI Models

Daisy chaining refers to the sequential execution of multiple machine learning models, where each model specializes in a particular task. This example chains a [YoloX](https://aihub.qualcomm.com/iot/models/yolox) object detection model with an [HRNet Pose](https://aihub.qualcomm.com/iot/models/hrnet_pose) estimation model — YoloX first detects people in the frame, then HRNet estimates the pose of each detected person.

<img src="https://mintcdn.com/qimsdk/xdnKhBBjxpS5mUYP/qimsdk-overview/images/daisychain.png?fit=max&auto=format&n=xdnKhBBjxpS5mUYP&q=85&s=a4b26c5afd54885095b887daff33035f" alt="gst-ai-video-daisychain-new" width="1681" height="1104" data-path="qimsdk-overview/images/daisychain.png" />

**Stage 1 — Person Detection:** [`qtimlvconverter`](../plugin-reference/qtimlvconverter) converts the NV12 frame to a tensor. [`qtimltflite`](../plugin-reference/qtimltflite) runs FootTrackNet inference. [`qtimlpostprocess`](../plugin-reference/qtimlpostprocess) parses the output into bounding boxes for detected persons.

**Stage 2 — Pose Estimation:** [`qtimlvconverter`](../plugin-reference/qtimlvconverter) in `roi-batch-cumulative` mode crops and centers each detected person's bounding box into individual tensors. [`qtimltflite`](../plugin-reference/qtimltflite) runs HRNet inference per person. [`qtimlpostprocess`](../plugin-reference/qtimlpostprocess) produces keypoints and skeleton connections.

All results are mapped back to the original frame and rendered by [`qtivoverlay`](../plugin-reference/qtivoverlay).

## Run example on device

<Steps>
  <Step title="Download Required Files">
    | File                  | Download                                                                                                                                               | Save as                       |
    | --------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------ | ----------------------------- |
    | YOLOX W8A8 model      | [Qualcomm AI Hub — YOLOX](https://aihub.qualcomm.com/iot/models/yolox)                                                                                 | `yolox_quantized.tflite`      |
    | HRNet Pose W8A8 model | [Qualcomm AI Hub — HRNet Pose](https://aihub.qualcomm.com/iot/models/hrnet_pose)                                                                       | `hrnet_pose_quantized.tflite` |
    | Detection labels      | <a href="../labels/coco.txt" download="coco.txt">coco.txt</a>                                                                                          | `coco.txt`                    |
    | Pose labels           | <a href="../labels/coco_pose.txt" download="coco_pose.txt">coco\_pose.txt</a>                                                                          | `coco_pose.txt`               |
    | Pose settings         | <a href="../labels/hrnet_settings.json" download="hrnet_settings.json">hrnet\_settings.json</a>                                                        | `hrnet_pose_settings.json`    |
    | Sample video          | <a href="https://github.com/qualcomm/sample-apps-for-qualcomm-linux/raw/refs/heads/main/qualcomm-linux/artifacts/videos/demo_samples/">Input video</a> | `ai_demo_sample.mp4`          |

    <Note>
      If any downloaded file is a `.zip` archive, extract it on your host machine before copying:
      `unzip filename.zip`
    </Note>
  </Step>

  <Step title="Copy files to device">
    Create the required directories and transfer the downloaded files to your device.

    <CodeGroup>
      ```bash SCP (SSH) theme={null}
      # Replace $HOME to the appropriate device path before running the commands.
      # For QLI:    /root
      # For Ubuntu: /home/ubuntu
      # Modify this based on your platform and ensure files are copied to the correct location on the device.
      # Run from your host machine — replace <user> and <device-ip>
      ssh <user>@<device-ip> "mkdir -p $HOME/{models,labels,media,media/output}"
      scp yolox_quantized.tflite  <user>@<device-ip>:$HOME/models/
      scp hrnet_pose_quantized.tflite        <user>@<device-ip>:$HOME/models/
      scp coco.txt                     <user>@<device-ip>:$HOME/labels/
      scp coco_pose.txt                <user>@<device-ip>:$HOME/labels/
      scp hrnet_pose_settings.json     <user>@<device-ip>:$HOME/labels/
      scp ai_demo_sample.mp4                    <user>@<device-ip>:$HOME/media/
      ```
    </CodeGroup>
  </Step>

  <Step title="Connect to device">
    <CodeGroup>
      ```bash SCP (SSH) theme={null}
      ssh <user>@<device-ip>
      ```
    </CodeGroup>
  </Step>

  <Step title="Set environment variables">
    ```bash theme={null}
    export MODEL_NAME_1=yolox_quantized.tflite
    export MODEL_NAME_2=hrnet_pose_quantized.tflite
    export LABELS_NAME_1=coco.txt
    export LABELS_NAME_2=coco_pose.txt
    export HRNET_SETTINGS=hrnet_pose_settings.json
    export SRC_VIDEO_NAME=ai_demo_sample.mp4
    export VIDEO_SOURCE="filesrc location=$HOME/media/$SRC_VIDEO_NAME ! qtdemux ! h264parse ! v4l2h264dec capture-io-mode=4 output-io-mode=4 ! video/x-raw,format=NV12"
    ```
  </Step>

  <Step title="Run example on device">
    <Tabs>
      <Tab title="GStreamer Command line">
        ```bash theme={null}
        gst-launch-1.0 $VIDEO_SOURCE ! \
          tee name=t1 \
          t1. ! qtimlvconverter name=detection-preprocess ! queue ! \
               qtimltflite name=detection-inference delegate=external \
                 external-delegate-path=libQnnTFLiteDelegate.so \
                 external-delegate-options="QNNExternalDelegate,backend_type=htp;" \
                 model=$HOME/models/$MODEL_NAME_1 ! queue ! \
               qtimlpostprocess name=detection-postprocess results=8 module=yolov8 \
                 labels=$HOME/labels/$LABELS_NAME_1 settings='{"confidence": 51.0}' ! \
               text/x-raw ! metamux_1. \
          t1. ! qtimetamux name=metamux_1 ! queue ! \
          tee name=t2 \
          t2. ! qtimlvconverter name=pose-preprocess mode=roi-batch-cumulative \
                 image-disposition=centre ! queue ! \
               qtimltflite name=pose-inference delegate=external \
                 external-delegate-path=libQnnTFLiteDelegate.so \
                 external-delegate-options="QNNExternalDelegate,backend_type=htp,htp_performance_mode=(string)2;" \
                 model=$HOME/models/$MODEL_NAME_2 ! queue ! \
               qtimlpostprocess name=pose-postprocess results=1 module=hrnet \
                 labels=$HOME/labels/$LABELS_NAME_2 \
                 settings=$HOME/labels/$HRNET_SETTINGS ! \
               text/x-raw ! metamux_2. \
          t2. ! qtimetamux name=metamux_2 ! qtivoverlay ! waylandsink fullscreen=true sync=true
        ```
      </Tab>

      <Tab title="GStreamer Python application">
        * **Python source code:** [gst-daisychain-detection-pose.py](https://github.com/qualcomm/gst-plugins-imsdk/tree/main/gst-python-examples/gst-daisychain-detection-pose.py)

        * **Run:**

          ```bash theme={null}
          python3 gst-ai-video-daisychain-pose-estimation.py -s "$VIDEO_SOURCE" -o display
          ```
      </Tab>

      <Tab title="GStreamer C/C++ application">
        * **Application source code:** [gst-ai-video-daisychain-pose-estimation](https://github.com/qualcomm/gst-plugins-imsdk/tree/main/gst-sample-apps/gst-ai-video-daisychain-pose-estimation)

        * **Build your application:**

                  <Tabs>
                    <Tab title="Yocto">
                      <a href="../advanced/yocto-build#steps-to-build-custom-application">
                        Steps to build custom application
                      </a>
                    </Tab>

                    <Tab title="Ubuntu">
                      <a href="../advanced/ubuntu-build#steps-to-build-custom-application">
                        Steps to build custom application
                      </a>
                    </Tab>
                  </Tabs>

        * **Run:**

          ```bash theme={null}
          gst-ai-video-daisychain-pose-estimation -s "$VIDEO_SOURCE" -o display
          ```
      </Tab>
    </Tabs>
  </Step>
</Steps>

## Expected output

Bounding boxes (from YOLOX) and skeleton keypoints (from HRNet) are overlaid on each video frame in real time.

## Exploring output options

The [`waylandsink`](../plugin-reference/waylandsink) in the pipeline above can be replaced with other output elements:

**Encode to file:**

```bash theme={null}
v4l2h264enc output-io-mode=5 capture-io-mode=4 ! queue ! h264parse ! mp4mux ! filesink location=$HOME/media/output.mp4
```

**Save raw frames:**

```bash theme={null}
filesink location=$HOME/media/frame.bin
```

**Stream over RTSP:**

```bash theme={null}
v4l2h264enc output-io-mode=4 capture-io-mode=4 ! queue ! h264parse config-interval=1 ! queue ! qtirtspbin address=0.0.0.0 port=8900
```

Access the stream at `rtsp://<device-ip>:8900/live`.
