Skip to content

Commit d1bb152

Browse files
authored
Camera app: Add --video-device arg instead of hardcoding /dev/video0 (project-chip#39552)
* Add app option to get video device path * Propagate the video device path to camera app * Apply gemini suggestions for error return & string reuse * Remove `AppOptions`, add arg to linux options
1 parent 30b358a commit d1bb152

File tree

5 files changed

+41
-14
lines changed

5 files changed

+41
-14
lines changed

examples/camera-app/linux/include/camera-device.h

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,8 @@ static constexpr uint16_t kMaxImageRotation = 359; // Spec constraint
6666

6767
namespace Camera {
6868

69+
constexpr const char * kDefaultVideoDevicePath = "/dev/video0";
70+
6971
// Camera defined constants for Pan, Tilt, Zoom bounding values
7072
constexpr int16_t kMinPanValue = -90;
7173
constexpr int16_t kMaxPanValue = 90;
@@ -89,6 +91,8 @@ class CameraDevice : public CameraDeviceInterface, public CameraDeviceInterface:
8991

9092
CameraDeviceInterface::CameraHALInterface & GetCameraHALInterface() override { return *this; }
9193

94+
void Init();
95+
9296
// HAL interface impl
9397
CameraError InitializeCameraDevice() override;
9498

@@ -267,8 +271,11 @@ class CameraDevice : public CameraDeviceInterface, public CameraDeviceInterface:
267271

268272
std::vector<SnapshotStream> & GetAvailableSnapshotStreams() override { return mSnapshotStreams; }
269273

274+
void SetVideoDevicePath(const std::string & path) { mVideoDevicePath = path; }
275+
270276
private:
271-
int videoDeviceFd = -1;
277+
int videoDeviceFd = -1;
278+
std::string mVideoDevicePath = kDefaultVideoDevicePath;
272279
std::vector<VideoStream> mVideoStreams; // Vector to hold available video streams
273280
std::vector<AudioStream> mAudioStreams; // Vector to hold available audio streams
274281
std::vector<SnapshotStream> mSnapshotStreams; // Vector to hold available snapshot streams

examples/camera-app/linux/main.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717

1818
#include "camera-app.h"
1919
#include "camera-device.h"
20+
2021
#include <AppMain.h>
2122
#include <platform/CHIPDeviceConfig.h>
2223

@@ -30,6 +31,17 @@ CameraDevice gCameraDevice;
3031
void ApplicationInit()
3132
{
3233
ChipLogProgress(Camera, "Matter Camera Linux App: ApplicationInit()");
34+
if (LinuxDeviceOptions::GetInstance().cameraVideoDevice.HasValue())
35+
{
36+
std::string videoDevicePath = LinuxDeviceOptions::GetInstance().cameraVideoDevice.Value();
37+
ChipLogDetail(Camera, "Using video device path from options: %s", videoDevicePath.c_str());
38+
gCameraDevice.SetVideoDevicePath(videoDevicePath);
39+
}
40+
else
41+
{
42+
ChipLogDetail(Camera, "Using default video device path: %s", Camera::kDefaultVideoDevicePath);
43+
}
44+
gCameraDevice.Init();
3345
CameraAppInit(&gCameraDevice);
3446
}
3547

examples/camera-app/linux/src/camera-device.cpp

Lines changed: 11 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -315,13 +315,6 @@ GstElement * CreateSnapshotPipelineLibcamerasrc(const SnapshotPipelineConfig & c
315315

316316
CameraDevice::CameraDevice()
317317
{
318-
InitializeCameraDevice();
319-
320-
InitializeStreams();
321-
322-
// Initialize WebRTC connnection
323-
mWebRTCProviderManager.Init();
324-
325318
// Set the CameraHALInterface in CameraAVStreamManager and CameraAVsettingsUserLevelManager.
326319
mCameraAVStreamManager.SetCameraDeviceHAL(this);
327320
mCameraAVSettingsUserLevelManager.SetCameraDeviceHAL(this);
@@ -341,6 +334,13 @@ CameraDevice::~CameraDevice()
341334
}
342335
}
343336

337+
void CameraDevice::Init()
338+
{
339+
InitializeCameraDevice();
340+
InitializeStreams();
341+
mWebRTCProviderManager.Init();
342+
}
343+
344344
CameraError CameraDevice::InitializeCameraDevice()
345345
{
346346
static bool gstreamerInitialized = false;
@@ -351,12 +351,10 @@ CameraError CameraDevice::InitializeCameraDevice()
351351
gstreamerInitialized = true;
352352
}
353353

354-
// TODO: Replace hardcoded device file with device passed in from
355-
// camera-app.
356-
videoDeviceFd = open("/dev/video0", O_RDWR);
354+
videoDeviceFd = open(mVideoDevicePath.c_str(), O_RDWR);
357355
if (videoDeviceFd == -1)
358356
{
359-
ChipLogError(Camera, "Error opening video device: %s", strerror(errno));
357+
ChipLogError(Camera, "Error opening video device: %s at %s", strerror(errno), mVideoDevicePath.c_str());
360358
return CameraError::ERROR_INIT_FAILED;
361359
}
362360

@@ -629,7 +627,7 @@ CameraError CameraDevice::StartVideoStream(uint16_t streamID)
629627
// Create Gstreamer video pipeline
630628
CameraError error = CameraError::SUCCESS;
631629
GstElement * videoPipeline =
632-
CreateVideoPipeline("/dev/video0", it->videoStreamParams.minResolution.width, it->videoStreamParams.minResolution.height,
630+
CreateVideoPipeline(mVideoDevicePath, it->videoStreamParams.minResolution.width, it->videoStreamParams.minResolution.height,
633631
it->videoStreamParams.minFrameRate, error);
634632
if (videoPipeline == nullptr)
635633
{
@@ -804,7 +802,7 @@ CameraError CameraDevice::StartSnapshotStream(uint16_t streamID)
804802
// Create the GStreamer pipeline
805803
CameraError error = CameraError::SUCCESS;
806804
GstElement * snapshotPipeline = CreateSnapshotPipeline(
807-
"/dev/video0", it->snapshotStreamParams.minResolution.width, it->snapshotStreamParams.minResolution.height,
805+
mVideoDevicePath, it->snapshotStreamParams.minResolution.width, it->snapshotStreamParams.minResolution.height,
808806
it->snapshotStreamParams.quality, it->snapshotStreamParams.frameRate, "capture_snapshot.jpg", error);
809807
if (snapshotPipeline == nullptr)
810808
{

examples/platform/linux/Options.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,7 @@ enum
140140
#endif
141141
#if ENABLE_CAMERA_SERVER
142142
kDeviceOption_Camera_DeferredOffer,
143+
kDeviceOption_Camera_VideoDevice,
143144
#endif
144145
kDeviceOption_VendorName,
145146
kDeviceOption_ProductName,
@@ -238,6 +239,7 @@ OptionDef sDeviceOptionDefs[] = {
238239
#endif
239240
#if ENABLE_CAMERA_SERVER
240241
{ "camera-deferred-offer", kNoArgument, kDeviceOption_Camera_DeferredOffer },
242+
{ "camera-video-device", kArgumentRequired, kDeviceOption_Camera_VideoDevice },
241243
#endif
242244
{}
243245
};
@@ -443,6 +445,9 @@ const char * sDeviceOptionHelp =
443445
"\n"
444446
" --camera-deferred-offer\n"
445447
" Indicates the delayed processing hint of the WebRTC Provider.\n"
448+
"\n"
449+
" --camera-video-device <path>\n"
450+
" Path to a V4L2 video capture device (default: /dev/video0).\n"
446451
#endif
447452
"\n";
448453

@@ -892,6 +897,10 @@ bool HandleOption(const char * aProgram, OptionSet * aOptions, int aIdentifier,
892897
LinuxDeviceOptions::GetInstance().cameraDeferredOffer = true;
893898
break;
894899
}
900+
case kDeviceOption_Camera_VideoDevice: {
901+
LinuxDeviceOptions::GetInstance().cameraVideoDevice.SetValue(aValue);
902+
break;
903+
}
895904
#endif
896905
default:
897906
PrintArgError("%s: INTERNAL ERROR: Unhandled option: %s\n", aProgram, aName);

examples/platform/linux/Options.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ struct LinuxDeviceOptions
5858
bool mWiFi = false;
5959
bool mThread = false;
6060
bool cameraDeferredOffer = false;
61+
chip::Optional<std::string> cameraVideoDevice;
6162
#if CHIP_DEVICE_CONFIG_ENABLE_WIFIPAF
6263
bool mWiFiPAF = false;
6364
const char * mWiFiPAFExtCmds = nullptr;

0 commit comments

Comments
 (0)