⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dvb.c

📁 linux下的dvb收看解析软件代码; 带参考程序
💻 C
字号:
/*
Copyright (C) 2006  Adam Charrett
 
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
 
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.
 
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
 
dvb.c
 
Opens/Closes and setups dvb adapter for use in the rest of the application.
 
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/poll.h>
#include <sys/ioctl.h>
#include <linux/dvb/dmx.h>
#include <linux/dvb/frontend.h>

#include "dvb.h"
#include "logging.h"

DVBAdapter_t *DVBInit(int adapter)
{
    DVBAdapter_t *result = NULL;
    result = (DVBAdapter_t*)calloc(sizeof(DVBAdapter_t), 1);
    if (result)
    {
        result->frontendfd = -1;
        result->demuxfd = -1;
        result->dvrfd = -1;
        result->adapter = adapter;
        sprintf(result->frontendPath, "/dev/dvb/adapter%d/frontend0", adapter);
        sprintf(result->demuxPath, "/dev/dvb/adapter%d/demux0", adapter);
        sprintf(result->dvrPath, "/dev/dvb/adapter%d/dvr0", adapter);
        result->frontendfd = open(result->frontendPath, O_RDWR);
        if (result->frontendfd == -1)
        {
            printlog(LOG_ERROR,"Failed to open %s : %s\n",result->frontendPath, strerror(errno));
            DVBDispose(result);
            return NULL;
        }
        result->demuxfd = open(result->demuxPath, O_RDWR);
        if (result->demuxfd == -1)
        {
            printlog(LOG_ERROR,"Failed to open %s : %s\n",result->demuxPath, strerror(errno));
            DVBDispose(result);
            return NULL;
        }
        result->dvrfd = open(result->dvrPath, O_RDONLY | O_NONBLOCK);
        if (result->dvrfd == -1)
        {
            printlog(LOG_ERROR,"Failed to open %s : %s\n",result->dvrPath, strerror(errno));
            DVBDispose(result);
            return NULL;
        }
    }
    return result;
}
void DVBDispose(DVBAdapter_t *adapter)
{
    if (adapter->dvrfd > -1)
    {
        printlog(LOG_DEBUGV,"Closing DVR file descriptor\n");
        close(adapter->dvrfd);
    }
    if (adapter->demuxfd > -1)
    {
        printlog(LOG_DEBUGV,"Closing Demux file descriptor\n");
        close(adapter->demuxfd);
    }
    if (adapter->frontendfd > -1)
    {
        printlog(LOG_DEBUGV,"Closing Frontend file descriptor\n");
        close(adapter->frontendfd);
    }
    free(adapter);
}

int DVBFrontEndTune(DVBAdapter_t *adapter, struct dvb_frontend_parameters *frontend)
{
    fe_status_t status = 0;
    /*  fe_status_t festatus; */
    struct dvb_frontend_event event;
    unsigned int strength;
    struct pollfd pfd[1];

    if (ioctl(adapter->frontendfd, FE_SET_FRONTEND, frontend) < 0)
    {
        printlog(LOG_ERROR,"setfront front: %s\n", strerror(errno));
        return 0;
    }

    pfd[0].fd = adapter->frontendfd;
    pfd[0].events = POLLIN;

    if (poll(pfd,1,3000))
    {
        if (pfd[0].revents & POLLIN)
        {
            if (ioctl(adapter->frontendfd, FE_GET_EVENT, &event) == -EOVERFLOW)
            {
                printlog(LOG_ERROR,"EOVERFLOW");
                return 0;
            }
            if (event.parameters.frequency <= 0)
            {
                return 0;
            }
        }
    }
