#include "mp4-file-reader.h" #include "mov-format.h" #include "avcodecid.h" #include "rtsp-payloads.h" extern "C" const struct mov_buffer_t* mov_file_buffer(void); MP4FileReader::MP4FileReader(const char* file) :m_fp(NULL), m_pos(0), m_reader(NULL) { memset(&m_utils, 0, sizeof(m_utils)); m_fp = fopen(file, "rb"); if (m_fp) { m_reader = mov_reader_create(mov_file_buffer(), m_fp); GetInfo(); } } MP4FileReader::~MP4FileReader() { avpktutil_destroy(&m_utils); if (m_reader) { mov_reader_destroy(m_reader); m_reader = NULL; } if (m_fp) fclose(m_fp); } int MP4FileReader::GetInfo() { if (!m_reader) return -1; struct mov_reader_trackinfo_t info = { OnVideoInfo, OnAudioInfo, OnSubtitleInfo}; return mov_reader_getinfo(m_reader, &info, this); } int MP4FileReader::GetInfo(struct mov_reader_trackinfo_t* info, void* param) { if (!m_reader) return -1; return mov_reader_getinfo(m_reader, info, param); } int MP4FileReader::Read(struct avpacket_t** pkt) { m_pkt = pkt; int r = mov_reader_read(m_reader, m_packet, sizeof(m_packet), MP4OnRead, this); if (r < 0 || NULL == *pkt) return *pkt ? r : -1; //ENOMEM if(*pkt) m_pos = (*pkt)->dts; // update offset return r; } int MP4FileReader::Seek(uint64_t* pos, int /*strategy*/) { int r = mov_reader_seek(m_reader, (int64_t*)pos); if (0 == r) m_pos = (int64_t)*pos; return r; } uint64_t MP4FileReader::GetPosotion() { return m_pos; } uint64_t MP4FileReader::GetDuration() { if (!m_reader) return 0; return mov_reader_getduration(m_reader); } void MP4FileReader::OnVideoInfo(void* param, uint32_t track, uint8_t object, int width, int height, const void* extra, size_t bytes) { MP4FileReader* self = (MP4FileReader*)param; int r = avpayload_find_by_mov(object); if (r == -1) return; avpktutil_addvideo(&self->m_utils, track, s_payloads[r].codecid, width, height, extra, bytes); } void MP4FileReader::OnAudioInfo(void* param, uint32_t track, uint8_t object, int channel_count, int bit_per_sample, int sample_rate, const void* extra, size_t bytes) { MP4FileReader* self = (MP4FileReader*)param; int r = avpayload_find_by_mov(object); if (r == -1) return; avpktutil_addaudio(&self->m_utils, track, s_payloads[r].codecid, channel_count, bit_per_sample, sample_rate, extra, bytes); } void MP4FileReader::OnSubtitleInfo(void* param, uint32_t track, uint8_t object, const void* extra, size_t bytes) { MP4FileReader* self = (MP4FileReader*)param; int r = avpayload_find_by_mov(object); if (r == -1) return; avpktutil_addsubtitle(&self->m_utils, track, s_payloads[r].codecid, extra, bytes); } void MP4FileReader::MP4OnRead(void* param, uint32_t track, const void* buffer, size_t bytes, int64_t pts, int64_t dts, int flags) { MP4FileReader* self = (MP4FileReader*)param; avpktutil_input(&self->m_utils, self->m_utils.streams[track-1], buffer, bytes, pts, dts, flags, self->m_pkt); }