13 #include <linux/videodev2.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>
60 if (firmwareVersion < 0x401)
77 ioctl(
fd_video, VIDEO_SELECT_SOURCE, VIDEO_SOURCE_DEMUX);
90 memset(&hdmiConfig, 0,
sizeof(hdmiConfig));
138 #define BUFFER_SIZE (sizeof(struct v4l2_pix_format) + 1920 * 1080 * 2)
141 uint8_t * result = NULL;
145 esyslog(
"GrabImage: failed open DVB video device");
155 if (readBytes < (
int)
sizeof(
struct v4l2_pix_format))
156 esyslog(
"GrabImage: failed reading from DVB video device");
158 struct v4l2_pix_format * pixfmt;
161 pixfmt = (
struct v4l2_pix_format *) buffer;
162 dsyslog(
"GrabImage: Read image of size %d x %d",
163 pixfmt->width, pixfmt->height);
164 dataSize = readBytes -
sizeof(
struct v4l2_pix_format);
165 if (dataSize < (
int) pixfmt->sizeimage)
166 esyslog(
"GrabImage: image is not complete");
170 temp = (uint8_t *) malloc(pixfmt->width * 3 * pixfmt->height);
172 int numPixels = pixfmt->width * pixfmt->height;
173 uint8_t * destData = temp;
174 uint8_t * srcData = buffer +
sizeof(
struct v4l2_pix_format);
175 while (numPixels > 0)
177 destData[0] = srcData[1];
178 destData[1] = srcData[0];
179 destData[2] = srcData[2];
180 destData[3] = srcData[3];
181 destData[4] = srcData[0];
182 destData[5] = srcData[2];
189 result =
YuvToJpeg(temp, pixfmt->width, pixfmt->height, Size, Quality);
196 snprintf(buf,
sizeof(buf),
"P6\n%d\n%d\n255\n",
197 pixfmt->width, pixfmt->height);
199 Size = l + pixfmt->width * 3 * pixfmt->height;
200 result = (uint8_t *) malloc(Size);
203 memcpy(result, buf, l);
204 uint8_t * destData = result + l;
205 uint8_t * srcData = buffer +
sizeof(
struct v4l2_pix_format);
206 int numPixels = pixfmt->width * pixfmt->height;
207 while (numPixels > 0)
209 int cb = srcData[0] - 128;
211 int cr = srcData[2] - 128;
217 r = y1 + (int) (1.402f * cr);
218 g = y1 - (int) (0.344f * cb + 0.714f * cr);
219 b = y1 + (int) (1.772f * cb);
220 destData[0] = r > 255 ? 255 : r < 0 ? 0 : r;
221 destData[1] = g > 255 ? 255 : g < 0 ? 0 : g;
222 destData[2] = b > 255 ? 255 : b < 0 ? 0 : b;
223 r = y2 + (int) (1.402f * cr);
224 g = y2 - (int) (0.344f * cb + 0.714f * cr);
225 b = y2 + (int) (1.772f * cb);
226 destData[3] = r > 255 ? 255 : r < 0 ? 0 : r;
227 destData[4] = g > 255 ? 255 : g < 0 ? 0 : g;
228 destData[5] = b > 255 ? 255 : b < 0 ? 0 : b;
250 switch (VideoDisplayFormat)
270 if (ioctl(
fd_video, VIDEO_GET_SIZE, &vs) == 0) {
273 switch (vs.aspect_ratio) {
275 case VIDEO_FORMAT_4_3: VideoAspect = 4.0 / 3.0;
break;
276 case VIDEO_FORMAT_16_9: VideoAspect = 16.0 / 9.0;
break;
277 case VIDEO_FORMAT_221_1: VideoAspect = 2.21;
break;
296 dmx_pes_filter_params pesFilterParams;
297 memset(&pesFilterParams, 0,
sizeof(pesFilterParams));
330 if (!(Type <= ptDolby && Handle->used <= 1)) {
331 pesFilterParams.pid = Handle->
pid;
332 pesFilterParams.input = DMX_IN_FRONTEND;
333 pesFilterParams.output = DMX_OUT_TS_TAP;
334 pesFilterParams.pes_type= DMX_PES_OTHER;
335 pesFilterParams.flags = DMX_IMMEDIATE_START;
336 if (ioctl(Handle->
handle, DMX_SET_PES_FILTER, &pesFilterParams) < 0) {
342 else if (!Handle->
used) {
391 int apid = Channel->
Apid(0);
392 int vpid = Channel->
Vpid();
393 int dpid = Channel->
Dpid(0);
400 bool TurnOffLivePIDs = DoTune
407 && (LiveView &&
HasPid(vpid ? vpid : apid) && (!pidHandlesVideo || (!pidHandlesAudio && (dpid ?
pidHandles[
ptAudio].
pid != dpid :
true)))
408 || !LiveView && (pidHandlesVideo || pidHandlesAudio)
415 bool TurnOnLivePIDs = !StartTransferMode && LiveView;
429 if (TurnOnLivePIDs) {
435 else if (StartTransferMode)
461 if (TrackId && TrackId->
id) {
463 #if (APIVERSNUM >= 20301)
512 ioctl(
fd_video, VIDEO_SELECT_SOURCE, VIDEO_SOURCE_DEMUX);
547 ioctl(
fd_video, VIDEO_SELECT_SOURCE, VIDEO_SOURCE_MEMORY);
560 if (ioctl(
fd_video, VIDEO_GET_PTS, &pts) == -1) {
600 double osdPixelAspect;
602 GetOsdSize(osdWidth, osdHeight, osdPixelAspect);
607 int x = (Rect.
X() * 1000 + osdWidth / 2) / osdWidth;
608 int y = (Rect.
Y() * 1000 + osdHeight / 2) / osdHeight;
609 int w = (Rect.
Width() * 1000 + osdWidth / 2) / osdWidth;
610 int h = (Rect.
Height() * 1000 + osdHeight / 2) / osdHeight;
628 #if (APIVERSNUM >= 20103)
635 mHdffCmdIf->CmdAvEnableSync(0,
false);
639 mHdffCmdIf->CmdAvSetVideoSpeed(0, 100 / Speed);
693 if (Data[0] == 0x47) {
697 else if (Data[0] == 0x00 && Data[1] == 0x00 && Data[2] == 0x01 && (Data[3] & 0xF0) == 0xE0) {
699 char *buf =
MALLOC(
char, Length);
704 while (i < Length - 6) {
705 if (Data[i] == 0x00 && Data[i + 1] == 0x00 && Data[i + 2] == 0x01) {
706 int len = Data[i + 4] * 256 + Data[i + 5];
707 if ((Data[i + 3] & 0xF0) == 0xE0) {
711 if ((Data[i + 6] & 0xC0) == 0x80) {
713 if (Data[i + 8] >= Length)
719 if (len < 0 || offs + len > Length)
724 while (offs < Length && len > 0 && Data[offs] == 0xFF) {
728 if (offs <= Length - 2 && len >= 2 && (Data[offs] & 0xC0) == 0x40) {
732 if (offs <= Length - 5 && len >= 5 && (Data[offs] & 0xF0) == 0x20) {
736 else if (offs <= Length - 10 && len >= 10 && (Data[offs] & 0xF0) == 0x30) {
740 else if (offs < Length && len > 0) {
745 if (blen + len > Length)
747 memcpy(&buf[blen], &Data[offs], len);
751 else if (Data[i + 3] >= 0xBD && Data[i + 3] <= 0xDF)
771 return Poller.
Poll(TimeoutMs);
783 TsBuffer[1] = PusiSet ? 0x40 : 0x00;
784 TsBuffer[1] |= Pid >> 8;
785 TsBuffer[2] = Pid & 0xFF;
788 TsBuffer[3] = 0x10 | Counter;
789 memcpy(TsBuffer + 4, Data, 184);
793 uint8_t adaptationLength;
795 TsBuffer[3] = 0x30 | Counter;
796 adaptationLength = 183 - Length;
797 TsBuffer[4] = adaptationLength;
798 if (adaptationLength > 0)
801 memset(TsBuffer + 6, 0xFF, adaptationLength - 1);
803 memcpy(TsBuffer + 5 + adaptationLength, Data, Length);
816 BuildTsPacket(TsBuffer + tsOffset, i == 0, Pid, Counter, Data + i * 184, Length);
821 Counter = (Counter + 1) & 15;
870 if (streamId >= 0xC0 && streamId <= 0xDF)
874 else if (streamId == 0xBD)
876 const uint8_t * payload = Data + 9 + Data[8];
877 if ((payload[0] & 0xF8) == 0xA0)
882 else if ((payload[0] & 0xF8) == 0x88)
887 else if ((payload[0] & 0xF8) == 0x80)
897 pid = 200 + (int) streamType;
919 int pid =
TsPid(Data);
955 int pid =
TsPid(Data);
958 int AudioStreamType = -1;
965 if (AudioStreamType < 0) {
984 return device->mHdffCmdIf;
998 static uint32_t SubsystemIds[] = {
1006 uint32_t SubsystemId = 0;
1007 FileName =
cString::sprintf(
"/sys/class/dvb/dvb%d.frontend%d/device/subsystem_vendor", Adapter, Frontend);
1008 if ((f = fopen(FileName,
"r")) != NULL) {
1009 if (
char *s = ReadLine.
Read(f))
1010 SubsystemId = strtoul(s, NULL, 0) << 16;
1013 FileName =
cString::sprintf(
"/sys/class/dvb/dvb%d.frontend%d/device/subsystem_device", Adapter, Frontend);
1014 if ((f = fopen(FileName,
"r")) != NULL) {
1015 if (
char *s = ReadLine.
Read(f))
1016 SubsystemId |= strtoul(s, NULL, 0);
1019 for (uint32_t *sid = SubsystemIds; *sid; sid++) {
1020 if (*sid == SubsystemId) {
1022 int fd = open(FileName, O_RDWR);
1030 dsyslog(
"cDvbHdFfDevice 2nd tuner disabled (outputonly)");
1041 #include <jpeglib.h>
1043 #define JPEGCOMPRESSMEM 4000000
1063 int Used = jcd->
size;
1065 if (
uchar *NewBuffer = (
uchar *)realloc(jcd->
mem, NewSize)) {
1066 jcd->
size = NewSize;
1067 jcd->
mem = NewBuffer;
1070 esyslog(
"ERROR: out of memory");
1074 cinfo->dest->next_output_byte = jcd->
mem + Used;
1075 cinfo->dest->free_in_buffer = jcd->
size - Used;
1086 int Used = cinfo->dest->next_output_byte - jcd->
mem;
1087 if (Used < jcd->size) {
1090 jcd->
mem = NewBuffer;
1093 esyslog(
"ERROR: out of memory");
1102 else if (Quality > 100)
1105 jpeg_destination_mgr jdm;
1111 struct jpeg_compress_struct cinfo;
1112 struct jpeg_error_mgr jerr;
1113 cinfo.err = jpeg_std_error(&jerr);
1114 jpeg_create_compress(&cinfo);
1117 cinfo.client_data = &jcd;
1118 cinfo.image_width = Width;
1119 cinfo.image_height = Height;
1120 cinfo.input_components = 3;
1121 cinfo.in_color_space = JCS_YCbCr;
1123 jpeg_set_defaults(&cinfo);
1124 jpeg_set_quality(&cinfo, Quality,
true);
1125 jpeg_start_compress(&cinfo,
true);
1128 JSAMPROW rp[Height];
1129 for (
int k = 0; k < Height; k++)
1130 rp[k] = &Mem[rs * k];
1131 jpeg_write_scanlines(&cinfo, rp, Height);
1132 jpeg_finish_compress(&cinfo);
1133 jpeg_destroy_compress(&cinfo);
#define LOCK_CHANNELS_READ
cChannelCamRelations ChannelCamRelations
void CmdAvSetAudioDownmix(HdffAudioDownmixMode_t DownmixMode)
void CmdAvEnableVideoAfterStop(uint8_t DecoderIndex, bool EnableVideoAfterStop)
void CmdAvShowStillImage(uint8_t DecoderIndex, const uint8_t *pStillImage, int Size, HdffVideoStreamType_t StreamType)
void CmdAvSetVideoWindow(uint8_t DecoderIndex, bool Enable, uint16_t X, uint16_t Y, uint16_t Width, uint16_t Height)
void CmdHdmiSetVideoMode(HdffVideoMode_t VideoMode)
void CmdAvSetAudioSpeed(uint8_t DecoderIndex, int32_t Speed)
void CmdAvSetDecoderInput(uint8_t DecoderIndex, uint8_t DemultiplexerIndex)
void CmdAvSetSyncShift(int16_t SyncShift)
void CmdAvSetAudioPid(uint8_t DecoderIndex, uint16_t AudioPid, HdffAudioStreamType_t StreamType, HdffAvContainerType_t ContainerType=HDFF_AV_CONTAINER_PES)
void CmdAvSetVideoPid(uint8_t DecoderIndex, uint16_t VideoPid, HdffVideoStreamType_t StreamType, bool PlaybackMode=false)
void CmdAvMuteAudio(uint8_t DecoderIndex, bool Mute)
void CmdAvSetPcrPid(uint8_t DecoderIndex, uint16_t PcrPid)
void CmdRemoteSetProtocol(HdffRemoteProtocol_t Protocol)
void CmdMuxSetVideoOut(HdffVideoOut_t VideoOut)
void CmdAvSetPlayMode(uint8_t PlayMode, bool Realtime)
void CmdAvSetAudioChannel(uint8_t AudioChannel)
void CmdHdmiConfigure(const HdffHdmiConfig_t *pConfig)
void CmdMuxSetVolume(uint8_t Volume)
void CmdAvSetVideoSpeed(uint8_t DecoderIndex, int32_t Speed)
void CmdAvSetStc(uint8_t DecoderIndex, uint64_t Stc)
void CmdRemoteSetAddressFilter(bool Enable, uint32_t Address)
uint32_t CmdGetFirmwareVersion(char *pString, uint32_t MaxLength)
void CmdAvEnableSync(uint8_t DecoderIndex, bool EnableSync)
void CmdAvSetAudioDelay(int16_t Delay)
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 Launch(cControl *Control)
void StopSectionHandler(void)
A device that has called StartSectionHandler() must call this function (typically in its destructor) ...
virtual void GetVideoSize(int &Width, int &Height, double &VideoAspect)
Returns the Width, Height and VideoAspect ratio of the currently displayed video material.
const cPatPmtParser * PatPmtParser(void) const
Returns a pointer to the patPmtParser, so that a derived device can use the stream information from i...
bool HasPid(int Pid) const
Returns true if this device is currently receiving the given PID.
static cDevice * GetDevice(int Index)
Gets the device with the given Index.
void DelPid(int Pid, ePidType PidType=ptOther)
Deletes a PID from the set of PIDs this device shall receive.
static int CurrentChannel(void)
Returns the number of the current channel on the primary device.
bool IsPrimaryDevice(bool CheckDecoder=true) const
bool Transferring(void) const
Returns true if we are currently in Transfer Mode.
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).
virtual bool CanReplay(void) const
Returns true if this device can currently start a replay session.
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.
static cDevice * device[MAXDEVICES]
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.
The cDvbDevice implements a DVB device which can be accessed through the Linux DVB driver API.
virtual int NumProvidedSystems(void) const override
Returns the number of individual "delivery systems" this device provides.
cTSBuffer * tsBuffer
< Controls how the DVB device handles Transfer Mode when replaying Dolby Digital audio.
virtual bool ProvidesSource(int Source) const override
Returns true if this device can provide the given source.
virtual bool IsTunedToTransponder(const cChannel *Channel) const override
Returns true if this device is currently tuned to the given Channel's transponder.
virtual bool SetChannelDevice(const cChannel *Channel, bool LiveView) override
Sets the device to the given channel (actual physical setup).
virtual bool Probe(int Adapter, int Frontend)
Probes for a DVB device at the given Adapter and creates the appropriate object derived from cDvbDevi...
cDvbHdFfDeviceProbe(void)
The cDvbHdFfDevice implements a DVB device which can be accessed through the Linux DVB driver API.
virtual void SetAudioTrackDevice(eTrackType Type)
Sets the current audio track to the given value.
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...
bool supportsPcrInTransferMode
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 int NumProvidedSystems(void) const
Returns the number of individual "delivery systems" this device provides.
virtual int GetAudioChannelDevice(void)
Gets the current audio channel, which is stereo (0), mono left (1) or mono right (2).
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 ScaleVideo(const cRect &Rect=cRect::Null)
Scales the currently shown video in such a way that it fits into the given Rect.
virtual void StillPicture(const uchar *Data, int Length)
Displays the given I-frame as a still picture.
virtual bool Flush(int TimeoutMs=0)
Returns true if the device's output buffers are empty, i.
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).
void BuildTsPacket(uint8_t *TsBuffer, bool PusiSet, uint16_t Pid, uint8_t Counter, const uint8_t *Data, uint32_t Length)
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.
uint32_t PesToTs(uint8_t *TsBuffer, uint16_t Pid, uint8_t &Counter, const uint8_t *Data, uint32_t Length)
virtual int PlayTsAudio(const uchar *Data, int Length)
Plays the given data block as audio.
virtual bool SetPlayMode(ePlayMode PlayMode)
Sets the device into the given play mode.
virtual int PlayAudio(const uchar *Data, int Length, uchar Id)
Plays the given data block as audio.
static HDFF::cHdffCmdIf * GetHdffCmdHandler(void)
virtual void Clear(void)
Clears all video and audio data from the device.
cDvbHdFfDevice(int Adapter, int Frontend, bool OutputOnly)
virtual void Mute(void)
Turns off audio while replaying.
virtual bool SetPid(cPidHandle *Handle, int Type, bool On)
Does the actual PID setting on this device.
virtual bool CanReplay(void) const
Returns true if this device can currently start a replay session.
HDFF::cHdffCmdIf * mHdffCmdIf
virtual ~cDvbHdFfDevice()
virtual int PlayTsVideo(const uchar *Data, int Length)
Plays the given data block as video.
virtual void Play(void)
Sets the device into play mode (after a previous trick mode).
cDvbSpuDecoder * spuDecoder
virtual uchar * GrabImage(int &Size, bool Jpeg=true, int Quality=-1, int SizeX=-1, int SizeY=-1)
Grabs the currently visible screen image.
void TurnOffLiveMode(bool LiveView)
virtual void SetVideoDisplayFormat(eVideoDisplayFormat VideoDisplayFormat)
Sets the video display format to the given one (only useful if this device has an MPEG decoder).
virtual int64_t GetSTC(void)
Gets the current System Time Counter, which can be used to synchronize audio, video and subtitles.
virtual void SetVolumeDevice(int Volume)
Sets the audio volume on this device (Volume = 0...255).
virtual void GetVideoSize(int &Width, int &Height, double &VideoAspect)
Returns the Width, Height and VideoAspect ratio of the currently displayed video material.
virtual bool HasDecoder(void) const
Tells whether this device has an MPEG decoder.
virtual int PlayVideo(const uchar *Data, int Length)
Plays the given data block as video.
virtual void MakePrimaryDevice(bool On)
Informs a device that it will be the primary device.
virtual void TrickSpeed(int Speed)
virtual bool ProvidesSource(int Source) const
Returns true if this device can provide the given source.
virtual void Freeze(void)
Puts the device into "freeze frame" mode.
bool Add(int FileHandle, bool Out)
bool Poll(int TimeoutMs=0)
static cString sprintf(const char *fmt,...) __attribute__((format(printf
static cDevice * ReceiverDevice(void)
@ 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 boolean JpegCompressEmptyOutputBuffer(j_compress_ptr cinfo)
static void JpegCompressInitDestination(j_compress_ptr cinfo)
static uchar * YuvToJpeg(uchar *Mem, int Width, int Height, int &Size, int Quality)
static HdffAudioStreamType_t MapAudioStreamTypes(int Atype)
static void JpegCompressTermDestination(j_compress_ptr cinfo)
static HdffVideoStreamType_t MapVideoStreamTypes(int Vtype)
@ HDFF_VIDEO_STREAM_MPEG1
@ HDFF_VIDEO_STREAM_MPEG2
@ HDFF_AUDIO_STREAM_MPEG2
@ HDFF_AUDIO_STREAM_HE_AAC
@ HDFF_AUDIO_STREAM_MPEG1
@ HDFF_VIDEO_CONVERSION_CENTRE_CUT_OUT
@ HDFF_VIDEO_CONVERSION_LETTERBOX_16_BY_9
@ HDFF_AV_CONTAINER_PES_DVD
@ EnhancedAC3DescriptorTag
int TsPid(const uchar *p)
HdffVideoModeAdaption_t VideoModeAdaption
void SetVideoFormat(HDFF::cHdffCmdIf *HdffCmdIf)
void GetOsdSize(int &Width, int &Height, double &PixelAspect)
HdffVideoMode_t GetVideoMode(void)