<html><head><style type="text/css"><!-- DIV {margin:0px;} --></style></head><body><div style="font-family:times new roman,new york,times,serif;font-size:12pt"><div>Hi,<br><br>I want to be able to access every frame that arrived from rtp just as the packets arrive from rtp. Frames include i-p(-b) frames; sequence parameter set, picture parameter set frames for h264.<br>I looked for a way to do this using existing classes (especially sink classes) but could not find a direct way. Existing implementations handle frames on a high level and do not give access to raw data in any way, I guess.<br><br>For that purpose, I made a memory sink class (inspired from filesink) that inherits mediasink class and calls an abstract class memorysinkcallable's onPacket method. when I want a class to be notified on packet arrive, I just make that class inherit memorysinkcallable and implement onPacket method. <br>Even though that works for me, with this approach I need
to have one more thread to receive frames from rtp which loops in env->taskScheduler().doEventLoop().<br>I was wondering if that was the right approach. Since sink classes do what I've implemented internally, I have doubts about my design. Could someone evaluate this approach please?<br><br>
Thanks in advance,<br>
<br>
Umit<br><br><br>
Since I can't upload attachments right now, I am writing classes down here. Sorry for the inconvenience.<br><br><br><br>HEADER FILE:<br><br>#ifndef MEMORYSINK_H_<br>#define MEMORYSINK_H_<br><br>#include "MediaSink.hh"<br><br>typedef void (callBackFunc)(unsigned char *frameData, uint32_t frameSize);<br><br>// classes which chould be notified when new packet arrives should inherit this abstract class<br>class MemorySinkCallable {<br> friend class MemorySink;<br>private:<br> virtual callBackFunc onPacket = 0;<br>};<br><br>class MemorySink: public MediaSink {<br>public:<br> // c++: this calls callable's onpacket method on packet arrive.<br> static MemorySink* createNew(UsageEnvironment& env, MemorySinkCallable* callable, uint32_t bufferSize = 20000);<br> // c: this calls function pcallback on packet arrive<br> //static MemorySink*
createNew(UsageEnvironment& env, callBackFunc pCallBack, uint32_t bufferSize = 20000);<br> // "bufferSize" should be at least as large as the largest expected<br> // input frame.<br><br> void addData(unsigned char* data, uint32_t dataSize);<br><br>protected:<br> //MemorySink(UsageEnvironment& env, callBackFunc pCallBack, uint32_t bufferSize);<br> MemorySink(UsageEnvironment& env, MemorySinkCallable* callable, uint32_t bufferSize);<br><br> virtual ~MemorySink();<br>protected:<br> static void afterGettingFrame(void* clientData, unsigned frameSize,<br> unsigned /*numTruncatedBytes*/,<br> struct timeval /*presentationTime*/,<br> unsigned
/*durationInMicroseconds*/);<br> virtual void afterGettingFrame1(uint32_t frameSize);<br><br> unsigned char* fBuffer;<br> unsigned fBufferSize;<br><br> //callBackFunc* pCallBackOnFrame;<br> MemorySinkCallable* pCallable;<br><br>private:<br> virtual Boolean continuePlaying();<br>};<br><br>#endif /* MEMORYSINK_H_ */<br><br><br><br>SOURCE FILE:<br><br>#include "MemorySink.h"<br><br>#include "GroupsockHelper.hh"<br>#include "OutputFile.hh"<br><br>void MemorySink::afterGettingFrame1(uint32_t frameSize) {<br> addData(fBuffer, frameSize);<br><br> // Then try getting the next frame:<br> continuePlaying();<br>}<br><br>MemorySink::~MemorySink() {<br> delete[] fBuffer;<br>}<br><br>/*MemorySink *MemorySink::createNew(UsageEnvironment & env,<br> callBackFunc pCallBack, uint32_t
bufferSize) {<br> return new MemorySink(env, pCallBack, bufferSize);<br> }*/<br><br>MemorySink *MemorySink::createNew(UsageEnvironment & env, MemorySinkCallable* callable, uint32_t bufferSize) {<br> return new MemorySink(env, callable, bufferSize);<br>}<br><br>/*MemorySink::MemorySink(UsageEnvironment & env, callBackFunc* pCallBack,<br> uint32_t bufferSize) :<br> MediaSink(env), fBufferSize(bufferSize), pCallBackOnFrame(pCallBack) {<br> fBuffer = new unsigned char[bufferSize];<br> }*/<br><br>MemorySink::MemorySink(UsageEnvironment & env, MemorySinkCallable* callable, uint32_t bufferSize) :<br> MediaSink(env), fBufferSize(bufferSize), pCallable(callable) {<br> fBuffer = new unsigned char[bufferSize];<br>}<br><br>void MemorySink::addData(unsigned char *data, uint32_t dataSize) {<br> // call callbackfunc to notify about new
frame<br> /*if ((pCallBackOnFrame != NULL) && (data != NULL)) {<br> (*pCallBackOnFrame)(data, dataSize);*/<br> if(pCallable != NULL && (data != NULL)) {<br> pCallable->onPacket(data, dataSize);<br> data = NULL;<br> dataSize = 0;<br> }<br>}<br><br>void MemorySink::afterGettingFrame(void* clientData, unsigned frameSize, unsigned /*numTruncatedBytes*/,<br> struct timeval /*presentationTime*/, unsigned /*durationInMicroseconds*/) {<br> MemorySink* sink = (MemorySink*) clientData;<br><br> sink->afterGettingFrame1(frameSize);<br>}<br><br>Boolean MemorySink::continuePlaying() {<br> if (fSource == NULL) {<br> return
False;<br> }<br><br> fSource->getNextFrame(fBuffer, fBufferSize, afterGettingFrame, this, onSourceClosure, this);<br><br> return True;<br>}<br></div></div><br>
</body></html>