int H264FileSource::Play() { m_status = 1; time64_t clock = time64_now(); if(0 == m_rtp_clock || m_rtp_clock + 40 < clock) { void* ptr = NULL; size_t bytes = 0; if(0 == m_reader.GetNextFrame(m_pos, ptr, bytes)) { rtp_h264_packer()->input(m_rtppacker, ptr, bytes, clock); m_rtp_clock = clock; SendRTCP(); return 1; } } return 0; }
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; }