#if 0
    do
    {
        status = 0;
        if (ioctl(adapter->frontendfd, FE_READ_STATUS, &status) < 0)
        {
            printlog(LOG_ERROR,"fe get event: %s\n", strerror(errno));
            return 0;
        }

        printlog(LOG_DEBUGV,"status: %x\n", status);
        if (status & FE_HAS_LOCK)
        {
            break;
        }
        usleep(500000);
        printlog(LOG_DEBUGV,"Trying to get lock...");
    }
    while (!(status & FE_TIMEDOUT));

    /* inform the user of frontend status */
    printlog(LOG_INFO,"Tuner status:  %c%c%c%c%c%c\n",
             (status & FE_HAS_SIGNAL)?'S':' ',
             (status & FE_TIMEDOUT)?'T':' ',
             (status & FE_HAS_LOCK)?'L':' ',
             (status & FE_HAS_CARRIER)?'C':' ',
             (status & FE_HAS_VITERBI)?'V':' ',
             (status & FE_HAS_SYNC)?'s':' '
            );

    strength=0;
    if(ioctl(adapter->frontendfd,FE_READ_BER,&strength) >= 0)
        printlog(LOG_INFO," Bit error rate: %i\n",strength);

    strength=0;
    if(ioctl(adapter->frontendfd,FE_READ_SIGNAL_STRENGTH,&strength) >= 0)
        printlog(LOG_INFO," Signal strength: %i\n",strength);

    strength=0;
    if(ioctl(adapter->frontendfd,FE_READ_SNR,&strength) >= 0)
        printlog(LOG_INFO," Signal/Noise Ratio: %i\n",strength);

    if (status & FE_HAS_LOCK && !(status & FE_TIMEDOUT))
    {
        printlog(LOG_DEBUGV," Lock achieved at %lu Hz\n",(unsigned long)frontend->frequency);
        return 1;
    }
    else
    {
        printlog(LOG_DEBUGV,"Unable to achieve lock at %lu Hz\n",(unsigned long)frontend->frequency);
        return 0;
    }
#endif
    return 1;
}

int DVBFrontEndStatus(DVBAdapter_t *adapter, fe_status_t *status, unsigned int *ber, unsigned int *strength, unsigned int *snr)
{
    if (ioctl(adapter->frontendfd, FE_READ_STATUS, status) < 0)
    {
        printlog(LOG_ERROR,"FE_READ_STATUS: %s\n", strerror(errno));
        return 0;
    }

    if(ioctl(adapter->frontendfd,FE_READ_BER, ber) < 0)
    {
        printlog(LOG_ERROR,"FE_READ_BER: %s\n", strerror(errno));
        return 0;
    }

    if(ioctl(adapter->frontendfd,FE_READ_SIGNAL_STRENGTH,strength) < 0)
    {
        printlog(LOG_ERROR,"FE_READ_SIGNAL_STRENGTH: %s\n", strerror(errno));
        return 0;
    }


    if(ioctl(adapter->frontendfd,FE_READ_SNR,snr) < 0)
    {
        printlog(LOG_ERROR,"FE_READ_SNR: %s\n", strerror(errno));
        return 0;
    }
    return 1;
}

int DVBDemuxStreamEntireTSToDVR(DVBAdapter_t *adapter)
{
    return DVBDemuxSetPESFilter(adapter, 8192, DMX_PES_OTHER, DMX_OUT_TS_TAP);
}

int DVBDemuxSetPESFilter(DVBAdapter_t *adapter, ushort pid, int pidtype, int taptype)
{
    struct dmx_pes_filter_params pesFilterParam;

    pesFilterParam.pid = pid;
    pesFilterParam.input = DMX_IN_FRONTEND;
    pesFilterParam.output = taptype;
    pesFilterParam.pes_type = pidtype;
    pesFilterParam.flags = DMX_IMMEDIATE_START;
    if (ioctl(adapter->demuxfd, DMX_SET_PES_FILTER, &pesFilterParam) < 0)
    {
        printlog(LOG_ERROR,"set_pid: %s\n", strerror(errno));
        return 0;
    }
    return 1;
}

int DVBDVRRead(DVBAdapter_t *adapter, char *data, int max, int timeout)
{
    int result = -1;
    struct pollfd pfd[1];

    pfd[0].fd = adapter->dvrfd;
    pfd[0].events = POLLIN;

    if (poll(pfd,1,timeout))
    {
        if (pfd[0].revents & POLLIN)
        {
            result = read(adapter->dvrfd, data, max);
        }
    }
    return result;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -