예제 #1
0
/*----------------------------------------------------------------------
|    OsxAudioUnitsOutput_Seek
+---------------------------------------------------------------------*/
BLT_METHOD
OsxAudioUnitsOutput_Seek(BLT_MediaNode* _self,
                         BLT_SeekMode*  mode,
                         BLT_SeekPoint* point)
{
    OsxAudioUnitsOutput* self = ATX_SELF_EX(OsxAudioUnitsOutput, BLT_BaseMediaNode, BLT_MediaNode);
    ComponentResult      result;
    
    BLT_COMPILER_UNUSED(mode);
    BLT_COMPILER_UNUSED(point);


    /* flush the queue */
    pthread_mutex_lock(&self->lock);
    ATX_List_Clear(self->packet_queue);
    pthread_mutex_unlock(&self->lock);
    
    /* reset the device */
    result = AudioUnitReset(self->audio_unit, kAudioUnitScope_Input, 0);
    if (result != noErr) {
        ATX_LOG_WARNING_1("AudioUnitReset failed (%d)", (int)result);
    }

    return BLT_SUCCESS;
}
예제 #2
0
/*----------------------------------------------------------------------
|    AlsaOutput_Seek
+---------------------------------------------------------------------*/
BLT_METHOD
AlsaOutput_Seek(BLT_MediaNode* _self,
                BLT_SeekMode*  mode,
                BLT_SeekPoint* point)
{
    AlsaOutput* self = ATX_SELF_EX(AlsaOutput, BLT_BaseMediaNode, BLT_MediaNode);
    BLT_COMPILER_UNUSED(mode);
    BLT_COMPILER_UNUSED(point);

    /* ignore unless we're prepared */
    if (self->state != BLT_ALSA_OUTPUT_STATE_PREPARED) {
        return BLT_SUCCESS;
    }

    /* reset the device */
    AlsaOutput_Reset(self);

    /* update the media time */
    if (point->mask & BLT_SEEK_POINT_MASK_TIME_STAMP) {
        self->media_time = BLT_TimeStamp_ToNanos(point->time_stamp);
        self->next_media_time = self->media_time;
    } else {
        self->media_time = 0;
        self->next_media_time = 0;
    }
    
    return BLT_SUCCESS;
}
예제 #3
0
/*----------------------------------------------------------------------
|       AlsaOutputModule_Probe
+---------------------------------------------------------------------*/
BLT_METHOD
AlsaOutputModule_Probe(BLT_Module*              self, 
                       BLT_Core*                core,
                       BLT_ModuleParametersType parameters_type,
                       BLT_AnyConst             parameters,
                       BLT_Cardinal*            match)
{
    BLT_COMPILER_UNUSED(self);
    BLT_COMPILER_UNUSED(core);

    switch (parameters_type) {
      case BLT_MODULE_PARAMETERS_TYPE_MEDIA_NODE_CONSTRUCTOR:
        {
            BLT_MediaNodeConstructor* constructor = 
                (BLT_MediaNodeConstructor*)parameters;

            /* the input protocol should be PACKET and the */
            /* output protocol should be NONE              */
            if ((constructor->spec.input.protocol !=
                 BLT_MEDIA_PORT_PROTOCOL_ANY &&
                 constructor->spec.input.protocol !=
                 BLT_MEDIA_PORT_PROTOCOL_PACKET) ||
                (constructor->spec.output.protocol !=
                 BLT_MEDIA_PORT_PROTOCOL_ANY &&
                 constructor->spec.output.protocol !=
                 BLT_MEDIA_PORT_PROTOCOL_NONE)) {
                return BLT_FAILURE;
            }

            /* the input type should be unknown, or audio/pcm */
            if (!(constructor->spec.input.media_type->id == 
                  BLT_MEDIA_TYPE_ID_AUDIO_PCM) &&
                !(constructor->spec.input.media_type->id == 
                  BLT_MEDIA_TYPE_ID_UNKNOWN)) {
                return BLT_FAILURE;
            }

            /* the name should be 'alsa:<name>' */
            if (constructor->name == NULL ||
                !ATX_StringsEqualN(constructor->name, "alsa:", 4)) {
                return BLT_FAILURE;
            }

            /* always an exact match, since we only respond to our name */
            *match = BLT_MODULE_PROBE_MATCH_EXACT;

            ATX_LOG_FINE_1("probe ok [%d]", *match);
            return BLT_SUCCESS;
        }    
        break;

      default:
        break;
    }

    return BLT_FAILURE;
}
예제 #4
0
/*----------------------------------------------------------------------
|    OsxAudioUnitsOutput_QueueItemDestructor
+---------------------------------------------------------------------*/
static void 
OsxAudioUnitsOutput_QueueItemDestructor(ATX_ListDataDestructor* self, 
                                        ATX_Any                 data, 
                                        ATX_UInt32              type)
{
    BLT_COMPILER_UNUSED(self);
    BLT_COMPILER_UNUSED(type);
    
    BLT_MediaPacket_Release((BLT_MediaPacket*)data);
}
예제 #5
0
/*----------------------------------------------------------------------
|    CrossFader_OnPropertyChanged
+---------------------------------------------------------------------*/
BLT_VOID_METHOD
CrossFader_OnPropertyChanged(ATX_PropertyListenerInstance* instance,
                             ATX_CString                   name,
                             ATX_PropertyType              type,
                             const ATX_PropertyValue*      value)
{
    /*CrossFader* fader = (CrossFader*)instance;*/
    BLT_COMPILER_UNUSED(instance);
    BLT_COMPILER_UNUSED(type);
    ATX_LOG_FINE_2("CrossFader::OnPropertyChanged - name=%s val=%d", 
                   name ? name : "*", value ? value->integer : 0);
}
예제 #6
0
/*----------------------------------------------------------------------
|   FileOutputModule_Probe
+---------------------------------------------------------------------*/
BLT_METHOD
FileOutputModule_Probe(BLT_Module*              self, 
                       BLT_Core*                core,
                       BLT_ModuleParametersType parameters_type,
                       BLT_AnyConst             parameters,
                       BLT_Cardinal*            match)
{
    BLT_COMPILER_UNUSED(self);
    BLT_COMPILER_UNUSED(core);

    switch (parameters_type) {
      case BLT_MODULE_PARAMETERS_TYPE_MEDIA_NODE_CONSTRUCTOR:
        {
            BLT_MediaNodeConstructor* constructor = 
                (BLT_MediaNodeConstructor*)parameters;

            /* the input protocol should be STREAM_PUSH and the */
            /* output protocol should be NONE                   */
            if ((constructor->spec.input.protocol !=
                 BLT_MEDIA_PORT_PROTOCOL_ANY &&
                 constructor->spec.input.protocol != 
                 BLT_MEDIA_PORT_PROTOCOL_STREAM_PUSH) ||
                (constructor->spec.output.protocol !=
                 BLT_MEDIA_PORT_PROTOCOL_ANY &&
                 constructor->spec.output.protocol != 
                 BLT_MEDIA_PORT_PROTOCOL_NONE)) {
                return BLT_FAILURE;
            }

            /* we need a name */
            if (constructor->name == NULL) {
                return BLT_FAILURE;
            }

            /* the name needs to be file:<filename> */
            if (!ATX_StringsEqualN(constructor->name, "file:", 5)) {
                return BLT_FAILURE;
            }

            /* always an exact match, since we only respond to our name */
            *match = BLT_MODULE_PROBE_MATCH_EXACT;

            ATX_LOG_FINE_1("FileOutputModule::Probe - Ok [%d]", *match);
            return BLT_SUCCESS;
        }    
        break;

      default:
        break;
    }

    return BLT_FAILURE;
}
예제 #7
0
/*----------------------------------------------------------------------
|   BLT_BaseModule_Attach
+---------------------------------------------------------------------*/
BLT_DIRECT_METHOD
BLT_BaseModule_Attach(BLT_Module* _self, BLT_Core* core)
{
    BLT_COMPILER_UNUSED(_self);
    BLT_COMPILER_UNUSED(core);
#if defined(BLT_DEBUG)
    {
        BLT_BaseModule* self = ATX_SELF(BLT_BaseModule, BLT_Module);
        ATX_LOG_FINE_1("attaching module name=%s", self->info.name?self->info.name:"");
    }
#endif
    return BLT_SUCCESS;
}
예제 #8
0
/*----------------------------------------------------------------------
|    CrossFader_Seek
+---------------------------------------------------------------------*/
BLT_METHOD
CrossFader_Seek(BLT_MediaNodeInstance* instance,
                BLT_SeekMode*          mode,
                BLT_SeekPoint*         point)
{
    BLT_COMPILER_UNUSED(instance);
    BLT_COMPILER_UNUSED(mode);
    BLT_COMPILER_UNUSED(point);
    /*CrossFader* fader = (CrossFader*)instance;*/
    
    /* flush pending input packets */
    /*CrossFaderInputPort_Flush(fader);*/

    return BLT_SUCCESS;
}
예제 #9
0
/*----------------------------------------------------------------------
|    SilenceRemover_Seek
+---------------------------------------------------------------------*/
BLT_METHOD
SilenceRemover_Seek(BLT_MediaNode* instance,
                    BLT_SeekMode*  mode,
                    BLT_SeekPoint* point)
{
    SilenceRemover* self = (SilenceRemover*)instance;
    BLT_COMPILER_UNUSED(mode);
    BLT_COMPILER_UNUSED(point);
    
    /* flush the pending packet */
    if (self->input.pending) {
        BLT_MediaPacket_Release(self->input.pending);
    } 
    self->input.pending = NULL;

    return BLT_SUCCESS;
}
예제 #10
0
/*----------------------------------------------------------------------
|    AacDecoder_Seek
+---------------------------------------------------------------------*/
BLT_METHOD
AacDecoder_Seek(BLT_MediaNode* _self,
                BLT_SeekMode*  mode,
                BLT_SeekPoint* point)
{
    AacDecoder* self = ATX_SELF_EX(AacDecoder, BLT_BaseMediaNode, BLT_MediaNode);

    BLT_COMPILER_UNUSED(mode);
    BLT_COMPILER_UNUSED(point);
    
    /* clear the eos flag */
    self->input.eos  = BLT_FALSE;

    /* remove any packets in the output list */
    AacDecoderOutput_Flush(self);

    /* reset the decoder */
    if (self->helix_decoder) AACFlushCodec(self->helix_decoder);

    return BLT_SUCCESS;
}
예제 #11
0
/*----------------------------------------------------------------------
|       AlsaOutput_Activate
+---------------------------------------------------------------------*/
BLT_METHOD
AlsaOutput_Activate(BLT_MediaNode* _self, BLT_Stream* stream)
{
    AlsaOutput* self = ATX_SELF_EX(AlsaOutput, BLT_BaseMediaNode, BLT_MediaNode);
    BLT_COMPILER_UNUSED(stream);
        
    ATX_LOG_FINER("activating output");

    /* open the device */
    AlsaOutput_Open(self);

    return BLT_SUCCESS;
}
예제 #12
0
/*----------------------------------------------------------------------
|    SdlVideoOutput_GetStatus
+---------------------------------------------------------------------*/
BLT_METHOD
SdlVideoOutput_GetStatus(BLT_OutputNode*       _self,
                         BLT_OutputNodeStatus* status)
{
    SdlVideoOutput* self = ATX_SELF(SdlVideoOutput, BLT_OutputNode);
    BLT_COMPILER_UNUSED(self);
    
    /* default value */
    status->media_time.seconds     = 0;
    status->media_time.nanoseconds = 0;

    return BLT_SUCCESS;
}
예제 #13
0
/*----------------------------------------------------------------------
|   CrossFaderOutputPort_QueryMediaType
+---------------------------------------------------------------------*/
BLT_METHOD
CrossFaderOutputPort_QueryMediaType(BLT_MediaPortInstance* instance,
                                    BLT_Ordinal            index,
                                    const BLT_MediaType**  media_type)
{
    BLT_COMPILER_UNUSED(instance);
    if (index == 0) {
        *media_type = &BLT_GenericPcmMediaType;
        return BLT_SUCCESS;
    } else {
        *media_type = NULL;
        return BLT_FAILURE;
    }
}
예제 #14
0
/*----------------------------------------------------------------------
|   PcmAdapterInput_QueryMediaType
+---------------------------------------------------------------------*/
BLT_METHOD
PcmAdapterInput_QueryMediaType(BLT_MediaPort*         self,
                               BLT_Ordinal            index,
                               const BLT_MediaType**  media_type)
{
    BLT_COMPILER_UNUSED(self);
    if (index == 0) {
        *media_type = &BLT_GenericPcmMediaType;
        return BLT_SUCCESS;
    } else {
        *media_type = NULL;
        return BLT_FAILURE;
    }
}
예제 #15
0
/*----------------------------------------------------------------------
|   DcfParserModule_Probe
+---------------------------------------------------------------------*/
BLT_METHOD
DcfParserModule_Probe(BLT_Module*              _self, 
                      BLT_Core*                core,
                      BLT_ModuleParametersType parameters_type,
                      BLT_AnyConst             parameters,
                      BLT_Cardinal*            match)
{
    DcfParserModule* self = ATX_SELF_EX(DcfParserModule, BLT_BaseModule, BLT_Module);
    BLT_COMPILER_UNUSED(core);

    switch (parameters_type) {
      case BLT_MODULE_PARAMETERS_TYPE_MEDIA_NODE_CONSTRUCTOR:
        {
            BLT_MediaNodeConstructor* constructor = 
                (BLT_MediaNodeConstructor*)parameters;

            /* we need the input protocol to be STREAM_PULL and the output */
            /* protocol to be STREAM_PULL                                  */
             if ((constructor->spec.input.protocol !=
                 BLT_MEDIA_PORT_PROTOCOL_ANY &&
                 constructor->spec.input.protocol != 
                 BLT_MEDIA_PORT_PROTOCOL_STREAM_PULL) ||
                (constructor->spec.output.protocol !=
                 BLT_MEDIA_PORT_PROTOCOL_ANY &&
                 constructor->spec.output.protocol != 
                 BLT_MEDIA_PORT_PROTOCOL_STREAM_PULL)) {
                return BLT_FAILURE;
            }

            /* we need the input media type to be 'application/vnd.oma.drm.content' */
            /* or 'application/vnd.oma.drm.dcf'                                     */
            if (constructor->spec.input.media_type->id != self->dcf1_type_id &&
                constructor->spec.input.media_type->id != self->dcf2_type_id) {
                return BLT_FAILURE;
            }

            /* the output type should be unknown at this point */
            if (constructor->spec.output.media_type->id != 
                BLT_MEDIA_TYPE_ID_UNKNOWN) {
                return BLT_FAILURE;
            }

            /* compute the match level */
            if (constructor->name != NULL) {
                /* we're being probed by name */
                if (ATX_StringsEqual(constructor->name, "DcfParser")) {
                    /* our name */
                    *match = BLT_MODULE_PROBE_MATCH_EXACT;
                } else {
                    /* not out name */
                    return BLT_FAILURE;
                }
            } else {
                /* we're probed by protocol/type specs only */
                *match = BLT_MODULE_PROBE_MATCH_MAX - 10;
            }

            ATX_LOG_FINE_1("DcfParserModule::Probe - Ok [%d]", *match);
            return BLT_SUCCESS;
        }    
        break;

      default:
        break;
    }

    return BLT_FAILURE;
}
예제 #16
0
/*----------------------------------------------------------------------
|   OsxAudioUnitsOutput_Activate
+---------------------------------------------------------------------*/
BLT_METHOD
OsxAudioUnitsOutput_Activate(BLT_MediaNode* _self, BLT_Stream* stream)
{
    OsxAudioUnitsOutput*   self = ATX_SELF_EX(OsxAudioUnitsOutput, BLT_BaseMediaNode, BLT_MediaNode);
    ComponentResult        result;
    AURenderCallbackStruct callback;
    
    BLT_COMPILER_UNUSED(stream);
        
    ATX_LOG_FINER("start");

    /* select the device */
    if (self->audio_device_id) {
        result = AudioUnitSetProperty(self->audio_unit,
                                      kAudioOutputUnitProperty_CurrentDevice,
                                      kAudioUnitScope_Global,
                                      0,
                                      &self->audio_device_id,
                                      sizeof(self->audio_device_id));
        if (result != noErr) {
            ATX_LOG_WARNING_1("AudioUnitSetProperty (kAudioOutputUnitProperty_CurrentDevice) failed (%d)", (int)result);
        }
    }

    /* initialize the output */
    if (self->audio_unit) {
        result = AudioUnitInitialize(self->audio_unit);
        if (result != noErr) {
            ATX_LOG_WARNING_1("AudioUnitInitialize failed (%d)", (int)result);
            return BLT_FAILURE;
        }
    }

    /* set some default audio format */
    {
        AudioStreamBasicDescription audio_desc;
        ATX_SetMemory(&audio_desc, 0, sizeof(audio_desc));
        
        /* setup the audio description */
        audio_desc.mFormatID         = kAudioFormatLinearPCM;
        audio_desc.mFormatFlags      = kAudioFormatFlagsNativeEndian | kLinearPCMFormatFlagIsSignedInteger | kAudioFormatFlagIsPacked;
        audio_desc.mFramesPerPacket  = 1;
        audio_desc.mSampleRate       = 44100;
        audio_desc.mChannelsPerFrame = 2;
        audio_desc.mBitsPerChannel   = 16;
        audio_desc.mBytesPerFrame    = (audio_desc.mBitsPerChannel * audio_desc.mChannelsPerFrame) / 8;
        audio_desc.mBytesPerPacket   = audio_desc.mBytesPerFrame * audio_desc.mFramesPerPacket;
        audio_desc.mReserved         = 0;
        result = AudioUnitSetProperty(self->audio_unit,
                                      kAudioUnitProperty_StreamFormat,
                                      kAudioUnitScope_Input,
                                      0,
                                      &audio_desc,
                                      sizeof(audio_desc));
        if (result != noErr) {
            ATX_LOG_WARNING_1("AudioUnitSetProperty failed (%d)", (int)result);
            return BLT_FAILURE;
        }
    }

    /* check for downmix based on the number of supported channels */
    OsxAudioUnitsOutput_CheckDownmix(self);
    
    /* setup the callback */
    callback.inputProc = OsxAudioUnitsOutput_RenderCallback;
    callback.inputProcRefCon = _self;
    result = AudioUnitSetProperty(self->audio_unit, 
                                  kAudioUnitProperty_SetRenderCallback, 
                                  kAudioUnitScope_Input, 
                                  0,
                                  &callback, 
                                  sizeof(callback));
    if (result != noErr) {
        ATX_LOG_SEVERE_1("AudioUnitSetProperty failed when setting callback (%d)", (int)result);
        return BLT_FAILURE;
    }

    return BLT_SUCCESS;
}
예제 #17
0
/*----------------------------------------------------------------------
|    OsxAudioUnitsOutput_RenderCallback
+---------------------------------------------------------------------*/
static OSStatus     
OsxAudioUnitsOutput_RenderCallback(void*						inRefCon,
                                   AudioUnitRenderActionFlags*	ioActionFlags,
                                   const AudioTimeStamp*		inTimeStamp,
                                   UInt32						inBusNumber,
                                   UInt32						inNumberFrames,
                                   AudioBufferList*			    ioData)
{
    OsxAudioUnitsOutput* self = (OsxAudioUnitsOutput*)inRefCon;
    ATX_ListItem*        item;
    unsigned int         requested;
    unsigned char*       out;
    ATX_Boolean          timestamp_measured = ATX_FALSE;
    
    BLT_COMPILER_UNUSED(ioActionFlags);
    BLT_COMPILER_UNUSED(inTimeStamp);
    BLT_COMPILER_UNUSED(inBusNumber);
    BLT_COMPILER_UNUSED(inNumberFrames);
                
    /* sanity check on the parameters */
    if (ioData == NULL || ioData->mNumberBuffers == 0) return 0;
    
    /* in case we have a strange request with more than one buffer, just return silence */
    if (ioData->mNumberBuffers != 1) {
        unsigned int i;
        ATX_LOG_FINEST_1("strange request with %d buffers", 
                         (int)ioData->mNumberBuffers);
        for (i=0; i<ioData->mNumberBuffers; i++) {
            ATX_SetMemory(ioData->mBuffers[i].mData, 0, ioData->mBuffers[i].mDataByteSize);
        }
        return 0;
    }
        
    /* init local variables */
    requested = ioData->mBuffers[0].mDataByteSize;
    out = (unsigned char*)ioData->mBuffers[0].mData;
    ATX_LOG_FINEST_2("request for %d bytes, %d frames", (int)requested, (int)inNumberFrames);

    /* lock the packet queue */
    pthread_mutex_lock(&self->lock);
    
    /* return now if we're paused */
    //if (self->paused) goto end;
    
    /* abort early if we have no packets */
    if (ATX_List_GetItemCount(self->packet_queue) == 0) goto end;
        
    /* fill as much as we can */
    while (requested && (item = ATX_List_GetFirstItem(self->packet_queue))) {
        BLT_MediaPacket*        packet = ATX_ListItem_GetData(item);
        const BLT_PcmMediaType* media_type;
        BLT_Size                payload_size;
        BLT_Size                chunk_size;
        BLT_TimeStamp           chunk_duration;
        BLT_TimeStamp           packet_ts;
        unsigned int            bytes_per_frame;
        unsigned int            sample_rate;
        
        /* get the packet info */
        BLT_MediaPacket_GetMediaType(packet, (const BLT_MediaType**)&media_type);
        packet_ts = BLT_MediaPacket_GetTimeStamp(packet);
        bytes_per_frame = media_type->channel_count*media_type->bits_per_sample/8;
        sample_rate = media_type->sample_rate;
        
        /* record the timestamp if we have not already done so */
        if (!timestamp_measured) {
            self->media_time_snapshot.rendered_packet_ts = packet_ts;
            self->media_time_snapshot.rendered_host_time = 
                AudioConvertHostTimeToNanos(AudioGetCurrentHostTime());
            BLT_TimeStamp_Set(self->media_time_snapshot.rendered_duration, 0, 0);
            timestamp_measured = ATX_TRUE;
            
            ATX_LOG_FINEST_2("rendered TS: packet ts=%lld, host ts=%lld",
                             BLT_TimeStamp_ToNanos(packet_ts),
                             self->media_time_snapshot.rendered_host_time);
        }
         
        /* compute how much to copy from this packet */
        payload_size = BLT_MediaPacket_GetPayloadSize(packet);
        if (payload_size <= requested) {
            /* copy the entire payload and remove the packet from the queue */
            chunk_size = payload_size;
            ATX_CopyMemory(out, BLT_MediaPacket_GetPayloadBuffer(packet), chunk_size);
            ATX_List_RemoveItem(self->packet_queue, item);
            packet = NULL;
            media_type = NULL;
            ATX_LOG_FINER_1("media packet fully consumed, %d left in queue",
                            ATX_List_GetItemCount(self->packet_queue));
        } else {
            /* only copy a portion of the payload */
            chunk_size = requested;
            ATX_CopyMemory(out, BLT_MediaPacket_GetPayloadBuffer(packet), chunk_size);            
        }
        
        /* update the counters */
        requested -= chunk_size;
        out       += chunk_size;
        
        /* update the media time snapshot */
        if (bytes_per_frame) {
            unsigned int frames_in_chunk = chunk_size/bytes_per_frame;
            chunk_duration = BLT_TimeStamp_FromSamples(frames_in_chunk, sample_rate);
        } else {
            BLT_TimeStamp_Set(chunk_duration, 0, 0);
        }
        self->media_time_snapshot.rendered_duration = 
            BLT_TimeStamp_Add(self->media_time_snapshot.rendered_duration, chunk_duration);
        
        /* update the packet unless we're done with it */
        if (packet) {
            /* update the packet offset and timestamp */
            BLT_MediaPacket_SetPayloadOffset(packet, BLT_MediaPacket_GetPayloadOffset(packet)+chunk_size);
            BLT_MediaPacket_SetTimeStamp(packet, BLT_TimeStamp_Add(packet_ts, chunk_duration));
        }
    }
   
end:
    /* fill whatever is left with silence */    
    if (requested) {
        ATX_LOG_FINEST_1("filling with %d bytes of silence", requested);
        ATX_SetMemory(out, 0, requested);
    }
    
    pthread_mutex_unlock(&self->lock);
        
    return 0;
}
예제 #18
0
/*----------------------------------------------------------------------
|   CrossFaderModule_Probe
+---------------------------------------------------------------------*/
BLT_METHOD
CrossFaderModule_Probe(BLT_ModuleInstance*      instance, 
                       BLT_Core*                core,
                       BLT_ModuleParametersType parameters_type,
                       BLT_AnyConst             parameters,
                       BLT_Cardinal*            match)
{
    BLT_COMPILER_UNUSED(core);
    BLT_COMPILER_UNUSED(instance);

    switch (parameters_type) {
      case BLT_MODULE_PARAMETERS_TYPE_MEDIA_NODE_CONSTRUCTOR:
        {
            BLT_MediaNodeConstructor* constructor = 
                (BLT_MediaNodeConstructor*)parameters;

            /* we need a name */
            if (constructor->name == NULL ||
                !ATX_StringsEqual(constructor->name, "CrossFader")) {
                return BLT_FAILURE;
            }

            /* the input and output protocols should be PACKET */
            if ((constructor->spec.input.protocol !=
                 BLT_MEDIA_PORT_PROTOCOL_ANY &&
                 constructor->spec.input.protocol != 
                 BLT_MEDIA_PORT_PROTOCOL_PACKET) ||
                (constructor->spec.output.protocol !=
                 BLT_MEDIA_PORT_PROTOCOL_ANY &&
                 constructor->spec.output.protocol != 
                 BLT_MEDIA_PORT_PROTOCOL_PACKET)) {
                return BLT_FAILURE;
            }

            /* the input type should be unspecified, or audio/pcm */
            if (!(constructor->spec.input.media_type->id == 
                  BLT_MEDIA_TYPE_ID_AUDIO_PCM) &&
                !(constructor->spec.input.media_type->id ==
                  BLT_MEDIA_TYPE_ID_UNKNOWN)) {
                return BLT_FAILURE;
            }

            /* the output type should be unspecified, or audio/pcm */
            if (!(constructor->spec.output.media_type->id == 
                  BLT_MEDIA_TYPE_ID_AUDIO_PCM) &&
                !(constructor->spec.output.media_type->id ==
                  BLT_MEDIA_TYPE_ID_UNKNOWN)) {
                return BLT_FAILURE;
            }

            /* match level is always exact */
            *match = BLT_MODULE_PROBE_MATCH_EXACT;

            ATX_LOG_FINE_1("CrossFaderModule::Probe - Ok [%d]", *match);
            return BLT_SUCCESS;
        }    
        break;

      default:
        break;
    }

    return BLT_FAILURE;
}
예제 #19
0
/*----------------------------------------------------------------------
|   PcmAdapterModule_Probe
+---------------------------------------------------------------------*/
BLT_METHOD
PcmAdapterModule_Probe(BLT_Module*              self,  
                       BLT_Core*                core,
                       BLT_ModuleParametersType parameters_type,
                       BLT_AnyConst             parameters,
                       BLT_Cardinal*            match)
{
    BLT_COMPILER_UNUSED(self);
    BLT_COMPILER_UNUSED(core);

    switch (parameters_type) {
      case BLT_MODULE_PARAMETERS_TYPE_MEDIA_NODE_CONSTRUCTOR:
        {
            BLT_MediaNodeConstructor* constructor = 
                (BLT_MediaNodeConstructor*)parameters;

            /* compute match based on specified name */
            if (constructor->name == NULL) {
                *match = BLT_MODULE_PROBE_MATCH_DEFAULT;

                /* the input protocol should be PACKET */
                if (constructor->spec.input.protocol != 
                    BLT_MEDIA_PORT_PROTOCOL_PACKET) {
                    return BLT_FAILURE;
                }

                /* output protocol should be PACKET */
                if (constructor->spec.output.protocol != 
                    BLT_MEDIA_PORT_PROTOCOL_PACKET) {
                    return BLT_FAILURE;
                }

                /* check that the in and out formats are supported */
                if (!BLT_Pcm_CanConvert(constructor->spec.input.media_type, 
                                        constructor->spec.output.media_type)) {
                    return BLT_FAILURE;
                }
            } else {
                /* if a name is specified, it needs to match exactly */
                if (!ATX_StringsEqual(constructor->name, "PcmAdapter")) {
                    return BLT_FAILURE;
                } else {
                    *match = BLT_MODULE_PROBE_MATCH_EXACT;
                }

                /* the input protocol should be PACKET or ANY */
                if (constructor->spec.input.protocol !=
                    BLT_MEDIA_PORT_PROTOCOL_ANY &&
                    constructor->spec.input.protocol != 
                    BLT_MEDIA_PORT_PROTOCOL_PACKET) {
                    return BLT_FAILURE;
                }

                /* output protocol should be PACKET or ANY */
                if ((constructor->spec.output.protocol !=
                    BLT_MEDIA_PORT_PROTOCOL_ANY &&
                    constructor->spec.output.protocol != 
                    BLT_MEDIA_PORT_PROTOCOL_PACKET)) {
                    return BLT_FAILURE;
                }

                /* check that the in and out formats are supported */
                if (!BLT_Pcm_CanConvert(constructor->spec.input.media_type, 
                                        constructor->spec.output.media_type)) {
                    return BLT_FAILURE;
                }
            }

            ATX_LOG_FINE_1("PcmAdapterModule::Probe - Ok [%d]", *match);
            return BLT_SUCCESS;
        }    
        break;

      default:
        break;
    }

    return BLT_FAILURE;
}
예제 #20
0
/*----------------------------------------------------------------------
|   WaveFormatterModule_Probe
+---------------------------------------------------------------------*/
BLT_METHOD
WaveFormatterModule_Probe(BLT_Module*              _self, 
                          BLT_Core*                core,
                          BLT_ModuleParametersType parameters_type,
                          BLT_AnyConst             parameters,
                          BLT_Cardinal*            match)
{
    WaveFormatterModule* self = ATX_SELF_EX(WaveFormatterModule, BLT_BaseModule, BLT_Module);
    BLT_COMPILER_UNUSED(core);

    switch (parameters_type) {
      case BLT_MODULE_PARAMETERS_TYPE_MEDIA_NODE_CONSTRUCTOR:
        {
            BLT_MediaNodeConstructor* constructor = 
                (BLT_MediaNodeConstructor*)parameters;

            /* the input protocol should be STREAM_PUSH and the */
            /* output protocol should be STREAM_PUSH            */
            if ((constructor->spec.input.protocol !=
                 BLT_MEDIA_PORT_PROTOCOL_ANY &&
                 constructor->spec.input.protocol != 
                 BLT_MEDIA_PORT_PROTOCOL_STREAM_PUSH) ||
                (constructor->spec.output.protocol !=
                 BLT_MEDIA_PORT_PROTOCOL_ANY &&
                 constructor->spec.output.protocol != 
                 BLT_MEDIA_PORT_PROTOCOL_STREAM_PUSH)) {
                return BLT_FAILURE;
            }

            /* the input type should be audio/pcm */
            if (constructor->spec.input.media_type->id !=
                BLT_MEDIA_TYPE_ID_AUDIO_PCM) {
                return BLT_FAILURE;
            }

            /* compute the match level */
            if (constructor->name != NULL) {
                /* we're being probed by name */
                if (ATX_StringsEqual(constructor->name, "WaveFormatter")) {
                    /* our name */
                    *match = BLT_MODULE_PROBE_MATCH_EXACT;
                } else {
                    /* not our name */
                    return BLT_FAILURE;
                }
            } else {
                /* we're probed by protocol/type specs only */

                /* the output type should be audio/wav */
                if (constructor->spec.output.media_type->id !=
                    self->wav_type_id) {
                    return BLT_FAILURE;
                }

                *match = BLT_MODULE_PROBE_MATCH_MAX - 10;
            }

            ATX_LOG_FINE_1("WaveFormatterModule::Probe - Ok [%d]", *match);
            return BLT_SUCCESS;
        }    
        break;

      default:
        break;
    }

    return BLT_FAILURE;
}
예제 #21
0
/*----------------------------------------------------------------------
|   Mp4ParserModule_Probe
+---------------------------------------------------------------------*/
BLT_METHOD
Mp4ParserModule_Probe(BLT_Module*              _self, 
                      BLT_Core*                core,
                      BLT_ModuleParametersType parameters_type,
                      BLT_AnyConst             parameters,
                      BLT_Cardinal*            match)
{
    Mp4ParserModule* self = ATX_SELF_EX(Mp4ParserModule, BLT_BaseModule, BLT_Module);
    BLT_COMPILER_UNUSED(core);

    switch (parameters_type) {
      case BLT_MODULE_PARAMETERS_TYPE_MEDIA_NODE_CONSTRUCTOR:
        {
            BLT_MediaNodeConstructor* constructor = (BLT_MediaNodeConstructor*)parameters;

            /* check if we're being probed by name */
            if (constructor->name != NULL) {
                /* we're being probed by name */
                if (ATX_StringsEqual(constructor->name, "com.bluetune.parsers.mp4")) {
                    /* our name */
                    *match = BLT_MODULE_PROBE_MATCH_EXACT;
                    return BLT_SUCCESS;
                } else {
                    /* not out name */
                    *match = 0;
                    return BLT_FAILURE;
                }
            }
            
            /* we need the input protocol to be STREAM_PULL and the output */
            /* protocol to be PACKET                                       */
             if ((constructor->spec.input.protocol  != BLT_MEDIA_PORT_PROTOCOL_ANY &&
                  constructor->spec.input.protocol  != BLT_MEDIA_PORT_PROTOCOL_STREAM_PULL) ||
                 (constructor->spec.output.protocol != BLT_MEDIA_PORT_PROTOCOL_ANY &&
                  constructor->spec.output.protocol != BLT_MEDIA_PORT_PROTOCOL_PACKET)) {
                return BLT_FAILURE;
            }

            /* we need the input media type to be 'audio/mp4' or 'video/mp4' */
            if (constructor->spec.input.media_type->id != self->mp4_audio_type_id &&
                constructor->spec.input.media_type->id != self->mp4_video_type_id) {
                return BLT_FAILURE;
            }

            /* the output type should be unknown at this point */
            if (constructor->spec.output.media_type->id != BLT_MEDIA_TYPE_ID_UNKNOWN) {
                return BLT_FAILURE;
            }

            /* set the match level */
            *match = BLT_MODULE_PROBE_MATCH_MAX - 10;

            ATX_LOG_FINE_1("match %d", *match);
            return BLT_SUCCESS;
        }    
        break;

      default:
        break;
    }

    return BLT_FAILURE;
}
예제 #22
0
/*----------------------------------------------------------------------
|   AacDecoderModule_Probe
+---------------------------------------------------------------------*/
BLT_METHOD
AacDecoderModule_Probe(BLT_Module*              _self, 
                       BLT_Core*                core,
                       BLT_ModuleParametersType parameters_type,
                       BLT_AnyConst             parameters,
                       BLT_Cardinal*            match)
{
    AacDecoderModule* self = ATX_SELF_EX(AacDecoderModule, BLT_BaseModule, BLT_Module);
    BLT_COMPILER_UNUSED(core);
    
    switch (parameters_type) {
      case BLT_MODULE_PARAMETERS_TYPE_MEDIA_NODE_CONSTRUCTOR:
        {
            BLT_MediaNodeConstructor* constructor = 
                (BLT_MediaNodeConstructor*)parameters;

            /* the input and output protocols should be PACKET */
            if ((constructor->spec.input.protocol !=
                 BLT_MEDIA_PORT_PROTOCOL_ANY &&
                 constructor->spec.input.protocol != 
                 BLT_MEDIA_PORT_PROTOCOL_PACKET) ||
                (constructor->spec.output.protocol !=
                 BLT_MEDIA_PORT_PROTOCOL_ANY &&
                 constructor->spec.output.protocol != 
                 BLT_MEDIA_PORT_PROTOCOL_PACKET)) {
                return BLT_FAILURE;
            }

            /* the input type should be BLT_MP4_ES_MIME_TYPE */
            if (constructor->spec.input.media_type->id != 
                self->mp4es_type_id) {
                return BLT_FAILURE;
            } else {
                /* check the object type id */
                BLT_Mp4AudioMediaType* media_type = (BLT_Mp4AudioMediaType*)constructor->spec.input.media_type;
                if (media_type->base.stream_type != BLT_MP4_STREAM_TYPE_AUDIO) return BLT_FAILURE;
                if (media_type->base.format_or_object_type_id != BLT_AAC_OBJECT_TYPE_ID_MPEG2_AAC_LC &&
                    media_type->base.format_or_object_type_id != BLT_AAC_OBJECT_TYPE_ID_MPEG4_AUDIO) {
                    return BLT_FAILURE;
                }
                if (media_type->base.format_or_object_type_id == BLT_AAC_OBJECT_TYPE_ID_MPEG4_AUDIO) {
                    /* check that this is AAC LC */
                    AacDecoderConfig decoder_config;
                    if (BLT_FAILED(AacDecoderConfig_Parse(media_type->decoder_info, media_type->decoder_info_length, &decoder_config))) {
                        return BLT_FAILURE;
                    }
                    if (decoder_config.object_type != BLT_AAC_OBJECT_TYPE_AAC_LC &&
                        decoder_config.object_type != BLT_AAC_OBJECT_TYPE_SBR) {
                        return BLT_FAILURE;
                    }
                }
            }

            /* the output type should be unspecified, or audio/pcm */
            if (!(constructor->spec.output.media_type->id == 
                  BLT_MEDIA_TYPE_ID_AUDIO_PCM) &&
                !(constructor->spec.output.media_type->id ==
                  BLT_MEDIA_TYPE_ID_UNKNOWN)) {
                return BLT_FAILURE;
            }

            /* compute the match level */
            if (constructor->name != NULL) {
                /* we're being probed by name */
                if (ATX_StringsEqual(constructor->name, "AacDecoder")) {
                    /* our name */
                    *match = BLT_MODULE_PROBE_MATCH_EXACT;
                } else {
                    /* not our name */
                    return BLT_FAILURE;
                }
            } else {
                /* we're probed by protocol/type specs only */
                *match = BLT_MODULE_PROBE_MATCH_MAX - 10;
            }

            ATX_LOG_FINE_1("AacDecoderModule::Probe - Ok [%d]", *match);
            return BLT_SUCCESS;
        }    
        break;

      default:
        break;
    }

    return BLT_FAILURE;
}