<table cellspacing="0" cellpadding="0" border="0" ><tr><td valign="top" style="font: inherit;"><div class="post-text">
<p>Hi all,</p><p><br></p>
<p>I would really appreciate some help with the following issue:</p>
<p>I have a gadget with a camera, producing H264 compressed video
frames, these frames are being sent to my application. These frames are
not in a container, just raw data.</p><p><br></p>
<p>I want to use ffmpeg and libav functions to create a video file, which can be used later.</p>
<p>If I decode the frames, then encode them, everything works fine, I
get a valid video file. (the decode/encode steps are the usual libav
commands, nothing fancy here, I took them from the almighty internet,
they are rock solid)... However, I waste a lot of time by decoding and
encoding, so I would like to skip this step and directly put the frames
in the output stream. Now, the problems come.</p>
<p>Here is the code I came up with for producing the encoding:</p>
<pre class="lang-c prettyprint"><code><span class="typ">AVFrame</span><span class="pun">*</span><span class="pln"> picture</span><span class="pun">;</span><span class="pln"><br><br>avpicture_fill</span><span class="pun">((</span><span class="typ">AVPicture</span><span class="pun">*)</span><span class="pln"> picture</span><span class="pun">,</span><span class="pln"> </span><span class="pun">(</span><span class="pln">uint8_t</span><span class="pun">*)</span><span class="pln">frameData</span><span class="pun">,</span><span class="pln"> <br> codecContext</span><span class="pun">-></span><span class="pln">pix_fmt</span><span class="pun">,</span><span class="pln"> codecContext</span><span class="pun">-></span><span class="pln">width</span><span class="pun">,</span><span class="pln"><br> codecContext</span><span
class="pun">-></span><span class="pln">height</span><span class="pun">);</span><span class="pln"><br></span><span class="kwd">int</span><span class="pln"> outSize </span><span class="pun">=</span><span class="pln"> avcodec_encode_video</span><span class="pun">(</span><span class="pln">codecContext</span><span class="pun">,</span><span class="pln"> videoOutBuf</span><span class="pun">,</span><span class="pln"> <br> </span><span class="kwd">sizeof</span><span class="pun">(</span><span class="pln">videoOutBuf</span><span class="pun">),</span><span class="pln"> picture</span><span class="pun">);</span><span class="pln"><br></span><span class="kwd">if</span><span class="pln"> </span><span class="pun">(</span><span class="pln">outSize </span><span class="pun">></span><span class="pln"> </span><span class="lit">0</span><span class="pun">)</span><span class="pln"> <br></span><span
class="pun">{</span><span class="pln"><br> </span><span class="typ">AVPacket</span><span class="pln"> packet</span><span class="pun">;</span><span class="pln"><br> av_init_packet</span><span class="pun">(&</span><span class="pln">packet</span><span class="pun">);</span><span class="pln"><br> packet</span><span class="pun">.</span><span class="pln">pts </span><span class="pun">=</span><span class="pln"> av_rescale_q</span><span class="pun">(</span><span class="pln">codecContext</span><span class="pun">-></span><span class="pln">coded_frame</span><span class="pun">-></span><span class="pln">pts</span><span class="pun">,</span><span class="pln"><br> codecContext</span><span class="pun">-></span><span class="pln">time_base</span><span class="pun">,</span><span class="pln"> videoStream</span><span class="pun">-></span><span
class="pln">time_base</span><span class="pun">);</span><span class="pln"><br> </span><span class="kwd">if</span><span class="pln"> </span><span class="pun">(</span><span class="pln">codecContext</span><span class="pun">-></span><span class="pln">coded_frame</span><span class="pun">-></span><span class="pln">key_frame</span><span class="pun">)</span><span class="pln"> <br> </span><span class="pun">{</span><span class="pln"><br> packet</span><span class="pun">.</span><span class="pln">flags </span><span class="pun">|=</span><span class="pln"> PKT_FLAG_KEY</span><span class="pun">;</span><span class="pln"><br> </span><span class="pun">}</span><span class="pln"><br> packet</span><span class="pun">.</span><span class="pln">stream_index </span><span class="pun">=</span><span class="pln"> videoStream</span><span class="pun">-></span><span class="pln">index</span><span
class="pun">;</span><span class="pln"><br> packet</span><span class="pun">.</span><span class="pln">data </span><span class="pun">=</span><span class="pln"> videoOutBuf</span><span class="pun">;</span><span class="pln"><br> packet</span><span class="pun">.</span><span class="pln">size </span><span class="pun">=</span><span class="pln"> outSize</span><span class="pun">;</span><span class="pln"><br><br> av_interleaved_write_frame</span><span class="pun">(</span><span class="pln">context</span><span class="pun">,</span><span class="pln"> </span><span class="pun">&</span><span class="pln">packet</span><span class="pun">);</span><span class="pln"><br> put_flush_packet</span><span class="pun">(</span><span class="pln">context</span><span class="pun">-></span><span class="pln">pb</span><span class="pun">);</span><span class="pln"><br></span><span class="pun">}</span><span
class="pln"><br></span></code></pre>
<p>Where the variables are like:</p>
<p><code>frameData</code> is the decoded frame data, that came from the camera, it was decoded in a previous step and <code>videoOutBuf</code> is a plain uint8_t buffer for holding the data</p>
<p>I have modified the application in order to not to decode the frames, but simply pass through the data like:</p>
<pre class="lang-c prettyprint"><code><span class="pln"> </span><span class="typ">AVPacket</span><span class="pln"> packet</span><span class="pun">;</span><span class="pln"><br> av_init_packet</span><span class="pun">(&</span><span class="pln">packet</span><span class="pun">);</span><span class="pln"><br><br> packet</span><span class="pun">.</span><span class="pln">stream_index </span><span class="pun">=</span><span class="pln"> videoStream</span><span class="pun">-></span><span class="pln">index</span><span class="pun">;</span><span class="pln"><br> packet</span><span class="pun">.</span><span class="pln">data </span><span class="pun">=</span><span class="pln"> </span><span class="pun">(</span><span class="pln">uint8_t</span><span class="pun">*)</span><span class="pln">frameData</span><span class="pun">;</span><span class="pln"><br> packet</span><span class="pun">.</span><span
class="pln">size </span><span class="pun">=</span><span class="pln"> currentFrameSize</span><span class="pun">;</span><span class="pln"><br><br> av_interleaved_write_frame</span><span class="pun">(</span><span class="pln">context</span><span class="pun">,</span><span class="pln"> </span><span class="pun">&</span><span class="pln">packet</span><span class="pun">);</span><span class="pln"><br> put_flush_packet</span><span class="pun">(</span><span class="pln">context</span><span class="pun">-></span><span class="pln">pb</span><span class="pun">);</span><span class="pln"><br></span></code></pre>
<p>where </p>
<p><code>frameData</code> is the raw H264 frame
and <code>currentFrameSize</code> is the size of the raw H264 frame, ie. the number of bytes I get from the gadget for every frame.</p>
<p>And suddenly the application is not working correctly anymore, the
produced video is unplayable. This is obvious, since I was not setting
a correct PTS for the packet. What I did was the following (I'm
desperate, you can see it from this approach :) )</p>
<pre class="lang-c prettyprint"><code><span class="pln"> packet</span><span class="pun">.</span><span class="pln">pts </span><span class="pun">=</span><span class="pln"> timestamps</span><span class="pun">[</span><span class="pln">timestamp_counter </span><span class="pun">++];</span><span class="pln"><br></span></code></pre>
<p>where <code>timestamps</code> is actually a list of PTS's produced
by the working code above, and written to a file (yes, you read it
properly, I logged all the PTS's for a 10 minute session, and wanted to
use them).</p>
<p>The application still does not work.</p>
<p>Now, here I am without any clue what to do, so here is the question:</p>
<p>I would like to create an "mpegts" video stream using libav
functions, insert in the stream already encoded video frames and create
a video file with it. How do I do it?</p><p><br></p>
<p>Thanks,
f.</p>
</div></td></tr></table>