Skip to content

Commit 166ee16

Browse files
committed
samples: subsys: Add libMP video examples
Add video examples for libMP which includes two pipelines: - camera source and display sink - camera source, video transform and display sink Signed-off-by: Phi Bang Nguyen <[email protected]> Signed-off-by: Trung Hieu Le <[email protected]>
1 parent a2a0d56 commit 166ee16

File tree

10 files changed

+381
-0
lines changed

10 files changed

+381
-0
lines changed
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
CMAKE_MINIMUM_REQUIRED (VERSION 3.20.0)
2+
3+
find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})
4+
5+
project(video_example)
6+
7+
target_sources(app PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/camera_display.c)
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
.. zephyr:code-sample:: video_examples/camera_display
2+
:name: Camera Display Example
3+
4+
A sample pipeline composed of two elements: a camera source and a display sink.
5+
6+
Description
7+
***********
8+
9+
::
10+
11+
+------------------+ +------------------+
12+
| Camera Source | ----> | Display Sink |
13+
+------------------+ +------------------+
14+
15+
This example demonstrates a pipeline consisting of two elements: source and sink.
16+
The source element, which acts as a capture device, generates video frames and pushes
17+
them to the sink element, which serves as a display device to render the content on screen.
18+
19+
Requirements
20+
************
21+
22+
* A board with input camera support
23+
* A board with output display support
24+
* Sufficient RAM for video buffering
25+
26+
This sample has been tested on the following boards:
27+
* native_sim/native/64
28+
* mimxrt1170_evk@B/mimxrt1176/cm7
29+
30+
Building and Running
31+
********************
32+
33+
For :zephyr:board:`native_sim`, build the sample with the following command:
34+
35+
.. zephyr-app-commands::
36+
:zephyr-app: samples/subsys/libmp/video_examples/camera_display
37+
:board: native_sim/native/64
38+
:goals: build
39+
:snippets: video-sw-generator
40+
:compact:
41+
42+
For :zephyr:board:`mimxrt1170_evk`, build the sample with the following command:
43+
44+
.. zephyr-app-commands::
45+
:zephyr-app: samples/subsys/libmp/video_examples/camera_display
46+
:board: mimxrt1170_evk@B/mimxrt1176/cm7
47+
:shield: nxp_btb44_ov5640,rk055hdmipi4ma0
48+
:goals: build
49+
:compact:
50+
51+
Wiring
52+
******
53+
54+
On :zephyr:board:`native_sim`, no wiring is needed since it uses a software video generator
55+
as source, however for the display output you need to ensure that your host system supports
56+
SDL2 to emulate the display.
57+
58+
59+
On :zephyr:board:`mimxrt1170_evk`, the OV5640 camera module should be plugged into the J2
60+
camera connector, the display module RK055HDMIPI4MA0 should be plugged into the J48 MIPI LCD connector.
61+
An additional USB cable is needed to connect USB debug port (J11) on the board to the host PC.
62+
63+
64+
Sample Output
65+
*************
66+
67+
The application will start the video pipeline and display the camera frames on the screen.
68+
Check for any error messages during initialization:
69+
70+
.. code-block:: console
71+
72+
*** Booting Zephyr OS build ***
73+
[00:00:00.321,000] <inf> mp_zdisp_sink: Display device: display-controller@40804000
74+
[00:00:00.373,000] <inf> mp_zvid_buffer_pool: Started streaming
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
CONFIG_VIDEO_BUFFER_POOL_SZ_MAX=3686800
Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
/*
2+
* Copyright 2025 NXP
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
#include <zephyr/drivers/video-controls.h>
8+
#include <zephyr/kernel.h>
9+
#include <zephyr/logging/log.h>
10+
11+
#include <mp.h>
12+
13+
LOG_MODULE_REGISTER(main);
14+
15+
#define LOG_LEVEL LOG_LEVEL_DBG
16+
17+
int main(void)
18+
{
19+
int ret;
20+
21+
/* Initialize built-in elements and plugins */
22+
mp_init();
23+
24+
/* Create elements */
25+
MpElement *source = mp_element_factory_create("zvid_src", "camsrc");
26+
27+
if (source == NULL) {
28+
LOG_ERR("Failed to create camsrc element");
29+
return 1;
30+
}
31+
32+
MpElement *sink = mp_element_factory_create("zdisp_sink", "dispsink");
33+
34+
if (sink == NULL) {
35+
LOG_ERR("Failed to create dispsink element");
36+
return 1;
37+
}
38+
39+
/* Set elements' properties */
40+
ret = mp_object_set_properties(MP_OBJECT(source), PROP_NUM_BUFS, 2, VIDEO_CID_HFLIP, 1,
41+
PROP_LIST_END);
42+
if (ret < 0) {
43+
return ret;
44+
}
45+
46+
/* Create a new pipeline */
47+
MpElement *pipeline = mp_pipeline_new("cam_disp");
48+
49+
if (pipeline == NULL) {
50+
LOG_ERR("Failed to create pipeline");
51+
return 1;
52+
}
53+
54+
/* Add elements to the pipeline - order does not matter */
55+
if (mp_bin_add(MP_BIN(pipeline), source, sink, NULL) == false) {
56+
LOG_ERR("Failed to add elements");
57+
return 1;
58+
}
59+
60+
/* Link elements together - order does matter */
61+
if (mp_element_link(source, sink, NULL) == false) {
62+
LOG_ERR("Failed to link elements");
63+
return 1;
64+
}
65+
66+
/* Start playing */
67+
if (mp_element_set_state(pipeline, MP_STATE_PLAYING) != MP_STATE_CHANGE_SUCCESS) {
68+
LOG_ERR("Failed to start pipeline");
69+
return 1;
70+
}
71+
72+
/* Handle message from the pipeline */
73+
MpBus *bus = mp_element_get_bus(pipeline);
74+
/* Wait until an Error or an EOS - blocking */
75+
MpMessage *msg = mp_bus_pop_msg(bus, MP_MESSAGE_ERROR | MP_MESSAGE_EOS);
76+
77+
if (msg != NULL) {
78+
switch (MP_MESSAGE_TYPE(msg)) {
79+
case MP_MESSAGE_ERROR:
80+
LOG_INF("Received ERROR from %s", msg->src->name);
81+
break;
82+
case MP_MESSAGE_EOS:
83+
LOG_INF("Received EOS from %s", msg->src->name);
84+
break;
85+
default:
86+
LOG_ERR("Unexpected message received from %s", msg->src->name);
87+
break;
88+
}
89+
}
90+
91+
/* TODO: Stop pipeline and free allocated resources */
92+
93+
return 0;
94+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
CONFIG_LOG=y
2+
3+
CONFIG_MP=y
4+
CONFIG_MP_PLUGIN_ZVID=y
5+
CONFIG_MP_PLUGIN_ZDISP=y
6+
7+
CONFIG_VIDEO=y
8+
CONFIG_DISPLAY=y
9+
10+
CONFIG_SHELL=y
11+
CONFIG_DEVICE_SHELL=y
12+
13+
CONFIG_HEAP_MEM_POOL_SIZE=10000
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
CMAKE_MINIMUM_REQUIRED (VERSION 3.20.0)
2+
3+
find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})
4+
5+
project(video_example)
6+
7+
target_sources(app PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/camera_transform_display.c)
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
.. zephyr:code-sample:: video_examples/camera_transform_display
2+
:name: Camera Transform Display Example
3+
4+
A sample pipeline composed of three elements: a camera source, a video transform, and a display sink.
5+
6+
Description
7+
***********
8+
9+
::
10+
11+
+-------------------+ +----------------------+ +------------------+
12+
| Source Element | --> | Transform Element | --> | Sink Element |
13+
+-------------------+ +----------------------+ +------------------+
14+
15+
This example demonstrates a pipeline consisting of three elements: source, transform, and sink.
16+
The source element, which acts as a capture device, generates video frames and pushes them to
17+
the transform element. The transform element then processes these frames and forwards them to
18+
the sink element, which serves as a display device to render the content on screen.
19+
20+
Requirements
21+
************
22+
23+
* A board with input camera support
24+
* A board with output display support
25+
* Sufficient RAM for video buffering
26+
27+
This sample has been tested on the following boards:
28+
* mimxrt1170_evk@B/mimxrt1176/cm7
29+
30+
Building and Running
31+
********************
32+
33+
For :zephyr:board:`mimxrt1170_evk`, build this sample application with the following commands:
34+
35+
.. zephyr-app-commands::
36+
:zephyr-app: samples/subsys/libmp/video_examples/camera_transform_display
37+
:board: mimxrt1170_evk@B/mimxrt1176/cm7
38+
:shield: nxp_btb44_ov5640,rk055hdmipi4ma0
39+
:goals: build flash
40+
:compact:
41+
42+
Wiring
43+
******
44+
On :zephyr:board:`mimxrt1170_evk`, the OV5640 camera module should be plugged into the J2
45+
camera connector, the display module RK055HDMIPI4MA0 should be plugged into the J48 MIPI LCD connector.
46+
An additional USB cable is needed to connect USB debug port (J11) on the board to the host PC.
47+
48+
49+
Sample Output
50+
*************
51+
52+
.. code-block:: console
53+
54+
*** Booting Zephyr OS build ***
55+
[00:00:00.321,000] <inf> mp_zdisp_sink: Display device: display-controller@40804000
56+
[00:00:00.373,000] <inf> mp_zvid_buffer_pool: Started streaming
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
CONFIG_VIDEO_BUFFER_POOL_SZ_MAX=3686800
2+
CONFIG_VIDEO_BUFFER_POOL_NUM_MAX=3
Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
/*
2+
* Copyright 2025 NXP
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
#include <zephyr/drivers/video-controls.h>
8+
#include <zephyr/kernel.h>
9+
#include <zephyr/logging/log.h>
10+
11+
#include <mp.h>
12+
13+
LOG_MODULE_REGISTER(main);
14+
15+
#define LOG_LEVEL LOG_LEVEL_DBG
16+
17+
int main(void)
18+
{
19+
int ret;
20+
21+
/* Initialize built-in elements and plugins */
22+
mp_init();
23+
24+
/* Create elements */
25+
MpElement *source = mp_element_factory_create("zvid_src", "camsrc");
26+
27+
if (source == NULL) {
28+
LOG_ERR("Failed to create camsrc element");
29+
return 0;
30+
}
31+
32+
MpElement *transform = mp_element_factory_create("zvid_transform", "vtransform");
33+
34+
if (transform == NULL) {
35+
LOG_ERR("Failed to create vtransform element");
36+
return 0;
37+
}
38+
39+
MpElement *sink = mp_element_factory_create("zdisp_sink", "dispsink");
40+
41+
if (sink == NULL) {
42+
LOG_ERR("Failed to create dispsink element");
43+
return 0;
44+
}
45+
46+
/* Set elements' properties */
47+
ret = mp_object_set_properties(MP_OBJECT(source), PROP_NUM_BUFS, 3, VIDEO_CID_HFLIP, 1,
48+
PROP_LIST_END);
49+
if (ret < 0) {
50+
return ret;
51+
}
52+
53+
static const struct device *const pxp_dev = DEVICE_DT_GET(DT_NODELABEL(pxp));
54+
55+
if (!device_is_ready(pxp_dev)) {
56+
LOG_ERR("%s: pxp device is not ready", pxp_dev->name);
57+
return -ENODEV;
58+
}
59+
60+
ret = mp_object_set_properties(MP_OBJECT(transform), PROP_DEVICE, pxp_dev, VIDEO_CID_ROTATE,
61+
90, PROP_LIST_END);
62+
if (ret < 0) {
63+
return ret;
64+
}
65+
66+
/* Create a new pipeline */
67+
MpElement *pipeline = mp_pipeline_new("cam_transform_disp");
68+
69+
if (pipeline == NULL) {
70+
LOG_ERR("Failed to create pipeline");
71+
return 0;
72+
}
73+
74+
/* Add elements to the pipeline - order does not matter */
75+
if (mp_bin_add(MP_BIN(pipeline), source, transform, sink, NULL) == false) {
76+
LOG_ERR("Failed to add elements");
77+
return 0;
78+
}
79+
80+
/* Link elements together - order does matter */
81+
if (mp_element_link(source, transform, sink, NULL) == false) {
82+
LOG_ERR("Failed to link elements");
83+
return 0;
84+
}
85+
86+
/* Start playing */
87+
if (mp_element_set_state(pipeline, MP_STATE_PLAYING) != MP_STATE_CHANGE_SUCCESS) {
88+
LOG_ERR("Failed to start pipeline");
89+
return 0;
90+
}
91+
92+
/* Handle message from the pipeline */
93+
MpBus *bus = mp_element_get_bus(pipeline);
94+
/* Wait until an Error or an EOS - blocking */
95+
MpMessage *msg = mp_bus_pop_msg(bus, MP_MESSAGE_ERROR | MP_MESSAGE_EOS);
96+
97+
if (msg != NULL) {
98+
switch (MP_MESSAGE_TYPE(msg)) {
99+
case MP_MESSAGE_ERROR:
100+
LOG_INF("Received ERROR from %s", msg->src->name);
101+
break;
102+
case MP_MESSAGE_EOS:
103+
LOG_INF("Received EOS from %s", msg->src->name);
104+
break;
105+
default:
106+
LOG_ERR("Unexpected message received from %s", msg->src->name);
107+
break;
108+
}
109+
}
110+
111+
/* TODO: Stop pipeline and free allocated resources */
112+
113+
return 0;
114+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
CONFIG_LOG=y
2+
3+
CONFIG_MP=y
4+
CONFIG_MP_PLUGIN_ZVID=y
5+
CONFIG_MP_PLUGIN_ZDISP=y
6+
7+
CONFIG_VIDEO=y
8+
CONFIG_DISPLAY=y
9+
10+
CONFIG_SHELL=y
11+
CONFIG_DEVICE_SHELL=y
12+
13+
CONFIG_HEAP_MEM_POOL_SIZE=12000

0 commit comments

Comments
 (0)