Esempio n. 1
0
void mov_reader_test(const char* mp4)
{
	s_vfp = fopen("v.h264", "wb");
	s_afp = fopen("a.aac", "wb");

	void* mov = mov_reader_create(mp4);

	mov_reader_getinfo(mov, mov_video_info, mov_audio_info, NULL);

	while (mov_reader_read(mov, s_buffer, sizeof(s_buffer), onread, NULL) > 0)
	{
	}

	mov_reader_destroy(mov);
	fclose(s_vfp);
	fclose(s_afp);
}
int MP4FileSource::Play()
{
	bool sendframe = false;
	if (3 == m_status)
		return 0;

SEND_PACKET:
	if (0 == m_frame.bytes)
	{
		int r = mov_reader_read(m_reader, m_frame.buffer, sizeof(m_frame.buffer), MP4OnRead, &m_frame);
		if (r == 0)
		{
			// 0-EOF
			m_status = 3;
			SendBye();
			return r;
		}
		else if (r < 0)
		{
			// error
			return r;
		}
	}

	m_status = 1;
	uint64_t clock = system_clock();
	for (int i = 0; i < m_count; i++)
	{
		struct media_t* m = &m_media[i];
		if (m->track != m_frame.track)
			continue;

		if (0 == m_clock || m_clock > clock)
			m_clock = clock;
		if (-1 == m_dts)
			m_dts = m_frame.dts;

		if (int64_t(clock - m_clock) + m_dts >= m_frame.dts)
		{
			if (0 == strcmp("H264", m->name))
			{
				// MPEG4 -> H.264 byte stream
				uint8_t* p = m_frame.buffer;
				size_t bytes = m_frame.bytes;
				while (bytes > 0)
				{
					// nalu size -> start code
					assert(bytes > 4);
					uint32_t n = (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3];
					p[0] = 0;
					p[1] = 0;
					p[2] = 0;
					p[3] = 1;
					bytes -= n + 4;
					p += n + 4;
				}

				//printf("[V] pts: %lld, dts: %lld, clock: %llu\n", m_frame.pts, m_frame.dts, clock);
			}
			else if (0 == strcmp("MP4A-LATM", m->name) || 0 == strcmp("MPEG4-GENERIC", m->name))
			{
				// add ADTS header
				//printf("[A] pts: %lld, dts: %lld, clock: %llu\n", m_frame.pts, m_frame.dts, clock);
			}
			else
			{
				assert(0);
			}

			if (-1 == m->dts_first)
				m->dts_first = m_frame.pts;
			m->dts_last = m_frame.pts;
			uint32_t timestamp = m->timestamp + m->dts_last - m->dts_first;
/*
			if (-1 == m->dts)
				m->dts = m_frame.dts;
			m->timestamp += m_frame.dts - m->dts;
			m->dts = m_frame.dts;
*/
			rtp_payload_encode_input(m->packer, m_frame.buffer, m_frame.bytes, (uint32_t)(timestamp * (m->frequency / 1000) /*kHz*/));
			SendRTCP(m, clock);

			m_frame.bytes = 0; // send flag
			sendframe = 1;
			goto SEND_PACKET;
		}

		break;
	}

	return sendframe ? 1 : 0;
}