vdr  2.4.0
dvbhdffdevice.c
Go to the documentation of this file.
1 /*
2  * dvbhdffdevice.c: The DVB HD Full Featured device interface
3  *
4  * See the README file for copyright information and how to reach the author.
5  */
6 
7 #include <stdint.h>
8 
9 #include "dvbhdffdevice.h"
10 #include <errno.h>
11 #include <limits.h>
12 #include <libsi/si.h>
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>
18 #include <sys/mman.h>
19 #include <vdr/eitscan.h>
20 #include <vdr/transfer.h>
21 #include "hdffosd.h"
22 #include "setup.h"
23 
24 
25 static uchar *YuvToJpeg(uchar *Mem, int Width, int Height, int &Size, int Quality);
26 
27 
28 // --- cDvbHdFfDevice --------------------------------------------------------
29 
31 
32 cDvbHdFfDevice::cDvbHdFfDevice(int Adapter, int Frontend, bool OutputOnly)
33 :cDvbDevice(Adapter, Frontend)
34 {
35  spuDecoder = NULL;
36  audioChannel = 0;
37  playMode = pmNone;
38  mHdffCmdIf = NULL;
39  outputOnly = OutputOnly;
40 
41  if (outputOnly) {
43  // cannot close fd_tuner, fd_ca and delete ciAdapter, dvbTuner here - are cDvbDevice private
44  }
45 
46  // Devices that are only present on cards with decoders:
47 
49  fd_video = DvbOpen(DEV_DVB_VIDEO, adapter, frontend, O_RDWR | O_NONBLOCK);
50  fd_audio = DvbOpen(DEV_DVB_AUDIO, adapter, frontend, O_RDWR | O_NONBLOCK);
51 
52  //TODO missing /dev/video offset calculation
53 
54  isHdffPrimary = false;
55  if (devHdffOffset < 0) {
57  isHdffPrimary = true;
59 
60  uint32_t firmwareVersion = mHdffCmdIf->CmdGetFirmwareVersion(NULL, 0);
61  if (firmwareVersion < 0x401)
63  else
65 
66  /* reset some stuff in case the VDR was killed before and had no chance
67  to clean up. */
69 
72 
77 
78  ioctl(fd_video, VIDEO_SELECT_SOURCE, VIDEO_SOURCE_DEMUX);
80  mHdffCmdIf->CmdAvEnableSync(0, true);
81  mHdffCmdIf->CmdAvSetPlayMode(0, true);
82  /* reset done */
83 
89 
90  HdffHdmiConfig_t hdmiConfig;
91  memset(&hdmiConfig, 0, sizeof(hdmiConfig));
92  hdmiConfig.TransmitAudio = true;
93  hdmiConfig.ForceDviMode = false;
94  hdmiConfig.CecEnabled = gHdffSetup.CecEnabled;
95  strcpy(hdmiConfig.CecDeviceName, "VDR");
97  mHdffCmdIf->CmdHdmiConfigure(&hdmiConfig);
98 
101  }
102 }
103 
105 {
106  delete spuDecoder;
107  if (isHdffPrimary)
108  {
109  delete mHdffCmdIf;
110  }
111  // We're not explicitly closing any device files here, since this sometimes
112  // caused segfaults. Besides, the program is about to terminate anyway...
113 }
114 
116 {
117  if (On) {
119 
121  }
123 }
124 
126 {
127  return isHdffPrimary;
128 }
129 
131 {
132  if (!spuDecoder && IsPrimaryDevice())
133  spuDecoder = new cDvbSpuDecoder();
134  return spuDecoder;
135 }
136 
137 uchar *cDvbHdFfDevice::GrabImage(int &Size, bool Jpeg, int Quality, int SizeX, int SizeY)
138 {
139  #define BUFFER_SIZE (sizeof(struct v4l2_pix_format) + 1920 * 1080 * 2)
140  int fd;
141  uint8_t * buffer;
142  uint8_t * result = NULL;
143 
144  fd = DvbOpen(DEV_DVB_VIDEO, adapter, frontend, O_RDONLY);
145  if (fd < 0) {
146  esyslog("GrabImage: failed open DVB video device");
147  return NULL;
148  }
149 
150  buffer = (uint8_t *) malloc(BUFFER_SIZE);
151  if (buffer)
152  {
153  int readBytes;
154 
155  readBytes = read(fd, buffer, BUFFER_SIZE);
156  if (readBytes < (int) sizeof(struct v4l2_pix_format))
157  esyslog("GrabImage: failed reading from DVB video device");
158  else {
159  struct v4l2_pix_format * pixfmt;
160  int dataSize;
161 
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");
168  else {
169  if (Jpeg) {
170  uint8_t * temp;
171  temp = (uint8_t *) malloc(pixfmt->width * 3 * pixfmt->height);
172  if (temp) {
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)
177  {
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];
184  srcData += 4;
185  destData += 6;
186  numPixels -= 2;
187  }
188  if (Quality < 0)
189  Quality = 100;
190  result = YuvToJpeg(temp, pixfmt->width, pixfmt->height, Size, Quality);
191  free(temp);
192  }
193  }
194  else {
195  // convert to PNM:
196  char buf[32];
197  snprintf(buf, sizeof(buf), "P6\n%d\n%d\n255\n",
198  pixfmt->width, pixfmt->height);
199  int l = strlen(buf);
200  Size = l + pixfmt->width * 3 * pixfmt->height;
201  result = (uint8_t *) malloc(Size);
202  if (result)
203  {
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)
209  {
210  int cb = srcData[0] - 128;
211  int y1 = srcData[1];
212  int cr = srcData[2] - 128;
213  int y2 = srcData[3];
214  int r;
215  int g;
216  int b;
217 
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;
230 
231  srcData += 4;
232  destData += 6;
233  numPixels -= 2;
234  }
235  }
236  }
237  }
238  }
239  free(buffer);
240  }
241 
242  close(fd);
243 
244  return result;
245 }
246 
248 {
250  {
251  switch (VideoDisplayFormat)
252  {
253  case vdfPanAndScan:
254  case vdfCenterCutOut:
256  break;
257 
258  case vdfLetterBox:
260  break;
261  }
263  }
264  cDevice::SetVideoDisplayFormat(VideoDisplayFormat);
265 }
266 
267 void cDvbHdFfDevice::GetVideoSize(int &Width, int &Height, double &VideoAspect)
268 {
269  if (fd_video >= 0) {
270  video_size_t vs;
271  if (ioctl(fd_video, VIDEO_GET_SIZE, &vs) == 0) {
272  Width = vs.w;
273  Height = vs.h;
274  switch (vs.aspect_ratio) {
275  default:
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;
279  }
280  return;
281  }
282  else
283  LOG_ERROR;
284  }
285  cDevice::GetVideoSize(Width, Height, VideoAspect);
286 }
287 
288 void cDvbHdFfDevice::GetOsdSize(int &Width, int &Height, double &PixelAspect)
289 {
290  gHdffSetup.GetOsdSize(Width, Height, PixelAspect);
291 }
292 
293 bool cDvbHdFfDevice::SetPid(cPidHandle *Handle, int Type, bool On)
294 {
295  //printf("SetPid Type %d, On %d, PID %5d, streamtype %d, handle %d, used %d\n", Type, On, Handle->pid, Handle->streamType, Handle->handle, Handle->used);
296  if (Handle->pid) {
297  dmx_pes_filter_params pesFilterParams;
298  memset(&pesFilterParams, 0, sizeof(pesFilterParams));
299  if (On) {
300  if (Handle->handle < 0) {
301  Handle->handle = DvbOpen(DEV_DVB_DEMUX, adapter, frontend, O_RDWR | O_NONBLOCK, true);
302  if (Handle->handle < 0) {
303  LOG_ERROR;
304  return false;
305  }
306  }
307  if (Type == ptPcr)
308  mHdffCmdIf->CmdAvSetPcrPid(0, Handle->pid);
309  else if (Type == ptVideo) {
310  if (Handle->streamType == 0x1B)
312  else
314  }
315  else if (Type == ptAudio) {
316  if (Handle->streamType == 0x03)
318  else if (Handle->streamType == 0x04)
320  else if (Handle->streamType == SI::AC3DescriptorTag)
322  else if (Handle->streamType == SI::EnhancedAC3DescriptorTag)
324  else if (Handle->streamType == 0x0F)
326  else if (Handle->streamType == 0x11)
328  else
330  }
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) {
338  LOG_ERROR;
339  return false;
340  }
341  }
342  }
343  else if (!Handle->used) {
344  CHECK(ioctl(Handle->handle, DMX_STOP));
345  if (Type == ptPcr)
346  mHdffCmdIf->CmdAvSetPcrPid(0, 0);
347  else if (Type == ptVideo)
349  else if (Type == ptAudio)
351  else if (Type == ptDolby)
353  //TODO missing setting to 0x1FFF??? see cDvbDevice::SetPid()
354  close(Handle->handle);
355  Handle->handle = -1;
356  }
357  }
358  return true;
359 }
360 
361 bool cDvbHdFfDevice::ProvidesSource(int Source) const
362 {
363  if (outputOnly)
364  return false;
365  return cDvbDevice::ProvidesSource(Source);
366 }
367 
369 {
370  if (outputOnly)
371  return 0;
373 }
374 
376 {
377  // Turn off live PIDs:
378 
381  DetachAll(pidHandles[ptPcr].pid);
383  DelPid(pidHandles[ptAudio].pid);
384  DelPid(pidHandles[ptVideo].pid);
385  DelPid(pidHandles[ptPcr].pid, ptPcr);
387  DelPid(pidHandles[ptDolby].pid);
388 }
389 
390 bool cDvbHdFfDevice::SetChannelDevice(const cChannel *Channel, bool LiveView)
391 {
392  int apid = Channel->Apid(0);
393  int vpid = Channel->Vpid();
394  int dpid = Channel->Dpid(0);
395 
396  bool DoTune = !IsTunedToTransponder(Channel);
397 
398  bool pidHandlesVideo = vpid && pidHandles[ptVideo].pid == vpid;
399  bool pidHandlesAudio = apid && pidHandles[ptAudio].pid == apid;
400 
401  bool TurnOffLivePIDs = DoTune
402  || !IsPrimaryDevice()
403  || LiveView // for a new live view the old PIDs need to be turned off
404  || pidHandlesVideo // for recording the PIDs must be shifted from DMX_PES_AUDIO/VIDEO to DMX_PES_OTHER
405  ;
406 
407  bool StartTransferMode = IsPrimaryDevice() && !DoTune
408  && (LiveView && HasPid(vpid ? vpid : apid) && (!pidHandlesVideo || (!pidHandlesAudio && (dpid ? pidHandles[ptAudio].pid != dpid : true)))// the PID is already set as DMX_PES_OTHER
409  || !LiveView && (pidHandlesVideo || pidHandlesAudio) // a recording is going to shift the PIDs from DMX_PES_AUDIO/VIDEO to DMX_PES_OTHER
410  );
412  StartTransferMode |= LiveView && IsPrimaryDevice() && Channel->Ca() >= CA_ENCRYPTED_MIN;
413 
414  //printf("SetChannelDevice Transfer %d, Live %d\n", StartTransferMode, LiveView);
415 
416  bool TurnOnLivePIDs = !StartTransferMode && LiveView;
417 
418  // Turn off live PIDs if necessary:
419 
420  if (TurnOffLivePIDs)
421  TurnOffLiveMode(LiveView);
422 
423  // Set the tuner:
424 
425  if (!cDvbDevice::SetChannelDevice(Channel, LiveView))
426  return false;
427 
428  // PID settings:
429 
430  if (TurnOnLivePIDs) {
431  if (!(AddPid(Channel->Ppid(), ptPcr) && AddPid(vpid, ptVideo, Channel->Vtype()) && AddPid(apid ? apid : dpid, ptAudio, apid ? 0 : Channel->Dtype(0)))) {
432  esyslog("ERROR: failed to set PIDs for channel %d on device %d", Channel->Number(), CardIndex() + 1);
433  return false;
434  }
435  }
436  else if (StartTransferMode)
437  cControl::Launch(new cTransferControl(this, Channel));
438 
439  return true;
440 }
441 
443 {
444  return audioChannel;
445 }
446 
448 {
449  mHdffCmdIf->CmdAvSetAudioChannel(AudioChannel);
450  audioChannel = AudioChannel;
451 }
452 
454 {
455  mHdffCmdIf->CmdMuxSetVolume(Volume * 100 / 255);
456 }
457 
459 {
460  //printf("SetAudioTrackDevice %d\n", Type);
461  const tTrackId *TrackId = GetTrack(Type);
462  if (TrackId && TrackId->id) {
463  int streamType = 0;
465  const cChannel * channel = Channels->GetByNumber(CurrentChannel());
466  if (channel) {
467  if (IS_AUDIO_TRACK(Type))
468  streamType = channel->Atype(Type - ttAudioFirst);
469  else if (IS_DOLBY_TRACK(Type))
470  streamType = channel->Dtype(Type - ttDolbyFirst);
471  }
472  //printf("SetAudioTrackDevice new %d %d, current %d\n", TrackId->id, streamType, pidHandles[ptAudio].pid);
473  if (pidHandles[ptAudio].pid && pidHandles[ptAudio].pid != TrackId->id) {
475  if (CamSlot())
476  CamSlot()->SetPid(pidHandles[ptAudio].pid, false);
477  pidHandles[ptAudio].pid = TrackId->id;
478  pidHandles[ptAudio].streamType = streamType;
479  SetPid(&pidHandles[ptAudio], ptAudio, true);
480  if (CamSlot()) {
481  CamSlot()->SetPid(pidHandles[ptAudio].pid, true);
483  }
484  }
485  }
486 }
487 
489 {
490  return cDevice::CanReplay();
491 }
492 
494 {
495  if (PlayMode == pmNone) {
496  if (fd_video == -1)
497  fd_video = DvbOpen(DEV_DVB_VIDEO, adapter, frontend, O_RDWR | O_NONBLOCK);
498  if (fd_audio == -1)
499  fd_audio = DvbOpen(DEV_DVB_AUDIO, adapter, frontend, O_RDWR | O_NONBLOCK);
500 
503 
505  mHdffCmdIf->CmdAvSetPcrPid(0, 0);
508 
509  ioctl(fd_video, VIDEO_SELECT_SOURCE, VIDEO_SOURCE_DEMUX);
511  mHdffCmdIf->CmdAvEnableSync(0, true);
512  mHdffCmdIf->CmdAvSetPlayMode(0, true);
513  mHdffCmdIf->CmdAvMuteAudio(0, false);
514  }
515  else {
516  if (playMode == pmNone)
517  TurnOffLiveMode(true);
518 
519  if (PlayMode == pmExtern_THIS_SHOULD_BE_AVOIDED)
520  {
521  close(fd_video);
522  fd_video = -1;
523  close(fd_audio);
524  fd_audio = -1;
525  }
526  else
527  {
530  mHdffCmdIf->CmdAvSetStc(0, 100000);
531  mHdffCmdIf->CmdAvEnableSync(0, false);
533 
534  playVideoPid = -1;
535  playAudioPid = -1;
536  playPcrPid = -1;
537  audioCounter = 0;
538  videoCounter = 0;
539  freezed = false;
540  trickMode = false;
541  isPlayingVideo = false;
542 
544  ioctl(fd_video, VIDEO_SELECT_SOURCE, VIDEO_SOURCE_MEMORY);
545  }
546  }
547  playMode = PlayMode;
548  return true;
549 }
550 
552 {
553  if (isPlayingVideo)
554  {
555  if (fd_video >= 0) {
556  uint64_t pts;
557  if (ioctl(fd_video, VIDEO_GET_PTS, &pts) == -1) {
558  esyslog("ERROR: pts %d: %m", CardIndex() + 1);
559  return -1;
560  }
561  //printf("video PTS %lld\n", pts);
562  return pts;
563  }
564  }
565  else
566  {
567  if (fd_audio >= 0) {
568  uint64_t pts;
569  if (ioctl(fd_audio, AUDIO_GET_PTS, &pts) == -1) {
570  esyslog("ERROR: pts %d: %m", CardIndex() + 1);
571  return -1;
572  }
573  //printf("audio PTS %lld\n", pts);
574  return pts;
575  }
576  }
577  return -1;
578 }
579 
580 cRect cDvbHdFfDevice::CanScaleVideo(const cRect &Rect, int Alignment)
581 {
582  return Rect;
583 }
584 
586 {
587  if (Rect == cRect::Null)
588  {
589  mHdffCmdIf->CmdAvSetVideoWindow(0, false, 0, 0, 0, 0);
590  }
591  else
592  {
593  //printf("ScaleVideo: Rect = %d %d %d %d\n", Rect.X(), Rect.Y(), Rect.Width(), Rect.Height());
594 
595  int osdWidth;
596  int osdHeight;
597  double osdPixelAspect;
598 
599  GetOsdSize(osdWidth, osdHeight, osdPixelAspect);
600  //printf("ScaleVideo: OsdSize = %d %d %g\n", osdWidth, osdHeight, osdPixelAspect);
601 
602  // Convert the video window coordinates in 1/10 percent of the display
603  // resolution.
604  int x = (Rect.X() * 1000 + osdWidth / 2) / osdWidth;
605  int y = (Rect.Y() * 1000 + osdHeight / 2) / osdHeight;
606  int w = (Rect.Width() * 1000 + osdWidth / 2) / osdWidth;
607  int h = (Rect.Height() * 1000 + osdHeight / 2) / osdHeight;
608  //printf("ScaleVideo: Win1 = %d %d %d %d\n", x, y, w, h);
609 
610  // fix aspect ratio, reposition video
611  if (w > h) {
612  x += (w - h) / 2;
613  w = h;
614  }
615  else if (w < h) {
616  y += (h - w) / 2;
617  h = w;
618  }
619 
620  //printf("ScaleVideo: Win2 = %d %d %d %d\n", x, y, w, h);
621  mHdffCmdIf->CmdAvSetVideoWindow(0, true, x, y, w, h);
622  }
623 }
624 
625 #if (APIVERSNUM >= 20103)
626 void cDvbHdFfDevice::TrickSpeed(int Speed, bool Forward)
627 #else
629 #endif
630 {
631  freezed = false;
632  mHdffCmdIf->CmdAvEnableSync(0, false);
633  mHdffCmdIf->CmdAvSetAudioPid(0, 0, HDFF_AUDIO_STREAM_MPEG1);
634  playAudioPid = -1;
635  if (Speed > 0)
636  mHdffCmdIf->CmdAvSetVideoSpeed(0, 100 / Speed);
637  trickMode = true;
638 }
639 
641 {
642  CHECK(ioctl(fd_video, VIDEO_CLEAR_BUFFER));
645  playVideoPid = -1;
646  playAudioPid = -1;
647  cDevice::Clear();
648 }
649 
651 {
652  freezed = false;
653  trickMode = false;
654  if (isPlayingVideo)
655  mHdffCmdIf->CmdAvEnableSync(0, true);
658  mHdffCmdIf->CmdAvMuteAudio(0, false);
659  cDevice::Play();
660 }
661 
663 {
664  freezed = true;
667  cDevice::Freeze();
668 }
669 
671 {
672  mHdffCmdIf->CmdAvMuteAudio(0, true);
673  cDevice::Mute();
674 }
675 
677 {
678  switch (Vtype) {
679  case 0x01: return HDFF_VIDEO_STREAM_MPEG1;
680  case 0x02: return HDFF_VIDEO_STREAM_MPEG2;
681  case 0x1B: return HDFF_VIDEO_STREAM_H264;
682  default: return HDFF_VIDEO_STREAM_MPEG2; // fallback to MPEG2
683  }
684 }
685 
686 void cDvbHdFfDevice::StillPicture(const uchar *Data, int Length)
687 {
688  if (!Data || Length < TS_SIZE)
689  return;
690  if (Data[0] == 0x47) {
691  // TS data
692  cDevice::StillPicture(Data, Length);
693  }
694  else if (Data[0] == 0x00 && Data[1] == 0x00 && Data[2] == 0x01 && (Data[3] & 0xF0) == 0xE0) {
695  // PES data
696  char *buf = MALLOC(char, Length);
697  if (!buf)
698  return;
699  int i = 0;
700  int blen = 0;
701  while (i < Length - 6) {
702  if (Data[i] == 0x00 && Data[i + 1] == 0x00 && Data[i + 2] == 0x01) {
703  int len = Data[i + 4] * 256 + Data[i + 5];
704  if ((Data[i + 3] & 0xF0) == 0xE0) { // video packet
705  // skip PES header
706  int offs = i + 6;
707  // skip header extension
708  if ((Data[i + 6] & 0xC0) == 0x80) {
709  // MPEG-2 PES header
710  if (Data[i + 8] >= Length)
711  break;
712  offs += 3;
713  offs += Data[i + 8];
714  len -= 3;
715  len -= Data[i + 8];
716  if (len < 0 || offs + len > Length)
717  break;
718  }
719  else {
720  // MPEG-1 PES header
721  while (offs < Length && len > 0 && Data[offs] == 0xFF) {
722  offs++;
723  len--;
724  }
725  if (offs <= Length - 2 && len >= 2 && (Data[offs] & 0xC0) == 0x40) {
726  offs += 2;
727  len -= 2;
728  }
729  if (offs <= Length - 5 && len >= 5 && (Data[offs] & 0xF0) == 0x20) {
730  offs += 5;
731  len -= 5;
732  }
733  else if (offs <= Length - 10 && len >= 10 && (Data[offs] & 0xF0) == 0x30) {
734  offs += 10;
735  len -= 10;
736  }
737  else if (offs < Length && len > 0) {
738  offs++;
739  len--;
740  }
741  }
742  if (blen + len > Length) // invalid PES length field
743  break;
744  memcpy(&buf[blen], &Data[offs], len);
745  i = offs + len;
746  blen += len;
747  }
748  else if (Data[i + 3] >= 0xBD && Data[i + 3] <= 0xDF) // other PES packets
749  i += len + 6;
750  else
751  i++;
752  }
753  else
754  i++;
755  }
756  mHdffCmdIf->CmdAvShowStillImage(0, (uint8_t *)buf, blen, MapVideoStreamTypes(PatPmtParser()->Vtype()));
757  free(buf);
758  }
759  else {
760  // non-PES data
761  mHdffCmdIf->CmdAvShowStillImage(0, Data, Length, MapVideoStreamTypes(PatPmtParser()->Vtype()));
762  }
763 }
764 
765 bool cDvbHdFfDevice::Poll(cPoller &Poller, int TimeoutMs)
766 {
767  Poller.Add(fd_video, true);
768  return Poller.Poll(TimeoutMs);
769 }
770 
771 bool cDvbHdFfDevice::Flush(int TimeoutMs)
772 {
773  //TODO actually this function should wait until all buffered data has been processed by the card, but how?
774  return true;
775 }
776 
777 void cDvbHdFfDevice::BuildTsPacket(uint8_t * TsBuffer, bool PusiSet, uint16_t Pid, uint8_t Counter, const uint8_t * Data, uint32_t Length)
778 {
779  TsBuffer[0] = 0x47;
780  TsBuffer[1] = PusiSet ? 0x40 : 0x00;
781  TsBuffer[1] |= Pid >> 8;
782  TsBuffer[2] = Pid & 0xFF;
783  if (Length >= 184)
784  {
785  TsBuffer[3] = 0x10 | Counter;
786  memcpy(TsBuffer + 4, Data, 184);
787  }
788  else
789  {
790  uint8_t adaptationLength;
791 
792  TsBuffer[3] = 0x30 | Counter;
793  adaptationLength = 183 - Length;
794  TsBuffer[4] = adaptationLength;
795  if (adaptationLength > 0)
796  {
797  TsBuffer[5] = 0x00;
798  memset(TsBuffer + 6, 0xFF, adaptationLength - 1);
799  }
800  memcpy(TsBuffer + 5 + adaptationLength, Data, Length);
801  }
802 }
803 
804 uint32_t cDvbHdFfDevice::PesToTs(uint8_t * TsBuffer, uint16_t Pid, uint8_t & Counter, const uint8_t * Data, uint32_t Length)
805 {
806  uint32_t tsOffset;
807  uint32_t i;
808 
809  tsOffset = 0;
810  i = 0;
811  while (Length > 0)
812  {
813  BuildTsPacket(TsBuffer + tsOffset, i == 0, Pid, Counter, Data + i * 184, Length);
814  if (Length >= 184)
815  Length -= 184;
816  else
817  Length = 0;
818  Counter = (Counter + 1) & 15;
819  tsOffset += 188;
820  i++;
821  }
822  return tsOffset;
823 }
824 
825 int cDvbHdFfDevice::PlayVideo(const uchar *Data, int Length)
826 {
827  if (freezed)
828  return -1;
829  if (!isPlayingVideo)
830  {
831  mHdffCmdIf->CmdAvEnableSync(0, true);
832  isPlayingVideo = true;
833  }
834 
835  // ignore padding PES packets
836  if (Data[3] == 0xBE)
837  return Length;
838 
839  //TODO: support greater Length
840  uint8_t tsBuffer[188 * 16];
841  uint32_t tsLength;
842  int pid = 100;
843 
844  tsLength = PesToTs(tsBuffer, pid, videoCounter, Data, Length);
845 
846  if (pid != playVideoPid) {
847  playVideoPid = pid;
849  }
850  if (WriteAllOrNothing(fd_video, tsBuffer, tsLength, 1000, 10) <= 0)
851  Length = 0;
852  return Length;
853 }
854 
855 int cDvbHdFfDevice::PlayAudio(const uchar *Data, int Length, uchar Id)
856 {
857  if (freezed)
858  return -1;
859  uint8_t streamId;
860  uint8_t tsBuffer[188 * 16];
861  uint32_t tsLength;
864  int pid;
865 
866  streamId = Data[3];
867  if (streamId >= 0xC0 && streamId <= 0xDF)
868  {
869  streamType = HDFF_AUDIO_STREAM_MPEG1;
870  }
871  else if (streamId == 0xBD)
872  {
873  const uint8_t * payload = Data + 9 + Data[8];
874  if ((payload[0] & 0xF8) == 0xA0)
875  {
876  containerType = HDFF_AV_CONTAINER_PES_DVD;
877  streamType = HDFF_AUDIO_STREAM_PCM;
878  }
879  else if ((payload[0] & 0xF8) == 0x88)
880  {
881  containerType = HDFF_AV_CONTAINER_PES_DVD;
882  streamType = HDFF_AUDIO_STREAM_DTS;
883  }
884  else if ((payload[0] & 0xF8) == 0x80)
885  {
886  containerType = HDFF_AV_CONTAINER_PES_DVD;
887  streamType = HDFF_AUDIO_STREAM_AC3;
888  }
889  else
890  {
891  streamType = HDFF_AUDIO_STREAM_AC3;
892  }
893  }
894  pid = 200 + (int) streamType;
895  tsLength = PesToTs(tsBuffer, pid, audioCounter, Data, Length);
896 
897  if (pid != playAudioPid) {
898  playAudioPid = pid;
899  mHdffCmdIf->CmdAvSetAudioPid(0, playAudioPid, streamType, containerType);
900  }
901  if (WriteAllOrNothing(fd_video, tsBuffer, tsLength, 1000, 10) <= 0)
902  Length = 0;
903  return Length;
904 }
905 
906 int cDvbHdFfDevice::PlayTsVideo(const uchar *Data, int Length)
907 {
908  if (freezed)
909  return -1;
910  if (!isPlayingVideo)
911  {
912  mHdffCmdIf->CmdAvEnableSync(0, true);
913  isPlayingVideo = true;
914  }
915 
916  int pid = TsPid(Data);
917  if (pid != playVideoPid) {
918  PatPmtParser();
919  if (pid == PatPmtParser()->Vpid()) {
920  playVideoPid = pid;
922  }
923  }
925  if (pid != playPcrPid) {
926  if (pid == PatPmtParser()->Ppid()) {
927  playPcrPid = pid;
929  }
930  }
931  }
932  return WriteAllOrNothing(fd_video, Data, Length, 1000, 10);
933 }
934 
936 {
937  switch (Atype) {
938  case 0x03: return HDFF_AUDIO_STREAM_MPEG1;
939  case 0x04: return HDFF_AUDIO_STREAM_MPEG2;
942  case 0x0F: return HDFF_AUDIO_STREAM_AAC;
943  case 0x11: return HDFF_AUDIO_STREAM_HE_AAC;
944  default: return HDFF_AUDIO_STREAM_MPEG1;
945  }
946 }
947 
948 int cDvbHdFfDevice::PlayTsAudio(const uchar *Data, int Length)
949 {
950  if (freezed)
951  return -1;
952  int pid = TsPid(Data);
953  if (pid != playAudioPid) {
954  playAudioPid = pid;
955  int AudioStreamType = -1;
956  for (int i = 0; PatPmtParser()->Apid(i); i++) {
957  if (playAudioPid == PatPmtParser()->Apid(i)) {
958  AudioStreamType = PatPmtParser()->Atype(i);
959  break;
960  }
961  }
962  if (AudioStreamType < 0) {
963  for (int i = 0; PatPmtParser()->Dpid(i); i++) {
964  if (playAudioPid == PatPmtParser()->Dpid(i)) {
965  AudioStreamType = PatPmtParser()->Dtype(i);
966  break;
967  }
968  }
969  }
971  }
972  return WriteAllOrNothing(fd_video, Data, Length, 1000, 10);
973 }
974 
976 {
977  //TODO why not just keep a pointer?
978  if (devHdffOffset >= 0) {
980  if (device)
981  return device->mHdffCmdIf;
982  }
983  return NULL;
984 }
985 
986 // --- cDvbHdFfDeviceProbe ---------------------------------------------------
987 
989 {
990  outputOnly = false;
991 }
992 
993 bool cDvbHdFfDeviceProbe::Probe(int Adapter, int Frontend)
994 {
995  static uint32_t SubsystemIds[] = {
996  0x13C23009, // Technotrend S2-6400 HDFF development samples
997  0x13C2300A, // Technotrend S2-6400 HDFF production version
998  0x00000000
999  };
1000  cString FileName;
1001  cReadLine ReadLine;
1002  FILE *f = NULL;
1003  uint32_t SubsystemId = 0;
1004  FileName = cString::sprintf("/sys/class/dvb/dvb%d.frontend%d/device/subsystem_vendor", Adapter, Frontend);
1005  if ((f = fopen(FileName, "r")) != NULL) {
1006  if (char *s = ReadLine.Read(f))
1007  SubsystemId = strtoul(s, NULL, 0) << 16;
1008  fclose(f);
1009  }
1010  FileName = cString::sprintf("/sys/class/dvb/dvb%d.frontend%d/device/subsystem_device", Adapter, Frontend);
1011  if ((f = fopen(FileName, "r")) != NULL) {
1012  if (char *s = ReadLine.Read(f))
1013  SubsystemId |= strtoul(s, NULL, 0);
1014  fclose(f);
1015  }
1016  for (uint32_t *sid = SubsystemIds; *sid; sid++) {
1017  if (*sid == SubsystemId) {
1018  FileName = cString::sprintf("/dev/dvb/adapter%d/osd0", Adapter);
1019  int fd = open(FileName, O_RDWR);
1020  if (fd != -1) { //TODO treat the second path of the S2-6400 as a budget device
1021  close(fd);
1022  dsyslog("creating cDvbHdFfDevice%s", outputOnly ? " (output only)" : "");
1023  new cDvbHdFfDevice(Adapter, Frontend, outputOnly);
1024  return true;
1025  }
1026  else if (outputOnly) {
1027  dsyslog("cDvbHdFfDevice 2nd tuner disabled (outputonly)");
1028  return true;
1029  }
1030  }
1031  }
1032  return false;
1033 }
1034 
1035 
1036 // --- YuvToJpeg -------------------------------------------------------------
1037 
1038 #include <jpeglib.h>
1039 
1040 #define JPEGCOMPRESSMEM 4000000
1041 
1043  int size;
1045  };
1046 
1047 static void JpegCompressInitDestination(j_compress_ptr cinfo)
1048 {
1049  tJpegCompressData *jcd = (tJpegCompressData *)cinfo->client_data;
1050  if (jcd) {
1051  cinfo->dest->free_in_buffer = jcd->size = JPEGCOMPRESSMEM;
1052  cinfo->dest->next_output_byte = jcd->mem = MALLOC(uchar, jcd->size);
1053  }
1054 }
1055 
1056 static boolean JpegCompressEmptyOutputBuffer(j_compress_ptr cinfo)
1057 {
1058  tJpegCompressData *jcd = (tJpegCompressData *)cinfo->client_data;
1059  if (jcd) {
1060  int Used = jcd->size;
1061  int NewSize = jcd->size + JPEGCOMPRESSMEM;
1062  if (uchar *NewBuffer = (uchar *)realloc(jcd->mem, NewSize)) {
1063  jcd->size = NewSize;
1064  jcd->mem = NewBuffer;
1065  }
1066  else {
1067  esyslog("ERROR: out of memory");
1068  return false;
1069  }
1070  if (jcd->mem) {
1071  cinfo->dest->next_output_byte = jcd->mem + Used;
1072  cinfo->dest->free_in_buffer = jcd->size - Used;
1073  return true;
1074  }
1075  }
1076  return false;
1077 }
1078 
1079 static void JpegCompressTermDestination(j_compress_ptr cinfo)
1080 {
1081  tJpegCompressData *jcd = (tJpegCompressData *)cinfo->client_data;
1082  if (jcd) {
1083  int Used = cinfo->dest->next_output_byte - jcd->mem;
1084  if (Used < jcd->size) {
1085  if (uchar *NewBuffer = (uchar *)realloc(jcd->mem, Used)) {
1086  jcd->size = Used;
1087  jcd->mem = NewBuffer;
1088  }
1089  else
1090  esyslog("ERROR: out of memory");
1091  }
1092  }
1093 }
1094 
1095 static uchar *YuvToJpeg(uchar *Mem, int Width, int Height, int &Size, int Quality)
1096 {
1097  if (Quality < 0)
1098  Quality = 0;
1099  else if (Quality > 100)
1100  Quality = 100;
1101 
1102  jpeg_destination_mgr jdm;
1103 
1104  jdm.init_destination = JpegCompressInitDestination;
1105  jdm.empty_output_buffer = JpegCompressEmptyOutputBuffer;
1106  jdm.term_destination = JpegCompressTermDestination;
1107 
1108  struct jpeg_compress_struct cinfo;
1109  struct jpeg_error_mgr jerr;
1110  cinfo.err = jpeg_std_error(&jerr);
1111  jpeg_create_compress(&cinfo);
1112  cinfo.dest = &jdm;
1113  tJpegCompressData jcd;
1114  cinfo.client_data = &jcd;
1115  cinfo.image_width = Width;
1116  cinfo.image_height = Height;
1117  cinfo.input_components = 3;
1118  cinfo.in_color_space = JCS_YCbCr;
1119 
1120  jpeg_set_defaults(&cinfo);
1121  jpeg_set_quality(&cinfo, Quality, true);
1122  jpeg_start_compress(&cinfo, true);
1123 
1124  int rs = Width * 3;
1125  JSAMPROW rp[Height];
1126  for (int k = 0; k < Height; k++)
1127  rp[k] = &Mem[rs * k];
1128  jpeg_write_scanlines(&cinfo, rp, Height);
1129  jpeg_finish_compress(&cinfo);
1130  jpeg_destroy_compress(&cinfo);
1131 
1132  Size = jcd.size;
1133  return jcd.mem;
1134 }
int AudioDownmix
Definition: setup.h:29
virtual void MakePrimaryDevice(bool On)
Informs a device that it will be the primary device.
unsigned char uchar
Definition: tools.h:31
virtual int PlayTsVideo(const uchar *Data, int Length)
Plays the given data block as video.
int Y(void) const
Definition: osd.h:366
void CmdAvSetDecoderInput(uint8_t DecoderIndex, uint8_t DemultiplexerIndex)
Definition: hdffcmd.c:106
virtual bool ProvidesSource(int Source) const
Returns true if this device can provide the given source.
Definition: dvbdevice.c:2012
void CmdMuxSetVolume(uint8_t Volume)
Definition: hdffcmd.c:363
int Apid(int i) const
Definition: remux.h:423
HdffVideoOut_t
Definition: hdffcmd_mux.h:28
#define dsyslog(a...)
Definition: tools.h:37
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...
Definition: device.h:469
uint8_t videoCounter
Definition: dvbhdffdevice.h:89
virtual int64_t GetSTC(void)
Gets the current System Time Counter, which can be used to synchronize audio, video and subtitles...
#define CA_ENCRYPTED_MIN
Definition: channels.h:44
virtual void StillPicture(const uchar *Data, int Length)
Displays the given I-frame as a still picture.
int Dpid(int i) const
Definition: channels.h:161
static cDevice * ReceiverDevice(void)
Definition: transfer.h:38
void DetachAll(int Pid)
Detaches all receivers from this device for this pid.
Definition: device.c:1829
int Ppid(void) const
Definition: channels.h:155
virtual int NumProvidedSystems(void) const
Returns the number of individual "delivery systems" this device provides.
void CmdRemoteSetAddressFilter(bool Enable, uint32_t Address)
Definition: hdffcmd.c:395
#define LOG_ERROR
Definition: tools.h:39
#define DEV_DVB_VIDEO
Definition: dvbdevice.h:79
cTSBuffer * tsBuffer
< Controls how the DVB device handles Transfer Mode when replaying Dolby Digital audio.
Definition: dvbdevice.h:292
virtual void StartDecrypting(void)
Sends all CA_PMT entries to the CAM that have been modified since the last call to this function...
Definition: ci.c:2697
bool IsPrimaryDevice(void) const
Definition: device.h:213
virtual void GetVideoSize(int &Width, int &Height, double &VideoAspect)
Returns the Width, Height and VideoAspect ratio of the currently displayed video material.
Definition: device.c:514
cHdffSetup gHdffSetup
Definition: setup.c:16
virtual void TrickSpeed(int Speed)
HdffVideoModeAdaption_t VideoModeAdaption
Definition: hdffcmd_hdmi.h:49
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
Definition: tools.c:1127
int Height(void) const
Definition: osd.h:368
int Atype(int i) const
Definition: remux.h:426
void CmdAvSetPlayMode(uint8_t PlayMode, bool Realtime)
Definition: hdffcmd.c:66
virtual void Freeze(void)
Puts the device into "freeze frame" mode.
bool Add(int FileHandle, bool Out)
Definition: tools.c:1485
virtual void MakePrimaryDevice(bool On)
Informs a device that it will be the primary device.
Definition: device.c:179
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)
#define esyslog(a...)
Definition: tools.h:35
int Dtype(int i) const
Definition: remux.h:427
virtual void SetVideoDisplayFormat(eVideoDisplayFormat VideoDisplayFormat)
Sets the video display format to the given one (only useful if this device has an MPEG decoder)...
Definition: device.c:487
int Atype(int i) const
Definition: channels.h:166
static cDevice * GetDevice(int Index)
Gets the device with the given Index.
Definition: device.c:223
virtual bool SetChannelDevice(const cChannel *Channel, bool LiveView)
Sets the device to the given channel (actual physical setup).
Definition: dvbdevice.c:2141
ePlayMode playMode
Definition: dvbhdffdevice.h:95
void DelPid(int Pid, ePidType PidType=ptOther)
Deletes a PID from the set of PIDs this device shall receive.
Definition: device.c:606
int Width(void) const
Definition: osd.h:367
void CmdAvSetAudioPid(uint8_t DecoderIndex, uint16_t AudioPid, HdffAudioStreamType_t StreamType, HdffAvContainerType_t ContainerType=HDFF_AV_CONTAINER_PES)
Definition: hdffcmd.c:77
virtual void Play(void)
Sets the device into play mode (after a previous trick mode).
Definition: device.c:1229
int VideoModeAdaption
Definition: setup.h:24
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.
Definition: device.c:1222
eTrackType
Definition: device.h:63
Definition: device.h:39
void CmdAvShowStillImage(uint8_t DecoderIndex, const uint8_t *pStillImage, int Size, HdffVideoStreamType_t StreamType)
Definition: hdffcmd.c:100
int Ca(int Index=0) const
Definition: channels.h:173
static HdffAudioStreamType_t MapAudioStreamTypes(int Atype)
int Vtype(void) const
Definition: channels.h:156
HdffAudioStreamType_t
Definition: hdffcmd_av.h:33
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)
Definition: dvbhdffdevice.c:32
bool Poll(int TimeoutMs=0)
Definition: tools.c:1517
virtual void Mute(void)
Turns off audio while replaying.
Definition: device.c:1243
virtual int NumProvidedSystems(void) const
Returns the number of individual "delivery systems" this device provides.
Definition: dvbdevice.c:2101
char * Read(FILE *f)
Definition: tools.c:1459
int Dtype(int i) const
Definition: channels.h:167
void CmdHdmiSetVideoMode(HdffVideoMode_t VideoMode)
Definition: hdffcmd.c:373
void CmdAvSetVideoPid(uint8_t DecoderIndex, uint16_t VideoPid, HdffVideoStreamType_t StreamType, bool PlaybackMode=false)
Definition: hdffcmd.c:71
void CmdAvEnableVideoAfterStop(uint8_t DecoderIndex, bool EnableVideoAfterStop)
Definition: hdffcmd.c:151
#define MALLOC(type, size)
Definition: tools.h:47
int TsPid(const uchar *p)
Definition: remux.h:87
int RemoteAddress
Definition: setup.h:36
int frontend
Definition: dvbdevice.h:186
void CmdAvSetAudioDelay(int16_t Delay)
Definition: hdffcmd.c:156
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.
Definition: device.c:1236
int Dpid(int i) const
Definition: remux.h:424
HdffVideoMode_t GetVideoMode(void)
Definition: setup.c:107
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.
Definition: device.h:350
#define CHECK(s)
Definition: tools.h:51
int X(void) const
Definition: osd.h:365
void StopSectionHandler(void)
A device that has called StartSectionHandler() must call this function (typically in its destructor) ...
Definition: device.c:662
char CecDeviceName[14]
Definition: hdffcmd_hdmi.h:50
static void JpegCompressInitDestination(j_compress_ptr cinfo)
void CmdHdmiConfigure(const HdffHdmiConfig_t *pConfig)
Definition: hdffcmd.c:379
uint32_t CmdGetFirmwareVersion(char *pString, uint32_t MaxLength)
Definition: hdffcmd.c:33
HDFF::cHdffCmdIf * mHdffCmdIf
Definition: osd.h:352
#define LOCK_CHANNELS_READ
Definition: channels.h:267
virtual bool CanReplay(void) const
Returns true if this device can currently start a replay session.
Definition: device.c:1203
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&#39;s transponder.
Definition: dvbdevice.c:2131
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)
Definition: hdffcmd.c:171
virtual ~cDvbHdFfDevice()
virtual bool SetPlayMode(ePlayMode PlayMode)
Sets the device into the given play mode.
eVideoDisplayFormat
Definition: device.h:58
#define IS_AUDIO_TRACK(t)
Definition: device.h:76
int AnalogueVideo
Definition: setup.h:27
virtual int PlayTsAudio(const uchar *Data, int Length)
Plays the given data block as audio.
bool CamDecrypt(tChannelID ChannelID, int CamSlotNumber)
Definition: ci.c:2921
int adapter
Definition: dvbdevice.h:186
virtual int PlayAudio(const uchar *Data, int Length, uchar Id)
Plays the given data block as audio.
ePlayMode
Definition: device.h:39
int Apid(int i) const
Definition: channels.h:160
int AvSyncShift
Definition: setup.h:30
virtual void GetVideoSize(int &Width, int &Height, double &VideoAspect)
Returns the Width, Height and VideoAspect ratio of the currently displayed video material.
static const cRect Null
Definition: osd.h:357
int CardIndex(void) const
Returns the card index of this device (0 ... MAXDEVICES - 1).
Definition: device.h:214
static void Launch(cControl *Control)
Definition: player.c:79
#define DEV_DVB_OSD
Definition: dvbdevice.h:75
int TvFormat
Definition: setup.h:25
void CmdOsdReset(void)
Definition: hdffcmd.c:186
void GetOsdSize(int &Width, int &Height, double &PixelAspect)
Definition: setup.c:64
void CmdAvSetAudioChannel(uint8_t AudioChannel)
Definition: hdffcmd.c:166
int Vpid(void) const
Definition: channels.h:154
virtual bool Flush(int TimeoutMs=0)
Returns true if the device&#39;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...
Definition: ci.c:2618
void CmdRemoteSetProtocol(HdffRemoteProtocol_t Protocol)
Definition: hdffcmd.c:389
bool supportsPcrInTransferMode
Definition: dvbhdffdevice.h:86
int WriteAllOrNothing(int fd, const uchar *Data, int Length, int TimeoutMs, int RetryMs)
Writes either all Data to the given file descriptor, or nothing at all.
Definition: tools.c:90
cDvbSpuDecoder * spuDecoder
Definition: dvbhdffdevice.h:31
void CmdAvSetVideoWindow(uint8_t DecoderIndex, bool Enable, uint16_t X, uint16_t Y, uint16_t Width, uint16_t Height)
Definition: hdffcmd.c:95
virtual void SetAudioChannelDevice(int AudioChannel)
Sets the audio channel to stereo (0), mono left (1) or mono right (2).
HdffAvContainerType_t
Definition: hdffcmd_av.h:27
const cPatPmtParser * PatPmtParser(void) const
Returns a pointer to the patPmtParser, so that a derived device can use the stream information from i...
Definition: device.h:634
void CmdMuxSetVideoOut(HdffVideoOut_t VideoOut)
Definition: hdffcmd.c:358
void CmdAvSetVideoSpeed(uint8_t DecoderIndex, int32_t Speed)
Definition: hdffcmd.c:141
tChannelID GetChannelID(void) const
Definition: channels.h:190
The cDvbHdFfDevice implements a DVB device which can be accessed through the Linux DVB driver API...
Definition: dvbhdffdevice.h:16
virtual bool ProvidesSource(int Source) const
Returns true if this device can provide the given source.
int AudioDelay
Definition: setup.h:28
const tTrackId * GetTrack(eTrackType Type)
Returns a pointer to the given track id, or NULL if Type is not less than ttMaxTrackTypes.
Definition: device.c:1077
HdffAudioDownmixMode_t
Definition: hdffcmd_av.h:87
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.
Definition: device.c:531
cChannelCamRelations ChannelCamRelations
Definition: ci.c:2864
#define DEV_DVB_DEMUX
Definition: dvbdevice.h:78
bool Transferring(void) const
Returns true if we are currently in Transfer Mode.
Definition: device.c:1312
void CmdAvSetStc(uint8_t DecoderIndex, uint64_t Stc)
Definition: hdffcmd.c:126
virtual uchar * GrabImage(int &Size, bool Jpeg=true, int Quality=-1, int SizeX=-1, int SizeY=-1)
Grabs the currently visible screen image.
HdffVideoStreamType_t
Definition: hdffcmd_av.h:46
int RemoteProtocol
Definition: setup.h:35
int CecEnabled
Definition: setup.h:32
The cDvbDevice implements a DVB device which can be accessed through the Linux DVB driver API...
Definition: dvbdevice.h:170
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)
Definition: hdffcmd.c:161
#define TS_SIZE
Definition: remux.h:34
#define JPEGCOMPRESSMEM
static HdffVideoStreamType_t MapVideoStreamTypes(int Vtype)
virtual void SetVolumeDevice(int Volume)
Sets the audio volume on this device (Volume = 0...255).
static int devHdffOffset
#define BUFFER_SIZE
#define IS_DOLBY_TRACK(t)
Definition: device.h:77
static uchar * YuvToJpeg(uchar *Mem, int Width, int Height, int &Size, int Quality)
void CmdAvSetPcrPid(uint8_t DecoderIndex, uint16_t PcrPid)
Definition: hdffcmd.c:84
HdffVideoModeAdaption_t
Definition: hdffcmd_hdmi.h:36
virtual cSpuDecoder * GetSpuDecoder(void)
Returns a pointer to the device&#39;s SPU decoder (or NULL, if this device doesn&#39;t have an SPU decoder)...
Definition: tools.h:393
int VideoConversion
Definition: setup.h:26
virtual void StillPicture(const uchar *Data, int Length)
Displays the given I-frame as a still picture.
Definition: device.c:1248
void SetVideoFormat(HDFF::cHdffCmdIf *HdffCmdIf)
Definition: setup.c:185
void CmdAvSetAudioSpeed(uint8_t DecoderIndex, int32_t Speed)
Definition: hdffcmd.c:146
virtual bool SetPid(cPidHandle *Handle, int Type, bool On)
Does the actual PID setting on this device.
cPidHandle pidHandles[MAXPIDHANDLES]
Definition: device.h:399
void CmdAvMuteAudio(uint8_t DecoderIndex, bool Mute)
Definition: hdffcmd.c:176
bool AddPid(int Pid, ePidType PidType=ptOther, int StreamType=0)
Adds a PID to the set of PIDs this device shall receive.
Definition: device.c:541
#define DEV_DVB_AUDIO
Definition: dvbdevice.h:80
int SlotNumber(void)
Returns the number of this CAM slot within the whole system.
Definition: ci.h:343
uint8_t audioCounter
Definition: dvbhdffdevice.h:90
Definition: tools.h:176
int Number(void) const
Definition: channels.h:179
static int DvbOpen(const char *Name, int Adapter, int Frontend, int Mode, bool ReportError=false)
Definition: dvbdevice.c:1634
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)
Definition: hdffcmd.c:136
static cDevice * device[MAXDEVICES]
Definition: device.h:124
HdffRemoteProtocol_t
uint16_t id
Definition: device.h:81
virtual void Mute(void)
Turns off audio while replaying.