<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&nbsp; 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-&gt;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>&nbsp;&nbsp;&nbsp; friend class MemorySink;<br>private:<br>&nbsp;&nbsp;&nbsp; virtual callBackFunc onPacket = 0;<br>};<br><br>class MemorySink: public MediaSink {<br>public:<br>&nbsp;&nbsp;&nbsp; // c++: this calls callable's onpacket method on packet arrive.<br>&nbsp;&nbsp;&nbsp; static MemorySink* createNew(UsageEnvironment&amp; env, MemorySinkCallable* callable, uint32_t bufferSize = 20000);<br>&nbsp;&nbsp;&nbsp; // c: this calls function pcallback on packet arrive<br>&nbsp;&nbsp;&nbsp; //static MemorySink*
 createNew(UsageEnvironment&amp; env, callBackFunc pCallBack, uint32_t bufferSize = 20000);<br>&nbsp;&nbsp;&nbsp; // "bufferSize" should be at least as large as the largest expected<br>&nbsp;&nbsp;&nbsp; // input frame.<br><br>&nbsp;&nbsp;&nbsp; void addData(unsigned char* data, uint32_t dataSize);<br><br>protected:<br>&nbsp;&nbsp;&nbsp; //MemorySink(UsageEnvironment&amp; env, callBackFunc pCallBack, uint32_t bufferSize);<br>&nbsp;&nbsp;&nbsp; MemorySink(UsageEnvironment&amp; env, MemorySinkCallable* callable, uint32_t bufferSize);<br><br>&nbsp;&nbsp;&nbsp; virtual ~MemorySink();<br>protected:<br>&nbsp;&nbsp;&nbsp; static void afterGettingFrame(void* clientData, unsigned frameSize,<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;unsigned /*numTruncatedBytes*/,<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;struct timeval /*presentationTime*/,<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;unsigned
 /*durationInMicroseconds*/);<br>&nbsp;&nbsp;&nbsp; virtual void afterGettingFrame1(uint32_t frameSize);<br><br>&nbsp;&nbsp;&nbsp; unsigned char* fBuffer;<br>&nbsp;&nbsp;&nbsp; unsigned fBufferSize;<br><br>&nbsp;&nbsp;&nbsp; //callBackFunc* pCallBackOnFrame;<br>&nbsp;&nbsp;&nbsp; MemorySinkCallable* pCallable;<br><br>private:<br>&nbsp;&nbsp;&nbsp; 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>&nbsp;&nbsp;&nbsp; addData(fBuffer, frameSize);<br><br>&nbsp;&nbsp;&nbsp; // Then try getting the next frame:<br>&nbsp;&nbsp;&nbsp; continuePlaying();<br>}<br><br>MemorySink::~MemorySink() {<br>&nbsp;&nbsp;&nbsp; delete[] fBuffer;<br>}<br><br>/*MemorySink *MemorySink::createNew(UsageEnvironment &amp; env,<br>&nbsp;callBackFunc pCallBack, uint32_t
 bufferSize) {<br>&nbsp;return new MemorySink(env, pCallBack, bufferSize);<br>&nbsp;}*/<br><br>MemorySink *MemorySink::createNew(UsageEnvironment &amp; env, MemorySinkCallable* callable, uint32_t bufferSize) {<br>&nbsp;&nbsp;&nbsp; return new MemorySink(env, callable, bufferSize);<br>}<br><br>/*MemorySink::MemorySink(UsageEnvironment &amp; env, callBackFunc* pCallBack,<br>&nbsp;uint32_t bufferSize) :<br>&nbsp;MediaSink(env), fBufferSize(bufferSize), pCallBackOnFrame(pCallBack) {<br>&nbsp;fBuffer = new unsigned char[bufferSize];<br>&nbsp;}*/<br><br>MemorySink::MemorySink(UsageEnvironment &amp; env, MemorySinkCallable* callable, uint32_t bufferSize) :<br>&nbsp;&nbsp;&nbsp; MediaSink(env), fBufferSize(bufferSize), pCallable(callable) {<br>&nbsp;&nbsp;&nbsp; fBuffer = new unsigned char[bufferSize];<br>}<br><br>void MemorySink::addData(unsigned char *data, uint32_t dataSize) {<br>&nbsp;&nbsp;&nbsp; // call callbackfunc to notify about new
 frame<br>&nbsp;&nbsp;&nbsp; /*if ((pCallBackOnFrame != NULL) &amp;&amp; (data != NULL)) {<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; (*pCallBackOnFrame)(data, dataSize);*/<br>&nbsp;&nbsp;&nbsp; if(pCallable != NULL &amp;&amp; (data != NULL)) {<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; pCallable-&gt;onPacket(data, dataSize);<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; data = NULL;<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; dataSize = 0;<br>&nbsp;&nbsp;&nbsp; }<br>}<br><br>void MemorySink::afterGettingFrame(void* clientData, unsigned frameSize, unsigned /*numTruncatedBytes*/,<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; struct timeval /*presentationTime*/, unsigned /*durationInMicroseconds*/) {<br>&nbsp;&nbsp;&nbsp; MemorySink* sink = (MemorySink*) clientData;<br><br>&nbsp;&nbsp;&nbsp; sink-&gt;afterGettingFrame1(frameSize);<br>}<br><br>Boolean MemorySink::continuePlaying() {<br>&nbsp;&nbsp;&nbsp; if (fSource == NULL) {<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; return
 False;<br>&nbsp;&nbsp;&nbsp; }<br><br>&nbsp;&nbsp;&nbsp; fSource-&gt;getNextFrame(fBuffer, fBufferSize, afterGettingFrame, this, onSourceClosure, this);<br><br>&nbsp;&nbsp;&nbsp; return True;<br>}<br></div></div><br>



      </body></html>