StreamProcessor.cpp 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. #include "StreamProcessor.h"
  2. #include "FLVHeader.h"
  3. StreamProcessor::StreamProcessor()
  4. {
  5. buffer.reserve(1024*1024);
  6. bytesWritten=0;
  7. readHeader=false;
  8. }
  9. int StreamProcessor::Write(void *data, size_t datalen, size_t *written)
  10. {
  11. *written = buffer.write(data, datalen);
  12. bytesWritten += *written;
  13. if (*written != datalen)
  14. return FLVPROCESSOR_WRITE_WAIT; // tell the FLVReader we need a break :)
  15. return FLVPROCESSOR_WRITE_OK;
  16. }
  17. int StreamProcessor::Process()
  18. {
  19. // we're actually not going to parse anything until the GetFrame() call.
  20. // since we can't seek anyway
  21. // but we do need to validate that this is an FLV stream
  22. if (!readHeader)
  23. {
  24. if (buffer.size() >= 9) // see if we have enough data
  25. {
  26. uint8_t data[9] = {0};
  27. buffer.read(data, 9);
  28. if (header.Read(data, 9))
  29. {
  30. readHeader=true;
  31. return FLV_OK;
  32. }
  33. else // not an FLV header
  34. {
  35. return FLV_ERROR;
  36. }
  37. }
  38. }
  39. return FLV_NEED_MORE_DATA;
  40. }
  41. uint64_t StreamProcessor::GetProcessedPosition()
  42. {
  43. // since we parse the bitstream on-demand, we'll just return how many bytes we've buffered so far
  44. if (readHeader) // make sure we've at least found the main FLV header
  45. return bytesWritten;
  46. else
  47. return 0;
  48. }
  49. uint32_t StreamProcessor::GetMaxTimestamp()
  50. {
  51. return -1000; // it's a stream! no length!
  52. }
  53. uint64_t StreamProcessor::Seek(uint64_t position)
  54. {
  55. // we can't really seek in a traditional sense, but since Seek gets called to simply advance the read pointer,
  56. // we'll advance within our buffer
  57. // we always set FrameData::location to 0, so can just call like this
  58. return buffer.advance((size_t)position);
  59. }
  60. size_t StreamProcessor::Read(void *data, size_t bytes)
  61. {
  62. // easy :)
  63. return buffer.read(data, bytes);
  64. }
  65. // the fun happens here
  66. bool StreamProcessor::GetFrame(size_t frameIndex, FrameData &frameData)
  67. {
  68. // since this is a stream, we're going to ignore frameIndex and just give them the next frame
  69. if (buffer.size() >= 15)
  70. {
  71. uint8_t data[15] = {0};
  72. buffer.peek(data, 15);
  73. if (frameData.header.Read(data, 15))
  74. {
  75. // first, make sure we have enough data buffered to read the whole thing
  76. // because the next thing to get called after this function is Read()
  77. if (frameData.header.dataSize + 15 <= buffer.size())
  78. {
  79. // since we're streaming and only processing one frame at a time
  80. // we're going to set the returned frame's location to 0 (start of the ring buffer)
  81. frameData.location = 0;
  82. return true;
  83. }
  84. }
  85. }
  86. return false; // not ready for a frame yet
  87. }
  88. bool StreamProcessor::GetPosition(int time_in_ms, size_t *frameIndex, bool needVideoKeyFrame)
  89. {
  90. return false; // can't seek!
  91. }
  92. FLVHeader *StreamProcessor::GetHeader()
  93. {
  94. if (readHeader)
  95. return &header;
  96. else
  97. return 0;
  98. }