<div>Dear all,</div>
<div> </div>
<div>This is a follow up email, regarding mp3 streamer. My previous mail is in the rear forwarded message part of this mail.</div>
<div>Below presents my full code, which can be compiled and executable.</div>
<div> </div>
<div>As I tested, the code will crush when it plays test.mp3 for the second round.</div>
<div>But if you change to use mpg file or ts file, the code will be OK.</div>
<div>Also, as I mentioned in previous mail, if I directly use MP3FileSource, without using MPEG2TransportStreamFromESSource related classes, the code will be OK without fault.</div>
<div> </div>
<div>Experts, please suggest whether my code is wrong or there is potential bug in livemedia lib?</div>
<div> </div>
<div>Thanks</div>
<div> </div>
<div>Woods</div>
<div> </div>
<div>-----------------------------------------------------------------------</div>
<div><br>#include &quot;liveMedia.hh&quot;<br>#include &quot;BasicUsageEnvironment.hh&quot;<br>#include &quot;GroupsockHelper.hh&quot;</div>
<div>#define TRANSPORT_PACKETS_PER_NETWORK_PACKET 7<br>#define TRANSPORT_PACKET_SIZE 188</div>
<div>class MyStreamer {</div>
<div> public:<br>  UsageEnvironment *env;</div>
<div>  char * fileName;<br>  char * indexName;<br>  char * address;<br>  unsigned short port;</div>
<div>  Groupsock *rtpGroupsock;<br>  MediaSink *sink;<br>  MPEG1or2Demux* baseDemultiplexor;<br>  FramedSource* source;</div>
<div> public:<br>  MyStreamer(UsageEnvironment* env, char *file, char * index, char * udpAddress, unsigned short udpPort);<br>  virtual ~MyStreamer();</div>
<div>  void play();<br>  void stop();<br>};</div>
<div>static void replay(void *param)<br>{<br> MyStreamer *streamer = (MyStreamer*)param;<br> streamer-&gt;stop();<br> streamer-&gt;play();<br>}</div>
<div>MyStreamer::<br> MyStreamer(UsageEnvironment* environment, char * file, char * index, char * udpAddress, unsigned short udpPort)<br>{<br> env = environment;</div>
<div> indexName = new char[strlen(index)+1];<br> strcpy(indexName,index);<br> address = new char[strlen(udpAddress)+1];<br> strcpy(address,udpAddress);<br> fileName = file;<br> fileName = new char[strlen(file)+1];<br> strcpy(fileName,file);<br>
 port = udpPort;<br> <br> const unsigned char ttl = 16; // reduce it in case routers don&#39;t admin scope<br> struct in_addr destinationAddress;<br> destinationAddress.s_addr = our_inet_addr(address);<br> Port destPort(udpPort);<br>
 rtpGroupsock = new Groupsock(*env, destinationAddress, destPort, ttl);<br> sink = BasicUDPSink::createNew(*env,rtpGroupsock,65536);</div>
<div> *env &lt;&lt; &quot;Streamer &quot; &lt;&lt; indexName &lt;&lt; &quot; starting...\n&quot;;<br> play();</div>
<div> return;<br>}</div>
<div>MyStreamer::<br> ~MyStreamer()<br>{<br> *env &lt;&lt; &quot;Streamer &quot; &lt;&lt; indexName &lt;&lt; &quot; stopping...\n&quot;;<br> stop();</div>
<div> Medium::close(sink);sink = NULL;<br> if(rtpGroupsock != NULL){<br>  delete rtpGroupsock;<br>  rtpGroupsock = NULL;<br> }<br> delete [] indexName;<br> delete [] address;<br> delete [] fileName;<br> <br> *env &lt;&lt; &quot;Streamer Closed\n&quot;;<br>
}</div>
<div>void MyStreamer::play() <br>{<br> unsigned const inputDataChunkSize  = TRANSPORT_PACKETS_PER_NETWORK_PACKET * TRANSPORT_PACKET_SIZE;<br> ByteStreamFileSource * fileSource  = ByteStreamFileSource::createNew(*env, fileName, inputDataChunkSize);<br>
 if(fileSource == NULL){<br>  *env &lt;&lt; &quot;unfound file\n&quot;;<br>  source = NULL;<br>  return;<br> }</div>
<div> char const* extension = strrchr(fileName, &#39;.&#39;);</div>
<div> if(strcmp(extension,&quot;.mpg&quot;)==0){<br>  baseDemultiplexor = MPEG1or2Demux::createNew(*env, fileSource);<br>  MPEG1or2DemuxedElementaryStream* pesSource = baseDemultiplexor-&gt;newRawPESStream();<br>  FramedSource* tsFrames = MPEG2TransportStreamFromPESSource::createNew(*env, pesSource);<br>
  source = MPEG2TransportStreamFramer::createNew(*env, tsFrames);<br> } else if(strcmp(extension,&quot;.ts&quot;)==0){<br>  source = MPEG2TransportStreamFramer::createNew(*env, fileSource);<br> } else if(strcmp(extension,&quot;.mp3&quot;)==0){<br>
  Medium::close(fileSource);<br>  source = MP3FileSource::createNew(*env,fileName);<br>  MPEG2TransportStreamFromESSource *m2ts = MPEG2TransportStreamFromESSource::createNew(*env);<br>  m2ts-&gt;addNewAudioSource(source,1);<br>
  source = MPEG2TransportStreamFramer::createNew(*env, m2ts);<br> }</div>
<div> *env &lt;&lt; &quot;Streaming file &quot; &lt;&lt; fileName &lt;&lt; &quot;...\n&quot;;<br> sink-&gt;startPlaying(*source, replay, this);<br>}</div>
<div>void MyStreamer::stop()<br>{<br> *env &lt;&lt; &quot;Stop sink\n&quot;;<br> if(sink != NULL)<br>  sink-&gt;stopPlaying();</div>
<div> *env &lt;&lt; &quot;Close source\n&quot;;<br> Medium::close(source);<br> source = NULL;</div>
<div> if(baseDemultiplexor != NULL){<br>  *env &lt;&lt; &quot;Close mpeg related souces\n&quot;;<br>  Medium::close(baseDemultiplexor);<br>  baseDemultiplexor = NULL;<br> }</div>
<div> *env &lt;&lt; &quot;Streamer stopped\n&quot;;<br>}</div>
<div>int main(int argc, char** argv){</div>
<div>// char file[] = &quot;test.mpg&quot;;<br>// char file[] = &quot;test.ts&quot;;<br> char file[] = &quot;test.mp3&quot;;</div>
<div> TaskScheduler* scheduler = BasicTaskScheduler::createNew();<br> UsageEnvironment *env = BasicUsageEnvironment::createNew(*scheduler);</div>
<div> MyStreamer *streamer1 = new MyStreamer(env, file, &quot;first&quot;, &quot;234.100.1.1&quot;, 9000);<br> MyStreamer *streamer2 = new MyStreamer(env, file, &quot;second&quot;, &quot;234.100.1.2&quot;, 9000);<br> scheduler-&gt;doEventLoop();<br>
}<br>-----------------------------------------------------------------------------<br><br></div>
<div class="gmail_quote">---------- Forwarded message ----------<br>From: <b class="gmail_sendername">Woods</b> <span dir="ltr">&lt;<a href="http://woods.biz">woods.biz</a>@<a href="http://gmail.com">gmail.com</a>&gt;</span><br>
Date: Tue, Jul 7, 2009 at 4:43 PM<br>Subject: mp3 streamer doubt<br>To: LIVE555 Streaming Media - development &amp; use &lt;<a href="mailto:live-devel@ns.live555.com">live-devel@ns.live555.com</a>&gt;<br><br><br>Dear Experts,<br>
<br>I have a doubt on my MP3 Streamer.<br><br>This streamer is based on testMP3Streamer code, but I changed to use BasicUDPSink. And it works fine.<br><br>As you know, in play() function, the code was like:<br><br>source = MP3FileSource::createNew(*env,fileName);<br>
<br><br><br>But after I slightly changed my code as follows:<br><br>MP3FileSource *mp3fileSource = MP3FileSource::createNew(*env,fileName);<br>MPEG2TransportStreamFromESSource *m2ts = MPEG2TransportStreamFromESSource::createNew(*env);<br>
m2ts-&gt;addNewAudioSource(mp3fileSource,1);<br>source = MPEG2TransportStreamFramer::createNew(*env, m2ts);<br><br>What I want is streaming mp3 within mpeg2ts / udp. For the first round of play, this is perfect. But, when mp3 file reaches end, the stop() and play() functions are called in sequence, the program segment fault when it starts to playing again.<br>
<br>But if I comment the Medium::close() in stop() function, (I do this only for testing purpose), I can repeatedly stream that mp3 file.<br><br>After testing in different ways, I suspect there is something wrong when I use MPEG2TransportStreamFromESSource, especially when I delete it. But according to my understanding, in my code, the delete operations should be:<br>
<br>stop() function --&gt; Medium::close(source) --&gt; delete MPEG2TransportStreamFramer --&gt; delete MPEG2TransportStreamFromESSource --&gt; delete MP3FileSource. It looks OK! But what is wrong? <br><br>Could anyone give me a suggestion?<br>
<br>Thanks<br><br><br>-- <br><font color="#888888">Woods<br></font></div><br><br clear="all">
<div></div><br>-- <br>Woods<br>