113 lines
2.8 KiB
C++
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);
|
||
|
|
}
|