12 #include <linux/videodev2.h>
13 #include <../kernel-headers-5.13/audio.h>
14 #include <linux/dvb/dmx.h>
15 #include <../kernel-headers-5.13/video.h>
16 #include <sys/ioctl.h>
18 #include <vdr/eitscan.h>
19 #include <vdr/transfer.h>
45 char buffer[PATH_MAX];
46 for (
int ofs = 0; ofs < 100; ofs++) {
47 snprintf(buffer,
sizeof(buffer),
"/proc/video/dev/video%d", ofs);
48 if ((f = fopen(buffer,
"r")) != NULL) {
49 if (fgets(buffer,
sizeof(buffer), f)) {
50 if (strstr(buffer,
"DVB Board")) {
106 char buffer[PATH_MAX];
108 int videoDev = open(buffer, O_RDWR);
110 uchar *result = NULL;
113 memset(&fmt, 0,
sizeof(fmt));
114 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
115 fmt.fmt.pix.width = SizeX;
116 fmt.fmt.pix.height = SizeY;
117 fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_BGR24;
118 fmt.fmt.pix.field = V4L2_FIELD_ANY;
119 if (ioctl(videoDev, VIDIOC_S_FMT, &fmt) == 0) {
120 v4l2_requestbuffers reqBuf;
121 memset(&reqBuf, 0,
sizeof(reqBuf));
123 reqBuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
124 reqBuf.memory = V4L2_MEMORY_MMAP;
125 if (ioctl(videoDev, VIDIOC_REQBUFS, &reqBuf) >= 0) {
127 memset(&mbuf, 0,
sizeof(mbuf));
128 mbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
129 mbuf.memory = V4L2_MEMORY_MMAP;
130 if (ioctl(videoDev, VIDIOC_QUERYBUF, &mbuf) == 0) {
131 int msize = mbuf.length;
132 unsigned char *mem = (
unsigned char *)mmap(0, msize, PROT_READ | PROT_WRITE, MAP_SHARED, videoDev, 0);
133 if (mem && mem != (
unsigned char *)-1) {
135 memset(&buf, 0,
sizeof(buf));
136 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
137 buf.memory = V4L2_MEMORY_MMAP;
139 if (ioctl(videoDev, VIDIOC_QBUF, &buf) == 0) {
140 v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
141 if (ioctl (videoDev, VIDIOC_STREAMON, &type) == 0) {
142 memset(&buf, 0,
sizeof(buf));
143 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
144 buf.memory = V4L2_MEMORY_MMAP;
146 if (ioctl(videoDev, VIDIOC_DQBUF, &buf) == 0) {
147 if (ioctl(videoDev, VIDIOC_STREAMOFF, &type) == 0) {
149 int memsize = fmt.fmt.pix.width * fmt.fmt.pix.height;
150 unsigned char *mem1 = mem;
151 for (
int i = 0; i < memsize; i++) {
152 unsigned char tmp = mem1[2];
161 dsyslog(
"grabbing to %s %d %d %d", Jpeg ?
"JPEG" :
"PNM", Quality, fmt.fmt.pix.width, fmt.fmt.pix.height);
164 result =
RgbToJpeg(mem, fmt.fmt.pix.width, fmt.fmt.pix.height, Size, Quality);
166 esyslog(
"ERROR: failed to convert image to JPEG");
171 snprintf(buf,
sizeof(buf),
"P6\n%d\n%d\n255\n", fmt.fmt.pix.width, fmt.fmt.pix.height);
173 int bytes = memsize * 3;
177 memcpy(result, buf, l);
178 memcpy(result + l, mem, bytes);
181 esyslog(
"ERROR: failed to convert image to PNM");
185 esyslog(
"ERROR: video device VIDIOC_STREAMOFF failed");
188 esyslog(
"ERROR: video device VIDIOC_DQBUF failed");
191 esyslog(
"ERROR: video device VIDIOC_STREAMON failed");
194 esyslog(
"ERROR: video device VIDIOC_QBUF failed");
198 esyslog(
"ERROR: failed to memmap video device");
201 esyslog(
"ERROR: video device VIDIOC_QUERYBUF failed");
204 esyslog(
"ERROR: video device VIDIOC_REQBUFS failed");
207 esyslog(
"ERROR: video device VIDIOC_S_FMT failed");
223 switch (VideoDisplayFormat) {
233 default:
esyslog(
"ERROR: unknown video display format %d", VideoDisplayFormat);
271 if (vs.
h != 480 && vs.
h != 240)
281 PixelAspect /= double(Width) / Height;
298 static dmx_pes_type_t
PesTypes[] = { DMX_PES_AUDIO, DMX_PES_VIDEO, DMX_PES_PCR, DMX_PES_TELETEXT, DMX_PES_OTHER, DMX_PES_OTHER };
303 dmx_pes_filter_params pesFilterParams;
304 memset(&pesFilterParams, 0,
sizeof(pesFilterParams));
313 pesFilterParams.pid = Handle->
pid;
314 pesFilterParams.input = DMX_IN_FRONTEND;
315 pesFilterParams.output = (Type <=
ptTeletext && Handle->
used <= 1) ? DMX_OUT_DECODER : DMX_OUT_TS_TAP;
317 pesFilterParams.flags = DMX_IMMEDIATE_START;
318 if (ioctl(Handle->
handle, DMX_SET_PES_FILTER, &pesFilterParams) < 0) {
323 else if (!Handle->
used) {
326 pesFilterParams.pid = 0x1FFF;
327 pesFilterParams.input = DMX_IN_FRONTEND;
328 pesFilterParams.output = DMX_OUT_DECODER;
329 pesFilterParams.pes_type=
PesTypes[Type];
330 pesFilterParams.flags = DMX_IMMEDIATE_START;
331 CHECK(ioctl(Handle->
handle, DMX_SET_PES_FILTER, &pesFilterParams));
332 if (
PesTypes[Type] == DMX_PES_VIDEO)
382 int apid = Channel->
Apid(0);
383 int vpid = Channel->
Vpid();
384 int dpid = Channel->
Dpid(0);
391 bool TurnOffLivePIDs = DoTune
398 && (LiveView &&
HasPid(vpid ? vpid : apid) && (!pidHandlesVideo || (!pidHandlesAudio && (dpid ?
pidHandles[
ptAudio].
pid != dpid :
true)))
399 || !LiveView && (pidHandlesVideo || pidHandlesAudio)
404 bool TurnOnLivePIDs = !StartTransferMode && LiveView;
418 if (TurnOnLivePIDs) {
431 else if (StartTransferMode)
472 if (TrackId && TrackId->
id) {
561 default:
esyslog(
"ERROR: unknown playmode %d", PlayMode);
572 if (ioctl(
fd_stc, DMX_GET_STC, &stc) == -1) {
576 return stc.stc / stc.base;
643 if (Data[0] == 0x47) {
647 else if (Data[0] == 0x00 && Data[1] == 0x00 && Data[2] == 0x01 && (Data[3] & 0xF0) == 0xE0) {
649 char *buf =
MALLOC(
char, Length);
654 while (i < Length - 6) {
655 if (Data[i] == 0x00 && Data[i + 1] == 0x00 && Data[i + 2] == 0x01) {
656 int len = Data[i + 4] * 256 + Data[i + 5];
657 if ((Data[i + 3] & 0xF0) == 0xE0) {
661 if ((Data[i + 6] & 0xC0) == 0x80) {
663 if (Data[i + 8] >= Length)
669 if (len < 0 || offs + len > Length)
674 while (offs < Length && len > 0 && Data[offs] == 0xFF) {
678 if (offs <= Length - 2 && len >= 2 && (Data[offs] & 0xC0) == 0x40) {
682 if (offs <= Length - 5 && len >= 5 && (Data[offs] & 0xF0) == 0x20) {
686 else if (offs <= Length - 10 && len >= 10 && (Data[offs] & 0xF0) == 0x30) {
690 else if (offs < Length && len > 0) {
695 if (blen + len > Length)
697 memcpy(&buf[blen], &Data[offs], len);
701 else if (Data[i + 3] >= 0xBD && Data[i + 3] <= 0xDF)
723 return Poller.
Poll(TimeoutMs);
761 static uint32_t SubsystemIds[] = {
776 for (uint32_t *sid = SubsystemIds; *sid; sid++) {
777 if (*sid == SubsystemId) {
778 dsyslog(
"creating cDvbSdFfDevice");
cChannelCamRelations ChannelCamRelations
virtual void SetPid(int Pid, bool Active)
Sets the given Pid (which has previously been added through a call to AddPid()) to Active.
virtual void StartDecrypting(void)
Sends all CA_PMT entries to the CAM that have been modified since the last call to this function.
int SlotNumber(void)
Returns the number of this CAM slot within the whole system.
bool CamDecrypt(tChannelID ChannelID, int CamSlotNumber)
tChannelID GetChannelID(void) const
int Ca(int Index=0) const
static void SleepMs(int TimeoutMs)
Creates a cCondWait object and uses it to sleep for TimeoutMs milliseconds, immediately giving up the...
static void Launch(cControl *Control)
bool IsPrimaryDevice(void) const
virtual void GetVideoSize(int &Width, int &Height, double &VideoAspect)
Returns the Width, Height and VideoAspect ratio of the currently displayed video material.
bool HasPid(int Pid) const
Returns true if this device is currently receiving the given PID.
void DelPid(int Pid, ePidType PidType=ptOther)
Deletes a PID from the set of PIDs this device shall receive.
virtual void MakePrimaryDevice(bool On)
Informs a device that it will be the primary device.
void DetachAll(int Pid)
Detaches all receivers from this device for this pid.
virtual void Play(void)
Sets the device into play mode (after a previous trick mode).
cPidHandle pidHandles[MAXPIDHANDLES]
const tTrackId * GetTrack(eTrackType Type)
Returns a pointer to the given track id, or NULL if Type is not less than ttMaxTrackTypes.
virtual void Mute(void)
Turns off audio while replaying.
virtual void Freeze(void)
Puts the device into "freeze frame" mode.
virtual void SetVideoDisplayFormat(eVideoDisplayFormat VideoDisplayFormat)
Sets the video display format to the given one (only useful if this device has an MPEG decoder).
static int CurrentVolume(void)
virtual bool CanReplay(void) const
Returns true if this device can currently start a replay session.
virtual void GetOsdSize(int &Width, int &Height, double &PixelAspect)
Returns the Width, Height and PixelAspect ratio the OSD should use to best fit the resolution of the ...
virtual void Clear(void)
Clears all video and audio data from the device.
int CardIndex(void) const
Returns the card index of this device (0 ... MAXDEVICES - 1).
bool AddPid(int Pid, ePidType PidType=ptOther, int StreamType=0)
Adds a PID to the set of PIDs this device shall receive.
void ForceTransferMode(void)
Forces the device into transfermode for the current channel.
cCamSlot * CamSlot(void) const
Returns the CAM slot that is currently used with this device, or NULL if no CAM slot is in use.
virtual void StillPicture(const uchar *Data, int Length)
Displays the given I-frame as a still picture.
static uint32_t GetSubsystemId(int Adapter, int Frontend)
The cDvbDevice implements a DVB device which can be accessed through the Linux DVB driver API.
virtual bool IsTunedToTransponder(const cChannel *Channel) const
Returns true if this device is currently tuned to the given Channel's transponder.
virtual int NumProvidedSystems(void) const
Returns the number of individual "delivery systems" this device provides.
virtual bool SetChannelDevice(const cChannel *Channel, bool LiveView)
Sets the device to the given channel (actual physical setup).
static int setTransferModeForDolbyDigital
virtual bool ProvidesSource(int Source) const
Returns true if this device can provide the given source.
virtual bool Probe(int Adapter, int Frontend)
Probes for a DVB device at the given Adapter and creates the appropriate object derived from cDvbDevi...
cDvbSdFfDeviceProbe(void)
The cDvbSdFfDevice implements a DVB device which can be accessed through the Linux DVB driver API.
virtual void SetVolumeDevice(int Volume)
Sets the audio volume on this device (Volume = 0...255).
void TurnOffLiveMode(bool LiveView)
virtual void SetDigitalAudioDevice(bool On)
Tells the output device that the current audio track is Dolby Digital.
virtual void Clear(void)
Clears all video and audio data from the device.
virtual void Freeze(void)
Puts the device into "freeze frame" mode.
virtual void Play(void)
Sets the device into play mode (after a previous trick mode).
virtual uchar * GrabImage(int &Size, bool Jpeg=true, int Quality=-1, int SizeX=-1, int SizeY=-1)
Grabs the currently visible screen image.
virtual void GetVideoSize(int &Width, int &Height, double &VideoAspect)
Returns the Width, Height and VideoAspect ratio of the currently displayed video material.
virtual int64_t GetSTC(void)
Gets the current System Time Counter, which can be used to synchronize audio, video and subtitles.
virtual bool CanReplay(void) const
Returns true if this device can currently start a replay session.
virtual void SetVideoFormat(bool VideoFormat16_9)
Sets the output video format to either 16:9 or 4:3 (only useful if this device has an MPEG decoder).
virtual int PlayTsAudio(const uchar *Data, int Length)
Plays the given data block as audio.
virtual bool ProvidesSource(int Source) const
Returns true if this device can provide the given source.
virtual void SetVideoDisplayFormat(eVideoDisplayFormat VideoDisplayFormat)
Sets the video display format to the given one (only useful if this device has an MPEG decoder).
virtual cSpuDecoder * GetSpuDecoder(void)
Returns a pointer to the device's SPU decoder (or NULL, if this device doesn't have an SPU decoder).
virtual void MakePrimaryDevice(bool On)
Informs a device that it will be the primary device.
virtual int NumProvidedSystems(void) const
Returns the number of individual "delivery systems" this device provides.
virtual bool SetPid(cPidHandle *Handle, int Type, bool On)
Does the actual PID setting on this device.
virtual bool Poll(cPoller &Poller, int TimeoutMs=0)
Returns true if the device itself or any of the file handles in Poller is ready for further action.
virtual void SetAudioTrackDevice(eTrackType Type)
Sets the current audio track to the given value.
cDvbSpuDecoder * spuDecoder
virtual void Mute(void)
Turns off audio while replaying.
virtual void TrickSpeed(int Speed, bool Forward)
Sets the device into a mode where replay is done slower.
virtual bool AvoidRecording(void) const
Returns true if this device should only be used for recording if no other device is available.
virtual void StillPicture(const uchar *Data, int Length)
Displays the given I-frame as a still picture.
virtual int GetAudioChannelDevice(void)
Gets the current audio channel, which is stereo (0), mono left (1) or mono right (2).
virtual int PlayTsVideo(const uchar *Data, int Length)
Plays the given data block as video.
virtual int PlayAudio(const uchar *Data, int Length, uchar Id)
Plays the given data block as audio.
virtual ~cDvbSdFfDevice()
virtual bool SetPlayMode(ePlayMode PlayMode)
Sets the device into the given play mode.
bool SetAudioBypass(bool On)
virtual bool Flush(int TimeoutMs=0)
Returns true if the device's output buffers are empty, i.
virtual bool HasDecoder(void) const
Tells whether this device has an MPEG decoder.
static int devVideoOffset
virtual void SetAudioChannelDevice(int AudioChannel)
Sets the audio channel to stereo (0), mono left (1) or mono right (2).
virtual int PlayVideo(const uchar *Data, int Length)
Plays the given data block as video.
cDvbSdFfDevice(int Adapter, int Frontend, bool OutputOnly)
virtual bool SetChannelDevice(const cChannel *Channel, bool LiveView)
Sets the device to the given channel (actual physical setup).
virtual void GetOsdSize(int &Width, int &Height, double &PixelAspect)
Returns the Width, Height and PixelAspect ratio the OSD should use to best fit the resolution of the ...
bool Add(int FileHandle, bool Out)
bool Poll(int TimeoutMs=0)
@ pmExtern_THIS_SHOULD_BE_AVOIDED
#define IS_AUDIO_TRACK(t)
#define IS_DOLBY_TRACK(t)
int DvbOpen(const char *Name, int Adapter, int Frontend, int Mode, bool ReportError)
static dmx_pes_type_t PesTypes[]
unsigned int volume_right
audio_channel_select_t channel_select
video_format_t aspect_ratio
#define VIDEO_SET_DISPLAY_FORMAT
#define VIDEO_SELECT_SOURCE
#define VIDEO_STILLPICTURE
#define VIDEO_CLEAR_BUFFER