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