vdr  2.0.5
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)
33 :cDvbDevice(Adapter, Frontend)
34 {
35  spuDecoder = NULL;
36  audioChannel = 0;
37  playMode = pmNone;
38  mHdffCmdIf = NULL;
39 
40  // Devices that are only present on cards with decoders:
41 
43  fd_video = DvbOpen(DEV_DVB_VIDEO, adapter, frontend, O_RDWR | O_NONBLOCK);
44  fd_audio = DvbOpen(DEV_DVB_AUDIO, adapter, frontend, O_RDWR | O_NONBLOCK);
45 
46  //TODO missing /dev/video offset calculation
47 
48  isHdffPrimary = false;
49  if (devHdffOffset < 0) {
51  isHdffPrimary = true;
53 
54  /* reset some stuff in case the VDR was killed before and had no chance
55  to clean up. */
57 
60 
65 
66  ioctl(fd_video, VIDEO_SELECT_SOURCE, VIDEO_SOURCE_DEMUX);
68  mHdffCmdIf->CmdAvEnableSync(0, true);
69  mHdffCmdIf->CmdAvSetPlayMode(0, true);
70  /* reset done */
71 
77 
78  HdffHdmiConfig_t hdmiConfig;
79  memset(&hdmiConfig, 0, sizeof(hdmiConfig));
80  hdmiConfig.TransmitAudio = true;
81  hdmiConfig.ForceDviMode = false;
82  hdmiConfig.CecEnabled = gHdffSetup.CecEnabled;
83  strcpy(hdmiConfig.CecDeviceName, "VDR");
85  mHdffCmdIf->CmdHdmiConfigure(&hdmiConfig);
86 
89  }
90 }
91 
93 {
94  delete spuDecoder;
95  if (isHdffPrimary)
96  {
97  delete mHdffCmdIf;
98  }
99  // We're not explicitly closing any device files here, since this sometimes
100  // caused segfaults. Besides, the program is about to terminate anyway...
101 }
102 
104 {
105  if (On)
108 }
109 
111 {
112  return isHdffPrimary;
113 }
114 
116 {
117  if (!spuDecoder && IsPrimaryDevice())
118  spuDecoder = new cDvbSpuDecoder();
119  return spuDecoder;
120 }
121 
122 uchar *cDvbHdFfDevice::GrabImage(int &Size, bool Jpeg, int Quality, int SizeX, int SizeY)
123 {
124  #define BUFFER_SIZE (sizeof(struct v4l2_pix_format) + 1920 * 1080 * 2)
125  int fd;
126  uint8_t * buffer;
127  uint8_t * result = NULL;
128 
129  fd = DvbOpen(DEV_DVB_VIDEO, adapter, frontend, O_RDONLY);
130  if (fd < 0) {
131  esyslog("GrabImage: failed open DVB video device");
132  return NULL;
133  }
134 
135  buffer = (uint8_t *) malloc(BUFFER_SIZE);
136  if (buffer)
137  {
138  int readBytes;
139 
140  readBytes = read(fd, buffer, BUFFER_SIZE);
141  if (readBytes < (int) sizeof(struct v4l2_pix_format))
142  esyslog("GrabImage: failed reading from DVB video device");
143  else {
144  struct v4l2_pix_format * pixfmt;
145  int dataSize;
146 
147  pixfmt = (struct v4l2_pix_format *) buffer;
148  dsyslog("GrabImage: Read image of size %d x %d",
149  pixfmt->width, pixfmt->height);
150  dataSize = readBytes - sizeof(struct v4l2_pix_format);
151  if (dataSize < (int) pixfmt->sizeimage)
152  esyslog("GrabImage: image is not complete");
153  else {
154  if (Jpeg) {
155  uint8_t * temp;
156  temp = (uint8_t *) malloc(pixfmt->width * 3 * pixfmt->height);
157  if (temp) {
158  int numPixels = pixfmt->width * pixfmt->height;
159  uint8_t * destData = temp;
160  uint8_t * srcData = buffer + sizeof(struct v4l2_pix_format);
161  while (numPixels > 0)
162  {
163  destData[0] = srcData[1];
164  destData[1] = srcData[0];
165  destData[2] = srcData[2];
166  destData[3] = srcData[3];
167  destData[4] = srcData[0];
168  destData[5] = srcData[2];
169  srcData += 4;
170  destData += 6;
171  numPixels -= 2;
172  }
173  if (Quality < 0)
174  Quality = 100;
175  result = YuvToJpeg(temp, pixfmt->width, pixfmt->height, Size, Quality);
176  free(temp);
177  }
178  }
179  else {
180  // convert to PNM:
181  char buf[32];
182  snprintf(buf, sizeof(buf), "P6\n%d\n%d\n255\n",
183  pixfmt->width, pixfmt->height);
184  int l = strlen(buf);
185  Size = l + pixfmt->width * 3 * pixfmt->height;
186  result = (uint8_t *) malloc(Size);
187  if (result)
188  {
189  memcpy(result, buf, l);
190  uint8_t * destData = result + l;
191  uint8_t * srcData = buffer + sizeof(struct v4l2_pix_format);
192  int numPixels = pixfmt->width * pixfmt->height;
193  while (numPixels > 0)
194  {
195  int cb = srcData[0] - 128;
196  int y1 = srcData[1];
197  int cr = srcData[2] - 128;
198  int y2 = srcData[3];
199  int r;
200  int g;
201  int b;
202 
203  r = y1 + (int) (1.402f * cr);
204  g = y1 - (int) (0.344f * cb + 0.714f * cr);
205  b = y1 + (int) (1.772f * cb);
206  destData[0] = r > 255 ? 255 : r < 0 ? 0 : r;
207  destData[1] = g > 255 ? 255 : g < 0 ? 0 : g;
208  destData[2] = b > 255 ? 255 : b < 0 ? 0 : b;
209  r = y2 + (int) (1.402f * cr);
210  g = y2 - (int) (0.344f * cb + 0.714f * cr);
211  b = y2 + (int) (1.772f * cb);
212  destData[3] = r > 255 ? 255 : r < 0 ? 0 : r;
213  destData[4] = g > 255 ? 255 : g < 0 ? 0 : g;
214  destData[5] = b > 255 ? 255 : b < 0 ? 0 : b;
215 
216  srcData += 4;
217  destData += 6;
218  numPixels -= 2;
219  }
220  }
221  }
222  }
223  }
224  free(buffer);
225  }
226 
227  close(fd);
228 
229  return result;
230 }
231 
233 {
234  //TODO???
235  cDevice::SetVideoDisplayFormat(VideoDisplayFormat);
236 }
237 
238 void cDvbHdFfDevice::SetVideoFormat(bool VideoFormat16_9)
239 {
240  HdffVideoFormat_t videoFormat;
241  videoFormat.AutomaticEnabled = true;
242  videoFormat.AfdEnabled = false;
243  videoFormat.TvFormat = (HdffTvFormat_t) gHdffSetup.TvFormat;
245  mHdffCmdIf->CmdAvSetVideoFormat(0, &videoFormat);
246 }
247 
249 {
250  eVideoSystem VideoSystem = vsPAL;
251  if (fd_video >= 0) {
252  video_size_t vs;
253  if (ioctl(fd_video, VIDEO_GET_SIZE, &vs) == 0) {
254  if (vs.h == 480 || vs.h == 240)
255  VideoSystem = vsNTSC;
256  }
257  else
258  LOG_ERROR;
259  }
260  return VideoSystem;
261 }
262 
263 void cDvbHdFfDevice::GetVideoSize(int &Width, int &Height, double &VideoAspect)
264 {
265  if (fd_video >= 0) {
266  video_size_t vs;
267  if (ioctl(fd_video, VIDEO_GET_SIZE, &vs) == 0) {
268  Width = vs.w;
269  Height = vs.h;
270  switch (vs.aspect_ratio) {
271  default:
272  case VIDEO_FORMAT_4_3: VideoAspect = 4.0 / 3.0; break;
273  case VIDEO_FORMAT_16_9: VideoAspect = 16.0 / 9.0; break;
274  case VIDEO_FORMAT_221_1: VideoAspect = 2.21; break;
275  }
276  return;
277  }
278  else
279  LOG_ERROR;
280  }
281  cDevice::GetVideoSize(Width, Height, VideoAspect);
282 }
283 
284 void cDvbHdFfDevice::GetOsdSize(int &Width, int &Height, double &PixelAspect)
285 {
286  gHdffSetup.GetOsdSize(Width, Height, PixelAspect);
287 }
288 
289 bool cDvbHdFfDevice::SetPid(cPidHandle *Handle, int Type, bool On)
290 {
291  //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);
292  if (Handle->pid) {
293  dmx_pes_filter_params pesFilterParams;
294  memset(&pesFilterParams, 0, sizeof(pesFilterParams));
295  if (On) {
296  if (Handle->handle < 0) {
297  Handle->handle = DvbOpen(DEV_DVB_DEMUX, adapter, frontend, O_RDWR | O_NONBLOCK, true);
298  if (Handle->handle < 0) {
299  LOG_ERROR;
300  return false;
301  }
302  }
303  if (Type == ptPcr)
304  mHdffCmdIf->CmdAvSetPcrPid(0, Handle->pid);
305  else if (Type == ptVideo) {
306  if (Handle->streamType == 0x1B)
308  else
310  }
311  else if (Type == ptAudio) {
312  if (Handle->streamType == 0x03)
314  else if (Handle->streamType == 0x04)
316  else if (Handle->streamType == SI::AC3DescriptorTag)
318  else if (Handle->streamType == SI::EnhancedAC3DescriptorTag)
320  else if (Handle->streamType == 0x0F)
322  else if (Handle->streamType == 0x11)
324  else
326  }
327  if (!(Type <= ptDolby && Handle->used <= 1)) {
328  pesFilterParams.pid = Handle->pid;
329  pesFilterParams.input = DMX_IN_FRONTEND;
330  pesFilterParams.output = DMX_OUT_TS_TAP;
331  pesFilterParams.pes_type= DMX_PES_OTHER;
332  pesFilterParams.flags = DMX_IMMEDIATE_START;
333  if (ioctl(Handle->handle, DMX_SET_PES_FILTER, &pesFilterParams) < 0) {
334  LOG_ERROR;
335  return false;
336  }
337  }
338  }
339  else if (!Handle->used) {
340  CHECK(ioctl(Handle->handle, DMX_STOP));
341  if (Type == ptPcr)
342  mHdffCmdIf->CmdAvSetPcrPid(0, 0);
343  else if (Type == ptVideo)
345  else if (Type == ptAudio)
347  else if (Type == ptDolby)
349  //TODO missing setting to 0x1FFF??? see cDvbDevice::SetPid()
350  close(Handle->handle);
351  Handle->handle = -1;
352  }
353  }
354  return true;
355 }
356 
358 {
359  // Turn off live PIDs:
360 
363  DetachAll(pidHandles[ptPcr].pid);
365  DelPid(pidHandles[ptAudio].pid);
366  DelPid(pidHandles[ptVideo].pid);
367  DelPid(pidHandles[ptPcr].pid, ptPcr);
369  DelPid(pidHandles[ptDolby].pid);
370 }
371 
372 bool cDvbHdFfDevice::SetChannelDevice(const cChannel *Channel, bool LiveView)
373 {
374  int apid = Channel->Apid(0);
375  int vpid = Channel->Vpid();
376  int dpid = Channel->Dpid(0);
377 
378  bool DoTune = !IsTunedToTransponder(Channel);
379 
380  bool pidHandlesVideo = pidHandles[ptVideo].pid == vpid;
381  bool pidHandlesAudio = pidHandles[ptAudio].pid == apid;
382 
383  bool TurnOffLivePIDs = DoTune
384  || !IsPrimaryDevice()
385  || LiveView // for a new live view the old PIDs need to be turned off
386  || pidHandlesVideo // for recording the PIDs must be shifted from DMX_PES_AUDIO/VIDEO to DMX_PES_OTHER
387  ;
388 
389  bool StartTransferMode = IsPrimaryDevice() && !DoTune
390  && (LiveView && HasPid(vpid ? vpid : apid) && (!pidHandlesVideo || (!pidHandlesAudio && (dpid ? pidHandles[ptAudio].pid != dpid : true)))// the PID is already set as DMX_PES_OTHER
391  || !LiveView && (pidHandlesVideo || pidHandlesAudio) // a recording is going to shift the PIDs from DMX_PES_AUDIO/VIDEO to DMX_PES_OTHER
392  );
394  StartTransferMode |= LiveView && IsPrimaryDevice() && Channel->Ca() >= CA_ENCRYPTED_MIN;
395 
396  //printf("SetChannelDevice Transfer %d, Live %d\n", StartTransferMode, LiveView);
397 
398  bool TurnOnLivePIDs = !StartTransferMode && LiveView;
399 
400  // Turn off live PIDs if necessary:
401 
402  if (TurnOffLivePIDs)
403  TurnOffLiveMode(LiveView);
404 
405  // Set the tuner:
406 
407  if (!cDvbDevice::SetChannelDevice(Channel, LiveView))
408  return false;
409 
410  // PID settings:
411 
412  if (TurnOnLivePIDs) {
413  if (!(AddPid(Channel->Ppid(), ptPcr) && AddPid(vpid, ptVideo, Channel->Vtype()) && AddPid(apid ? apid : dpid, ptAudio, apid ? 0 : Channel->Dtype(0)))) {
414  esyslog("ERROR: failed to set PIDs for channel %d on device %d", Channel->Number(), CardIndex() + 1);
415  return false;
416  }
417  }
418  else if (StartTransferMode)
419  cControl::Launch(new cTransferControl(this, Channel));
420 
421  return true;
422 }
423 
425 {
426  return audioChannel;
427 }
428 
430 {
431  mHdffCmdIf->CmdAvSetAudioChannel(AudioChannel);
432  audioChannel = AudioChannel;
433 }
434 
436 {
437  mHdffCmdIf->CmdMuxSetVolume(Volume * 100 / 255);
438 }
439 
441 {
442  // not needed
443 }
444 
446 {
447  //printf("SetAudioTrackDevice %d\n", Type);
448  const tTrackId *TrackId = GetTrack(Type);
449  if (TrackId && TrackId->id) {
450  int streamType = 0;
452  if (channel) {
453  if (IS_AUDIO_TRACK(Type))
454  streamType = channel->Atype(Type - ttAudioFirst);
455  else if (IS_DOLBY_TRACK(Type))
456  streamType = channel->Dtype(Type - ttDolbyFirst);
457  }
458  //printf("SetAudioTrackDevice new %d %d, current %d\n", TrackId->id, streamType, pidHandles[ptAudio].pid);
459  if (pidHandles[ptAudio].pid && pidHandles[ptAudio].pid != TrackId->id) {
461  if (CamSlot())
462  CamSlot()->SetPid(pidHandles[ptAudio].pid, false);
463  pidHandles[ptAudio].pid = TrackId->id;
464  pidHandles[ptAudio].streamType = streamType;
465  SetPid(&pidHandles[ptAudio], ptAudio, true);
466  if (CamSlot()) {
467  CamSlot()->SetPid(pidHandles[ptAudio].pid, true);
469  }
470  }
471  }
472 }
473 
475 {
476  return cDevice::CanReplay();
477 }
478 
480 {
481  if (PlayMode == pmNone) {
482  if (fd_video == -1)
483  fd_video = DvbOpen(DEV_DVB_VIDEO, adapter, frontend, O_RDWR | O_NONBLOCK);
484  if (fd_audio == -1)
485  fd_audio = DvbOpen(DEV_DVB_AUDIO, adapter, frontend, O_RDWR | O_NONBLOCK);
486 
489 
491  mHdffCmdIf->CmdAvSetPcrPid(0, 0);
494 
495  ioctl(fd_video, VIDEO_SELECT_SOURCE, VIDEO_SOURCE_DEMUX);
497  mHdffCmdIf->CmdAvEnableSync(0, true);
498  mHdffCmdIf->CmdAvSetPlayMode(0, true);
499  mHdffCmdIf->CmdAvMuteAudio(0, false);
500  }
501  else {
502  if (playMode == pmNone)
503  TurnOffLiveMode(true);
504 
505  if (PlayMode == pmExtern_THIS_SHOULD_BE_AVOIDED)
506  {
507  close(fd_video);
508  fd_video = -1;
509  close(fd_audio);
510  fd_audio = -1;
511  }
512  else
513  {
515  mHdffCmdIf->CmdAvSetStc(0, 100000);
516  mHdffCmdIf->CmdAvEnableSync(0, false);
518 
519  playVideoPid = -1;
520  playAudioPid = -1;
521  audioCounter = 0;
522  videoCounter = 0;
523  freezed = false;
524  trickMode = false;
525  isPlayingVideo = false;
526 
528  ioctl(fd_video, VIDEO_SELECT_SOURCE, VIDEO_SOURCE_MEMORY);
529  }
530  }
531  playMode = PlayMode;
532  return true;
533 }
534 
536 {
537  if (isPlayingVideo)
538  {
539  if (fd_video >= 0) {
540  uint64_t pts;
541  if (ioctl(fd_video, VIDEO_GET_PTS, &pts) == -1) {
542  esyslog("ERROR: pts %d: %m", CardIndex() + 1);
543  return -1;
544  }
545  //printf("video PTS %lld\n", pts);
546  return pts;
547  }
548  }
549  else
550  {
551  if (fd_audio >= 0) {
552  uint64_t pts;
553  if (ioctl(fd_audio, AUDIO_GET_PTS, &pts) == -1) {
554  esyslog("ERROR: pts %d: %m", CardIndex() + 1);
555  return -1;
556  }
557  //printf("audio PTS %lld\n", pts);
558  return pts;
559  }
560  }
561  return -1;
562 }
563 
564 cRect cDvbHdFfDevice::CanScaleVideo(const cRect &Rect, int Alignment)
565 {
566  return Rect;
567 }
568 
570 {
571  if (Rect == cRect::Null)
572  {
573  mHdffCmdIf->CmdAvSetVideoWindow(0, false, 0, 0, 0, 0);
574  }
575  else
576  {
577  //printf("ScaleVideo: Rect = %d %d %d %d\n", Rect.X(), Rect.Y(), Rect.Width(), Rect.Height());
578 
579  int osdWidth;
580  int osdHeight;
581  double osdPixelAspect;
582 
583  GetOsdSize(osdWidth, osdHeight, osdPixelAspect);
584  //printf("ScaleVideo: OsdSize = %d %d %g\n", osdWidth, osdHeight, osdPixelAspect);
585 
586  // Convert the video window coordinates in 1/10 percent of the display
587  // resolution.
588  int x = (Rect.X() * 1000 + osdWidth / 2) / osdWidth;
589  int y = (Rect.Y() * 1000 + osdHeight / 2) / osdHeight;
590  int w = (Rect.Width() * 1000 + osdWidth / 2) / osdWidth;
591  int h = (Rect.Height() * 1000 + osdHeight / 2) / osdHeight;
592  //printf("ScaleVideo: Win1 = %d %d %d %d\n", x, y, w, h);
593 
594  // fix aspect ratio, reposition video
595  if (w > h) {
596  x += (w - h) / 2;
597  w = h;
598  }
599  else if (w < h) {
600  y += (h - w) / 2;
601  h = w;
602  }
603 
604  //printf("ScaleVideo: Win2 = %d %d %d %d\n", x, y, w, h);
605  mHdffCmdIf->CmdAvSetVideoWindow(0, true, x, y, w, h);
606  }
607 }
608 
610 {
611  freezed = false;
612  mHdffCmdIf->CmdAvEnableSync(0, false);
614  playAudioPid = -1;
615  if (Speed > 0)
616  mHdffCmdIf->CmdAvSetVideoSpeed(0, 100 / Speed);
617  trickMode = true;
618 }
619 
621 {
622  CHECK(ioctl(fd_video, VIDEO_CLEAR_BUFFER));
625  playVideoPid = -1;
626  playAudioPid = -1;
627  cDevice::Clear();
628 }
629 
631 {
632  freezed = false;
633  trickMode = false;
634  if (isPlayingVideo)
635  mHdffCmdIf->CmdAvEnableSync(0, true);
638  mHdffCmdIf->CmdAvMuteAudio(0, false);
639  cDevice::Play();
640 }
641 
643 {
644  freezed = true;
647  cDevice::Freeze();
648 }
649 
651 {
652  mHdffCmdIf->CmdAvMuteAudio(0, true);
653  cDevice::Mute();
654 }
655 
657 {
658  switch (Vtype) {
659  case 0x01: return HDFF_VIDEO_STREAM_MPEG1;
660  case 0x02: return HDFF_VIDEO_STREAM_MPEG2;
661  case 0x1B: return HDFF_VIDEO_STREAM_H264;
662  default: return HDFF_VIDEO_STREAM_MPEG2; // fallback to MPEG2
663  }
664 }
665 
666 void cDvbHdFfDevice::StillPicture(const uchar *Data, int Length)
667 {
668  if (!Data || Length < TS_SIZE)
669  return;
670  if (Data[0] == 0x47) {
671  // TS data
672  cDevice::StillPicture(Data, Length);
673  }
674  else if (Data[0] == 0x00 && Data[1] == 0x00 && Data[2] == 0x01 && (Data[3] & 0xF0) == 0xE0) {
675  // PES data
676  char *buf = MALLOC(char, Length);
677  if (!buf)
678  return;
679  int i = 0;
680  int blen = 0;
681  while (i < Length - 6) {
682  if (Data[i] == 0x00 && Data[i + 1] == 0x00 && Data[i + 2] == 0x01) {
683  int len = Data[i + 4] * 256 + Data[i + 5];
684  if ((Data[i + 3] & 0xF0) == 0xE0) { // video packet
685  // skip PES header
686  int offs = i + 6;
687  // skip header extension
688  if ((Data[i + 6] & 0xC0) == 0x80) {
689  // MPEG-2 PES header
690  if (Data[i + 8] >= Length)
691  break;
692  offs += 3;
693  offs += Data[i + 8];
694  len -= 3;
695  len -= Data[i + 8];
696  if (len < 0 || offs + len > Length)
697  break;
698  }
699  else {
700  // MPEG-1 PES header
701  while (offs < Length && len > 0 && Data[offs] == 0xFF) {
702  offs++;
703  len--;
704  }
705  if (offs <= Length - 2 && len >= 2 && (Data[offs] & 0xC0) == 0x40) {
706  offs += 2;
707  len -= 2;
708  }
709  if (offs <= Length - 5 && len >= 5 && (Data[offs] & 0xF0) == 0x20) {
710  offs += 5;
711  len -= 5;
712  }
713  else if (offs <= Length - 10 && len >= 10 && (Data[offs] & 0xF0) == 0x30) {
714  offs += 10;
715  len -= 10;
716  }
717  else if (offs < Length && len > 0) {
718  offs++;
719  len--;
720  }
721  }
722  if (blen + len > Length) // invalid PES length field
723  break;
724  memcpy(&buf[blen], &Data[offs], len);
725  i = offs + len;
726  blen += len;
727  }
728  else if (Data[i + 3] >= 0xBD && Data[i + 3] <= 0xDF) // other PES packets
729  i += len + 6;
730  else
731  i++;
732  }
733  else
734  i++;
735  }
736  mHdffCmdIf->CmdAvShowStillImage(0, (uint8_t *)buf, blen, MapVideoStreamTypes(PatPmtParser()->Vtype()));
737  free(buf);
738  }
739  else {
740  // non-PES data
741  mHdffCmdIf->CmdAvShowStillImage(0, Data, Length, MapVideoStreamTypes(PatPmtParser()->Vtype()));
742  }
743 }
744 
745 bool cDvbHdFfDevice::Poll(cPoller &Poller, int TimeoutMs)
746 {
747  Poller.Add(fd_video, true);
748  return Poller.Poll(TimeoutMs);
749 }
750 
751 bool cDvbHdFfDevice::Flush(int TimeoutMs)
752 {
753  //TODO actually this function should wait until all buffered data has been processed by the card, but how?
754  return true;
755 }
756 
757 void cDvbHdFfDevice::BuildTsPacket(uint8_t * TsBuffer, bool PusiSet, uint16_t Pid, uint8_t Counter, const uint8_t * Data, uint32_t Length)
758 {
759  TsBuffer[0] = 0x47;
760  TsBuffer[1] = PusiSet ? 0x40 : 0x00;
761  TsBuffer[1] |= Pid >> 8;
762  TsBuffer[2] = Pid & 0xFF;
763  if (Length >= 184)
764  {
765  TsBuffer[3] = 0x10 | Counter;
766  memcpy(TsBuffer + 4, Data, 184);
767  }
768  else
769  {
770  uint8_t adaptationLength;
771 
772  TsBuffer[3] = 0x30 | Counter;
773  adaptationLength = 183 - Length;
774  TsBuffer[4] = adaptationLength;
775  if (adaptationLength > 0)
776  {
777  TsBuffer[5] = 0x00;
778  memset(TsBuffer + 6, 0xFF, adaptationLength - 1);
779  }
780  memcpy(TsBuffer + 5 + adaptationLength, Data, Length);
781  }
782 }
783 
784 uint32_t cDvbHdFfDevice::PesToTs(uint8_t * TsBuffer, uint16_t Pid, uint8_t & Counter, const uint8_t * Data, uint32_t Length)
785 {
786  uint32_t tsOffset;
787  uint32_t i;
788 
789  tsOffset = 0;
790  i = 0;
791  while (Length > 0)
792  {
793  BuildTsPacket(TsBuffer + tsOffset, i == 0, Pid, Counter, Data + i * 184, Length);
794  if (Length >= 184)
795  Length -= 184;
796  else
797  Length = 0;
798  Counter = (Counter + 1) & 15;
799  tsOffset += 188;
800  i++;
801  }
802  return tsOffset;
803 }
804 
805 int cDvbHdFfDevice::PlayVideo(const uchar *Data, int Length)
806 {
807  if (freezed)
808  return -1;
809  if (!isPlayingVideo)
810  {
811  mHdffCmdIf->CmdAvEnableSync(0, true);
812  isPlayingVideo = true;
813  }
814  //TODO: support greater Length
815  uint8_t tsBuffer[188 * 16];
816  uint32_t tsLength;
817  int pid = 100;
818 
819  tsLength = PesToTs(tsBuffer, pid, videoCounter, Data, Length);
820 
821  if (pid != playVideoPid) {
822  playVideoPid = pid;
824  }
825  if (WriteAllOrNothing(fd_video, tsBuffer, tsLength, 1000, 10) <= 0)
826  Length = 0;
827  return Length;
828 }
829 
830 int cDvbHdFfDevice::PlayAudio(const uchar *Data, int Length, uchar Id)
831 {
832  if (freezed)
833  return -1;
834  uint8_t streamId;
835  uint8_t tsBuffer[188 * 16];
836  uint32_t tsLength;
839  int pid;
840 
841  streamId = Data[3];
842  if (streamId >= 0xC0 && streamId <= 0xDF)
843  {
844  streamType = HDFF_AUDIO_STREAM_MPEG1;
845  }
846  else if (streamId == 0xBD)
847  {
848  const uint8_t * payload = Data + 9 + Data[8];
849  if ((payload[0] & 0xF8) == 0xA0)
850  {
851  containerType = HDFF_AV_CONTAINER_PES_DVD;
852  streamType = HDFF_AUDIO_STREAM_PCM;
853  }
854  else if ((payload[0] & 0xF8) == 0x88)
855  {
856  containerType = HDFF_AV_CONTAINER_PES_DVD;
857  streamType = HDFF_AUDIO_STREAM_DTS;
858  }
859  else if ((payload[0] & 0xF8) == 0x80)
860  {
861  containerType = HDFF_AV_CONTAINER_PES_DVD;
862  streamType = HDFF_AUDIO_STREAM_AC3;
863  }
864  else
865  {
866  streamType = HDFF_AUDIO_STREAM_AC3;
867  }
868  }
869  pid = 200 + (int) streamType;
870  tsLength = PesToTs(tsBuffer, pid, audioCounter, Data, Length);
871 
872  if (pid != playAudioPid) {
873  playAudioPid = pid;
874  mHdffCmdIf->CmdAvSetAudioPid(0, playAudioPid, streamType, containerType);
875  }
876  if (WriteAllOrNothing(fd_video, tsBuffer, tsLength, 1000, 10) <= 0)
877  Length = 0;
878  return Length;
879 }
880 
881 int cDvbHdFfDevice::PlayTsVideo(const uchar *Data, int Length)
882 {
883  if (freezed)
884  return -1;
885  if (!isPlayingVideo)
886  {
887  mHdffCmdIf->CmdAvEnableSync(0, true);
888  isPlayingVideo = true;
889  }
890 
891  int pid = TsPid(Data);
892  if (pid != playVideoPid) {
893  PatPmtParser();
894  if (pid == PatPmtParser()->Vpid()) {
895  playVideoPid = pid;
897  }
898  }
899  return WriteAllOrNothing(fd_video, Data, Length, 1000, 10);
900 }
901 
903 {
904  switch (Atype) {
905  case 0x03: return HDFF_AUDIO_STREAM_MPEG1;
906  case 0x04: return HDFF_AUDIO_STREAM_MPEG2;
909  case 0x0F: return HDFF_AUDIO_STREAM_AAC;
910  case 0x11: return HDFF_AUDIO_STREAM_HE_AAC;
911  default: return HDFF_AUDIO_STREAM_MPEG1;
912  }
913 }
914 
915 int cDvbHdFfDevice::PlayTsAudio(const uchar *Data, int Length)
916 {
917  if (freezed)
918  return -1;
919  int pid = TsPid(Data);
920  if (pid != playAudioPid) {
921  playAudioPid = pid;
922  int AudioStreamType = -1;
923  for (int i = 0; PatPmtParser()->Apid(i); i++) {
924  if (playAudioPid == PatPmtParser()->Apid(i)) {
925  AudioStreamType = PatPmtParser()->Atype(i);
926  break;
927  }
928  }
929  if (AudioStreamType < 0) {
930  for (int i = 0; PatPmtParser()->Dpid(i); i++) {
931  if (playAudioPid == PatPmtParser()->Dpid(i)) {
932  AudioStreamType = PatPmtParser()->Dtype(i);
933  break;
934  }
935  }
936  }
938  }
939  return WriteAllOrNothing(fd_video, Data, Length, 1000, 10);
940 }
941 
943 {
944  //TODO why not just keep a pointer?
945  if (devHdffOffset >= 0) {
947  if (device)
948  return device->mHdffCmdIf;
949  }
950  return NULL;
951 }
952 
953 // --- cDvbHdFfDeviceProbe ---------------------------------------------------
954 
955 bool cDvbHdFfDeviceProbe::Probe(int Adapter, int Frontend)
956 {
957  static uint32_t SubsystemIds[] = {
958  0x13C23009, // Technotrend S2-6400 HDFF development samples
959  0x13C2300A, // Technotrend S2-6400 HDFF production version
960  0x00000000
961  };
962  cString FileName;
963  cReadLine ReadLine;
964  FILE *f = NULL;
965  uint32_t SubsystemId = 0;
966  FileName = cString::sprintf("/sys/class/dvb/dvb%d.frontend%d/device/subsystem_vendor", Adapter, Frontend);
967  if ((f = fopen(FileName, "r")) != NULL) {
968  if (char *s = ReadLine.Read(f))
969  SubsystemId = strtoul(s, NULL, 0) << 16;
970  fclose(f);
971  }
972  FileName = cString::sprintf("/sys/class/dvb/dvb%d.frontend%d/device/subsystem_device", Adapter, Frontend);
973  if ((f = fopen(FileName, "r")) != NULL) {
974  if (char *s = ReadLine.Read(f))
975  SubsystemId |= strtoul(s, NULL, 0);
976  fclose(f);
977  }
978  for (uint32_t *sid = SubsystemIds; *sid; sid++) {
979  if (*sid == SubsystemId) {
980  FileName = cString::sprintf("/dev/dvb/adapter%d/osd0", Adapter);
981  int fd = open(FileName, O_RDWR);
982  if (fd != -1) { //TODO treat the second path of the S2-6400 as a budget device
983  close(fd);
984  dsyslog("creating cDvbHdFfDevice");
985  new cDvbHdFfDevice(Adapter, Frontend);
986  return true;
987  }
988  }
989  }
990  return false;
991 }
992 
993 
994 // --- YuvToJpeg -------------------------------------------------------------
995 
996 #include <jpeglib.h>
997 
998 #define JPEGCOMPRESSMEM 4000000
999 
1001  int size;
1003  };
1004 
1005 static void JpegCompressInitDestination(j_compress_ptr cinfo)
1006 {
1007  tJpegCompressData *jcd = (tJpegCompressData *)cinfo->client_data;
1008  if (jcd) {
1009  cinfo->dest->free_in_buffer = jcd->size = JPEGCOMPRESSMEM;
1010  cinfo->dest->next_output_byte = jcd->mem = MALLOC(uchar, jcd->size);
1011  }
1012 }
1013 
1014 static boolean JpegCompressEmptyOutputBuffer(j_compress_ptr cinfo)
1015 {
1016  tJpegCompressData *jcd = (tJpegCompressData *)cinfo->client_data;
1017  if (jcd) {
1018  int Used = jcd->size;
1019  int NewSize = jcd->size + JPEGCOMPRESSMEM;
1020  if (uchar *NewBuffer = (uchar *)realloc(jcd->mem, NewSize)) {
1021  jcd->size = NewSize;
1022  jcd->mem = NewBuffer;
1023  }
1024  else {
1025  esyslog("ERROR: out of memory");
1026  return false;
1027  }
1028  if (jcd->mem) {
1029  cinfo->dest->next_output_byte = jcd->mem + Used;
1030  cinfo->dest->free_in_buffer = jcd->size - Used;
1031  return true;
1032  }
1033  }
1034  return false;
1035 }
1036 
1037 static void JpegCompressTermDestination(j_compress_ptr cinfo)
1038 {
1039  tJpegCompressData *jcd = (tJpegCompressData *)cinfo->client_data;
1040  if (jcd) {
1041  int Used = cinfo->dest->next_output_byte - jcd->mem;
1042  if (Used < jcd->size) {
1043  if (uchar *NewBuffer = (uchar *)realloc(jcd->mem, Used)) {
1044  jcd->size = Used;
1045  jcd->mem = NewBuffer;
1046  }
1047  else
1048  esyslog("ERROR: out of memory");
1049  }
1050  }
1051 }
1052 
1053 static uchar *YuvToJpeg(uchar *Mem, int Width, int Height, int &Size, int Quality)
1054 {
1055  if (Quality < 0)
1056  Quality = 0;
1057  else if (Quality > 100)
1058  Quality = 100;
1059 
1060  jpeg_destination_mgr jdm;
1061 
1062  jdm.init_destination = JpegCompressInitDestination;
1063  jdm.empty_output_buffer = JpegCompressEmptyOutputBuffer;
1064  jdm.term_destination = JpegCompressTermDestination;
1065 
1066  struct jpeg_compress_struct cinfo;
1067  struct jpeg_error_mgr jerr;
1068  cinfo.err = jpeg_std_error(&jerr);
1069  jpeg_create_compress(&cinfo);
1070  cinfo.dest = &jdm;
1071  tJpegCompressData jcd;
1072  cinfo.client_data = &jcd;
1073  cinfo.image_width = Width;
1074  cinfo.image_height = Height;
1075  cinfo.input_components = 3;
1076  cinfo.in_color_space = JCS_YCbCr;
1077 
1078  jpeg_set_defaults(&cinfo);
1079  jpeg_set_quality(&cinfo, Quality, true);
1080  jpeg_start_compress(&cinfo, true);
1081 
1082  int rs = Width * 3;
1083  JSAMPROW rp[Height];
1084  for (int k = 0; k < Height; k++)
1085  rp[k] = &Mem[rs * k];
1086  jpeg_write_scanlines(&cinfo, rp, Height);
1087  jpeg_finish_compress(&cinfo);
1088  jpeg_destroy_compress(&cinfo);
1089 
1090  Size = jcd.size;
1091  return jcd.mem;
1092 }
int AudioDownmix
Definition: setup.h:28
virtual void MakePrimaryDevice(bool On)
Informs a device that it will be the primary device.
unsigned char uchar
Definition: tools.h:30
virtual int PlayTsVideo(const uchar *Data, int Length)
Plays the given data block as video.
void CmdAvSetDecoderInput(uint8_t DecoderIndex, uint8_t DemultiplexerIndex)
Definition: hdffcmd.c:106
int Vpid(void) const
Definition: channels.h:165
void CmdMuxSetVolume(uint8_t Volume)
Definition: hdffcmd.c:363
int Number(void) const
Definition: channels.h:191
cChannels Channels
Definition: channels.c:845
HdffVideoOut_t
Definition: hdffcmd_mux.h:28
#define dsyslog(a...)
Definition: tools.h:36
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...
uint8_t videoCounter
Definition: dvbhdffdevice.h:85
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:48
virtual void StillPicture(const uchar *Data, int Length)
Displays the given I-frame as a still picture.
int Dtype(int i) const
Definition: channels.h:178
virtual bool IsTunedToTransponder(const cChannel *Channel) const
Returns true if this device is currently tuned to the given Channel's transponder.
Definition: dvbdevice.c:1557
static cDevice * ReceiverDevice(void)
Definition: transfer.h:36
void DetachAll(int Pid)
Detaches all receivers from this device for this pid.
Definition: device.c:1721
virtual void SetDigitalAudioDevice(bool On)
Tells the actual device that digital audio output shall be switched on or off.
void CmdRemoteSetAddressFilter(bool Enable, uint32_t Address)
Definition: hdffcmd.c:395
#define LOG_ERROR
Definition: tools.h:38
#define DEV_DVB_VIDEO
Definition: dvbdevice.h:80
cTSBuffer * tsBuffer
< Controls how the DVB device handles Transfer Mode when replaying Dolby Digital audio.
Definition: dvbdevice.h:277
int Ca(int Index=0) const
Definition: channels.h:186
void StartDecrypting(void)
Triggers sending all currently active CA_PMT entries to the CAM, so that it will start decrypting...
Definition: ci.c:1961
int Dpid(int i) const
Definition: channels.h:172
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:438
cHdffSetup gHdffSetup
Definition: setup.c:16
virtual void TrickSpeed(int Speed)
Sets the device into a mode where replay is done slower.
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:1011
virtual bool HasDecoder(void) const
Tells whether this device has an MPEG decoder.
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:1355
int Width(void) const
Definition: osd.h:363
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).
virtual bool CanReplay(void) const
Returns true if this device can currently start a replay session.
static void JpegCompressTermDestination(j_compress_ptr cinfo)
#define esyslog(a...)
Definition: tools.h:34
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:406
static cDevice * GetDevice(int Index)
Gets the device with the given Index.
Definition: device.c:222
virtual bool SetChannelDevice(const cChannel *Channel, bool LiveView)
Sets the device to the given channel (actual physical setup).
Definition: dvbdevice.c:1567
ePlayMode playMode
Definition: dvbhdffdevice.h:91
void DelPid(int Pid, ePidType PidType=ptOther)
Deletes a PID from the set of PIDs this device shall receive.
Definition: device.c:528
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:1131
int VideoModeAdaption
Definition: setup.h:23
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:1124
eTrackType
Definition: device.h:65
Definition: device.h:37
void CmdAvShowStillImage(uint8_t DecoderIndex, const uint8_t *pStillImage, int Size, HdffVideoStreamType_t StreamType)
Definition: hdffcmd.c:100
int Ppid(void) const
Definition: channels.h:166
void CmdAvSetVideoFormat(uint8_t DecoderIndex, const HdffVideoFormat_t *pVideoFormat)
Definition: hdffcmd.c:116
static HdffAudioStreamType_t MapAudioStreamTypes(int Atype)
HdffAudioStreamType_t
Definition: hdffcmd_av.h:33
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)
Definition: tools.c:1374
virtual void Mute(void)
Turns off audio while replaying.
Definition: device.c:1145
char * Read(FILE *f)
Definition: tools.c:1329
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:46
int TsPid(const uchar *p)
Definition: remux.h:85
int RemoteAddress
Definition: setup.h:35
int frontend
Definition: dvbdevice.h:173
void CmdAvSetAudioDelay(int16_t Delay)
Definition: hdffcmd.c:156
bool IsPrimaryDevice(void) const
Definition: device.h:199
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...
Definition: device.h:426
bool Transferring(void) const
Returns true if we are currently in Transfer Mode.
Definition: device.c:1214
virtual void Freeze(void)
Puts the device into "freeze frame" mode.
Definition: device.c:1138
HdffVideoMode_t GetVideoMode(void)
Definition: setup.c:105
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:313
cDvbHdFfDevice(int Adapter, int Frontend)
Definition: dvbhdffdevice.c:32
#define CHECK(s)
Definition: tools.h:50
char CecDeviceName[14]
Definition: hdffcmd_hdmi.h:50
virtual eVideoSystem GetVideoSystem(void)
Returns the video system of the currently displayed material (default is PAL).
static void JpegCompressInitDestination(j_compress_ptr cinfo)
void CmdHdmiConfigure(const HdffHdmiConfig_t *pConfig)
Definition: hdffcmd.c:379
HDFF::cHdffCmdIf * mHdffCmdIf
Definition: osd.h:348
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)
Definition: hdffcmd.c:171
int Apid(int i) const
Definition: remux.h:408
virtual ~cDvbHdFfDevice()
Definition: dvbhdffdevice.c:92
virtual bool SetPlayMode(ePlayMode PlayMode)
Sets the device into the given play mode.
eVideoDisplayFormat
Definition: device.h:60
#define IS_AUDIO_TRACK(t)
Definition: device.h:78
int Atype(int i) const
Definition: channels.h:177
int AnalogueVideo
Definition: setup.h:26
virtual int PlayTsAudio(const uchar *Data, int Length)
Plays the given data block as audio.
bool CamDecrypt(tChannelID ChannelID, int CamSlotNumber)
Definition: ci.c:2125
int adapter
Definition: dvbdevice.h:173
int Dpid(int i) const
Definition: remux.h:409
tChannelID GetChannelID(void) const
Definition: channels.h:202
virtual int PlayAudio(const uchar *Data, int Length, uchar Id)
Plays the given data block as audio.
ePlayMode
Definition: device.h:37
int AvSyncShift
Definition: setup.h:29
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:353
eVideoSystem
Definition: device.h:56
static void Launch(cControl *Control)
Definition: player.c:79
int Dtype(int i) const
Definition: remux.h:412
#define DEV_DVB_OSD
Definition: dvbdevice.h:76
int TvFormat
Definition: setup.h:24
void CmdOsdReset(void)
Definition: hdffcmd.c:186
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:590
void GetOsdSize(int &Width, int &Height, double &PixelAspect)
Definition: setup.c:62
virtual void SetVideoFormat(bool VideoFormat16_9)
Sets the output video format to either 16:9 or 4:3 (only useful if this device has an MPEG decoder)...
int CardIndex(void) const
Returns the card index of this device (0 ... MAXDEVICES - 1).
Definition: device.h:200
void CmdAvSetAudioChannel(uint8_t AudioChannel)
Definition: hdffcmd.c:166
virtual bool Flush(int TimeoutMs=0)
Returns true if the device's output buffers are empty, i.
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:1881
void CmdRemoteSetProtocol(HdffRemoteProtocol_t Protocol)
Definition: hdffcmd.c:389
HdffTvFormat_t TvFormat
Definition: hdffcmd_av.h:77
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:30
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
void CmdMuxSetVideoOut(HdffVideoOut_t VideoOut)
Definition: hdffcmd.c:358
int Height(void) const
Definition: osd.h:364
void CmdAvSetVideoSpeed(uint8_t DecoderIndex, int32_t Speed)
Definition: hdffcmd.c:141
Definition: device.h:56
cChannel * GetByNumber(int Number, int SkipGap=0)
Definition: channels.c:944
The cDvbHdFfDevice implements a DVB device which can be accessed through the Linux DVB driver API...
Definition: dvbhdffdevice.h:16
HdffTvFormat_t
Definition: hdffcmd_av.h:56
int AudioDelay
Definition: setup.h:27
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:979
HdffAudioDownmixMode_t
Definition: hdffcmd_av.h:87
int Apid(int i) const
Definition: channels.h:171
cChannelCamRelations ChannelCamRelations
Definition: ci.c:2068
#define DEV_DVB_DEMUX
Definition: dvbdevice.h:79
HdffVideoConversion_t VideoConversion
Definition: hdffcmd_av.h:78
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:34
int CecEnabled
Definition: setup.h:31
The cDvbDevice implements a DVB device which can be accessed through the Linux DVB driver API...
Definition: dvbdevice.h:158
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.
Definition: device.c:1105
int X(void) const
Definition: osd.h:361
static HDFF::cHdffCmdIf * GetHdffCmdHandler(void)
void CmdAvSetAudioDownmix(HdffAudioDownmixMode_t DownmixMode)
Definition: hdffcmd.c:161
#define TS_SIZE
Definition: remux.h:34
bool HasPid(int Pid) const
Returns true if this device is currently receiving the given PID.
Definition: device.c:455
#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:79
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
HdffVideoConversion_t
Definition: hdffcmd_av.h:62
HdffVideoModeAdaption_t
Definition: hdffcmd_hdmi.h:36
virtual cSpuDecoder * GetSpuDecoder(void)
Returns a pointer to the device's SPU decoder (or NULL, if this device doesn't have an SPU decoder)...
Definition: tools.h:347
int VideoConversion
Definition: setup.h:25
int Y(void) const
Definition: osd.h:362
virtual void StillPicture(const uchar *Data, int Length)
Displays the given I-frame as a still picture.
Definition: device.c:1150
Definition: device.h:57
void CmdAvSetAudioSpeed(uint8_t DecoderIndex, int32_t Speed)
Definition: hdffcmd.c:146
int Atype(int i) const
Definition: remux.h:411
virtual bool SetPid(cPidHandle *Handle, int Type, bool On)
Does the actual PID setting on this device.
int Vtype(void) const
Definition: channels.h:167
cPidHandle pidHandles[MAXPIDHANDLES]
Definition: device.h:355
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:464
#define DEV_DVB_AUDIO
Definition: dvbdevice.h:81
int SlotNumber(void)
Returns the number of this CAM slot within the whole system.
Definition: ci.h:169
uint8_t audioCounter
Definition: dvbhdffdevice.h:86
Definition: tools.h:166
static int DvbOpen(const char *Name, int Adapter, int Frontend, int Mode, bool ReportError=false)
Definition: dvbdevice.c:1066
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:110
HdffRemoteProtocol_t
uint16_t id
Definition: device.h:83
virtual void Mute(void)
Turns off audio while replaying.