12 #include <linux/videodev2.h> 13 #include <linux/dvb/audio.h> 14 #include <linux/dvb/dmx.h> 15 #include <linux/dvb/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");
220 CHECK(ioctl(
fd_video, VIDEO_SET_DISPLAY_FORMAT, VIDEO_LETTER_BOX));
223 switch (VideoDisplayFormat) {
225 CHECK(ioctl(
fd_video, VIDEO_SET_DISPLAY_FORMAT, VIDEO_PAN_SCAN));
228 CHECK(ioctl(
fd_video, VIDEO_SET_DISPLAY_FORMAT, VIDEO_LETTER_BOX));
231 CHECK(ioctl(
fd_video, VIDEO_SET_DISPLAY_FORMAT, VIDEO_CENTER_CUT_OUT));
233 default:
esyslog(
"ERROR: unknown video display format %d", VideoDisplayFormat);
240 CHECK(ioctl(
fd_video, VIDEO_SET_FORMAT, VideoFormat16_9 ? VIDEO_FORMAT_16_9 : VIDEO_FORMAT_4_3));
248 if (ioctl(
fd_video, VIDEO_GET_SIZE, &vs) == 0) {
251 switch (vs.aspect_ratio) {
253 case VIDEO_FORMAT_4_3: VideoAspect = 4.0 / 3.0;
break;
254 case VIDEO_FORMAT_16_9: VideoAspect = 16.0 / 9.0;
break;
255 case VIDEO_FORMAT_221_1: VideoAspect = 2.21;
break;
269 if (ioctl(
fd_video, VIDEO_GET_SIZE, &vs) == 0) {
271 if (vs.h != 480 && vs.h != 240)
277 case VIDEO_FORMAT_4_3: PixelAspect = 4.0 / 3.0;
break;
278 case VIDEO_FORMAT_221_1:
279 case VIDEO_FORMAT_16_9: PixelAspect = 16.0 / 9.0;
break;
281 PixelAspect /= double(Width) / Height;
294 return ioctl(
fd_audio, AUDIO_SET_BYPASS_MODE, On) == 0;
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)
441 return as.channel_select;
455 am.volume_left = am.volume_right = 2 * Volume - Volume * Volume / 255;
472 if (TrackId && TrackId->
id) {
514 CHECK(ioctl(
fd_video, VIDEO_SELECT_SOURCE, VIDEO_SOURCE_MEMORY));
521 CHECK(ioctl(
fd_video, VIDEO_SELECT_SOURCE, VIDEO_SOURCE_DEMUX));
522 CHECK(ioctl(
fd_audio, AUDIO_SELECT_SOURCE, AUDIO_SOURCE_DEMUX));
531 CHECK(ioctl(
fd_audio, AUDIO_SELECT_SOURCE, AUDIO_SOURCE_MEMORY));
534 CHECK(ioctl(
fd_video, VIDEO_SELECT_SOURCE, VIDEO_SOURCE_MEMORY));
541 CHECK(ioctl(
fd_audio, AUDIO_SELECT_SOURCE, AUDIO_SOURCE_MEMORY));
549 CHECK(ioctl(
fd_audio, AUDIO_SELECT_SOURCE, AUDIO_SOURCE_DEMUX));
553 CHECK(ioctl(
fd_video, VIDEO_SELECT_SOURCE, VIDEO_SOURCE_MEMORY));
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)
709 video_still_picture sp = { buf, blen };
715 video_still_picture sp = { (
char *)Data, Length };
723 return Poller.
Poll(TimeoutMs);
761 static uint32_t SubsystemIds[] = {
775 uint32_t SubsystemId = GetSubsystemId(Adapter, Frontend);
776 for (uint32_t *sid = SubsystemIds; *sid; sid++) {
777 if (*sid == SubsystemId) {
778 dsyslog(
"creating cDvbSdFfDevice");
virtual void Clear(void)
Clears all video and audio data from the device.
virtual bool ProvidesSource(int Source) const
Returns true if this device can provide the given source.
virtual void SetAudioTrackDevice(eTrackType Type)
Sets the current audio track to the given value.
virtual bool IsTunedToTransponder(const cChannel *Channel) const
Returns true if this device is currently tuned to the given Channel's transponder.
void DetachAll(int Pid)
Detaches all receivers from this device for this pid.
virtual int PlayTsAudio(const uchar *Data, int Length)
Plays the given data block as audio.
int Ca(int Index=0) const
virtual void SetVolumeDevice(int Volume)
Sets the audio volume on this device (Volume = 0...255).
virtual void StartDecrypting(void)
Triggers sending all currently active CA_PMT entries to the CAM, so that it will start decrypting...
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 PlayTsVideo(const uchar *Data, int Length)
Plays the given data block as video.
virtual void GetVideoSize(int &Width, int &Height, double &VideoAspect)
Returns the Width, Height and VideoAspect ratio of the currently displayed video material.
virtual void Freeze(void)
Puts the device into "freeze frame" mode.
virtual bool CanReplay(void) const
Returns true if this device can currently start a replay session.
virtual void TrickSpeed(int Speed, bool Forward)
Sets the device into a mode where replay is done slower.
bool Add(int FileHandle, bool Out)
virtual void MakePrimaryDevice(bool On)
Informs a device that it will be the primary device.
virtual ~cDvbSdFfDevice()
virtual void SetVideoDisplayFormat(eVideoDisplayFormat VideoDisplayFormat)
Sets the video display format to the given one (only useful if this device has an MPEG decoder)...
virtual bool SetChannelDevice(const cChannel *Channel, bool LiveView)
Sets the device to the given channel (actual physical setup).
void DelPid(int Pid, ePidType PidType=ptOther)
Deletes a PID from the set of PIDs this device shall receive.
virtual int PlayAudio(const uchar *Data, int Length, uchar Id)
Plays the given data block as audio.
virtual void Mute(void)
Turns off audio while replaying.
virtual void Play(void)
Sets the device into play mode (after a previous trick mode).
virtual bool AvoidRecording(void) const
Returns true if this device should only be used for recording if no other device is available...
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.
cDvbSpuDecoder * spuDecoder
virtual int64_t GetSTC(void)
Gets the current System Time Counter, which can be used to synchronize audio, video and subtitles...
virtual void MakePrimaryDevice(bool On)
Informs a device that it will be the primary device.
bool Poll(int TimeoutMs=0)
virtual bool ProvidesSource(int Source) const
Returns true if this device can provide the given source.
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 Play(void)
Sets the device into play mode (after a previous trick mode).
virtual void Mute(void)
Turns off audio while replaying.
virtual bool HasDecoder(void) const
Tells whether this device has an MPEG decoder.
virtual void SetDigitalAudioDevice(bool On)
Tells the output device that the current audio track is Dolby Digital.
virtual bool SetChannelDevice(const cChannel *Channel, bool LiveView)
Sets the device to the given channel (actual physical setup).
virtual void SetAudioChannelDevice(int AudioChannel)
Sets the audio channel to stereo (0), mono left (1) or mono right (2).
static int CurrentVolume(void)
bool IsPrimaryDevice(void) const
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 Freeze(void)
Puts the device into "freeze frame" mode.
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 int NumProvidedSystems(void) const
Returns the number of individual "delivery systems" this device provides.
virtual bool Probe(int Adapter, int Frontend)
Probes for a DVB device at the given Adapter and creates the appropriate object derived from cDvbDevi...
static void SleepMs(int TimeoutMs)
Creates a cCondWait object and uses it to sleep for TimeoutMs milliseconds, immediately giving up the...
virtual void StillPicture(const uchar *Data, int Length)
Displays the given I-frame as a still picture.
#define IS_AUDIO_TRACK(t)
bool SetAudioBypass(bool On)
bool CamDecrypt(tChannelID ChannelID, int CamSlotNumber)
virtual cSpuDecoder * GetSpuDecoder(void)
Returns a pointer to the device's SPU decoder (or NULL, if this device doesn't have an SPU decoder)...
tChannelID GetChannelID(void) const
virtual bool Flush(int TimeoutMs=0)
Returns true if the device's output buffers are empty, i.
static void Launch(cControl *Control)
cDvbSdFfDevice(int Adapter, int Frontend, bool OutputOnly)
static dmx_pes_type_t PesTypes[]
int CardIndex(void) const
Returns the card index of this device (0 ... MAXDEVICES - 1).
virtual int NumProvidedSystems(void) const
Returns the number of individual "delivery systems" this device provides.
virtual void SetPid(int Pid, bool Active)
Sets the given Pid (which has previously been added through a call to AddPid()) to Active...
virtual int PlayVideo(const uchar *Data, int Length)
Plays the given data block as video.
static int setTransferModeForDolbyDigital
void TurnOffLiveMode(bool LiveView)
const tTrackId * GetTrack(eTrackType Type)
Returns a pointer to the given track id, or NULL if Type is not less than ttMaxTrackTypes.
cChannelCamRelations ChannelCamRelations
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 SetVideoDisplayFormat(eVideoDisplayFormat VideoDisplayFormat)
Sets the video display format to the given one (only useful if this device has an MPEG decoder)...
The cDvbDevice implements a DVB device which can be accessed through the Linux DVB driver API...
virtual bool CanReplay(void) const
Returns true if this device can currently start a replay session.
static int devVideoOffset
bool HasPid(int Pid) const
Returns true if this device is currently receiving the given PID.
virtual bool SetPid(cPidHandle *Handle, int Type, bool On)
Does the actual PID setting on this device.
void ForceTransferMode(void)
Forces the device into transfermode for the current channel.
#define IS_DOLBY_TRACK(t)
cDvbSdFfDeviceProbe(void)
virtual bool SetPlayMode(ePlayMode PlayMode)
Sets the device into the given play mode.
virtual void StillPicture(const uchar *Data, int Length)
Displays the given I-frame as a still picture.
virtual void GetVideoSize(int &Width, int &Height, double &VideoAspect)
Returns the Width, Height and VideoAspect ratio of the currently displayed video material.
cPidHandle pidHandles[MAXPIDHANDLES]
bool AddPid(int Pid, ePidType PidType=ptOther, int StreamType=0)
Adds a PID to the set of PIDs this device shall receive.
int SlotNumber(void)
Returns the number of this CAM slot within the whole system.
virtual int GetAudioChannelDevice(void)
Gets the current audio channel, which is stereo (0), mono left (1) or mono right (2).
static int DvbOpen(const char *Name, int Adapter, int Frontend, int Mode, bool ReportError=false)