예제 #1
0
static void mov_video_info(void* /*param*/, int /*avtype*/, int /*width*/, int /*height*/, const void* extra, size_t bytes)
{
	mpeg4_avc_decoder_configuration_record_load((const uint8_t*)extra, bytes, &s_avc);

	// write sps/pps
	int n = mpeg4_avc_to_nalu(&s_avc, (uint8_t*)s_buffer, sizeof(s_buffer));
	fwrite(s_buffer, 1, n, s_vfp);
}
예제 #2
0
static int dash_live_onflv(void* param, int codec, const void* data, size_t bytes, uint32_t pts, uint32_t dts, int flags)
{
    struct mpeg4_aac_t aac;
    struct mpeg4_avc_t avc;
    struct mpeg4_hevc_t hevc;
    dash_playlist_t* dash = (dash_playlist_t*)param;

    switch (codec)
    {
    case FLV_VIDEO_AVCC:
        if (-1 == dash->adapation_video && mpeg4_avc_decoder_configuration_record_load((const uint8_t*)data, bytes, &avc) > 0)
            dash->adapation_video = dash_mpd_add_video_adaptation_set(dash->mpd, dash->name.c_str(), MOV_OBJECT_H264, dash->width, dash->height, data, bytes);
        break;

    case FLV_VIDEO_HVCC:
        if (-1 == dash->adapation_video && mpeg4_hevc_decoder_configuration_record_load((const uint8_t*)data, bytes, &hevc) > 0)
            dash->adapation_video = dash_mpd_add_video_adaptation_set(dash->mpd, dash->name.c_str(), MOV_OBJECT_HEVC, dash->width, dash->height, data, bytes);
        break;

    case FLV_AUDIO_ASC:
        if (-1 == dash->adapation_audio && mpeg4_aac_audio_specific_config_load((const uint8_t*)data, bytes, &aac) > 0)
        {
            int rate = mpeg4_aac_audio_frequency_to((enum mpeg4_aac_frequency)aac.sampling_frequency_index);
            dash->adapation_audio = dash_mpd_add_audio_adaptation_set(dash->mpd, dash->name.c_str(), MOV_OBJECT_AAC, aac.channel_configuration, 32, rate, data, bytes);
        }
        break;

    case FLV_AUDIO_AAC:
        return dash_mpd_input(dash->mpd, dash->adapation_audio, data, bytes, pts, dts, 0);

    case FLV_VIDEO_H264:
        return dash_mpd_input(dash->mpd, dash->adapation_video, data, bytes, pts, dts, flags ? MOV_AV_FLAG_KEYFREAME : 0);

    case FLV_VIDEO_H265:
        return dash_mpd_input(dash->mpd, dash->adapation_video, data, bytes, pts, dts, flags ? MOV_AV_FLAG_KEYFREAME : 0);

    default:
        assert(0);
    }
    return 0;
}
예제 #3
0
void MP4FileSource::MP4OnVideo(void* param, uint32_t track, uint8_t object, int /*width*/, int /*height*/, const void* extra, size_t bytes)
{
	int n = 0;
	MP4FileSource* self = (MP4FileSource*)param;
	struct media_t* m = &self->m_media[self->m_count++];
	m->track = track;
	m->rtcp_clock = 0;
	m->ssrc = (uint32_t)rtp_ssrc();
	m->timestamp = m->ssrc;
	m->bandwidth = 4 * 1024 * 1024;
	m->dts_first = -1;
	m->dts_last = -1;

	if (MOV_OBJECT_H264 == object)
	{
		struct mpeg4_avc_t avc;
		mpeg4_avc_decoder_configuration_record_load((const uint8_t*)extra, bytes, &avc);
		assert(avc.nb_pps + avc.nb_sps > 0);

		static const char* pattern =
			"m=video 0 RTP/AVP %d\n"
			"a=rtpmap:%d H264/90000\n"
			"a=fmtp:%d profile-level-id=%02X%02X%02X;packetization-mode=1;sprop-parameter-sets=";

		n = snprintf((char*)self->m_frame.buffer, sizeof(self->m_frame.buffer), pattern,
			RTP_PAYLOAD_H264, RTP_PAYLOAD_H264, RTP_PAYLOAD_H264,
			(unsigned int)avc.profile, (unsigned int)avc.compatibility, (unsigned int)avc.level);

		for (uint8_t i = 0; i < avc.nb_sps; i++)
		{
			if(i > 0) self->m_frame.buffer[n++] = ',';
			n += base64_encode((char*)self->m_frame.buffer + n, avc.sps[i].data, avc.sps[i].bytes);
			self->m_frame.buffer[n] = '\0';
		}

		for (uint8_t i = 0; i < avc.nb_pps; i++)
		{
			self->m_frame.buffer[n++] = ',';
			n += base64_encode((char*)self->m_frame.buffer + n, avc.pps[i].data, avc.pps[i].bytes);
			self->m_frame.buffer[n] = '\0';
		}

		self->m_frame.buffer[n++] = '\n';
		m->frequency = 90000;
		m->payload = RTP_PAYLOAD_H264;
		snprintf(m->name, sizeof(m->name), "%s", "H264");
	}
	else if (MOV_OBJECT_HEVC == object)
	{
		assert(0);
		m->frequency = 90000;
		m->payload = RTP_PAYLOAD_H264;
		snprintf(m->name, sizeof(m->name), "%s", "H265");
	}
	else
	{
		assert(0);
		return;
	}
	
	struct rtp_payload_t rtpfunc = {
		MP4FileSource::RTPAlloc,
		MP4FileSource::RTPFree,
		MP4FileSource::RTPPacket,
	};
	m->packer = rtp_payload_encode_create(m->payload, m->name, (uint16_t)m->ssrc, m->ssrc, &rtpfunc, m);

	struct rtp_event_t event;
	event.on_rtcp = OnRTCPEvent;
	m->rtp = rtp_create(&event, self, m->ssrc, m->frequency, m->bandwidth);

	n += snprintf((char*)self->m_frame.buffer + n, sizeof(self->m_frame.buffer) - n, "a=control:track%d\n", m->track);
	self->m_sdp += (const char*)self->m_frame.buffer;
}