Пример #1
0
static switch_status_t mp4_file_open(switch_file_handle_t *handle, const char *path)
{
	mp4_file_context_t *context;
	char *ext;
	unsigned int flags = 0;
	const char *tmp = NULL;

	if ((ext = strrchr(path, '.')) == 0) {
		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid Format\n");
		return SWITCH_STATUS_GENERR;
	}
	ext++;

	if ((context = switch_core_alloc(handle->memory_pool, sizeof(mp4_file_context_t))) == 0) {
		return SWITCH_STATUS_MEMERR;
	}

	memset(context, 0, sizeof(mp4_file_context_t));

	context->offset = -100;
	if (handle->params && (tmp = switch_event_get_header(handle->params, "mp4v2_video_offset"))) {
		context->offset = atoi(tmp);
	}

	context->audio_type = MP4_ULAW_AUDIO_TYPE; // default

	if (handle->params && (tmp = switch_event_get_header(handle->params, "mp4v2_audio_codec"))) {
		if (!strcasecmp(tmp, "PCMU")) {
			context->audio_type = MP4_ULAW_AUDIO_TYPE;
		} else if (!strcasecmp(tmp, "MP3")) {
			context->audio_type = MP4_MP3_AUDIO_TYPE;
		} else if (!strcasecmp(tmp, "AAC")) {
			context->audio_type = MP4_MPEG4_AUDIO_TYPE;
		} else if (!strcasecmp(tmp, "L16")) {
			context->audio_type = MP4_PCM16_LITTLE_ENDIAN_AUDIO_TYPE;
		}
	}

	switch_mutex_init(&context->mutex, SWITCH_MUTEX_NESTED, handle->memory_pool);

	if (switch_test_flag(handle, SWITCH_FILE_FLAG_WRITE)) {
		flags |= SWITCH_FOPEN_WRITE | SWITCH_FOPEN_CREATE;
		if (switch_test_flag(handle, SWITCH_FILE_WRITE_APPEND) || switch_test_flag(handle, SWITCH_FILE_WRITE_OVER)) {
			flags |= SWITCH_FOPEN_READ;
		} else {
			flags |= SWITCH_FOPEN_TRUNCATE;
		}
	}

	if (switch_test_flag(handle, SWITCH_FILE_FLAG_READ)) {
		flags |= SWITCH_FOPEN_READ;
	}

	if ((context->fd = MP4CreateEx(path, 0, 1, 1, NULL, 0, NULL, 0)) == MP4_INVALID_FILE_HANDLE) {
		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Error opening file %s\n", path);
		return SWITCH_STATUS_GENERR;
	}

	switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "sample rate: %d, channels: %d\n", handle->samplerate, handle->channels);

	if (context->audio_type == MP4_ULAW_AUDIO_TYPE) {
		context->audio = MP4AddULawAudioTrack(context->fd, handle->samplerate);
		MP4SetTrackIntegerProperty(context->fd, context->audio, "mdia.minf.stbl.stsd.ulaw.channels", handle->channels);
		MP4SetTrackIntegerProperty(context->fd, context->audio, "mdia.minf.stbl.stsd.ulaw.sampleSize", 8);
	} else if (context->audio_type == MP4_MP3_AUDIO_TYPE) {
		// handle->samplerate = 44100;
		context->audio = MP4AddAudioTrack(context->fd, handle->samplerate, handle->samplerate, MP4_MP3_AUDIO_TYPE);
		MP4SetTrackName(context->fd, context->audio, ".mp3");
		MP4SetTrackIntegerProperty(context->fd, context->audio, "mdia.minf.stbl.stsd.mp4a.channels", handle->channels);
		// MP4SetTrackIntegerProperty(context->fd, context->audio, "mdia.minf.stbl.stsd..mp3.channels", handle->channels);
	} else if (context->audio_type == MP4_PCM16_LITTLE_ENDIAN_AUDIO_TYPE) {
		context->audio = MP4AddAudioTrack(context->fd, handle->samplerate, handle->samplerate, MP4_PCM16_LITTLE_ENDIAN_AUDIO_TYPE);
		MP4SetTrackName(context->fd, context->audio, "lpcm");
		MP4SetTrackIntegerProperty(context->fd, context->audio, "mdia.minf.stbl.stsd.mp4a.channels", handle->channels);
		MP4SetTrackIntegerProperty(context->fd, context->audio, "mdia.minf.stbl.stsd.lpcm.channels", handle->channels);
		MP4SetTrackIntegerProperty(context->fd, context->audio, "mdia.minf.stbl.stsd.lpcm.sampleSize", 16);
	} else if (context->audio_type == MP4_MPEG4_AUDIO_TYPE) {
		/* AAC object types */
		#define AAC_MAIN 1
		#define AAC_LOW  2
		#define AAC_SSR  3
		#define AAC_LTP  4

		uint16_t info = 0;

		info |= AAC_LOW << 11; // aacObjectType (5bit)
		info |= get_aac_sample_rate_index(handle->samplerate) << 7; //(4bit)
		info |= handle->channels << 3; //(4bit)
		info = htons(info);

		context->audio = MP4AddAudioTrack(context->fd, handle->samplerate, handle->samplerate, MP4_MPEG4_AUDIO_TYPE);
		MP4SetTrackESConfiguration(context->fd, context->audio, (uint8_t *)&info, sizeof(info));
		MP4SetTrackIntegerProperty(context->fd, context->audio, "mdia.minf.stbl.stsd.mp4a.channels", handle->channels);
	}

	handle->format = 0;
	handle->sections = 0;
	handle->seekable = 0;
	handle->speed = 0;
	handle->pos = 0;
	handle->private_info = context;
	context->pool = handle->memory_pool;

	switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Opening File [%s] %dhz %s\n",
		path, handle->samplerate, switch_test_flag(handle, SWITCH_FILE_FLAG_VIDEO) ? " with VIDEO" : "");

	if (switch_core_codec_init(&context->audio_codec,
							   get_audio_codec_name(context->audio_type),
							   NULL,
							   NULL,
							   handle->samplerate,
							   20,//ms
							   handle->channels, SWITCH_CODEC_FLAG_ENCODE,
							   NULL, handle->memory_pool) == SWITCH_STATUS_SUCCESS) {
		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Audio Codec Activation Success\n");
	} else {
		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Audio Codec Activation Fail\n");
		goto end;
	}

	if (switch_test_flag(handle, SWITCH_FILE_FLAG_VIDEO)) {
		if (switch_core_codec_init(&context->video_codec,
								   "H264",
								   NULL,
								   NULL,
								   90000,
								   0,//ms
								   1, SWITCH_CODEC_FLAG_ENCODE,
								   NULL, handle->memory_pool) == SWITCH_STATUS_SUCCESS) {
			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Video Codec H264 Activation Success\n");
		} else {
			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Video Codec H264 Activation Fail\n");
			goto end;
		}
	}

	if (switch_test_flag(handle, SWITCH_FILE_FLAG_WRITE)) {
		MP4SetAudioProfileLevel(context->fd, 0x7F);
	}

	switch_buffer_create_dynamic(&context->buf, 512, 512, 1024000);

	return SWITCH_STATUS_SUCCESS;

