13#include <linux/videodev2.h>
14#include <linux/dvb/audio.h>
15#include <linux/dvb/dmx.h>
16#include <linux/dvb/video.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)");
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);
#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) ...
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.
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 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).
const cPatPmtParser * PatPmtParser(void) const
Returns a pointer to the patPmtParser, so that a derived device can use the stream information from i...
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).
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 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]
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 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).
cTSBuffer * tsBuffer
< Controls how the DVB device handles Transfer Mode when replaying Dolby Digital audio.
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...
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)