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