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> 55 if (firmwareVersion < 0x401)
72 ioctl(
fd_video, VIDEO_SELECT_SOURCE, VIDEO_SOURCE_DEMUX);
85 memset(&hdmiConfig, 0,
sizeof(hdmiConfig));
133 #define BUFFER_SIZE (sizeof(struct v4l2_pix_format) + 1920 * 1080 * 2) 136 uint8_t * result = NULL;
140 esyslog(
"GrabImage: failed open DVB video device");
150 if (readBytes < (
int)
sizeof(
struct v4l2_pix_format))
151 esyslog(
"GrabImage: failed reading from DVB video device");
153 struct v4l2_pix_format * pixfmt;
156 pixfmt = (
struct v4l2_pix_format *) buffer;
157 dsyslog(
"GrabImage: Read image of size %d x %d",
158 pixfmt->width, pixfmt->height);
159 dataSize = readBytes -
sizeof(
struct v4l2_pix_format);
160 if (dataSize < (
int) pixfmt->sizeimage)
161 esyslog(
"GrabImage: image is not complete");
165 temp = (uint8_t *) malloc(pixfmt->width * 3 * pixfmt->height);
167 int numPixels = pixfmt->width * pixfmt->height;
168 uint8_t * destData = temp;
169 uint8_t * srcData = buffer +
sizeof(
struct v4l2_pix_format);
170 while (numPixels > 0)
172 destData[0] = srcData[1];
173 destData[1] = srcData[0];
174 destData[2] = srcData[2];
175 destData[3] = srcData[3];
176 destData[4] = srcData[0];
177 destData[5] = srcData[2];
184 result =
YuvToJpeg(temp, pixfmt->width, pixfmt->height, Size, Quality);
191 snprintf(buf,
sizeof(buf),
"P6\n%d\n%d\n255\n",
192 pixfmt->width, pixfmt->height);
194 Size = l + pixfmt->width * 3 * pixfmt->height;
195 result = (uint8_t *) malloc(Size);
198 memcpy(result, buf, l);
199 uint8_t * destData = result + l;
200 uint8_t * srcData = buffer +
sizeof(
struct v4l2_pix_format);
201 int numPixels = pixfmt->width * pixfmt->height;
202 while (numPixels > 0)
204 int cb = srcData[0] - 128;
206 int cr = srcData[2] - 128;
212 r = y1 + (int) (1.402f * cr);
213 g = y1 - (int) (0.344f * cb + 0.714f * cr);
214 b = y1 + (int) (1.772f * cb);
215 destData[0] = r > 255 ? 255 : r < 0 ? 0 : r;
216 destData[1] = g > 255 ? 255 : g < 0 ? 0 : g;
217 destData[2] = b > 255 ? 255 : b < 0 ? 0 : b;
218 r = y2 + (int) (1.402f * cr);
219 g = y2 - (int) (0.344f * cb + 0.714f * cr);
220 b = y2 + (int) (1.772f * cb);
221 destData[3] = r > 255 ? 255 : r < 0 ? 0 : r;
222 destData[4] = g > 255 ? 255 : g < 0 ? 0 : g;
223 destData[5] = b > 255 ? 255 : b < 0 ? 0 : b;
245 switch (VideoDisplayFormat)
265 if (ioctl(
fd_video, VIDEO_GET_SIZE, &vs) == 0) {
268 switch (vs.aspect_ratio) {
270 case VIDEO_FORMAT_4_3: VideoAspect = 4.0 / 3.0;
break;
271 case VIDEO_FORMAT_16_9: VideoAspect = 16.0 / 9.0;
break;
272 case VIDEO_FORMAT_221_1: VideoAspect = 2.21;
break;
291 dmx_pes_filter_params pesFilterParams;
292 memset(&pesFilterParams, 0,
sizeof(pesFilterParams));
325 if (!(Type <= ptDolby && Handle->used <= 1)) {
326 pesFilterParams.pid = Handle->
pid;
327 pesFilterParams.input = DMX_IN_FRONTEND;
328 pesFilterParams.output = DMX_OUT_TS_TAP;
329 pesFilterParams.pes_type= DMX_PES_OTHER;
330 pesFilterParams.flags = DMX_IMMEDIATE_START;
331 if (ioctl(Handle->
handle, DMX_SET_PES_FILTER, &pesFilterParams) < 0) {
337 else if (!Handle->
used) {
372 int apid = Channel->
Apid(0);
373 int vpid = Channel->
Vpid();
374 int dpid = Channel->
Dpid(0);
381 bool TurnOffLivePIDs = DoTune
388 && (LiveView &&
HasPid(vpid ? vpid : apid) && (!pidHandlesVideo || (!pidHandlesAudio && (dpid ?
pidHandles[
ptAudio].
pid != dpid :
true)))
389 || !LiveView && (pidHandlesVideo || pidHandlesAudio)
396 bool TurnOnLivePIDs = !StartTransferMode && LiveView;
410 if (TurnOnLivePIDs) {
416 else if (StartTransferMode)
442 if (TrackId && TrackId->
id) {
488 ioctl(
fd_video, VIDEO_SELECT_SOURCE, VIDEO_SOURCE_DEMUX);
523 ioctl(
fd_video, VIDEO_SELECT_SOURCE, VIDEO_SOURCE_MEMORY);
536 if (ioctl(
fd_video, VIDEO_GET_PTS, &pts) == -1) {
548 if (ioctl(
fd_audio, AUDIO_GET_PTS, &pts) == -1) {
576 double osdPixelAspect;
578 GetOsdSize(osdWidth, osdHeight, osdPixelAspect);
583 int x = (Rect.
X() * 1000 + osdWidth / 2) / osdWidth;
584 int y = (Rect.
Y() * 1000 + osdHeight / 2) / osdHeight;
585 int w = (Rect.
Width() * 1000 + osdWidth / 2) / osdWidth;
586 int h = (Rect.
Height() * 1000 + osdHeight / 2) / osdHeight;
604 #if (APIVERSNUM >= 20103) 669 if (Data[0] == 0x47) {
673 else if (Data[0] == 0x00 && Data[1] == 0x00 && Data[2] == 0x01 && (Data[3] & 0xF0) == 0xE0) {
675 char *buf =
MALLOC(
char, Length);
680 while (i < Length - 6) {
681 if (Data[i] == 0x00 && Data[i + 1] == 0x00 && Data[i + 2] == 0x01) {
682 int len = Data[i + 4] * 256 + Data[i + 5];
683 if ((Data[i + 3] & 0xF0) == 0xE0) {
687 if ((Data[i + 6] & 0xC0) == 0x80) {
689 if (Data[i + 8] >= Length)
695 if (len < 0 || offs + len > Length)
700 while (offs < Length && len > 0 && Data[offs] == 0xFF) {
704 if (offs <= Length - 2 && len >= 2 && (Data[offs] & 0xC0) == 0x40) {
708 if (offs <= Length - 5 && len >= 5 && (Data[offs] & 0xF0) == 0x20) {
712 else if (offs <= Length - 10 && len >= 10 && (Data[offs] & 0xF0) == 0x30) {
716 else if (offs < Length && len > 0) {
721 if (blen + len > Length)
723 memcpy(&buf[blen], &Data[offs], len);
727 else if (Data[i + 3] >= 0xBD && Data[i + 3] <= 0xDF)
747 return Poller.
Poll(TimeoutMs);
759 TsBuffer[1] = PusiSet ? 0x40 : 0x00;
760 TsBuffer[1] |= Pid >> 8;
761 TsBuffer[2] = Pid & 0xFF;
764 TsBuffer[3] = 0x10 | Counter;
765 memcpy(TsBuffer + 4, Data, 184);
769 uint8_t adaptationLength;
771 TsBuffer[3] = 0x30 | Counter;
772 adaptationLength = 183 - Length;
773 TsBuffer[4] = adaptationLength;
774 if (adaptationLength > 0)
777 memset(TsBuffer + 6, 0xFF, adaptationLength - 1);
779 memcpy(TsBuffer + 5 + adaptationLength, Data, Length);
792 BuildTsPacket(TsBuffer + tsOffset, i == 0, Pid, Counter, Data + i * 184, Length);
797 Counter = (Counter + 1) & 15;
846 if (streamId >= 0xC0 && streamId <= 0xDF)
850 else if (streamId == 0xBD)
852 const uint8_t * payload = Data + 9 + Data[8];
853 if ((payload[0] & 0xF8) == 0xA0)
858 else if ((payload[0] & 0xF8) == 0x88)
863 else if ((payload[0] & 0xF8) == 0x80)
873 pid = 200 + (int) streamType;
895 int pid =
TsPid(Data);
931 int pid =
TsPid(Data);
934 int AudioStreamType = -1;
941 if (AudioStreamType < 0) {
969 static uint32_t SubsystemIds[] = {
977 uint32_t SubsystemId = 0;
978 FileName =
cString::sprintf(
"/sys/class/dvb/dvb%d.frontend%d/device/subsystem_vendor", Adapter, Frontend);
979 if ((f = fopen(FileName,
"r")) != NULL) {
980 if (
char *s = ReadLine.
Read(f))
981 SubsystemId = strtoul(s, NULL, 0) << 16;
984 FileName =
cString::sprintf(
"/sys/class/dvb/dvb%d.frontend%d/device/subsystem_device", Adapter, Frontend);
985 if ((f = fopen(FileName,
"r")) != NULL) {
986 if (
char *s = ReadLine.
Read(f))
987 SubsystemId |= strtoul(s, NULL, 0);
990 for (uint32_t *sid = SubsystemIds; *sid; sid++) {
991 if (*sid == SubsystemId) {
993 int fd = open(FileName, O_RDWR);
996 dsyslog(
"creating cDvbHdFfDevice");
1008 #include <jpeglib.h> 1010 #define JPEGCOMPRESSMEM 4000000 1030 int Used = jcd->
size;
1032 if (
uchar *NewBuffer = (
uchar *)realloc(jcd->
mem, NewSize)) {
1033 jcd->
size = NewSize;
1034 jcd->
mem = NewBuffer;
1037 esyslog(
"ERROR: out of memory");
1041 cinfo->dest->next_output_byte = jcd->
mem + Used;
1042 cinfo->dest->free_in_buffer = jcd->
size - Used;
1053 int Used = cinfo->dest->next_output_byte - jcd->
mem;
1054 if (Used < jcd->size) {
1057 jcd->
mem = NewBuffer;
1060 esyslog(
"ERROR: out of memory");
1069 else if (Quality > 100)
1072 jpeg_destination_mgr jdm;
1078 struct jpeg_compress_struct cinfo;
1079 struct jpeg_error_mgr jerr;
1080 cinfo.err = jpeg_std_error(&jerr);
1081 jpeg_create_compress(&cinfo);
1084 cinfo.client_data = &jcd;
1085 cinfo.image_width = Width;
1086 cinfo.image_height = Height;
1087 cinfo.input_components = 3;
1088 cinfo.in_color_space = JCS_YCbCr;
1090 jpeg_set_defaults(&cinfo);
1091 jpeg_set_quality(&cinfo, Quality,
true);
1092 jpeg_start_compress(&cinfo,
true);
1095 JSAMPROW rp[Height];
1096 for (
int k = 0; k < Height; k++)
1097 rp[k] = &Mem[rs * k];
1098 jpeg_write_scanlines(&cinfo, rp, Height);
1099 jpeg_finish_compress(&cinfo);
1100 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)
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...
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.
virtual bool IsTunedToTransponder(const cChannel *Channel) const
Returns true if this device is currently tuned to the given Channel's transponder.
static cDevice * ReceiverDevice(void)
void DetachAll(int Pid)
Detaches all receivers from this device for this pid.
void CmdRemoteSetAddressFilter(bool Enable, uint32_t Address)
cTSBuffer * tsBuffer
< Controls how the DVB device handles Transfer Mode when replaying Dolby Digital audio.
int Ca(int Index=0) const
virtual void StartDecrypting(void)
Triggers sending all currently active CA_PMT entries to the CAM, so that it will start decrypting...
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
virtual bool HasDecoder(void) const
Tells whether this device has an MPEG decoder.
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).
virtual bool CanReplay(void) const
Returns true if this device can currently start a replay session.
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)
static HdffAudioStreamType_t MapAudioStreamTypes(int Atype)
static boolean JpegCompressEmptyOutputBuffer(j_compress_ptr cinfo)
virtual void Play(void)
Sets the device into play mode (after a previous trick mode).
bool Poll(int TimeoutMs=0)
virtual void Mute(void)
Turns off audio while replaying.
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)
bool IsPrimaryDevice(void) const
virtual void SetVideoDisplayFormat(eVideoDisplayFormat VideoDisplayFormat)
Sets the video display format to the given one (only useful if this device has an MPEG decoder)...
cCamSlot * CamSlot(void) const
Returns the CAM slot that is currently used with this device, or NULL if no CAM slot is in use...
bool Transferring(void) const
Returns true if we are currently in Transfer Mode.
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.
cDvbHdFfDevice(int Adapter, int Frontend)
static void JpegCompressInitDestination(j_compress_ptr cinfo)
void CmdHdmiConfigure(const HdffHdmiConfig_t *pConfig)
uint32_t CmdGetFirmwareVersion(char *pString, uint32_t MaxLength)
HDFF::cHdffCmdIf * mHdffCmdIf
virtual bool SetChannelDevice(const cChannel *Channel, bool LiveView)
Sets the device to the given channel (actual physical setup).
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)
tChannelID GetChannelID(void) const
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.
static void Launch(cControl *Control)
const cPatPmtParser * PatPmtParser(void) const
Returns a pointer to the patPmtParser, so that a derived device can use the stream information from i...
void GetOsdSize(int &Width, int &Height, double &PixelAspect)
int CardIndex(void) const
Returns the card index of this device (0 ... MAXDEVICES - 1).
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).
void CmdMuxSetVideoOut(HdffVideoOut_t VideoOut)
void CmdAvSetVideoSpeed(uint8_t DecoderIndex, int32_t Speed)
cChannel * GetByNumber(int Number, int SkipGap=0)
The cDvbHdFfDevice implements a DVB device which can be accessed through the Linux DVB driver API...
const tTrackId * GetTrack(eTrackType Type)
Returns a pointer to the given track id, or NULL if Type is not less than ttMaxTrackTypes.
cChannelCamRelations ChannelCamRelations
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...
virtual bool CanReplay(void) const
Returns true if this device can currently start a replay session.
static HDFF::cHdffCmdIf * GetHdffCmdHandler(void)
void CmdAvSetAudioDownmix(HdffAudioDownmixMode_t DownmixMode)
bool HasPid(int Pid) const
Returns true if this device is currently receiving the given PID.
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.
static int DvbOpen(const char *Name, int Adapter, int Frontend, int Mode, bool ReportError=false)
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.