Ejemplo n.º 1
0
/*----------------------------------------------------------------------
|    SilenceRemoverInput_PutPacket
+---------------------------------------------------------------------*/
BLT_METHOD
SilenceRemoverInput_PutPacket(BLT_PacketConsumer* _self,
                              BLT_MediaPacket*    packet)
{
    SilenceRemover* self = ATX_SELF_M(input, SilenceRemover, BLT_PacketConsumer);
    BLT_Flags       packet_flags;
    BLT_Cardinal    zero_head = 0;
    BLT_Cardinal    zero_tail = 0;
    BLT_Offset      payload_offset;
    BLT_Size        payload_size;
    ATX_Result      result;

    ATX_LOG_FINER("SilenceRemoverInput::PutPacket");

    /* get the packet info */
    packet_flags   = BLT_MediaPacket_GetFlags(packet);
    payload_offset = BLT_MediaPacket_GetPayloadOffset(packet);
    payload_size   = BLT_MediaPacket_GetPayloadSize(packet);

    /* scan the packet for zeros */
    if (payload_size != 0) {
        result = ScanPacket(packet, &zero_head, &zero_tail);    
        if (BLT_FAILED(result)) return result;
        if (zero_head || zero_tail) {
            ATX_LOG_FINER_2("SilenceRemoverInput::PutPacket zero_head=%d, zero_tail=%d",
                            (int)zero_head, (int)zero_tail);
        }
    }

    /* decide how to process the packet */
    if (self->state == SILENCE_REMOVER_STATE_START_OF_STREAM) {
        if (zero_head == payload_size) {
            /* packet is all silence */
            if (packet_flags != 0) {
                /* packet has flags, don't discard it, just empty it */
                ATX_LOG_FINER("SilenceRemover: emptying packet");
                BLT_MediaPacket_SetPayloadSize(packet, 0);
                SilenceRemover_AcceptPacket(self, packet);
            } else {
                ATX_LOG_FINER("SilenceRemover: dropping packet");
            }
        } else {
            /* remove silence at the start of the packet */
            BLT_MediaPacket_SetPayloadOffset(packet, payload_offset+zero_head);
            SilenceRemover_AcceptPacket(self, packet);

            /* we're now in the stream unless this is also the end */
            if (!(packet_flags & BLT_MEDIA_PACKET_FLAG_END_OF_STREAM)) {
                ATX_LOG_FINER("SilenceRemover: new state = IN_STREAM");
                self->state =  SILENCE_REMOVER_STATE_IN_STREAM;
            }
        }
    } else {
        /* in stream */
        if (zero_head == payload_size) {
            /* packet is all silence */
            ATX_LOG_FINER("SilenceRemover: packet is all silence");
            if (packet_flags) {
                /* packet has flags, don't discard it, just empty it */
                SilenceRemover_TrimPending(self);
                BLT_MediaPacket_SetPayloadSize(packet, 0);
                SilenceRemover_AcceptPacket(self, packet);
            } else {
                ATX_LOG_FINER("SilenceRemover: dropping packet");
            }
        } else {
            /* accept the pending packet */
            SilenceRemover_AcceptPending(self);
            if (zero_tail) {
                /* packet has some silence at the end */
                ATX_LOG_FINER("SilenceRemover: packet has silence at end");
                SilenceRemover_HoldPacket(self, packet);
            } else {
                /* packet has no silence at the end */
                ATX_LOG_FINER("SilenceRemover: packet has no silence at end");
                SilenceRemover_AcceptPacket(self, packet);
            }
        }
        if (packet_flags & BLT_MEDIA_PACKET_FLAG_END_OF_STREAM ||
            packet_flags & BLT_MEDIA_PACKET_FLAG_START_OF_STREAM) {
            ATX_LOG_FINER("SilenceRemover: new state = START_OF_STREAM");
            self->state = SILENCE_REMOVER_STATE_START_OF_STREAM;
        }
    }

    return BLT_SUCCESS;
}
Ejemplo n.º 2
0
/*----------------------------------------------------------------------
|   AacDecoderInput_PutPacket
+---------------------------------------------------------------------*/
BLT_METHOD
AacDecoderInput_PutPacket(BLT_PacketConsumer* _self,
                          BLT_MediaPacket*    packet)
{
    AacDecoder* self = ATX_SELF_M(input, AacDecoder, BLT_PacketConsumer);
    ATX_Result  result;

    /* check to see if this is the end of a stream */
    if (BLT_MediaPacket_GetFlags(packet) & 
        BLT_MEDIA_PACKET_FLAG_END_OF_STREAM) {
        self->input.eos = BLT_TRUE;
    }

    /* check to see if we need to create a decoder for this */
    if (self->helix_decoder == NULL) {
        AacDecoderConfig             decoder_config;
        AACFrameInfo                 aac_frame_info;
        const BLT_MediaType*         media_type;
        const BLT_Mp4AudioMediaType* mp4_media_type;

        BLT_MediaPacket_GetMediaType(packet, &media_type);
        if (media_type == NULL || media_type->id != self->mp4es_type_id) {
            return BLT_ERROR_INVALID_MEDIA_TYPE;
        }
        mp4_media_type = (const BLT_Mp4AudioMediaType*)media_type;
        if (mp4_media_type->base.stream_type != BLT_MP4_STREAM_TYPE_AUDIO) {
            return BLT_ERROR_INVALID_MEDIA_TYPE;
        }
        if (BLT_FAILED(AacDecoderConfig_Parse(mp4_media_type->decoder_info, mp4_media_type->decoder_info_length, &decoder_config))) {
            return BLT_ERROR_INVALID_MEDIA_FORMAT;
        }
        if (decoder_config.object_type != BLT_AAC_OBJECT_TYPE_AAC_LC &&
            decoder_config.object_type != BLT_AAC_OBJECT_TYPE_SBR) {
            return BLT_ERROR_UNSUPPORTED_CODEC;
        }
        
        /* create the decoder */
        self->helix_decoder = AACInitDecoder();
        if (self->helix_decoder == NULL) return BLT_ERROR_OUT_OF_MEMORY;

        /* configure the decoder */
        ATX_SetMemory(&aac_frame_info, 0, sizeof(aac_frame_info));
        aac_frame_info.nChans       = AacDecoderConfig_GetChannelCount(&decoder_config);
        aac_frame_info.sampRateCore = AacDecoderConfig_GetSampleRate(&decoder_config);
        if (decoder_config.object_type == BLT_AAC_OBJECT_TYPE_AAC_LC) {
            aac_frame_info.profile = AAC_PROFILE_LC;
        }
        self->sample_buffer_size = BLT_AAC_FRAME_SIZE*2*aac_frame_info.nChans*2; /* the last *2 is for SBR support */
        AACSetRawBlockParams(self->helix_decoder, 0, &aac_frame_info);        
    }

    {
        unsigned char*   in_buffer;
        int              in_size;
        short*           out_buffer;
        BLT_MediaPacket* out_packet;
        AACFrameInfo     aac_frame_info;
        
        /* create a PCM packet for the output */
        result = BLT_Core_CreateMediaPacket(ATX_BASE(self, BLT_BaseMediaNode).core,
                                            self->sample_buffer_size,
                                            (BLT_MediaType*)&self->output.media_type,
                                            &out_packet);
        if (BLT_FAILED(result)) return result;

        /* copy the timestamp */
        BLT_MediaPacket_SetTimeStamp(out_packet, BLT_MediaPacket_GetTimeStamp(packet));

        /* decode the packet as a frame */
        in_buffer  = BLT_MediaPacket_GetPayloadBuffer(packet);
        in_size    = BLT_MediaPacket_GetPayloadSize(packet);
        out_buffer = (short*)BLT_MediaPacket_GetPayloadBuffer(out_packet);
        result = AACDecode(self->helix_decoder, &in_buffer, &in_size, out_buffer); 
        if (result != 0) {
            BLT_MediaPacket_Release(out_packet);
            return BLT_ERROR_INVALID_MEDIA_FORMAT;
        }

        /* check that the sample buffer matches our current media type */
        AACGetLastFrameInfo(self->helix_decoder, &aac_frame_info);
        if (self->output.media_type.channel_count == 0) {
            /* first time, setup our media type */
            self->output.media_type.channel_count   = aac_frame_info.nChans;
            self->output.media_type.sample_rate     = aac_frame_info.sampRateOut;
            self->output.media_type.bits_per_sample = 16;
            self->output.media_type.sample_format   = BLT_PCM_SAMPLE_FORMAT_SIGNED_INT_NE;
            self->output.media_type.channel_mask    = 0;

            /* update the stream info */
            if (ATX_BASE(self, BLT_BaseMediaNode).context) {
                BLT_StreamInfo stream_info;
                stream_info.data_type     = "MPEG-4 AAC";
                stream_info.sample_rate   = aac_frame_info.sampRateOut;
                stream_info.channel_count = aac_frame_info.nChans;
                stream_info.mask = BLT_STREAM_INFO_MASK_DATA_TYPE    |
                                   BLT_STREAM_INFO_MASK_SAMPLE_RATE  |
                                   BLT_STREAM_INFO_MASK_CHANNEL_COUNT;
                BLT_Stream_SetInfo(ATX_BASE(self, BLT_BaseMediaNode).context, &stream_info);
            }

            /* update the packet media type */
            BLT_MediaPacket_SetMediaType(out_packet, (BLT_MediaType*)&self->output.media_type);
        } else {
            /* we've already setup a media type, check that this is the same */
            if (self->output.media_type.sample_rate   != (unsigned int)aac_frame_info.sampRateOut || 
                self->output.media_type.channel_count != aac_frame_info.nChans) {
                BLT_MediaPacket_Release(out_packet);
                return BLT_ERROR_INVALID_MEDIA_FORMAT;
            }
        }

        /* add to the output packet list */
        BLT_MediaPacket_SetPayloadSize(out_packet, aac_frame_info.outputSamps*2);
        ATX_List_AddData(self->output.packets, out_packet);
    }

    return BLT_SUCCESS;
}