コード例 #1
0
ファイル: dvb_audio.c プロジェクト: backtrack2016/tdt
/*{{{  AudioIoctlStop*/
int AudioIoctlStop (struct DeviceContext_s* Context)
{
    int Result  = 0;

    DVB_DEBUG("\n");
    /*if (Context->AudioState.play_state == AUDIO_PLAYING)*/
    if (Context->AudioStream != NULL)
    {
        struct mutex*   WriteLock       = Context->ActiveAudioWriteLock;

        /* Discard previously injected data to free the lock. */
        StreamDrain (Context->AudioStream, true);

        /*mutex_lock (WriteLock);*/
        if (mutex_lock_interruptible (WriteLock) != 0)
            return -ERESTARTSYS;                /* Give up for now.  The stream will be removed later by the release */

        /*StreamEnable (Context->PlayerContext, STREAM_CONTENT_AUDIO, false);*/
        Result  = PlaybackRemoveStream (Context->Playback, Context->AudioStream);
        if (Result == 0)
        {
            Context->AudioStream                = NULL;
            Context->AudioState.play_state      = AUDIO_STOPPED;
            Context->ActiveAudioWriteLock       = &(Context->AudioWriteLock);
            /*AudioInit (Context);*/
        }
        mutex_unlock (WriteLock);
    }
    DVB_DEBUG("Play state = %d\n", Context->AudioState.play_state);

    return Result;
}
コード例 #2
0
ファイル: dvb_audio.c プロジェクト: backtrack2016/tdt
/*{{{  AudioIoctlSetSpeed*/
static int AudioIoctlSetSpeed (struct DeviceContext_s* Context, int Speed)
{
#if 0
    int Result;

    DVB_DEBUG("\n");
    if (Context->Playback == NULL)
    {
        Context->PlaySpeed      = Speed;
        return 0;
    }

    Result      = PlaybackSetSpeed (Context->Playback, Speed);
    if (Result < 0)
        return Result;
    Result      = PlaybackGetSpeed (Context->Playback, &Context->PlaySpeed);
    if (Result < 0)
        return Result;

    DVB_DEBUG("Speed set to %d\n", Context->PlaySpeed);

    return Result;
#else
    int DirectionChange;
    int Result;

    DVB_DEBUG("\n");
    if (Context->Playback == NULL)
    {
        Context->PlaySpeed      = Speed;
        return 0;
    }

    /* If changing direction we require a write lock */
    DirectionChange     = ((Speed * Context->PlaySpeed) < 0);
    if (DirectionChange)
    {
        /* Discard previously injected data to free the lock. */
        StreamDrain (Context->AudioStream, true);
        if  (mutex_lock_interruptible (Context->ActiveAudioWriteLock) != 0)
            return -ERESTARTSYS;                /* Give up for now. */
    }

    Result      = PlaybackSetSpeed (Context->Playback, Speed);
    if (Result >= 0)
        Result  = PlaybackGetSpeed (Context->Playback, &Context->PlaySpeed);

    /* If changing direction release write lock*/
    if (DirectionChange)
        mutex_unlock( Context->ActiveAudioWriteLock );

    DVB_DEBUG("Speed set to %d\n", Context->PlaySpeed);

    return Result;
#endif
}
コード例 #3
0
ファイル: dvb_audio.c プロジェクト: backtrack2016/tdt
/*{{{  AudioRelease*/
static int AudioRelease (struct inode*  Inode,
                         struct file*   File)
{
    struct dvb_device*          DvbDevice       = (struct dvb_device*)File->private_data;
    struct DeviceContext_s*     Context         = (struct DeviceContext_s*)DvbDevice->priv;
    struct DvbContext_s*        DvbContext      = Context->DvbContext;

    DVB_DEBUG("\n");