end:
	if (context->fd) {
		MP4Close(context->fd, 0);
		context->fd = NULL;
	}
	return SWITCH_STATUS_FALSE;
}
Пример #2
0
/**
    \fn initAudio
*/
bool muxerMp4v2::initAudio(void)
{
    audioTrackIds=new MP4TrackId[nbAStreams];
    audioPackets=new mp4v2AudioPacket[nbAStreams];
    
    for(int i=0;i<nbAStreams;i++)
    {
        WAVHeader *header=aStreams[i]->getInfo();
        ADM_audioStream*a=aStreams[i];
        audioPackets[i].clock=new audioClock(header->frequency);
        // Preload this track...
        if(false==loadAndToggleAudioSlot(i))
        {
            audioPackets[i].eos=true;
            continue;
        }
        
        switch(header->encoding)
        {
            case WAV_AAC:
                    {
                        uint8_t *extraData=NULL;
                        uint32_t extraDataLen=0;
                        if(!a->getExtraData(&extraDataLen,&extraData))
                            {
                                 GUI_Error_HIG("AAC","Cannot get AAC Extra data\n");
                                 return false;
                            }
                        audioTrackIds[i]=MP4AddAudioTrack(handle,
                                                      header->frequency,
                                                      1024,
                                                      MP4_MPEG4_AUDIO_TYPE);
                        if(MP4_INVALID_TRACK_ID==audioTrackIds[i])
                        {
                            ADM_error("Error adding audio track %i of type 0x%x\n",i,header->encoding);
                            return false;
                        }
                        aprintf("Add Track %d fq %d\n",audioTrackIds[i],header->frequency);
                        MP4SetAudioProfileLevel(handle,0x0f);
                        MP4SetTrackIntegerProperty(handle,audioTrackIds[i],"mdia.minf.stbl.stsd.mp4a.channels",
                                    header->channels);
                        MP4SetTrackESConfiguration(handle,audioTrackIds[i],extraData,extraDataLen);
                    break;
                    }
            case WAV_AC3:
                    if(false==addAc3(i, header))
                    {
                            return false;
                    }
                    break;
            case WAV_MP2:
            case WAV_MP3:
                    audioTrackIds[i]=MP4AddAudioTrack(handle,
                                                      header->frequency,
                                                      audioPackets[i].blocks[0].nbSamples,
                                                      MP4_MPEG2_AUDIO_TYPE);
                    if(MP4_INVALID_TRACK_ID==audioTrackIds[i])
                    {
                        ADM_error("Error adding audio track %i of type 0x%x\n",i,header->encoding);
                        return false;
                    }
                    aprintf("Add Track %d fq %d\n",audioTrackIds[i],header->frequency);
                    MP4SetAudioProfileLevel(handle,0x0f);
                    MP4SetTrackIntegerProperty(handle,audioTrackIds[i],"mdia.minf.stbl.stsd.mp4a.channels",
                                header->channels);
                    break;
            default:
                    ADM_error("Cannot create audio track of type 0x%x\n",header->encoding);
                    return false;
        }
        if(aStreams[i]->isLanguageSet())
        {
                MP4SetTrackLanguage(handle,audioTrackIds[i],aStreams[i]->getLanguage().c_str());
                ADM_info("[MP4v2] Setting language to %s \n",aStreams[i]->getLanguage().c_str());
        }else
            ADM_warning("[MP4v2] Language is undefined\n");

         MP4SetTrackBytesProperty(handle,audioTrackIds[i],"udta.name.value",
                    (const uint8_t*)"Stereo", strlen("Stereo"));

    }
    if(nbAStreams)
         MP4SetTrackIntegerProperty(handle, audioTrackIds[0], "tkhd.flags", 3);
    return true;
}