# Script EMMC access

> This example requires a device with onboard EMMC memory (e.g. OAK-1-POE). To check whether your device has EMMC memory, run the
bootloader version script at
> [Bootloader Version](https://docs.luxonis.com/software/depthai/examples/bootloader_version.md)
> and check whether the output contains
> `Memory.EMMC`
> .

This example shows how to use [Script](https://docs.luxonis.com/software/depthai-components/nodes/script.md) node to access EMMC
memory of the device. Default location for EMMC memory is /media/mmcsd-0-0/. The first script in the pipeline works by writing an
image to EMMC memory. The second script starts a webserver on :/media/mmcsd-0-0/ directory and serves the image from EMMC memory.

## Setup

Please run the [install script](https://github.com/luxonis/depthai-python/blob/main/examples/install_requirements.py) to download
all required dependencies. Please note that this script must be ran from git context, so you have to download the
[depthai-python](https://github.com/luxonis/depthai-python) repository first and then run the script

```bash
git clone https://github.com/luxonis/depthai-python.git
cd depthai-python/examples
python3 install_requirements.py
```

For additional information, please follow the [installation guide](https://docs.luxonis.com/software/depthai/manual-install.md).

## Prerequisites

We first need to enable the EMMC memory as storage on the device. To do so, we need to flash the device with an application that
has EMMC enabled.

Example application:

```bash
import depthai as dai

    # Create pipeline
    pipeline = dai.Pipeline()

    # Set board config
    board = dai.BoardConfig()
    board.emmc = True
    config = dai.Device.Config()
    config.board = board
    pipeline.setBoardConfig(board)

    (f, bl) = dai.DeviceBootloader.getFirstAvailableDevice()
    bootloader = dai.DeviceBootloader(bl)
    progress = lambda p : print(f'Flashing progress: {p*100:.1f}%')
    (r, errmsg) = bootloader.flash(progress, pipeline, memory=dai.DeviceBootloader.Memory.EMMC)
    if r: print("Flash OK")
```

The above code will flash the device with the application that enables the script node to access EMMC memory. Now we should be
able to access EMMC memory even when the device is in standard mode (connected to the host PC).

## Source code

#### Python

```python
#!/usr/bin/env python3

import depthai as dai
import cv2

# Start defining a pipeline
pipeline = dai.Pipeline()

board = dai.BoardConfig()
board.emmc = True
pipeline.setBoardConfig(board)

# Define source and output
camRgb = pipeline.create(dai.node.ColorCamera)
jpegEncoder = pipeline.create(dai.node.VideoEncoder)

# Properties
camRgb.setResolution(dai.ColorCameraProperties.SensorResolution.THE_4_K)
jpegEncoder.setDefaultProfilePreset(1, dai.VideoEncoderProperties.Profile.MJPEG)

#Set a write script
script_write = pipeline.createScript()
script_write.setProcessor(dai.ProcessorType.LEON_CSS)
script_write.setScript("""

    import os
    index = 1000
    import time
    while True:
        # Find an unused file name first
        while True:
            path = '/media/mmcsd-0-0/' + str(index) + '.jpg'
            if not os.path.exists(path):
                break
            index += 1
        frame = node.io['jpeg'].get()
        node.warn(f'Saving to EMMC: {path}')
        with open(path, 'wb') as f:
            f.write(frame.getData())
        index += 1
        time.sleep(3)

""")
                      
#Set a read script
script_read = pipeline.createScript()
script_read.setProcessor(dai.ProcessorType.LEON_CSS)
script_read.setScript("""

    import http.server
    import socketserver
    import socket
    import fcntl
    import struct
    import os

    def get_ip_address(ifname):
        s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        return socket.inet_ntoa(fcntl.ioctl(
            s.fileno(),
            -1071617759,  # SIOCGIFADDR
            struct.pack('256s', ifname[:15].encode())
        )[20:24])

    # Note: `chdir` here will prevent unmount, this should be improved!
    os.chdir('/media/mmcsd-0-0')

    PORT = 80
    Handler = http.server.SimpleHTTPRequestHandler

    with socketserver.TCPServer(("", PORT), Handler) as httpd:
        ip = get_ip_address('re0')
        node.warn(f'===== HTTP file server accessible at: http://{ip}')
        httpd.serve_forever()

""")
                      
# Linking

camRgb.video.link(jpegEncoder.input)
jpegEncoder.bitstream.link(script_write.inputs['jpeg'])
script_write.inputs['jpeg'].setBlocking(False)
xout = pipeline.create(dai.node.XLinkOut)
xout.setStreamName("rgb")
script_read.outputs['jpeg'].link(xout.input)

# Pipeline defined, now the device is connected to
with dai.Device(pipeline) as device:
    # Output queue will be used to get the rgb frames from the output defined above
    qRgb = device.getOutputQueue(name="rgb", maxSize=100, blocking=False)

    while True:
        inRgb = qRgb.tryGet() 
        
        if inRgb is not None:
            cv2.imshow("rgb", inRgb.getCvFrame())
            
        if cv2.waitKey(1) == ord('q'):
            break
```

## Pipeline

### examples/script_emmc_access.pipeline.json

```json
{
  "pipeline": {
    "connections": [
      {
        "node1Id": 0,
        "node1Output": "video",
        "node1OutputGroup": "",
        "node2Id": 1,
        "node2Input": "in",
        "node2InputGroup": ""
      },
      {
        "node1Id": 1,
        "node1Output": "bitstream",
        "node1OutputGroup": "",
        "node2Id": 2,
        "node2Input": "jpeg",
        "node2InputGroup": "io"
      },
      {
        "node1Id": 3,
        "node1Output": "jpeg",
        "node1OutputGroup": "io",
        "node2Id": 4,
        "node2Input": "in",
        "node2InputGroup": ""
      }
    ],
    "globalProperties": {
      "calibData": null,
      "cameraTuningBlobSize": null,
      "cameraTuningBlobUri": "",
      "leonCssFrequencyHz": 700000000.0,
      "leonMssFrequencyHz": 700000000.0,
      "pipelineName": null,
      "pipelineVersion": null,
      "sippBufferSize": 18432,
      "sippDmaBufferSize": 16384,
      "xlinkChunkSize": -1
    },
    "nodes": [
      [
        0,
        {
          "id": 0,
          "ioInfo": [
            [
              [
                "",
                "inputConfig"
              ],
              {
                "blocking": false,
                "group": "",
                "id": 1,
                "name": "inputConfig",
                "queueSize": 8,
                "type": 3,
                "waitForMessage": false
              }
            ],
            [
              [
                "",
                "raw"
              ],
              {
                "blocking": false,
                "group": "",
                "id": 6,
                "name": "raw",
                "queueSize": 8,
                "type": 0,
                "waitForMessage": false
              }
            ],
            [
              [
                "",
                "still"
              ],
              {
                "blocking": false,
                "group": "",
                "id": 7,
                "name": "still",
                "queueSize": 8,
                "type": 0,
                "waitForMessage": false
              }
            ],
            [
              [
                "",
                "inputControl"
              ],
              {
                "blocking": true,
                "group": "",
                "id": 2,
                "name": "inputControl",
                "queueSize": 8,
                "type": 3,
                "waitForMessage": false
              }
            ],
            [
              [
                "",
                "video"
              ],
              {
                "blocking": false,
                "group": "",
                "id": 3,
                "name": "video",
                "queueSize": 8,
                "type": 0,
                "waitForMessage": false
              }
            ],
            [
              [
                "",
                "isp"
              ],
              {
                "blocking": false,
                "group": "",
                "id": 4,
                "name": "isp",
                "queueSize": 8,
                "type": 0,
                "waitForMessage": false
              }
            ],
            [
              [
                "",
                "preview"
              ],
              {
                "blocking": false,
                "group": "",
                "id": 5,
                "name": "preview",
                "queueSize": 8,
                "type": 0,
                "waitForMessage": false
              }
            ],
            [
              [
                "",
                "frameEvent"
              ],
              {
                "blocking": false,
                "group": "",
                "id": 8,
                "name": "frameEvent",
                "queueSize": 8,
                "type": 0,
                "waitForMessage": false
              }
            ]
          ],
          "name": "ColorCamera",
          "properties": {
            "boardSocket": -1,
            "cameraName": "",
            "colorOrder": 0,
            "fp16": false,
            "fps": 30.0,
            "imageOrientation": -1,
            "initialControl": {
              "aeLockMode": false,
              "aeMaxExposureTimeUs": 0,
              "aeRegion": {
                "height": 0,
                "priority": 0,
                "width": 0,
                "x": 0,
                "y": 0
              },
              "afRegion": {
                "height": 0,
                "priority": 0,
                "width": 0,
                "x": 0,
                "y": 0
              },
              "antiBandingMode": 0,
              "autoFocusMode": 3,
              "awbLockMode": false,
              "awbMode": 0,
              "brightness": 0,
              "captureIntent": 0,
              "chromaDenoise": 0,
              "cmdMask": 0,
              "contrast": 0,
              "controlMode": 0,
              "effectMode": 0,
              "expCompensation": 0,
              "expManual": {
                "exposureTimeUs": 0,
                "frameDurationUs": 0,
                "sensitivityIso": 0
              },
              "frameSyncMode": 0,
              "lensPosAutoInfinity": 0,
              "lensPosAutoMacro": 0,
              "lensPosition": 0,
              "lensPositionRaw": 0.0,
              "lowPowerNumFramesBurst": 0,
              "lowPowerNumFramesDiscard": 0,
              "lumaDenoise": 0,
              "saturation": 0,
              "sceneMode": 0,
              "sharpness": 0,
              "strobeConfig": {
                "activeLevel": 0,
                "enable": 0,
                "gpioNumber": 0
              },
              "strobeTimings": {
                "durationUs": 0,
                "exposureBeginOffsetUs": 0,
                "exposureEndOffsetUs": 0
              },
              "wbColorTemp": 0
            },
            "interleaved": true,
            "isp3aFps": 0,
            "ispScale": {
              "horizDenominator": 0,
              "horizNumerator": 0,
              "vertDenominator": 0,
              "vertNumerator": 0
            },
            "numFramesPoolIsp": 3,
            "numFramesPoolPreview": 4,
            "numFramesPoolRaw": 3,
            "numFramesPoolStill": 4,
            "numFramesPoolVideo": 4,
            "previewHeight": 300,
            "previewKeepAspectRatio": true,
            "previewWidth": 300,
            "rawPacked": null,
            "resolution": 1,
            "sensorCropX": -1.0,
            "sensorCropY": -1.0,
            "stillHeight": -1,
            "stillWidth": -1,
            "videoHeight": -1,
            "videoWidth": -1
          }
        }
      ],
      [
        1,
        {
          "id": 1,
          "ioInfo": [
            [
              [
                "",
                "in"
              ],
              {
                "blocking": true,
                "group": "",
                "id": 9,
                "name": "in",
                "queueSize": 4,
                "type": 3,
                "waitForMessage": true
              }
            ],
            [
              [
                "",
                "bitstream"
              ],
              {
                "blocking": false,
                "group": "",
                "id": 10,
                "name": "bitstream",
                "queueSize": 8,
                "type": 0,
                "waitForMessage": false
              }
            ],
            [
              [
                "",
                "out"
              ],
              {
                "blocking": false,
                "group": "",
                "id": 11,
                "name": "out",
                "queueSize": 8,
                "type": 0,
                "waitForMessage": false
              }
            ]
          ],
          "name": "VideoEncoder",
          "properties": {
            "bitrate": 0,
            "frameRate": 1.0,
            "keyframeFrequency": 30,
            "lossless": false,
            "maxBitrate": 0,
            "numBFrames": 0,
            "numFramesPool": 0,
            "outputFrameSize": 0,
            "profile": 4,
            "quality": 95,
            "rateCtrlMode": 0
          }
        }
      ],
      [
        2,
        {
          "id": 2,
          "ioInfo": [
            [
              [
                "io",
                "jpeg"
              ],
              {
                "blocking": false,
                "group": "io",
                "id": 12,
                "name": "jpeg",
                "queueSize": 8,
                "type": 3,
                "waitForMessage": false
              }
            ]
          ],
          "name": "Script",
          "properties": {
            "processor": 0,
            "scriptName": "<script>",
            "scriptUri": "asset:__script"
          }
        }
      ],
      [
        3,
        {
          "id": 3,
          "ioInfo": [
            [
              [
                "io",
                "jpeg"
              ],
              {
                "blocking": false,
                "group": "io",
                "id": 13,
                "name": "jpeg",
                "queueSize": 8,
                "type": 0,
                "waitForMessage": false
              }
            ]
          ],
          "name": "Script",
          "properties": {
            "processor": 0,
            "scriptName": "<script>",
            "scriptUri": "asset:__script"
          }
        }
      ],
      [
        4,
        {
          "id": 4,
          "ioInfo": [
            [
              [
                "",
                "in"
              ],
              {
                "blocking": true,
                "group": "",
                "id": 14,
                "name": "in",
                "queueSize": 8,
                "type": 3,
                "waitForMessage": true
              }
            ]
          ],
          "name": "XLinkOut",
          "properties": {
            "maxFpsLimit": -1.0,
            "metadataOnly": false,
            "streamName": "rgb"
          }
        }
      ]
    ]
  }
}
```

### Need assistance?

Head over to [Discussion Forum](https://discuss.luxonis.com/) for technical support or any other questions you might have.