    if ((File->f_flags & O_ACCMODE) != O_RDONLY)
    {
        mutex_lock (&(DvbContext->Lock));
        if (Context->AudioStream != NULL)
        {
            unsigned int    MutexIsLocked   = true;
            /* Discard previously injected data to free the lock. */
            StreamDrain (Context->AudioStream, true);

            if (mutex_lock_interruptible (Context->ActiveAudioWriteLock) != 0)
                MutexIsLocked       = false;

            PlaybackRemoveStream (Context->Playback, Context->AudioStream);
            Context->AudioStream    = NULL;

            if (MutexIsLocked)
                mutex_unlock (Context->ActiveAudioWriteLock);
        }

        DisplayDelete (BACKEND_AUDIO_ID, Context->Id);

        /* Check to see if video and demux have also finished so we can release the playback */
        if ((Context->VideoStream == NULL) && (Context->DemuxStream == NULL) && (Context->Playback != NULL))
        {
            /* Check to see if our playback has already been deleted by the demux context */
            if (Context->DemuxContext->Playback != NULL)
            {
                /* Try and delete playback then set our demux to Null if succesful or not.  If we fail someone else
                   is still using it but we are done. */
                if (PlaybackDelete (Context->Playback) == 0)
                    DVB_DEBUG("Playback deleted successfully\n");
            }
            Context->Playback               = NULL;
            Context->StreamType             = STREAM_TYPE_TRANSPORT;
            Context->PlaySpeed              = DVB_SPEED_NORMAL_PLAY;
            Context->PlayInterval.start     = DVB_TIME_NOT_BOUNDED;
            Context->PlayInterval.end       = DVB_TIME_NOT_BOUNDED;
            Context->SyncContext            = Context;
        }

        AudioInit (Context);

        mutex_unlock (&(DvbContext->Lock));
    }
    return dvb_generic_release (Inode, File);
}
コード例 #4
0
ファイル: dvb_audio.c プロジェクト: backtrack2016/tdt
/*{{{  AudioIoctlSelectSource*/
static int AudioIoctlSelectSource (struct DeviceContext_s* Context, audio_stream_source_t Source)
{
    DVB_DEBUG("\n");
    Context->AudioState.stream_source = Source;
    if (Source == AUDIO_SOURCE_DEMUX)
        Context->StreamType = STREAM_TYPE_TRANSPORT;
    else
        Context->StreamType = STREAM_TYPE_PES;
    DVB_DEBUG("Source = %x\n", Context->AudioState.stream_source);

    return 0;
}
コード例 #5
0
ファイル: dvb_audio.c プロジェクト: backtrack2016/tdt
/*{{{  AudioIoctlGetStatus*/
static int AudioIoctlGetStatus (struct DeviceContext_s* Context, struct audio_status* Status)
{
    memcpy (Status, &Context->AudioState, sizeof(struct audio_status));
    DVB_DEBUG("\n");

    return 0;
}
コード例 #6
0
ファイル: dvb_audio.c プロジェクト: backtrack2016/tdt
/*{{{  AudioIoctlGetCapabilities*/
static int AudioIoctlGetCapabilities (struct DeviceContext_s* Context, int* Capabilities)
{
    *Capabilities = AUDIO_CAP_DTS | AUDIO_CAP_LPCM | AUDIO_CAP_MP1 | AUDIO_CAP_MP2 | AUDIO_CAP_MP3 | AUDIO_CAP_AAC | AUDIO_CAP_AC3;
    DVB_DEBUG("Capabilities returned = %x\n", *Capabilities);

    return 0;
}
コード例 #7
0
ファイル: dvb_audio.c プロジェクト: backtrack2016/tdt
/*{{{  AudioIoctlSetSyncGroup*/
static int AudioIoctlSetSyncGroup (struct DeviceContext_s* Context, unsigned int Group)
{
    int         Result  = 0;

    if (Context != Context->SyncContext)
    {
        DVB_ERROR("Sync group already set - cannot reset\n");
        return -EPERM;
    }

    if ((Group < 0) || (Group >= DVB_MAX_DEVICES_PER_ADAPTER))
    {
        DVB_ERROR("Invalid sync group - out of range.\n");
        return -EPERM;
    }

    if (Context->SyncContext->Playback)
    {
        DVB_ERROR("Sync group already set - cannot reset\n");
        return -EPERM;
    }

    Context->SyncContext        = &Context->DvbContext->DeviceContext[Group];

    DVB_DEBUG("Sync group set to device %d\n", Group);

    return Result;
}
コード例 #8
0
ファイル: dvb_audio.c プロジェクト: backtrack2016/tdt
/*{{{  AudioIoctlSetSpdifSource*/
static int AudioIoctlSetSpdifSource (struct DeviceContext_s* Context, unsigned int Mode)
{
    int Result;
    int BypassCodedData = (Mode == AUDIO_SPDIF_SOURCE_ES);

    DVB_DEBUG("\n");
    if ((Mode != AUDIO_SPDIF_SOURCE_PP) && (Mode != AUDIO_SPDIF_SOURCE_ES))
        return -EINVAL;

    DVB_DEBUG("Bypass = %s\n", BypassCodedData ? "Enabled (ES)" : "Disabled (Post-proc LPCM)");

    if (Context->AudioState.bypass_mode == BypassCodedData)
        return 0;

    Result      = StreamSetOption (Context->AudioStream, PLAY_OPTION_AUDIO_SPDIF_SOURCE, (unsigned int)BypassCodedData);
    if (Result == 0)
        Context->AudioState.bypass_mode  = Mode;

    return Result;
}
コード例 #9
0
ファイル: dvb_audio.c プロジェクト: backtrack2016/tdt
/*{{{  AudioIoctlSetStreamType*/
static int AudioIoctlSetStreamType(struct DeviceContext_s* Context, unsigned int Type)
{
    DVB_DEBUG("Set type to %x\n", Type);

    /*if ((Type < STREAM_TYPE_TRANSPORT) || (Type > STREAM_TYPE_PES))*/
    if ((Type < STREAM_TYPE_NONE) || (Type > STREAM_TYPE_RAW))
        return  -EINVAL;

    Context->StreamType         = (stream_type_t)Type;

    return 0;
}
コード例 #10
0
ファイル: dvb_audio.c プロジェクト: backtrack2016/tdt
static int AudioIoctlSetAvSync (struct DeviceContext_s* Context, unsigned int State)
#endif
{
    int Result  = 0;

    DVB_DEBUG("\n");
    /* implicitly un-mute audio when we re-enable AV sync */
    if (Context->AudioState.play_state == AUDIO_PLAYING)
        StreamEnable (Context->AudioStream, true);

    if (Context->AudioStream != NULL)
        Result  = StreamSetOption (Context->AudioStream, PLAY_OPTION_AV_SYNC, State ? PLAY_OPTION_VALUE_ENABLE : PLAY_OPTION_VALUE_DISABLE);

    if (Result != 0)
        return Result;

    Context->AudioState.AV_sync_state = (int)State;
    DVB_DEBUG("AV Sync = %d\n", Context->AudioState.AV_sync_state);

    return Result;
}
コード例 #11
0
ファイル: dvb_module.c プロジェクト: MarkusVolk/martii-tdt
static void __exit StmUnloadModule (void)
{
    int i;

    BackendDelete ();

    for (i = 0; i < DVB_MAX_DEVICES_PER_ADAPTER; i++)
    {
        struct DeviceContext_s* DeviceContext   = &DvbContext->DeviceContext[i];
        struct dvb_demux*       DvbDemux        = &DeviceContext->DvbDemux;
        struct dmxdev*          DmxDevice       = &DeviceContext->DmxDevice;

#if defined (USE_KERNEL_DEMUX)
        if (DmxDevice != NULL)
        {
            /* We don't need to unregister DmxDevice->dvr_dvbdev as this will be done by dvb_dmxdev_release */
            dvb_dmxdev_release (DmxDevice);
        }
        if (DvbDemux != NULL)
        {
            DvbDemux->dmx.remove_frontend (&DvbDemux->dmx, &DeviceContext->MemoryFrontend);
            dvb_dmx_release    (DvbDemux);
        }
#else
        dvb_unregister_device  (DeviceContext->DemuxDevice);
        dvb_unregister_device  (DeviceContext->DvrDevice);
#endif
        if (DeviceContext->AudioDevice != NULL)
            dvb_unregister_device  (DeviceContext->AudioDevice);
        if (DeviceContext->VideoDevice != NULL)
            dvb_unregister_device  (DeviceContext->VideoDevice);

        PlaybackDelete (DeviceContext->Playback);
        DeviceContext->AudioStream              = NULL;
        DeviceContext->VideoStream              = NULL;
        DeviceContext->Playback                 = NULL;
	kfree(DeviceContext->dvr_in);
	kfree(DeviceContext->dvr_out);
    }


    if (DvbContext != NULL)
    {
        dvb_unregister_adapter (&DvbContext->DvbAdapter);
        kfree (DvbContext);
    }
    DvbContext  = NULL;

    DVB_DEBUG("STM stream device unloaded\n");

    return;
}
コード例 #12
0
ファイル: dvb_audio.c プロジェクト: backtrack2016/tdt
/*{{{  AudioIoctlSetMute*/
static int AudioIoctlSetMute (struct DeviceContext_s* Context, unsigned int State)
{
    int Result  = 0;

    DVB_DEBUG("Mute = %d (was %d)\n", State, Context->AudioState.mute_state);
    if (Context->AudioStream != NULL)
        Result  = StreamEnable (Context->AudioStream, !State);

    if (Result == 0)
        Context->AudioState.mute_state  = (int)State;


    return Result;
}
コード例 #13
0
ファイル: dvb_audio.c プロジェクト: backtrack2016/tdt
/*{{{  AudioIoctlChannelSelect*/
static int AudioIoctlChannelSelect (struct DeviceContext_s* Context, audio_channel_select_t Channel)
{
    int                 Result  = 0;

    DVB_DEBUG("Channel = %x\n", Channel);
    if (Context->AudioStream != NULL)
        Result  = StreamChannelSelect (Context->AudioStream, (channel_select_t)Channel);

    if (Result != 0)
        return Result;

    Context->AudioState.channel_select  = Channel;

    return Result;
}
コード例 #14
0
ファイル: dvb_audio.c プロジェクト: backtrack2016/tdt
static int AudioIoctlPause (struct DeviceContext_s* Context)
#endif
{
    int Result  = 0;

    DVB_DEBUG("\n");
    if (Context->AudioState.play_state == AUDIO_PLAYING)
    {
        Result  = AudioIoctlSetSpeed (Context, DVB_SPEED_STOPPED);
        if (Result < 0)
            return Result;
        Context->AudioState.play_state  = AUDIO_PAUSED;
    }

    return 0;
}
コード例 #15
0
ファイル: dvb_audio.c プロジェクト: backtrack2016/tdt
static int AudioIoctlContinue (struct DeviceContext_s* Context)
#endif
{
    int Result  = 0;

    DVB_DEBUG("\n");
    if ((Context->AudioState.play_state == AUDIO_PAUSED) || (Context->AudioState.play_state == AUDIO_PLAYING))
    {
        Result  = AudioIoctlSetSpeed (Context, DVB_SPEED_NORMAL_PLAY);
        if (Result < 0)
            return Result;
        Context->AudioState.play_state  = AUDIO_PLAYING;
    }

    return 0;
}
コード例 #16
0
ファイル: dvb_audio.c プロジェクト: backtrack2016/tdt
/*{{{  AudioIoctlSetId*/
int AudioIoctlSetId (struct DeviceContext_s* Context, int Id)
{
    int                 Result  = 0;
    unsigned int        DemuxId = (Context->AudioState.stream_source == AUDIO_SOURCE_DEMUX) ? Context->DemuxContext->Id : DEMUX_INVALID_ID;

    DVB_DEBUG("Setting Audio Id to %04x\n", Id);

    if (Context->AudioStream != NULL)
        Result  = StreamSetId (Context->AudioStream, DemuxId, Id);

    if (Result != 0)
        return Result;

    Context->AudioId    = Id;

    return Result;
}
コード例 #17
0
ファイル: dvb_audio.c プロジェクト: backtrack2016/tdt
/*{{{  AudioIoctlSetPlayInterval*/
static int AudioIoctlSetPlayInterval (struct DeviceContext_s* Context, dvb_play_interval_t* PlayInterval)
{
    int Result;

    DVB_DEBUG("\n");

    memcpy (&Context->PlayInterval, PlayInterval, sizeof(dvb_play_interval_t));

    if (Context->Playback == NULL)
        return 0;

    Result      = PlaybackSetPlayInterval (Context->Playback, (play_interval_t*)PlayInterval);
    if (Result < 0)
        return Result;

    return Result;
}
コード例 #18
0
static int DvrOpen     (struct inode*     Inode,
			struct file*      File)
{
    struct dvb_device*          DvbDevice       = (struct dvb_device*)File->private_data;
    struct dmxdev*              DmxDevice       = (struct dmxdev*)DvbDevice->priv;
    struct dvb_demux*           DvbDemux        = (struct dvb_demux*)DmxDevice->demux->priv;
    struct DeviceContext_s*     Context         = (struct DeviceContext_s*)DvbDemux->priv;

