Beispiel #1
0
bool cDvbHdFfDevice::SetPlayMode(ePlayMode PlayMode)
{
    if (PlayMode == pmNone) {
        if (fd_video == -1)
            fd_video = DvbOpen(DEV_DVB_VIDEO,  adapter, frontend, O_RDWR | O_NONBLOCK);
        if (fd_audio == -1)
            fd_audio = DvbOpen(DEV_DVB_AUDIO,  adapter, frontend, O_RDWR | O_NONBLOCK);

        mHdffCmdIf->CmdAvSetVideoSpeed(0, 100);
        mHdffCmdIf->CmdAvSetAudioSpeed(0, 100);

        mHdffCmdIf->CmdAvEnableVideoAfterStop(0, false);
        mHdffCmdIf->CmdAvSetPcrPid(0, 0);
        mHdffCmdIf->CmdAvSetVideoPid(0, 0, HDFF_VIDEO_STREAM_MPEG1);
        mHdffCmdIf->CmdAvSetAudioPid(0, 0, HDFF_AUDIO_STREAM_MPEG1);

        ioctl(fd_video, VIDEO_SELECT_SOURCE, VIDEO_SOURCE_DEMUX);
        mHdffCmdIf->CmdAvSetDecoderInput(0, 0);
        mHdffCmdIf->CmdAvEnableSync(0, true);
        mHdffCmdIf->CmdAvSetPlayMode(0, true);
        mHdffCmdIf->CmdAvMuteAudio(0, false);
    }
    else {
        if (playMode == pmNone)
            TurnOffLiveMode(true);

        if (PlayMode == pmExtern_THIS_SHOULD_BE_AVOIDED)
        {
            close(fd_video);
            fd_video = -1;
            close(fd_audio);
            fd_audio = -1;
        }
        else
        {
            isTransferMode = Transferring() || (cTransferControl::ReceiverDevice() == this);
            mHdffCmdIf->CmdAvSetPlayMode(1, isTransferMode);
            mHdffCmdIf->CmdAvSetStc(0, 100000);
            mHdffCmdIf->CmdAvEnableSync(0, false);
            mHdffCmdIf->CmdAvEnableVideoAfterStop(0, true);

            playVideoPid = -1;
            playAudioPid = -1;
            playPcrPid = -1;
            audioCounter = 0;
            videoCounter = 0;
            freezed = false;
            trickMode = false;
            isPlayingVideo = false;

            mHdffCmdIf->CmdAvSetDecoderInput(0, 2);
            ioctl(fd_video, VIDEO_SELECT_SOURCE, VIDEO_SOURCE_MEMORY);
        }
    }
    playMode = PlayMode;
    return true;
}
bool cDvbDevice::SetPid(cPidHandle *Handle, int Type, bool On)
{
  if (Handle->pid) {
     dmx_pes_filter_params pesFilterParams;
     memset(&pesFilterParams, 0, sizeof(pesFilterParams));
     if (On) {
        if (Handle->handle < 0) {
           Handle->handle = DvbOpen(DEV_DVB_DEMUX, CardIndex(), O_RDWR | O_NONBLOCK, true);
           if (Handle->handle < 0) {
              LOG_ERROR;
              return false;
              }
           }
        pesFilterParams.pid     = Handle->pid;
        pesFilterParams.input   = DMX_IN_FRONTEND;
        pesFilterParams.output  = (Type <= ptTeletext && Handle->used <= 1) ? DMX_OUT_DECODER : DMX_OUT_TS_TAP;
        pesFilterParams.pes_type= PesTypes[Type < ptOther ? Type : ptOther];
        pesFilterParams.flags   = DMX_IMMEDIATE_START;
        if (ioctl(Handle->handle, DMX_SET_PES_FILTER, &pesFilterParams) < 0) {
           LOG_ERROR;
           return false;
           }
        }
     else if (!Handle->used) {
        CHECK(ioctl(Handle->handle, DMX_STOP));
        if (Type <= ptTeletext) {
           pesFilterParams.pid     = 0x1FFF;
           pesFilterParams.input   = DMX_IN_FRONTEND;
           pesFilterParams.output  = DMX_OUT_DECODER;
           pesFilterParams.pes_type= PesTypes[Type];
           pesFilterParams.flags   = DMX_IMMEDIATE_START;
           CHECK(ioctl(Handle->handle, DMX_SET_PES_FILTER, &pesFilterParams));
           if (PesTypes[Type] == DMX_PES_VIDEO) // let's only do this once
              SetPlayMode(pmNone); // necessary to switch a PID from DMX_PES_VIDEO/AUDIO to DMX_PES_OTHER
           }
        close(Handle->handle);
        Handle->handle = -1;
        }
     }
  return true;
}
bool cDvbDevice::SetPlayMode(ePlayMode PlayMode)
{
  if (PlayMode != pmExtern_THIS_SHOULD_BE_AVOIDED && fd_video < 0 && fd_audio < 0) {
     // reopen the devices
     fd_video = DvbOpen(DEV_DVB_VIDEO,  CardIndex(), O_RDWR | O_NONBLOCK);
     fd_audio = DvbOpen(DEV_DVB_AUDIO,  CardIndex(), O_RDWR | O_NONBLOCK);
     SetVideoFormat(Setup.VideoFormat);
     }

  switch (PlayMode) {
    case pmNone:
         // special handling to return from PCM replay:
         CHECK(ioctl(fd_video, VIDEO_SET_BLANK, true));
         CHECK(ioctl(fd_video, VIDEO_SELECT_SOURCE, VIDEO_SOURCE_MEMORY));
         CHECK(ioctl(fd_video, VIDEO_PLAY));

         CHECK(ioctl(fd_video, VIDEO_STOP, true));
         CHECK(ioctl(fd_audio, AUDIO_STOP, true));
         CHECK(ioctl(fd_video, VIDEO_CLEAR_BUFFER));
         CHECK(ioctl(fd_audio, AUDIO_CLEAR_BUFFER));
         CHECK(ioctl(fd_video, VIDEO_SELECT_SOURCE, VIDEO_SOURCE_DEMUX));
         CHECK(ioctl(fd_audio, AUDIO_SELECT_SOURCE, AUDIO_SOURCE_DEMUX));
         CHECK(ioctl(fd_audio, AUDIO_SET_AV_SYNC, true));
         CHECK(ioctl(fd_audio, AUDIO_SET_MUTE, false));
         break;
    case pmAudioVideo:
    case pmAudioOnlyBlack:
         if (playMode == pmNone)
            TurnOffLiveMode(true);
         CHECK(ioctl(fd_video, VIDEO_SET_BLANK, true));
         CHECK(ioctl(fd_audio, AUDIO_SELECT_SOURCE, AUDIO_SOURCE_MEMORY));
         CHECK(ioctl(fd_audio, AUDIO_SET_AV_SYNC, PlayMode == pmAudioVideo));
         CHECK(ioctl(fd_audio, AUDIO_PLAY));
         CHECK(ioctl(fd_video, VIDEO_SELECT_SOURCE, VIDEO_SOURCE_MEMORY));
         CHECK(ioctl(fd_video, VIDEO_PLAY));
         break;
    case pmAudioOnly:
         CHECK(ioctl(fd_video, VIDEO_SET_BLANK, true));
         CHECK(ioctl(fd_audio, AUDIO_STOP, true));
         CHECK(ioctl(fd_audio, AUDIO_CLEAR_BUFFER));
         CHECK(ioctl(fd_audio, AUDIO_SELECT_SOURCE, AUDIO_SOURCE_MEMORY));
         CHECK(ioctl(fd_audio, AUDIO_SET_AV_SYNC, false));
         CHECK(ioctl(fd_audio, AUDIO_PLAY));
         CHECK(ioctl(fd_video, VIDEO_SET_BLANK, false));
         break;
    case pmVideoOnly:
         CHECK(ioctl(fd_video, VIDEO_SET_BLANK, true));
         CHECK(ioctl(fd_video, VIDEO_STOP, true));
         CHECK(ioctl(fd_audio, AUDIO_SELECT_SOURCE, AUDIO_SOURCE_DEMUX));
         CHECK(ioctl(fd_audio, AUDIO_SET_AV_SYNC, false));
         CHECK(ioctl(fd_audio, AUDIO_PLAY));
         CHECK(ioctl(fd_video, VIDEO_CLEAR_BUFFER));
         CHECK(ioctl(fd_video, VIDEO_SELECT_SOURCE, VIDEO_SOURCE_MEMORY));
         CHECK(ioctl(fd_video, VIDEO_PLAY));
         break;
    case pmExtern_THIS_SHOULD_BE_AVOIDED:
         close(fd_video);
         close(fd_audio);
         fd_video = fd_audio = -1;
         break;
    }
  playMode = PlayMode;
  return true;
}
cDvbDevice::cDvbDevice(int n)
{
  dvbTuner = NULL;
  frontendType = fe_type_t(-1); // don't know how else to initialize this - there is no FE_UNKNOWN
  spuDecoder = NULL;
  digitalAudio = false;
  playMode = pmNone;

  // Devices that are present on all card types:

  int fd_frontend = DvbOpen(DEV_DVB_FRONTEND, n, O_RDWR | O_NONBLOCK);

  // Devices that are only present on cards with decoders:

  fd_osd      = DvbOpen(DEV_DVB_OSD,    n, O_RDWR);
  fd_video    = DvbOpen(DEV_DVB_VIDEO,  n, O_RDWR | O_NONBLOCK);
  fd_audio    = DvbOpen(DEV_DVB_AUDIO,  n, O_RDWR | O_NONBLOCK);
  fd_stc      = DvbOpen(DEV_DVB_DEMUX,  n, O_RDWR);

  // The DVR device (will be opened and closed as needed):

  fd_dvr = -1;

  // The offset of the /dev/video devices:

  if (devVideoOffset < 0) { // the first one checks this
     FILE *f = NULL;
     char buffer[PATH_MAX];
     for (int ofs = 0; ofs < 100; ofs++) {
         snprintf(buffer, sizeof(buffer), "/proc/video/dev/video%d", ofs);
         if ((f = fopen(buffer, "r")) != NULL) {
            if (fgets(buffer, sizeof(buffer), f)) {
               if (strstr(buffer, "DVB Board")) { // found the _first_ DVB card
                  devVideoOffset = ofs;
                  dsyslog("video device offset is %d", devVideoOffset);
                  break;
                  }
               }
            else
               break;
            fclose(f);
            }
         else
            break;
         }
     if (devVideoOffset < 0)
        devVideoOffset = 0;
     if (f)
        fclose(f);
     }
  devVideoIndex = (devVideoOffset >= 0 && HasDecoder()) ? devVideoOffset++ : -1;

  // Video format:

  SetVideoFormat(Setup.VideoFormat);

  // We only check the devices that must be present - the others will be checked before accessing them://XXX

  if (fd_frontend >= 0) {
     dvb_frontend_info feinfo;
     if (ioctl(fd_frontend, FE_GET_INFO, &feinfo) >= 0) {
        frontendType = feinfo.type;
        ciHandler = cCiHandler::CreateCiHandler(*cDvbName(DEV_DVB_CA, n));
        dvbTuner = new cDvbTuner(fd_frontend, CardIndex(), frontendType, ciHandler);
        }
     else
        LOG_ERROR;
     }
  else
     esyslog("ERROR: can't open DVB device %d", n);

  StartSectionHandler();
}
Beispiel #5
0
cDvbHdFfDevice::cDvbHdFfDevice(int Adapter, int Frontend)
:cDvbDevice(Adapter, Frontend)
{
  spuDecoder = NULL;
  audioChannel = 0;
  playMode = pmNone;
  mHdffCmdIf = NULL;

  // Devices that are only present on cards with decoders:

  fd_osd      = DvbOpen(DEV_DVB_OSD,    adapter, frontend, O_RDWR);
  fd_video    = DvbOpen(DEV_DVB_VIDEO,  adapter, frontend, O_RDWR | O_NONBLOCK);
  fd_audio    = DvbOpen(DEV_DVB_AUDIO,  adapter, frontend, O_RDWR | O_NONBLOCK);

  //TODO missing /dev/video offset calculation

  isHdffPrimary = false;
  if (devHdffOffset < 0) {
     devHdffOffset = adapter;
     isHdffPrimary = true;
     mHdffCmdIf = new HDFF::cHdffCmdIf(fd_osd);

     uint32_t firmwareVersion = mHdffCmdIf->CmdGetFirmwareVersion(NULL, 0);
     if (firmwareVersion < 0x401)
        supportsPcrInTransferMode = false;
     else
        supportsPcrInTransferMode = true;

     /* reset some stuff in case the VDR was killed before and had no chance
        to clean up. */
     mHdffCmdIf->CmdOsdReset();

     mHdffCmdIf->CmdAvSetVideoSpeed(0, 100);
     mHdffCmdIf->CmdAvSetAudioSpeed(0, 100);

     mHdffCmdIf->CmdAvEnableVideoAfterStop(0, false);
     mHdffCmdIf->CmdAvSetPcrPid(0, 0);
     mHdffCmdIf->CmdAvSetVideoPid(0, 0, HDFF_VIDEO_STREAM_MPEG1);
     mHdffCmdIf->CmdAvSetAudioPid(0, 0, HDFF_AUDIO_STREAM_MPEG1);

     ioctl(fd_video, VIDEO_SELECT_SOURCE, VIDEO_SOURCE_DEMUX);
     mHdffCmdIf->CmdAvSetDecoderInput(0, 0);
     mHdffCmdIf->CmdAvEnableSync(0, true);
     mHdffCmdIf->CmdAvSetPlayMode(0, true);
     /* reset done */

     mHdffCmdIf->CmdAvSetAudioDelay(gHdffSetup.AudioDelay);
     mHdffCmdIf->CmdAvSetAudioDownmix((HdffAudioDownmixMode_t) gHdffSetup.AudioDownmix);
     mHdffCmdIf->CmdAvSetSyncShift(gHdffSetup.AvSyncShift);
     mHdffCmdIf->CmdMuxSetVideoOut((HdffVideoOut_t) gHdffSetup.AnalogueVideo);
     mHdffCmdIf->CmdHdmiSetVideoMode(gHdffSetup.GetVideoMode());

     HdffHdmiConfig_t hdmiConfig;
     memset(&hdmiConfig, 0, sizeof(hdmiConfig));
     hdmiConfig.TransmitAudio = true;
     hdmiConfig.ForceDviMode = false;
     hdmiConfig.CecEnabled = gHdffSetup.CecEnabled;
     strcpy(hdmiConfig.CecDeviceName, "VDR");
     hdmiConfig.VideoModeAdaption = (HdffVideoModeAdaption_t) gHdffSetup.VideoModeAdaption;
     mHdffCmdIf->CmdHdmiConfigure(&hdmiConfig);

     mHdffCmdIf->CmdRemoteSetProtocol((HdffRemoteProtocol_t) gHdffSetup.RemoteProtocol);
     mHdffCmdIf->CmdRemoteSetAddressFilter(gHdffSetup.RemoteAddress >= 0, gHdffSetup.RemoteAddress);
     }
}
Beispiel #6
0
bool cDvbHdFfDevice::SetPid(cPidHandle *Handle, int Type, bool On)
{
    //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);
    if (Handle->pid) {
        dmx_pes_filter_params pesFilterParams;
        memset(&pesFilterParams, 0, sizeof(pesFilterParams));
        if (On) {
            if (Handle->handle < 0) {
                Handle->handle = DvbOpen(DEV_DVB_DEMUX, adapter, frontend, O_RDWR | O_NONBLOCK, true);
                if (Handle->handle < 0) {
                    LOG_ERROR;
                    return false;
                }
            }
            if (Type == ptPcr)
                mHdffCmdIf->CmdAvSetPcrPid(0, Handle->pid);
            else if (Type == ptVideo) {
                if (Handle->streamType == 0x1B)
                    mHdffCmdIf->CmdAvSetVideoPid(0, Handle->pid, HDFF_VIDEO_STREAM_H264);
                else
                    mHdffCmdIf->CmdAvSetVideoPid(0, Handle->pid, HDFF_VIDEO_STREAM_MPEG2);
            }
            else if (Type == ptAudio) {
                if (Handle->streamType == 0x03)
                    mHdffCmdIf->CmdAvSetAudioPid(0, Handle->pid, HDFF_AUDIO_STREAM_MPEG1);
                else if (Handle->streamType == 0x04)
                    mHdffCmdIf->CmdAvSetAudioPid(0, Handle->pid, HDFF_AUDIO_STREAM_MPEG2);
                else if (Handle->streamType == SI::AC3DescriptorTag)
                    mHdffCmdIf->CmdAvSetAudioPid(0, Handle->pid, HDFF_AUDIO_STREAM_AC3);
                else if (Handle->streamType == SI::EnhancedAC3DescriptorTag)
                    mHdffCmdIf->CmdAvSetAudioPid(0, Handle->pid, HDFF_AUDIO_STREAM_EAC3);
                else if (Handle->streamType == 0x0F)
                    mHdffCmdIf->CmdAvSetAudioPid(0, Handle->pid, HDFF_AUDIO_STREAM_AAC);
                else if (Handle->streamType == 0x11)
                    mHdffCmdIf->CmdAvSetAudioPid(0, Handle->pid, HDFF_AUDIO_STREAM_HE_AAC);
                else
                    mHdffCmdIf->CmdAvSetAudioPid(0, Handle->pid, HDFF_AUDIO_STREAM_MPEG1);
            }
            if (!(Type <= ptDolby && Handle->used <= 1)) {
                pesFilterParams.pid     = Handle->pid;
                pesFilterParams.input   = DMX_IN_FRONTEND;
                pesFilterParams.output  = DMX_OUT_TS_TAP;
                pesFilterParams.pes_type= DMX_PES_OTHER;
                pesFilterParams.flags   = DMX_IMMEDIATE_START;
                if (ioctl(Handle->handle, DMX_SET_PES_FILTER, &pesFilterParams) < 0) {
                    LOG_ERROR;
                    return false;
                }
            }
        }
        else if (!Handle->used) {
            CHECK(ioctl(Handle->handle, DMX_STOP));
            if (Type == ptPcr)
                mHdffCmdIf->CmdAvSetPcrPid(0, 0);
            else if (Type == ptVideo)
                mHdffCmdIf->CmdAvSetVideoPid(0, 0, HDFF_VIDEO_STREAM_MPEG1);
            else if (Type == ptAudio)
                mHdffCmdIf->CmdAvSetAudioPid(0, 0, HDFF_AUDIO_STREAM_MPEG1);
            else if (Type == ptDolby)
                mHdffCmdIf->CmdAvSetAudioPid(0, 0, HDFF_AUDIO_STREAM_AC3);
            //TODO missing setting to 0x1FFF??? see cDvbDevice::SetPid()
            close(Handle->handle);
            Handle->handle = -1;
        }
    }
    return true;
}
Beispiel #7
0
uchar *cDvbHdFfDevice::GrabImage(int &Size, bool Jpeg, int Quality, int SizeX, int SizeY)
{
    #define BUFFER_SIZE  (sizeof(struct v4l2_pix_format) + 1920 * 1080 * 2)
    int fd;
    uint8_t * buffer;
    uint8_t * result = NULL;

    fd = DvbOpen(DEV_DVB_VIDEO, adapter, frontend, O_RDONLY);
    if (fd < 0) {
        esyslog("GrabImage: failed open DVB video device");
        return NULL;
    }

    buffer = (uint8_t *) malloc(BUFFER_SIZE);
    if (buffer)
    {
        int readBytes;

        readBytes = read(fd, buffer, BUFFER_SIZE);
        if (readBytes < (int) sizeof(struct v4l2_pix_format))
            esyslog("GrabImage: failed reading from DVB video device");
        else {
            struct v4l2_pix_format * pixfmt;
            int dataSize;

            pixfmt = (struct v4l2_pix_format *) buffer;
            dsyslog("GrabImage: Read image of size %d x %d",
                    pixfmt->width, pixfmt->height);
            dataSize = readBytes - sizeof(struct v4l2_pix_format);
            if (dataSize < (int) pixfmt->sizeimage)
                esyslog("GrabImage: image is not complete");
            else {
                if (Jpeg) {
                    uint8_t * temp;
                    temp = (uint8_t *) malloc(pixfmt->width * 3 * pixfmt->height);
                    if (temp) {
                        int numPixels = pixfmt->width * pixfmt->height;
                        uint8_t * destData = temp;
                        uint8_t * srcData = buffer + sizeof(struct v4l2_pix_format);
                        while (numPixels > 0)
                        {
                            destData[0] = srcData[1];
                            destData[1] = srcData[0];
                            destData[2] = srcData[2];
                            destData[3] = srcData[3];
                            destData[4] = srcData[0];
                            destData[5] = srcData[2];
                            srcData += 4;
                            destData += 6;
                            numPixels -= 2;
                        }
                        if (Quality < 0)
                            Quality = 100;
                        result = YuvToJpeg(temp, pixfmt->width, pixfmt->height, Size, Quality);
                        free(temp);
                    }
                }
                else {
                    // convert to PNM:
                    char buf[32];
                    snprintf(buf, sizeof(buf), "P6\n%d\n%d\n255\n",
                             pixfmt->width, pixfmt->height);
                    int l = strlen(buf);
                    Size = l + pixfmt->width * 3 * pixfmt->height;
                    result = (uint8_t *) malloc(Size);
                    if (result)
                    {
                        memcpy(result, buf, l);
                        uint8_t * destData = result + l;
                        uint8_t * srcData = buffer + sizeof(struct v4l2_pix_format);
                        int numPixels = pixfmt->width * pixfmt->height;
                        while (numPixels > 0)
                        {
                            int cb = srcData[0] - 128;
                            int y1 = srcData[1];
                            int cr = srcData[2] - 128;
                            int y2 = srcData[3];
                            int r;
                            int g;
                            int b;

                            r = y1 + (int) (1.402f * cr);
                            g = y1 - (int) (0.344f * cb + 0.714f * cr);
                            b = y1 + (int) (1.772f * cb);
                            destData[0] = r > 255 ? 255 : r < 0 ? 0 : r;
                            destData[1] = g > 255 ? 255 : g < 0 ? 0 : g;
                            destData[2] = b > 255 ? 255 : b < 0 ? 0 : b;
                            r = y2 + (int) (1.402f * cr);
                            g = y2 - (int) (0.344f * cb + 0.714f * cr);
                            b = y2 + (int) (1.772f * cb);
                            destData[3] = r > 255 ? 255 : r < 0 ? 0 : r;
                            destData[4] = g > 255 ? 255 : g < 0 ? 0 : g;
                            destData[5] = b > 255 ? 255 : b < 0 ? 0 : b;

                            srcData += 4;
                            destData += 6;
                            numPixels -= 2;
                        }
                    }
                }
            }
        }
        free(buffer);
    }

    close(fd);

    return result;
}