stream-deploy/ZLM/3rdpart/media-server/librtsp/test/media/mp4-file-reader.cpp

113 lines
2.8 KiB
C++

#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);
}