    DVB_DEBUG("\n");
#if 0
    if ((Context->Playback == NULL) && (Context->DemuxContext->Playback == NULL))
    {
	Result      = DvbPlaybackCreate (&Context->Playback);
	if (Result < 0)
	    return Result;
	Result      = DvbPlaybackSetSpeed (Context->Playback, Context->PlaySpeed);
	if (Result < 0)
	    return Result;
	if (Context != Context->DemuxContext)
	    Context->DemuxContext->Playback    = Context->Playback;
    }
    if ((Context->DemuxStream == NULL) && (Context->DemuxContext->DemuxStream == NULL))
    {
	Result      = DvbPlaybackAddDemux (Context->Playback, Context->DemuxContext->Id, &Context->DemuxStream);
	if (Result < 0)
	    return Result;
	if (Context != Context->DemuxContext)
	    Context->DemuxContext->DemuxStream  = Context->DemuxStream;
    }
#endif

#ifdef __TDT__
    //sylvester: wenn der stream vom user kommt soll WriteToDecoder nix
    //tun, da das ja hier schon passiert. keine ahnung wie man das ansonsten
    //verhindern soll;-)
    Context->dvr_write = 0;
#else
    Context->StartOffset = -1;
    Context->EndOffset   = -1;
#endif
    return OriginalDvrFops.open (Inode, File);

}
コード例 #19
0
ファイル: dvb_audio.c プロジェクト: backtrack2016/tdt
/*{{{  AudioIoctlFlush*/
static int AudioIoctlFlush (struct DeviceContext_s* Context)
{
    int                         Result  = 0;
    struct DvbContext_s*        DvbContext      = Context->DvbContext;

    DVB_DEBUG("\n");
    /* If the stream is frozen it cannot be drained so an error is returned. */
    if ((Context->PlaySpeed == 0) || (Context->PlaySpeed == DVB_SPEED_REVERSE_STOPPED))
        return -EPERM;

    if (mutex_lock_interruptible (Context->ActiveAudioWriteLock) != 0)
        return -ERESTARTSYS;
    mutex_unlock (&(DvbContext->Lock));                 /* release lock so non-writing ioctls still work while draining */

    Result      = StreamDrain (Context->AudioStream, false);

    mutex_unlock (Context->ActiveAudioWriteLock);       /* release write lock so actions which have context lock can complete */
    mutex_lock (&(DvbContext->Lock));                   /* reclaim lock so can be released by outer function */

    return Result;
}
コード例 #20
0
ファイル: dvb_audio.c プロジェクト: backtrack2016/tdt
/*{{{  AudioIoctlDiscontinuity*/
static int AudioIoctlDiscontinuity (struct DeviceContext_s* Context, audio_discontinuity_t Discontinuity)
{
    int                 Result  = 0;

    DVB_DEBUG("%d\n", Discontinuity);

    /*
    If the stream is frozen a discontinuity cannot be injected.
    */
    if ((Context->AudioState.play_state == AUDIO_PAUSED) || (Context->PlaySpeed == 0) || (Context->PlaySpeed == DVB_SPEED_REVERSE_STOPPED))
        return -EINVAL;

    /*mutex_lock (Context->ActiveAudioWriteLock);*/
    if (mutex_lock_interruptible (Context->ActiveAudioWriteLock) != 0)
        return -ERESTARTSYS;

    Result      = StreamDiscontinuity (Context->AudioStream, (discontinuity_t)Discontinuity);
    mutex_unlock (Context->ActiveAudioWriteLock);

    return Result;
}
コード例 #21
0
ファイル: dvb_audio.c プロジェクト: backtrack2016/tdt
/*{{{  AudioIoctlSetEncoding*/
static int AudioIoctlSetEncoding (struct DeviceContext_s* Context, unsigned int Encoding)
{
    DVB_DEBUG("Set encoding to %d\n", Encoding);

    if ((Encoding < AUDIO_ENCODING_AUTO) || (Encoding > AUDIO_ENCODING_PRIVATE))
        return  -EINVAL;

    if ((Context->AudioState.play_state != AUDIO_STOPPED) && (Context->AudioState.play_state != AUDIO_INCOMPLETE))
    {
        DVB_ERROR("Cannot change encoding after play has started\n");
        return -EPERM;
    }

    Context->AudioEncoding      = (audio_encoding_t)Encoding;

    /* At this point we have received the missing piece of information which will allow the
     * stream to be fully populated so we can reissue the play. */
    if (Context->AudioState.play_state == AUDIO_INCOMPLETE)
        AudioIoctlPlay (Context);

    return 0;
}
コード例 #22
0
ファイル: dvb_audio.c プロジェクト: backtrack2016/tdt
static int AudioIoctlClearBuffer (struct DeviceContext_s* Context)
#endif
{
    int                 Result  = 0;
#ifdef __TDT__
    int prevSpeed = 0;
#endif
    dvb_discontinuity_t Discontinuity   = DVB_DISCONTINUITY_SKIP | DVB_DISCONTINUITY_SURPLUS_DATA;

    DVB_DEBUG("\n");

#ifdef __TDT__
    prevSpeed = Context->AudioState.play_state;
#endif

    /* Discard previously injected data to free the lock. */
    StreamDrain (Context->AudioStream, true);

    /*mutex_lock (Context->ActiveAudioWriteLock);*/
    if (mutex_lock_interruptible (Context->ActiveAudioWriteLock) != 0)
        return -ERESTARTSYS;

    StreamDrain (Context->AudioStream, true);
    if (Result == 0)
        Result  = StreamDiscontinuity (Context->AudioStream, Discontinuity);
    mutex_unlock (Context->ActiveAudioWriteLock);

#ifdef __TDT__
    //it seems like the player forgets our current status after clear buffer
    if(prevSpeed == AUDIO_PAUSED)
    {
        AudioIoctlSetSpeed (Context, DVB_SPEED_STOPPED);
    }
#endif
    return Result;
}
コード例 #23
0
ファイル: dvb_audio.c プロジェクト: backtrack2016/tdt
/*{{{  AudioIoctlPlay*/
int AudioIoctlPlay (struct DeviceContext_s* Context)
{
    int Result  = 0;
    sigset_t newsigs, oldsigs;

    DVB_DEBUG("\n");

    if ((Context->AudioState.play_state == AUDIO_STOPPED) || (Context->AudioState.play_state == AUDIO_INCOMPLETE))
    {
        if (Context->Playback == NULL)
        {
            /*
               Check to see if we are wired to a demux.  If so the demux should create the playback and we will get
                another play call.  Just exit in this case.  If we are playing from memory we need to create a playback.
            */
            if (Context->AudioState.stream_source == AUDIO_SOURCE_DEMUX)
            {
                if (Context->DemuxContext->Playback == NULL)
                    return 0;
                else
                    Context->Playback   = Context->DemuxContext->Playback;
            }
            else if (Context->SyncContext->Playback == NULL)
            {
                Result      = PlaybackCreate (&Context->Playback);
                if (Result < 0)
                    return Result;
                if (Context->PlaySpeed != DVB_SPEED_NORMAL_PLAY)
                {
                    Result      = AudioIoctlSetSpeed (Context, Context->PlaySpeed);
                    if (Result < 0)
                        return Result;
                }
                if ((Context->PlayInterval.start != DVB_TIME_NOT_BOUNDED) ||
                        (Context->PlayInterval.end   != DVB_TIME_NOT_BOUNDED))
                {
                    Result      = AudioIoctlSetPlayInterval (Context, &Context->PlayInterval);
                    if (Result < 0)
                        return Result;
                }
                Context->SyncContext->Playback  = Context->Playback;
            }
            else
                Context->Playback       = Context->SyncContext->Playback;
        }
        PlaybackInit (Context);

        if ((Context->AudioStream == NULL) || (Context->AudioState.play_state == AUDIO_INCOMPLETE))
        {
            unsigned int DemuxId = (Context->AudioState.stream_source == AUDIO_SOURCE_DEMUX) ? Context->DemuxContext->Id : DEMUX_INVALID_ID;

            /* a signal received in here can cause issues! Lets turn them off, just for this bit... */
            sigfillset(&newsigs);
            sigprocmask(SIG_BLOCK, &newsigs, &oldsigs);

            Result      = PlaybackAddStream    (Context->Playback,
                                                BACKEND_AUDIO_ID,
                                                BACKEND_PES_ID,
                                                AudioContent[Context->AudioEncoding],
                                                DemuxId,
                                                Context->Id,
                                                &Context->AudioStream);

            sigprocmask(SIG_SETMASK, &oldsigs, NULL);

            if (Result == STREAM_INCOMPLETE)
            {
                Context->AudioState.play_state    = AUDIO_INCOMPLETE;
                return 0;
            }

            if (Result == 0)
                Result  = AudioIoctlSetId     (Context, Context->AudioId);
            if (Result == 0)
                Result  = AudioIoctlSetAvSync (Context, Context->AudioState.AV_sync_state);
            if (Result == 0)
                Result  = AudioIoctlChannelSelect (Context, Context->AudioState.channel_select);
            /*
            If we are connected to a demux we will want to use the VIDEO write lock of the demux device
            (which could be us).
            */
            if ((Result == 0) && (Context->AudioState.stream_source == AUDIO_SOURCE_DEMUX))
                Context->ActiveAudioWriteLock   = &(Context->DemuxContext->VideoWriteLock);
        }
    }
    else
    {
        /* Play is used implicitly to exit slow motion and fast forward states so
           set speed to times 1 if audio is playing or has been paused */
        Result  = AudioIoctlSetSpeed (Context, DVB_SPEED_NORMAL_PLAY);
    }

    if (Result == 0)
    {
        StreamEnable (Context->AudioStream, true);
        Context->AudioState.play_state    = AUDIO_PLAYING;
    }
    DVB_DEBUG("State = %d\n", Context->AudioState.play_state);

    return Result;
}
コード例 #24
0
ファイル: dvb_module.c プロジェクト: miciomaxx/driver
/*static*/ int __init StmLoadModule(void)
{
	int Result;
	int i;
	short int AdapterNumbers[] = { -1 };
	DvbContext = kzalloc(sizeof(struct DvbContext_s), GFP_KERNEL);
	if (DvbContext == NULL)
	{
		DVB_ERROR("Unable to allocate device memory\n");
		return -ENOMEM;
	}
#ifdef __TDT__
	memset(DvbContext, 0, sizeof * DvbContext);
#endif
#ifdef __TDT__
	if (swts)
		printk("swts ->routing streams from dvr0 to tsm to pti to player\n");
	else
		printk("no swts ->routing streams from dvr0 direct to the player\n");
#endif
#if DVB_API_VERSION < 5
	Result = dvb_register_adapter(&DvbContext->DvbAdapter, MODULE_NAME, THIS_MODULE, NULL);
#else
	Result = dvb_register_adapter(&DvbContext->DvbAdapter, MODULE_NAME, THIS_MODULE, NULL, AdapterNumbers);
#endif
	if (Result < 0)
	{
		DVB_ERROR("Failed to register adapter (%d)\n", Result);
		kfree(DvbContext);
		DvbContext = NULL;
		return -ENOMEM;
	}
	mutex_init(&(DvbContext->Lock));
	mutex_lock(&(DvbContext->Lock));
	/*{{{  Register devices*/
	for (i = 0; i < DVB_MAX_DEVICES_PER_ADAPTER; i++)
	{
		struct DeviceContext_s* DeviceContext   = &DvbContext->DeviceContext[i];
		struct dvb_demux*       DvbDemux        = &DeviceContext->DvbDemux;
		struct dmxdev*          DmxDevice       = &DeviceContext->DmxDevice;
		struct dvb_device*      DvrDevice;
#ifdef __TDT__
		//sylvester: wenn der stream vom user kommt soll WriteToDecoder nix
		//tun, da das ja hier schon passiert. keine ahnung wie man das ansonsten
		//verhindern soll;-)
		DeviceContext->dvr_write = 0;
#endif
		DeviceContext->DvbContext = DvbContext;
#if defined (USE_KERNEL_DEMUX)
		memset(DvbDemux, 0, sizeof(struct dvb_demux));
#ifdef __TDT__
		DvbDemux->dmx.capabilities = DMX_TS_FILTERING | DMX_SECTION_FILTERING | DMX_MEMORY_BASED_FILTERING | DMX_TS_DESCRAMBLING;
		/* currently only dummy to avoid EINVAL error. Later we need it for second frontend ?! */
		DvbDemux->dmx.set_source = SetSource;
#else
		DvbDemux->dmx.capabilities = DMX_TS_FILTERING | DMX_SECTION_FILTERING | DMX_MEMORY_BASED_FILTERING;
#endif
		DvbDemux->priv = DeviceContext;
		DvbDemux->filternum = 32;
		DvbDemux->feednum = 32;
		DvbDemux->start_feed = StartFeed;
		DvbDemux->stop_feed = StopFeed;
#ifdef __TDT__
		DvbDemux->write_to_decoder = WriteToDecoder;
#else
		DvbDemux->write_to_decoder = NULL;
#endif
		Result = dvb_dmx_init(DvbDemux);
		if (Result < 0)
		{
			DVB_ERROR("dvb_dmx_init failed (errno = %d)\n", Result);
			return Result;
		}
		memset(DmxDevice, 0, sizeof(struct dmxdev));
		DmxDevice->filternum = DvbDemux->filternum;
		DmxDevice->demux = &DvbDemux->dmx;
		DmxDevice->capabilities = 0;
		Result = dvb_dmxdev_init(DmxDevice, &DvbContext->DvbAdapter);
		if (Result < 0)
		{
			DVB_ERROR("dvb_dmxdev_init failed (errno = %d)\n", Result);
			dvb_dmx_release(DvbDemux);
			return Result;
		}
		DvrDevice = DvrInit(DmxDevice->dvr_dvbdev->fops);
#ifdef __TDT__
		printk("%d: DeviceContext %p, DvbDemux %p, DmxDevice %p\n", i, DeviceContext, DvbDemux, DmxDevice);
#endif
		/* Unregister the built-in dvr device and replace it with our own version */
		dvb_unregister_device(DmxDevice->dvr_dvbdev);
		dvb_register_device(&DvbContext->DvbAdapter,
							&DmxDevice->dvr_dvbdev,
							DvrDevice, DmxDevice, DVB_DEVICE_DVR);
		DeviceContext->MemoryFrontend.source = DMX_MEMORY_FE;
		Result = DvbDemux->dmx.add_frontend(&DvbDemux->dmx, &DeviceContext->MemoryFrontend);
		if (Result < 0)
		{
			DVB_ERROR("add_frontend failed (errno = %d)\n", Result);
			dvb_dmxdev_release(DmxDevice);
			dvb_dmx_release(DvbDemux);
			return Result;
		}
#else
		dvb_register_device(&DvbContext->DvbAdapter,
							&DeviceContext->DemuxDevice,
							DemuxInit(DeviceContext),
							DeviceContext, DVB_DEVICE_DEMUX);
		dvb_register_device(&DvbContext->DvbAdapter,
							&DeviceContext->DvrDevice,
							DvrInit(DeviceContext),
							DeviceContext, DVB_DEVICE_DVR);
#endif
		dvb_register_device(&DvbContext->DvbAdapter,
							&DeviceContext->AudioDevice,
							AudioInit(DeviceContext),
							DeviceContext, DVB_DEVICE_AUDIO);
#ifdef __TDT__
		/* register the CA device (e.g. CIMAX) */
		if (i < 3)
#ifndef VIP2_V1
			dvb_register_device(&DvbContext->DvbAdapter,
								&DeviceContext->CaDevice,
								CaInit(DeviceContext),
								DeviceContext, DVB_DEVICE_CA);
#endif
#else
		dvb_register_device(&DvbContext->DvbAdapter,
							&DeviceContext->CaDevice,
							CaInit(DeviceContext),
							DeviceContext, DVB_DEVICE_CA);
#endif
		dvb_register_device(&DvbContext->DvbAdapter,
							&DeviceContext->VideoDevice,
							VideoInit(DeviceContext),
							DeviceContext, DVB_DEVICE_VIDEO);
		DeviceContext->Id                       = i;
		DeviceContext->numRunningFeeds          = 0;
		DeviceContext->DemuxContext             = DeviceContext;        /* wire directly to own demux by default */
		DeviceContext->SyncContext              = DeviceContext;        /* we are our own sync group by default */
		DeviceContext->Playback                 = NULL;
		DeviceContext->StreamType               = STREAM_TYPE_TRANSPORT;
		DeviceContext->DvbContext               = DvbContext;
		DeviceContext->DemuxStream              = NULL;
		DeviceContext->VideoStream              = NULL;
		DeviceContext->AudioStream              = NULL;
		DeviceContext->PlaySpeed                = DVB_SPEED_NORMAL_PLAY;
		DeviceContext->dvr_in                   = kmalloc(65536, GFP_KERNEL); // 128Kbytes is quite a lot per device.
		DeviceContext->dvr_out                  = kmalloc(65536, GFP_KERNEL); // However allocating on each write is expensive.
		DeviceContext->EncryptionOn             = 0;
#ifdef __TDT__
		DeviceContext->VideoPlaySpeed           = DVB_SPEED_NORMAL_PLAY;
		DeviceContext->provideToDecoder         = 0;
		DeviceContext->feedPesType              = 0;
		mutex_init(&DeviceContext->injectMutex);
		if (i < 4)
		{
			ptiInit(DeviceContext);
		}
		if (i < 1)
		{
			init_e2_proc(DeviceContext);
		}
#endif
	}
	mutex_unlock(&(DvbContext->Lock));
	DvbBackendInit();
#ifndef __TDT__
#if defined (CONFIG_CPU_SUBTYPE_STX7105) // || defined (CONFIG_CPU_SUBTYPE_STX7200)
	cap_init();
#endif
#endif
	linuxdvb_v4l2_init();
	DVB_DEBUG("STM stream device loaded\n");
	return 0;
}
コード例 #25
0
ファイル: dvb_audio.c プロジェクト: backtrack2016/tdt
static int AudioIoctlSetBypassMode (struct DeviceContext_s* Context, unsigned int Mode)
#endif
{
#ifdef __TDT__
    int vLoop;
    int number = 0;
    struct snd_kcontrol *single_control = NULL;
    struct snd_kcontrol ** kcontrol = pseudoGetControls(&number);

    //DVB_DEBUG("(not implemented)\n");
    //mpeg2=4, ac3=6
    //e2 : 1=mpegm 0=ac3, 2=dts, 8=aac, 9=aache, 6=lpcm
    //libdreamdvd : 5=dts 6=lpcm
    DVB_DEBUG("Set BypassMode to %d\n", Mode);

    if (Mode == 0)
        Context->AudioEncoding      = (audio_encoding_t) AUDIO_ENCODING_AC3;
    else if (Mode == 5 || Mode == 2)
        Context->AudioEncoding      = (audio_encoding_t) AUDIO_ENCODING_DTS;
    else if (Mode == 6)
        Context->AudioEncoding      = (audio_encoding_t) AUDIO_ENCODING_LPCM;
    else if (Mode == 8)
        Context->AudioEncoding      = (audio_encoding_t) AUDIO_ENCODING_AAC;
    else
        Context->AudioEncoding      = (audio_encoding_t) AUDIO_ENCODING_MPEG2;

//before we jump to any conclusions, does the user really want passtrough, its possible that he wants downmix!
//ask e2_proc_audio what the user wants

    for (vLoop = 0; vLoop < number; vLoop++) {
        if (kcontrol[vLoop]->private_value == PSEUDO_ADDR(spdif_bypass)) {
            single_control = kcontrol[vLoop];
            printk("Find spdif_bypass control at %p\n", single_control);
            break;
        }
    }

    if ((kcontrol != NULL) && (single_control != NULL)) {
        struct snd_ctl_elem_value ucontrol;
        ucontrol.value.integer.value[0] = e2_proc_audio_getPassthrough();

        snd_pseudo_switch_put(single_control, &ucontrol);

    } else {
        printk("Pseudo Mixer does not deliver controls\n");
    }

#ifdef use_hdmi_bypass
    /* Dagobert; set hdmi bypass, maybe we need another prco for this? */
    for (vLoop = 0; vLoop < number; vLoop++) {
        if (kcontrol[vLoop]->private_value == PSEUDO_ADDR(hdmi_bypass)) {
            single_control = kcontrol[vLoop];
            printk("Find hdmi_bypass control at %p\n", single_control);
            break;
        }
    }

    if ((kcontrol != NULL) && (single_control != NULL)) {
        struct snd_ctl_elem_value ucontrol;
        ucontrol.value.integer.value[0] = e2_proc_audio_getPassthrough();

        snd_pseudo_switch_put(single_control, &ucontrol);

    } else {
        printk("Pseudo Mixer does not deliver controls\n");
    }
#endif

    return 0;
#else
    DVB_DEBUG("(not implemented)\n");
    return -EPERM;
#endif
}
コード例 #26
0
static ssize_t DvrWrite (struct file *File, const char __user* Buffer, size_t Count, loff_t* ppos)
{
    struct dvb_device*          DvbDevice       = (struct dvb_device*)File->private_data;
    struct dmxdev*              DmxDevice       = (struct dmxdev*)DvbDevice->priv;
    struct dvb_demux*           DvbDemux        = (struct dvb_demux*)DmxDevice->demux->priv;
    struct DeviceContext_s*     Context         = (struct DeviceContext_s*)DvbDemux->priv;
    int                         Result          = 0;

#ifdef __TDT__
    // attach to the video stream context
    struct DeviceContext_s* Context0 = &Context->DvbContext->DeviceContext[0];
#endif

    if (!DmxDevice->demux->write)
	return -EOPNOTSUPP;

    if ((File->f_flags & O_ACCMODE) != O_WRONLY)
	return -EINVAL;

#ifdef __TDT__
    while(1)
    {
      // Check whether a video stream is available and in FREEZED state.
      // If the video stream is freezed and the number of buffers with
      // decoded video frames exceeds a limit then sleep until the video
      // stream is playing or the write operation is cancelled.
      // It solves the issue with the first timeshift start after reboot.
      // It also allows e2 to interrupt the video stream while it is
      // paused (until now e2 kept sending SIGUSR1 to the file push thread).
      if((Context0->VideoStream != NULL) &&
         (Context0->VideoState.play_state == VIDEO_FREEZED))
      {
         int NumberOfBuffers = 0;
         int BuffersInUse = 0;

         DvbStreamGetDecodeBufferPoolStatus(Context0->VideoStream,
                          &NumberOfBuffers,&BuffersInUse);

         if(BuffersInUse > 5)
         {
           // 40 milliseconds corresponds to one full frame
           if(msleep_interruptible(40) != 0)
           {
             DVB_DEBUG("interrupted\n");
             return 0;
           }
         }
         else
         {
            break;
         }
      }
      else
        break;
    }
#endif

    if (mutex_lock_interruptible (&DmxDevice->mutex))
	return -ERESTARTSYS;

#if 0 // We should enable this for security reasons, just want to check the impact because it can be performed inline.
    if (!access_ok(VERIFY_READ, Buffer, Count))
	return -EINVAL;
#endif

#ifdef __TDT__
     //sylvester: wenn der stream vom user kommt soll WriteToDecoder nix
     //tun, da das ja hier schon passiert. keine ahnung wie man das ansonsten
     //verhindern soll;-)
     Context->dvr_write = 1;
#endif

    /*
     * Assume that we have a blueray packet if content size is divisible by 192 but not by 188
     * If ordinary ts call demux write function on whole lot.  If bdts give data to write function
     * 188 bytes at a time.
     */
    if ((((Count % TRANSPORT_PACKET_SIZE) == 0) || ((Count % BLUERAY_PACKET_SIZE) != 0)) && !Context->EncryptionOn)
    {
#ifdef __TDT__
        if (swts)
        {
           /* inject data through tsm */
           stm_tsm_inject_user_data(Buffer, Count);
        }
        else
           demultiplexDvbPackets (DvbDemux, Buffer, Count/188);

        mutex_unlock (&DmxDevice->mutex);

        //printk("Context %p, DvbDemux %p, DmxDevice %p\n",
        //      Context, DvbDemux, DmxDevice);

        //Dagobert: dvbtest does not care the return value but e2 does.
        //StreamInject seems to return zero if it has injected all
        //(must be investigate for further versions and maybe for this).
        if (Result == 0)
           Result = Count;
#else
	// Nicks modified version of chris's patch to reduce the injected size to chunks of a suitable size, and corectly accumulate the result as in blu-ray example below
	size_t                  Transfer;
	size_t                  RemainingSize   = Count;
	const char __user*      BufferPointer   = Buffer;
	while( RemainingSize != 0 )
	{
	    Transfer             = min( RemainingSize, (0x10000 - (0x10000 % TRANSPORT_PACKET_SIZE)) );         // limit to whole number of packets less than 64kb
	    Result              += DmxDevice->demux->write (DmxDevice->demux, BufferPointer, Transfer);

	    RemainingSize       -= Transfer;
	    BufferPointer       += Transfer;
	}

	mutex_unlock (&DmxDevice->mutex);

	if (Context->DemuxStream)
	{
		mutex_lock (&(Context->VideoWriteLock));
		Result  = DvbStreamInject (Context->DemuxStream, Buffer, Count);
		mutex_unlock (&(Context->VideoWriteLock));
	}

#endif
	return Result;

    }
    else if ( (Count % (192*32)) || (!Context->EncryptionOn))
    {
	int n;

	for (n=0;n<Count;n+=192)
		Result += DmxDevice->demux->write (DmxDevice->demux, &Buffer[n+4], TRANSPORT_PACKET_SIZE) + 4;
	mutex_unlock (&DmxDevice->mutex);

	if (Context->DemuxStream)
	{
		mutex_lock (&(Context->VideoWriteLock));
		Result  = DvbStreamInject (Context->DemuxStream, Buffer, Count);
		mutex_unlock (&(Context->VideoWriteLock));
	}
	return Result;
    }
    else
    {
	int n;
	unsigned long ptr = (unsigned long)stm_v4l2_findbuffer((unsigned long)Buffer,Count,0);

	// We need to support partial injection, rather nastally unfortunatley
	unsigned char *out = Context->dvr_out;
	unsigned int Size  = Count;
	int StartOffset = 0;

	if (ptr && (ptr & ~31))
	{
		//tkdma_bluray_decrypt_data(&Context->dvr_out[0],(void*)ptr,Count / (32*192),0); // Need to do an interruptibility test
	} else {
	  copy_from_user(Context->dvr_in,&Buffer[0],Count);
	  //copy_from_user(&Context->dvr_out[16],Buffer,16);
	  //tkdma_bluray_decrypt_data(&Context->dvr_out[0],Context->dvr_in,Count / (32*192),0); //Need to do an interruptibility test       
	}

	if (Context->StartOffset>0 && Context->StartOffset < Count)
	{
		out += Context->StartOffset;
		Size -= Context->StartOffset;
		StartOffset = Context->StartOffset;
		Context->StartOffset = -1;
	}

	if (Context->EndOffset>0 && Context->EndOffset < Count && Context->EndOffset > StartOffset)
	{
		Size -= Context->EndOffset - StartOffset;
		Context->EndOffset = -1;
	}

#if 1
	for (n=0;n<Size;n+=192)
	     Result += DmxDevice->demux->write (DmxDevice->demux, &out[n+4], TRANSPORT_PACKET_SIZE) + 4;
#endif

	mutex_unlock (&DmxDevice->mutex);

	if (Context->DemuxStream)
	{
		mutex_lock (&(Context->VideoWriteLock));
		Result  = DvbStreamInject (Context->DemuxStream, &out[0], Size);
		mutex_unlock (&(Context->VideoWriteLock));
	}
	return Result;
    }

}
コード例 #27
0
int StartFeed (struct dvb_demux_feed* Feed)
{
    struct dvb_demux*                   DvbDemux        = Feed->demux;
    struct dmxdev_filter*               Filter          = (struct dmxdev_filter*)Feed->feed.ts.priv;
    struct dmx_pes_filter_params*       Params          = &Filter->params.pes;
    struct DeviceContext_s*             Context         = (struct DeviceContext_s*)DvbDemux->priv;
    struct DvbContext_s*                DvbContext      = Context->DvbContext;
    int                                 Result          = 0;
    int                                 i;
    unsigned int                        Video           = false;
    unsigned int                        Audio           = false;
#ifdef __TDT__
    struct DeviceContext_s *AvContext = NULL;
#endif

    DVB_DEBUG ("(demux%d)\n", Context->Id);

    /* either numRunningFeeds == 0 and reset_tsm == 1 or reset_tsm > 1 */
#ifdef __TDT__
	// fix recoding freezer on tuner0 and demux1/2 or tuner1 and demux0/2 or tuner2 and demux0/1
	int tsm_reset = 1;
	
	for (i = 0; i < DVB_MAX_DEVICES_PER_ADAPTER; i++)
	{
	    struct DeviceContext_s* DeviceContext = &DvbContext->DeviceContext[i];
	    if(DeviceContext->numRunningFeeds != 0)
	    	tsm_reset = 0;
	}
	
	if (tsm_reset && reset_tsm)
	{
	    printk(KERN_WARNING "reset_tsm: %d numRunningFeeds: %d => calling stm_tsm_init(1)\n", reset_tsm, Context->numRunningFeeds);
	    stm_tsm_init(1);
	}
#else
    if (Context->numRunningFeeds == 0 && reset_tsm)
    {
        printk(KERN_WARNING "reset_tsm: %d numRunningFeeds: %d => calling stm_tsm_init(1)\n", reset_tsm, Context->numRunningFeeds);
        stm_tsm_init(1);
    }
#endif

#if defined(ADB_BOX)//tutaj
 if (glowica == SINGLE) {
            
 if ((Context->pPtiSession->source==DMX_SOURCE_FRONT1)&&(StartFeed_!=NULL)) StartFeed_(Feed);
           
         }
         else if (glowica == TWIN) {
if ((Context->pPtiSession->source==DMX_SOURCE_FRONT2)&&(StartFeed_!=NULL)) StartFeed_(Feed);
           
         }
#endif

#ifdef __TDT__
#ifdef no_subtitles
  if ((Feed->type == DMX_TYPE_TS) && (Feed->pes_type > DMX_TS_PES_OTHER))
    {
      DVB_DEBUG ("pes_type %d > %d (OTHER)>\n", Feed->pes_type,
                 DMX_TS_PES_OTHER);
      return -EINVAL;
    }
#endif
  DVB_DEBUG("t = %d, pt = %d, pid = %d\n", Feed->type, Feed->pes_type, Feed->pid);
#endif

    switch (Feed->type)
    {
        case DMX_TYPE_TS:
            if (Feed->pes_type > DMX_TS_PES_OTHER)
                return -EINVAL;

            for (i = 0; i < DVB_MAX_DEVICES_PER_ADAPTER; i++)
            {
                if (Feed->pes_type == AudioId[i])
                {
                    Audio       = true;
                    break;
                }
                if (Feed->pes_type == VideoId[i])
                {
                    Video       = true;
                    break;
                }
            }
#ifdef __TDT__
          AvContext = &Context->DvbContext->DeviceContext[i];
          //fix freeze if record starts in background
          //AvContext->DemuxContext      = Context;

          //videotext & subtitles (other)
          if ((Feed->pes_type == DMX_TS_PES_TELETEXT) ||
              (Feed->pes_type == DMX_TS_PES_OTHER))
            {
              mutex_lock (&(DvbContext->Lock));

              Context->numRunningFeeds++;
              //printk("%s:%d numRunningFeeds: %d\n", __func__,__LINE__,Context->numRunningFeeds);

              stpti_start_feed (Feed, Context);
              mutex_unlock (&(DvbContext->Lock));

              break;
            }
#endif

            if (!Audio && !Video)
            {
#ifdef __TDT__
		DVB_DEBUG ("pes_type = %d\n<\n", Feed->pes_type);
#endif
                /*mutex_unlock (&(DvbContext->Lock));  This doesn't look right we haven't taken it yet*/
                return 0;
            }

            mutex_lock (&(DvbContext->Lock));
#ifndef __TDT__
            if ((Video && !Context->VideoOpenWrite) || (Audio && !Context->AudioOpenWrite))
            {
                mutex_unlock (&(DvbContext->Lock));
                return -EBADF;
            }
#endif
            if ((Context->Playback == NULL) && (Context->SyncContext->Playback == NULL))
            {
                Result      = DvbPlaybackCreate (&Context->Playback);
                if (Result < 0)
                {
                    mutex_unlock (&(DvbContext->Lock));
                    return Result;
                }
                Context->SyncContext->Playback      = Context->Playback;
                if (Context->PlaySpeed != DVB_SPEED_NORMAL_PLAY)
                {
                    Result      = VideoIoctlSetSpeed (Context, Context->PlaySpeed);
                    if (Result < 0)
#ifdef __TDT__
                    {
                        mutex_unlock (&(DvbContext->Lock));
                        return Result;
                    }
#else
                        return Result;
#endif
                }
#ifdef __TDT__
		        if ((Context->VideoPlayInterval.start != DVB_TIME_NOT_BOUNDED) ||
                            (Context->VideoPlayInterval.end   != DVB_TIME_NOT_BOUNDED))
		        {
                    Result = VideoIoctlSetPlayInterval (Context, &Context->AudioPlayInterval);
		            if (Result < 0)
                            {
                  	        mutex_unlock (&(DvbContext->Lock));
                  	        return Result;
                            }
		        }
#endif
            }
            else if (Context->Playback == NULL)
                Context->Playback               = Context->SyncContext->Playback;
            else if (Context->SyncContext->Playback == NULL)
                Context->SyncContext->Playback  = Context->Playback;
            else if (Context->Playback != Context->SyncContext->Playback)
                DVB_ERROR ("Context playback not equal to sync context playback\n");

            if (Context->DemuxStream == NULL)
            {
                Result      = DvbPlaybackAddDemux (Context->Playback, Context->DemuxContext->Id, &Context->DemuxStream);
                if (Result < 0)
                {
                    mutex_unlock (&(DvbContext->Lock));
                    return Result;
                }
            }

#ifdef __TDT__
	        if (Video)
	        {

			Context->numRunningFeeds++;
                       //printk("%s:%d numRunningFeeds: %d\n", __func__,__LINE__,Context->numRunningFeeds);

		       stpti_start_feed (Feed, Context);

		       if(Feed->ts_type & TS_DECODER)
		          VideoIoctlSetId (AvContext, Feed->pid);
	        }
	        else if (Audio)
	        {

		        Context->numRunningFeeds++;
			//printk("%s:%d numRunningFeeds: %d\n", __func__,__LINE__,Context->numRunningFeeds);

		       stpti_start_feed (Feed, Context);

		       if(Feed->ts_type & TS_DECODER)
		          AudioIoctlSetId (AvContext, Feed->pid);
	        }
#else
            if (Video)
            {
                struct DeviceContext_s* VideoContext    = &Context->DvbContext->DeviceContext[i];

                VideoContext->DemuxContext      = Context;
                VideoIoctlSetId (VideoContext, Feed->pid | (Params->flags & DMX_FILTER_BY_PRIORITY_MASK));
                VideoIoctlPlay (VideoContext);
                if ((Context->VideoPlayInterval.start != DVB_TIME_NOT_BOUNDED) ||
                    (Context->VideoPlayInterval.end   != DVB_TIME_NOT_BOUNDED))
                    VideoIoctlSetPlayInterval (Context, &Context->AudioPlayInterval);
            }
            else
            {
                struct DeviceContext_s*         AudioContext    = &Context->DvbContext->DeviceContext[i];

                AudioContext->DemuxContext      = Context;
                AudioIoctlSetId (AudioContext, Feed->pid | (Params->flags & DMX_FILTER_BY_PRIORITY_MASK));
                AudioIoctlPlay (AudioContext);
                if ((Context->AudioPlayInterval.start != DVB_TIME_NOT_BOUNDED) ||
                    (Context->AudioPlayInterval.end   != DVB_TIME_NOT_BOUNDED))
                    AudioIoctlSetPlayInterval (Context, &Context->AudioPlayInterval);
            }
#endif
            mutex_unlock (&(DvbContext->Lock));

            break;
        case DMX_TYPE_SEC:
#ifdef __TDT__
            //DVB_DEBUG ("feed type = SEC\n");

            mutex_lock (&(DvbContext->Lock));

	    Context->numRunningFeeds++;
            //printk("%s:%d numRunningFeeds: %d\n", __func__,__LINE__,Context->numRunningFeeds);

            stpti_start_feed (Feed, Context);
            mutex_unlock (&(DvbContext->Lock));
#endif
            break;
        default:
#ifdef __TDT
	        DVB_DEBUG ("< (type = %d unknown\n", Feed->type);
#endif
            return -EINVAL;
    }

    return 0;
}
コード例 #28
0
static int DvrRelease  (struct inode*  Inode,
			struct file*   File)
{
    struct dvb_device*          DvbDevice       = (struct dvb_device*)File->private_data;
    struct dmxdev*              DmxDevice       = (struct dmxdev*)DvbDevice->priv;
    struct dvb_demux*           DvbDemux        = (struct dvb_demux*)DmxDevice->demux->priv;
    struct DeviceContext_s*     Context         = (struct DeviceContext_s*)DvbDemux->priv;
    int                         Result          = 0;

#ifdef __TDT__
    DVB_DEBUG("%p, %x\n", DvbDemux, File->f_flags & O_ACCMODE);

//Dagobert: This is also responsible for the crash when ending timeshift.
//Not sure if this is a good idea, must be tested
#if 0
    //dagobert: the dvr device can be opened for
    //recording. so for this case it is a bad idea
    //to destroy the live stream playback ;-)
    if (Context->dvr_write == 1)
    {

       if (Context->DemuxStream != NULL)
       {
           Result      = PlaybackRemoveDemux (Context->Playback, Context->DemuxStream);
           Context->DemuxStream                    = NULL;
           if (Context != Context->DemuxContext)
               Context->DemuxContext->DemuxStream  = NULL;
       }

       /* Check to see if audio and video have also finished so we can release the playback */
       if ((Context->AudioStream == NULL) && (Context->VideoStream == NULL) && (Context->Playback != NULL))
       {
           /* Try and delete playback then set our demux to Null if succesful or not.  If we fail someone else
              is still using it but we are done. */
           if (PlaybackDelete (Context->Playback) == 0)
               DVB_TRACE("Playback deleted successfully\n");

           Context->Playback               = NULL;
           Context->StreamType             = STREAM_TYPE_TRANSPORT;
           Context->PlaySpeed              = DVB_SPEED_NORMAL_PLAY;
           Context->PlayInterval.start     = DVB_TIME_NOT_BOUNDED;
           Context->PlayInterval.end       = DVB_TIME_NOT_BOUNDED;
           Context->SyncContext            = Context;
       }

       Context->StreamType         = STREAM_TYPE_TRANSPORT;
    }   
#endif
    Result = OriginalDvrFops.release (Inode, File);

