You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

113 lines
2.8KB

  1. #include "mp4-file-reader.h"
  2. #include "mov-format.h"
  3. #include "avcodecid.h"
  4. #include "rtsp-payloads.h"
  5. extern "C" const struct mov_buffer_t* mov_file_buffer(void);
  6. MP4FileReader::MP4FileReader(const char* file)
  7. :m_fp(NULL), m_pos(0), m_reader(NULL)
  8. {
  9. memset(&m_utils, 0, sizeof(m_utils));
  10. m_fp = fopen(file, "rb");
  11. if (m_fp)
  12. {
  13. m_reader = mov_reader_create(mov_file_buffer(), m_fp);
  14. GetInfo();
  15. }
  16. }
  17. MP4FileReader::~MP4FileReader()
  18. {
  19. avpktutil_destroy(&m_utils);
  20. if (m_reader)
  21. {
  22. mov_reader_destroy(m_reader);
  23. m_reader = NULL;
  24. }
  25. if (m_fp)
  26. fclose(m_fp);
  27. }
  28. int MP4FileReader::GetInfo()
  29. {
  30. if (!m_reader)
  31. return -1;
  32. struct mov_reader_trackinfo_t info = { OnVideoInfo, OnAudioInfo, OnSubtitleInfo};
  33. return mov_reader_getinfo(m_reader, &info, this);
  34. }
  35. int MP4FileReader::GetInfo(struct mov_reader_trackinfo_t* info, void* param)
  36. {
  37. if (!m_reader)
  38. return -1;
  39. return mov_reader_getinfo(m_reader, info, param);
  40. }
  41. int MP4FileReader::Read(struct avpacket_t** pkt)
  42. {
  43. m_pkt = pkt;
  44. int r = mov_reader_read(m_reader, m_packet, sizeof(m_packet), MP4OnRead, this);
  45. if (r < 0 || NULL == *pkt)
  46. return *pkt ? r : -1; //ENOMEM
  47. if(*pkt)
  48. m_pos = (*pkt)->dts; // update offset
  49. return r;
  50. }
  51. int MP4FileReader::Seek(uint64_t* pos, int /*strategy*/)
  52. {
  53. int r = mov_reader_seek(m_reader, (int64_t*)pos);
  54. if (0 == r)
  55. m_pos = (int64_t)*pos;
  56. return r;
  57. }
  58. uint64_t MP4FileReader::GetPosotion()
  59. {
  60. return m_pos;
  61. }
  62. uint64_t MP4FileReader::GetDuration()
  63. {
  64. if (!m_reader)
  65. return 0;
  66. return mov_reader_getduration(m_reader);
  67. }
  68. void MP4FileReader::OnVideoInfo(void* param, uint32_t track, uint8_t object, int width, int height, const void* extra, size_t bytes)
  69. {
  70. MP4FileReader* self = (MP4FileReader*)param;
  71. int r = avpayload_find_by_mov(object);
  72. if (r == -1)
  73. return;
  74. avpktutil_addvideo(&self->m_utils, track, s_payloads[r].codecid, width, height, extra, bytes);
  75. }
  76. 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)
  77. {
  78. MP4FileReader* self = (MP4FileReader*)param;
  79. int r = avpayload_find_by_mov(object);
  80. if (r == -1)
  81. return;
  82. avpktutil_addaudio(&self->m_utils, track, s_payloads[r].codecid, channel_count, bit_per_sample, sample_rate, extra, bytes);
  83. }
  84. void MP4FileReader::OnSubtitleInfo(void* param, uint32_t track, uint8_t object, const void* extra, size_t bytes)
  85. {
  86. MP4FileReader* self = (MP4FileReader*)param;
  87. int r = avpayload_find_by_mov(object);
  88. if (r == -1)
  89. return;
  90. avpktutil_addsubtitle(&self->m_utils, track, s_payloads[r].codecid, extra, bytes);
  91. }
  92. void MP4FileReader::MP4OnRead(void* param, uint32_t track, const void* buffer, size_t bytes, int64_t pts, int64_t dts, int flags)
  93. {
  94. MP4FileReader* self = (MP4FileReader*)param;
  95. avpktutil_input(&self->m_utils, self->m_utils.streams[track-1], buffer, bytes, pts, dts, flags, self->m_pkt);
  96. }