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