    //sylvester: wenn der stream vom user kommt soll WriteToDecoder nix
    //tun, da das ja hier schon passiert. keine ahnung wie man das ansonsten
    //verhindern soll;-)
    Context->dvr_write = 0;

    return Result;
#else
    DVB_DEBUG("\n");

    if (Context->DemuxStream != NULL)
    {
	Result      = DvbPlaybackRemoveDemux (Context->Playback, Context->DemuxStream);
	Context->DemuxStream                    = NULL;
	/*
	if (Context != Context->DemuxContext)
	    Context->DemuxContext->DemuxStream  = NULL;
	*/
    }

    /* Check to see if audio and video have also finished so we can release the playback */
    if ((Context->AudioStream == NULL) && (Context->VideoStream == NULL) && (Context->Playback != NULL))
    {
	/* Check to see if our playback has already been deleted by the demux context */
	if (Context->DemuxContext->Playback != NULL)
	{
	    /* Try and delete playback then set our demux to Null if succesful or not.  If we fail someone else
	       is still using it but we are done. */
	    if (DvbPlaybackDelete (Context->Playback) == 0)
		DVB_TRACE("Playback deleted successfully\n");
	}

	Context->Playback                       = NULL;
	Context->StreamType                     = STREAM_TYPE_TRANSPORT;
	Context->PlaySpeed                      = DVB_SPEED_NORMAL_PLAY;
	Context->AudioPlayInterval.start        = DVB_TIME_NOT_BOUNDED;
	Context->AudioPlayInterval.end          = DVB_TIME_NOT_BOUNDED;
	Context->VideoPlayInterval.start        = DVB_TIME_NOT_BOUNDED;
	Context->VideoPlayInterval.end          = DVB_TIME_NOT_BOUNDED;
	Context->SyncContext                    = Context;
    }

    Context->StreamType         = STREAM_TYPE_TRANSPORT;

    return OriginalDvrFops.release (Inode, File);
#endif
}