13 #include <linux/videodev2.h> 14 #include <linux/dvb/audio.h> 15 #include <linux/dvb/dmx.h> 16 #include <linux/dvb/video.h> 17 #include <sys/ioctl.h> 19 #include <vdr/eitscan.h> 20 #include <vdr/transfer.h> 61 if (firmwareVersion < 0x401)
78 ioctl(
fd_video, VIDEO_SELECT_SOURCE, VIDEO_SOURCE_DEMUX);
91 memset(&hdmiConfig, 0,
sizeof(hdmiConfig));
139 #define BUFFER_SIZE (sizeof(struct v4l2_pix_format) + 1920 * 1080 * 2) 142 uint8_t * result = NULL;
146 esyslog(
"GrabImage: failed open DVB video device");
156 if (readBytes < (
int)
sizeof(
struct v4l2_pix_format))
157 esyslog(
"GrabImage: failed reading from DVB video device");
159 struct v4l2_pix_format * pixfmt;
162 pixfmt = (
struct v4l2_pix_format *) buffer;
163 dsyslog(
"GrabImage: Read image of size %d x %d",
164 pixfmt->width, pixfmt->height);
165 dataSize = readBytes -
sizeof(
struct v4l2_pix_format);
166 if (dataSize < (
int) pixfmt->sizeimage)
167 esyslog(
"GrabImage: image is not complete");
171 temp = (uint8_t *) malloc(pixfmt->width * 3 * pixfmt->height);
173 int numPixels = pixfmt->width * pixfmt->height;
174 uint8_t * destData = temp;
175 uint8_t * srcData = buffer +
sizeof(
struct v4l2_pix_format);
176 while (numPixels > 0)
178 destData[0] = srcData[1];
179 destData[1] = srcData[0];
180 destData[2] = srcData[2];
181 destData[3] = srcData[3];
182 destData[4] = srcData[0];
183 destData[5] = srcData[2];
190 result =
YuvToJpeg(temp, pixfmt->width, pixfmt->height, Size, Quality);
197 snprintf(buf,
sizeof(buf),
"P6\n%d\n%d\n255\n",
198 pixfmt->width, pixfmt->height);
200 Size = l + pixfmt->width * 3 * pixfmt->height;
201 result = (uint8_t *) malloc(Size);
204 memcpy(result, buf, l);
205 uint8_t * destData = result + l;
206 uint8_t * srcData = buffer +
sizeof(
struct v4l2_pix_format);
207 int numPixels = pixfmt->width * pixfmt->height;
208 while (numPixels > 0)
210 int cb = srcData[0] - 128;
212 int cr = srcData[2] - 128;
218 r = y1 + (int) (1.402f * cr);
219 g = y1 - (int) (0.344f * cb + 0.714f * cr);
220 b = y1 + (int) (1.772f * cb);
221 destData[0] = r > 255 ? 255 : r < 0 ? 0 : r;
222 destData[1] = g > 255 ? 255 : g < 0 ? 0 : g;
223 destData[2] = b > 255 ? 255 : b < 0 ? 0 : b;
224 r = y2 + (int) (1.402f * cr);
225 g = y2 - (int) (0.344f * cb + 0.714f * cr);
226 b = y2 + (int) (1.772f * cb);
227 destData[3] = r > 255 ? 255 : r < 0 ? 0 : r;
228 destData[4] = g > 255 ? 255 : g < 0 ? 0 : g;
229 destData[5] = b > 255 ? 255 : b < 0 ? 0 : b;
251 switch (VideoDisplayFormat)
271 if (ioctl(
fd_video, VIDEO_GET_SIZE, &vs) == 0) {
274 switch (vs.aspect_ratio) {
276 case VIDEO_FORMAT_4_3: VideoAspect = 4.0 / 3.0;
break;
277 case VIDEO_FORMAT_16_9: VideoAspect = 16.0 / 9.0;
break;
278 case VIDEO_FORMAT_221_1: VideoAspect = 2.21;
break;
297 dmx_pes_filter_params pesFilterParams;
298 memset(&pesFilterParams, 0,
sizeof(pesFilterParams));
331 if (!(Type <= ptDolby && Handle->used <= 1)) {
332 pesFilterParams.pid = Handle->
pid;
333 pesFilterParams.input = DMX_IN_FRONTEND;
334 pesFilterParams.output = DMX_OUT_TS_TAP;
335 pesFilterParams.pes_type= DMX_PES_OTHER;
336 pesFilterParams.flags = DMX_IMMEDIATE_START;
337 if (ioctl(Handle->
handle, DMX_SET_PES_FILTER, &pesFilterParams) < 0) {
343 else if (!Handle->
used) {
392 int apid = Channel->
Apid(0);
393 int vpid = Channel->
Vpid();
394 int dpid = Channel->
Dpid(0);
401 bool TurnOffLivePIDs = DoTune
408 && (LiveView &&
HasPid(vpid ? vpid : apid) && (!pidHandlesVideo || (!pidHandlesAudio && (dpid ?
pidHandles[
ptAudio].
pid != dpid :
true)))
409 || !LiveView && (pidHandlesVideo || pidHandlesAudio)
416 bool TurnOnLivePIDs = !StartTransferMode && LiveView;
430 if (TurnOnLivePIDs) {
436 else if (StartTransferMode)
462 if (TrackId && TrackId->
id) {
464 #if (APIVERSNUM >= 20301) 513 ioctl(
fd_video, VIDEO_SELECT_SOURCE, VIDEO_SOURCE_DEMUX);
548 ioctl(
fd_video, VIDEO_SELECT_SOURCE, VIDEO_SOURCE_MEMORY);
561 if (ioctl(
fd_video, VIDEO_GET_PTS, &pts) == -1) {
601 double osdPixelAspect;
603 GetOsdSize(osdWidth, osdHeight, osdPixelAspect);
608 int x = (Rect.
X() * 1000 + osdWidth / 2) / osdWidth;
609 int y = (Rect.
Y() * 1000 + osdHeight / 2) / osdHeight;
610 int w = (Rect.
Width() * 1000 + osdWidth / 2) / osdWidth;
611 int h = (Rect.
Height() * 1000 + osdHeight / 2) / osdHeight;
629 #if (APIVERSNUM >= 20103) 636 mHdffCmdIf->CmdAvEnableSync(0,
false);
640 mHdffCmdIf->CmdAvSetVideoSpeed(0, 100 / Speed);
694 if (Data[0] == 0x47) {
698 else if (Data[0] == 0x00 && Data[1] == 0x00 && Data[2] == 0x01 && (Data[3] & 0xF0) == 0xE0) {
700 char *buf =
MALLOC(
char, Length);
705 while (i < Length - 6) {
706 if (Data[i] == 0x00 && Data[i + 1] == 0x00 && Data[i + 2] == 0x01) {
707 int len = Data[i + 4] * 256 + Data[i + 5];
708 if ((Data[i + 3] & 0xF0) == 0xE0) {
712 if ((Data[i + 6] & 0xC0) == 0x80) {
714 if (Data[i + 8] >= Length)
720 if (len < 0 || offs + len > Length)
725 while (offs < Length && len > 0 && Data[offs] == 0xFF) {
729 if (offs <= Length - 2 && len >= 2 && (Data[offs] & 0xC0) == 0x40) {
733 if (offs <= Length - 5 && len >= 5 && (Data[offs] & 0xF0) == 0x20) {
737 else if (offs <= Length - 10 && len >= 10 && (Data[offs] & 0xF0) == 0x30) {
741 else if (offs < Length && len > 0) {
746 if (blen + len > Length)
748 memcpy(&buf[blen], &Data[offs], len);
752 else if (Data[i + 3] >= 0xBD && Data[i + 3] <= 0xDF)
772 return Poller.
Poll(TimeoutMs);
784 TsBuffer[1] = PusiSet ? 0x40 : 0x00;
785 TsBuffer[1] |= Pid >> 8;
786 TsBuffer[2] = Pid & 0xFF;
789 TsBuffer[3] = 0x10 | Counter;
790 memcpy(TsBuffer + 4, Data, 184);
794 uint8_t adaptationLength;
796 TsBuffer[3] = 0x30 | Counter;
797 adaptationLength = 183 - Length;
798 TsBuffer[4] = adaptationLength;
799 if (adaptationLength > 0)
802 memset(TsBuffer + 6, 0xFF, adaptationLength - 1);
804 memcpy(TsBuffer + 5 + adaptationLength, Data, Length);
817 BuildTsPacket(TsBuffer + tsOffset, i == 0, Pid, Counter, Data + i * 184, Length);
822 Counter = (Counter + 1) & 15;
871 if (streamId >= 0xC0 && streamId <= 0xDF)
875 else if (streamId == 0xBD)
877 const uint8_t * payload = Data + 9 + Data[8];
878 if ((payload[0] & 0xF8) == 0xA0)
883 else if ((payload[0] & 0xF8) == 0x88)
888 else if ((payload[0] & 0xF8) == 0x80)
898 pid = 200 + (int) streamType;
920 int pid =
TsPid(Data);
956 int pid =
TsPid(Data);
959 int AudioStreamType = -1;
966 if (AudioStreamType < 0) {
985 return device->mHdffCmdIf;
999 static uint32_t SubsystemIds[] = {
1007 uint32_t SubsystemId = 0;
1008 FileName =
cString::sprintf(
"/sys/class/dvb/dvb%d.frontend%d/device/subsystem_vendor", Adapter, Frontend);
1009 if ((f = fopen(FileName,
"r")) != NULL) {
1010 if (
char *s = ReadLine.
Read(f))
1011 SubsystemId = strtoul(s, NULL, 0) << 16;
1014 FileName =
cString::sprintf(
"/sys/class/dvb/dvb%d.frontend%d/device/subsystem_device", Adapter, Frontend);
1015 if ((f = fopen(FileName,
"r")) != NULL) {
1016 if (
char *s = ReadLine.
Read(f))
1017 SubsystemId |= strtoul(s, NULL, 0);
1020 for (uint32_t *sid = SubsystemIds; *sid; sid++) {
1021 if (*sid == SubsystemId) {
1023 int fd = open(FileName, O_RDWR);
1031 dsyslog(
"cDvbHdFfDevice 2nd tuner disabled (outputonly)");
1042 #include <jpeglib.h> 1044 #define JPEGCOMPRESSMEM 4000000 1064 int Used = jcd->
size;
1066 if (
uchar *NewBuffer = (
uchar *)realloc(jcd->
mem, NewSize)) {
1067 jcd->
size = NewSize;
1068 jcd->
mem = NewBuffer;
1071 esyslog(
"ERROR: out of memory");
1075 cinfo->dest->next_output_byte = jcd->
mem + Used;
1076 cinfo->dest->free_in_buffer = jcd->
size - Used;
1087 int Used = cinfo->dest->next_output_byte - jcd->
mem;
1088 if (Used < jcd->size) {
1091 jcd->
mem = NewBuffer;
1094 esyslog(
"ERROR: out of memory");
1103 else if (Quality > 100)
1106 jpeg_destination_mgr jdm;
1112 struct jpeg_compress_struct cinfo;
1113 struct jpeg_error_mgr jerr;
1114 cinfo.err = jpeg_std_error(&jerr);
1115 jpeg_create_compress(&cinfo);
1118 cinfo.client_data = &jcd;
1119 cinfo.image_width = Width;
1120 cinfo.image_height = Height;
1121 cinfo.input_components = 3;
1122 cinfo.in_color_space = JCS_YCbCr;
1124 jpeg_set_defaults(&cinfo);
1125 jpeg_set_quality(&cinfo, Quality,
true);
1126 jpeg_start_compress(&cinfo,
true);
1129 JSAMPROW rp[Height];
1130 for (
int k = 0; k < Height; k++)
1131 rp[k] = &Mem[rs * k];
1132 jpeg_write_scanlines(&cinfo, rp, Height);
1133 jpeg_finish_compress(&cinfo);
1134 jpeg_destroy_compress(&cinfo);
virtual void MakePrimaryDevice(bool On)
Informs a device that it will be the primary device.
virtual int PlayTsVideo(const uchar *Data, int Length)
Plays the given data block as video.
void CmdAvSetDecoderInput(uint8_t DecoderIndex, uint8_t DemultiplexerIndex)
virtual bool ProvidesSource(int Source) const
Returns true if this device can provide the given source.
void CmdMuxSetVolume(uint8_t Volume)
virtual cRect CanScaleVideo(const cRect &Rect, int Alignment=taCenter)
Asks the output device whether it can scale the currently shown video in such a way that it fits into...
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 int64_t GetSTC(void)
Gets the current System Time Counter, which can be used to synchronize audio, video and subtitles...
virtual void StillPicture(const uchar *Data, int Length)
Displays the given I-frame as a still picture.
static cDevice * ReceiverDevice(void)
void DetachAll(int Pid)
Detaches all receivers from this device for this pid.
virtual int NumProvidedSystems(void) const
Returns the number of individual "delivery systems" this device provides.
void CmdRemoteSetAddressFilter(bool Enable, uint32_t Address)
cTSBuffer * tsBuffer
< Controls how the DVB device handles Transfer Mode when replaying Dolby Digital audio.
virtual void StartDecrypting(void)
Sends all CA_PMT entries to the CAM that have been modified since the last call to this function...
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.
virtual void TrickSpeed(int Speed)
HdffVideoModeAdaption_t VideoModeAdaption
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 ...
static cString sprintf(const char *fmt,...) __attribute__((format(printf
void CmdAvSetPlayMode(uint8_t PlayMode, bool Realtime)
virtual void Freeze(void)
Puts the device into "freeze frame" mode.
bool Add(int FileHandle, bool Out)
virtual void MakePrimaryDevice(bool On)
Informs a device that it will be the primary device.
virtual int GetAudioChannelDevice(void)
Gets the current audio channel, which is stereo (0), mono left (1) or mono right (2).
static void JpegCompressTermDestination(j_compress_ptr cinfo)
virtual void SetVideoDisplayFormat(eVideoDisplayFormat VideoDisplayFormat)
Sets the video display format to the given one (only useful if this device has an MPEG decoder)...
static cDevice * GetDevice(int Index)
Gets the device with the given Index.
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.
void CmdAvSetAudioPid(uint8_t DecoderIndex, uint16_t AudioPid, HdffAudioStreamType_t StreamType, HdffAvContainerType_t ContainerType=HDFF_AV_CONTAINER_PES)
virtual void Play(void)
Sets the device into play mode (after a previous trick mode).
virtual void Clear(void)
Clears all video and audio data from the device.
virtual void ScaleVideo(const cRect &Rect=cRect::Null)
Scales the currently shown video in such a way that it fits into the given Rect.
virtual int PlayVideo(const uchar *Data, int Length)
Plays the given data block as video.
virtual void Clear(void)
Clears all video and audio data from the device.
void CmdAvShowStillImage(uint8_t DecoderIndex, const uint8_t *pStillImage, int Size, HdffVideoStreamType_t StreamType)
int Ca(int Index=0) const
static HdffAudioStreamType_t MapAudioStreamTypes(int Atype)
virtual bool HasDecoder(void) const
Tells whether this device has an MPEG decoder.
static boolean JpegCompressEmptyOutputBuffer(j_compress_ptr cinfo)
virtual void Play(void)
Sets the device into play mode (after a previous trick mode).
cDvbHdFfDevice(int Adapter, int Frontend, bool OutputOnly)
bool Poll(int TimeoutMs=0)
virtual void Mute(void)
Turns off audio while replaying.
virtual int NumProvidedSystems(void) const
Returns the number of individual "delivery systems" this device provides.
void CmdHdmiSetVideoMode(HdffVideoMode_t VideoMode)
void CmdAvSetVideoPid(uint8_t DecoderIndex, uint16_t VideoPid, HdffVideoStreamType_t StreamType, bool PlaybackMode=false)
void CmdAvEnableVideoAfterStop(uint8_t DecoderIndex, bool EnableVideoAfterStop)
int TsPid(const uchar *p)
void CmdAvSetAudioDelay(int16_t Delay)
virtual void SetVideoDisplayFormat(eVideoDisplayFormat VideoDisplayFormat)
Sets the video display format to the given one (only useful if this device has an MPEG decoder)...
virtual void Freeze(void)
Puts the device into "freeze frame" mode.
HdffVideoMode_t GetVideoMode(void)
uint32_t PesToTs(uint8_t *TsBuffer, uint16_t Pid, uint8_t &Counter, const uint8_t *Data, uint32_t Length)
static int CurrentChannel(void)
Returns the number of the current channel on the primary device.
void StopSectionHandler(void)
A device that has called StartSectionHandler() must call this function (typically in its destructor) ...
static void JpegCompressInitDestination(j_compress_ptr cinfo)
void CmdHdmiConfigure(const HdffHdmiConfig_t *pConfig)
uint32_t CmdGetFirmwareVersion(char *pString, uint32_t MaxLength)
HDFF::cHdffCmdIf * mHdffCmdIf
#define LOCK_CHANNELS_READ
virtual bool CanReplay(void) const
Returns true if this device can currently start a replay session.
virtual bool SetChannelDevice(const cChannel *Channel, bool LiveView)
Sets the device to the given channel (actual physical setup).
virtual bool IsTunedToTransponder(const cChannel *Channel) const
Returns true if this device is currently tuned to the given Channel's transponder.
void BuildTsPacket(uint8_t *TsBuffer, bool PusiSet, uint16_t Pid, uint8_t Counter, const uint8_t *Data, uint32_t Length)
void CmdAvSetSyncShift(int16_t SyncShift)
virtual ~cDvbHdFfDevice()
virtual bool SetPlayMode(ePlayMode PlayMode)
Sets the device into the given play mode.
#define IS_AUDIO_TRACK(t)
virtual int PlayTsAudio(const uchar *Data, int Length)
Plays the given data block as audio.
bool CamDecrypt(tChannelID ChannelID, int CamSlotNumber)
int DvbOpen(const char *Name, int Adapter, int Frontend, int Mode, bool ReportError)
virtual int PlayAudio(const uchar *Data, int Length, uchar Id)
Plays the given data block as audio.
virtual void GetVideoSize(int &Width, int &Height, double &VideoAspect)
Returns the Width, Height and VideoAspect ratio of the currently displayed video material.
int CardIndex(void) const
Returns the card index of this device (0 ... MAXDEVICES - 1).
static void Launch(cControl *Control)
void GetOsdSize(int &Width, int &Height, double &PixelAspect)
void CmdAvSetAudioChannel(uint8_t AudioChannel)
virtual bool Flush(int TimeoutMs=0)
Returns true if the device's output buffers are empty, i.
virtual void SetPid(int Pid, bool Active)
Sets the given Pid (which has previously been added through a call to AddPid()) to Active...
void CmdRemoteSetProtocol(HdffRemoteProtocol_t Protocol)
bool supportsPcrInTransferMode
cDvbSpuDecoder * spuDecoder
void CmdAvSetVideoWindow(uint8_t DecoderIndex, bool Enable, uint16_t X, uint16_t Y, uint16_t Width, uint16_t Height)
virtual void SetAudioChannelDevice(int AudioChannel)
Sets the audio channel to stereo (0), mono left (1) or mono right (2).
const cPatPmtParser * PatPmtParser(void) const
Returns a pointer to the patPmtParser, so that a derived device can use the stream information from i...
void CmdMuxSetVideoOut(HdffVideoOut_t VideoOut)
void CmdAvSetVideoSpeed(uint8_t DecoderIndex, int32_t Speed)
cDvbHdFfDeviceProbe(void)
tChannelID GetChannelID(void) const
The cDvbHdFfDevice implements a DVB device which can be accessed through the Linux DVB driver API...
virtual bool ProvidesSource(int Source) const
Returns true if this device can provide the given source.
const tTrackId * GetTrack(eTrackType Type)
Returns a pointer to the given track id, or NULL if Type is not less than ttMaxTrackTypes.
virtual bool CanReplay(void) const
Returns true if this device can currently start a replay session.
bool HasPid(int Pid) const
Returns true if this device is currently receiving the given PID.
cChannelCamRelations ChannelCamRelations
bool Transferring(void) const
Returns true if we are currently in Transfer Mode.
void CmdAvSetStc(uint8_t DecoderIndex, uint64_t Stc)
virtual uchar * GrabImage(int &Size, bool Jpeg=true, int Quality=-1, int SizeX=-1, int SizeY=-1)
Grabs the currently visible screen image.
The cDvbDevice implements a DVB device which can be accessed through the Linux DVB driver API...
void TurnOffLiveMode(bool LiveView)
virtual void SetAudioTrackDevice(eTrackType Type)
Sets the current audio track to the given value.
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 HDFF::cHdffCmdIf * GetHdffCmdHandler(void)
void CmdAvSetAudioDownmix(HdffAudioDownmixMode_t DownmixMode)
static HdffVideoStreamType_t MapVideoStreamTypes(int Vtype)
virtual void SetVolumeDevice(int Volume)
Sets the audio volume on this device (Volume = 0...255).
#define IS_DOLBY_TRACK(t)
static uchar * YuvToJpeg(uchar *Mem, int Width, int Height, int &Size, int Quality)
void CmdAvSetPcrPid(uint8_t DecoderIndex, uint16_t PcrPid)
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 StillPicture(const uchar *Data, int Length)
Displays the given I-frame as a still picture.
void SetVideoFormat(HDFF::cHdffCmdIf *HdffCmdIf)
void CmdAvSetAudioSpeed(uint8_t DecoderIndex, int32_t Speed)
virtual bool SetPid(cPidHandle *Handle, int Type, bool On)
Does the actual PID setting on this device.
cPidHandle pidHandles[MAXPIDHANDLES]
void CmdAvMuteAudio(uint8_t DecoderIndex, bool Mute)
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 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...
void CmdAvEnableSync(uint8_t DecoderIndex, bool EnableSync)
static cDevice * device[MAXDEVICES]
virtual void Mute(void)
Turns off audio while replaying.