<div dir="ltr"><div><div class="gmail_signature"><div dir="ltr"><div><div dir="ltr"><span style="font-size:12.8000001907349px">Hi folks!</span><div style="font-size:12.8000001907349px"><br></div><div style="font-size:12.8000001907349px">I'm working on an application written in C that makes use of the ffmpeg libraries to record the desktop on OS X using the avfoundation device. I've included the relevant parts of the code in this email. Full code can be found here <a href="http://stackoverflow.com/q/29341161/799285" target="_blank">http://stackoverflow.com/q/29341161/799285</a>. I think I'm doing everything properly upto the decode encode loop which I've included below. </div><div style="font-size:12.8000001907349px"><br></div><div style="font-size:12.8000001907349px">When I run this program, I'm able to encode about 50-100 frames before I receive a SIGSEGV. Valgrind analysis can be found here: <a href="http://pastebin.com/MPeRhjhN" target="_blank">http://pastebin.com/MPeRhjhN</a>. For each frame that was encoded, my memory usage goes up by about 4-6MB so I know something is not being freed properly. Can I get some feedback on this code? Anything that I've done wrong? or am using incorrectly? Your help is much appreciated, and if you ever are in Waterloo, ON, I shall buy you a pint or two. </div><div style="font-size:12.8000001907349px"><p><span style="font-size:12.8000001907349px">int frame_count = 0;</span></p><p><span style="font-size:12.8000001907349px"><br></span></p><p><span style="font-size:12.8000001907349px">while (av_read_frame(inFmtCtx, &inPacket) >= 0) {</span></p><p><span style="font-size:12.8000001907349px"><br></span></p><p><span style="font-size:12.8000001907349px">  if (inPacket.stream_index == videostream) {</span></p><p><span style="font-size:12.8000001907349px"><br></span></p><p><span style="font-size:12.8000001907349px">    avcodec_decode_video2(inCodecCtx, inFrame, &frameFinished, &inPacket);</span></p><p><span style="font-size:12.8000001907349px"><br></span></p><p><span style="font-size:12.8000001907349px">    // 1 Frame might need more than 1 packet to be filled</span></p><p><span style="font-size:12.8000001907349px"><br></span></p><p><span style="font-size:12.8000001907349px">    if (frameFinished) {</span></p><p><span style="font-size:12.8000001907349px"><br></span></p><p><span style="font-size:12.8000001907349px">      outFrameYUV = av_frame_alloc();</span></p><p><span style="font-size:12.8000001907349px"><br></span></p><p><span style="font-size:12.8000001907349px">      uint8_t *buffer = (uint8_t *)av_malloc(numBytes);</span></p><p><span style="font-size:12.8000001907349px"><br></span></p><p><span style="font-size:12.8000001907349px">      int ret =</span></p><p><span style="font-size:12.8000001907349px">          avpicture_fill((AVPicture *)outFrameYUV, buffer, PIX_FMT_YUV420P,</span></p><p><span style="font-size:12.8000001907349px"><br></span></p><p><span style="font-size:12.8000001907349px">                         inCodecCtx->width, inCodecCtx->height);</span></p><p><span style="font-size:12.8000001907349px"><br></span></p><p><span style="font-size:12.8000001907349px">      if (ret < 0) {</span></p><p><span style="font-size:12.8000001907349px"><br></span></p><p><span style="font-size:12.8000001907349px">        printf("%d is return val for fill\n", ret);</span></p><p><span style="font-size:12.8000001907349px"><br></span></p><p><span style="font-size:12.8000001907349px">        return -1;</span></p><p><span style="font-size:12.8000001907349px">      }</span></p><p><span style="font-size:12.8000001907349px"><br></span></p><p><span style="font-size:12.8000001907349px">      // convert image to YUV</span></p><p><span style="font-size:12.8000001907349px"><br></span></p><p><span style="font-size:12.8000001907349px">      sws_scale(swsCtx, (uint8_t const *const *)inFrame->data,</span></p><p><span style="font-size:12.8000001907349px"><br></span></p><p><span style="font-size:12.8000001907349px">                inFrame->linesize, 0, inCodecCtx->height,</span></p><p><span style="font-size:12.8000001907349px"><br></span></p><p><span style="font-size:12.8000001907349px">                outFrameYUV->data, outFrameYUV->linesize);</span></p><p><span style="font-size:12.8000001907349px"><br></span></p><p><span style="font-size:12.8000001907349px">      // outFrameYUV now holds the YUV scaled frame/picture</span></p><p><span style="font-size:12.8000001907349px"><br></span></p><p><span style="font-size:12.8000001907349px">      outFrameYUV->format = outCodecCtx->pix_fmt;</span></p><p><span style="font-size:12.8000001907349px"><br></span></p><p><span style="font-size:12.8000001907349px">      outFrameYUV->width = outCodecCtx->width;</span></p><p><span style="font-size:12.8000001907349px"><br></span></p><p><span style="font-size:12.8000001907349px">      outFrameYUV->height = outCodecCtx->height;</span></p><p><span style="font-size:12.8000001907349px"><br></span></p><p><span style="font-size:12.8000001907349px">      AVPacket pkt;</span></p><p><span style="font-size:12.8000001907349px"><br></span></p><p><span style="font-size:12.8000001907349px">      int got_output;</span></p><p><span style="font-size:12.8000001907349px"><br></span></p><p><span style="font-size:12.8000001907349px">      av_init_packet(&pkt);</span></p><p><span style="font-size:12.8000001907349px"><br></span></p><p><span style="font-size:12.8000001907349px">      pkt.data = NULL;</span></p><p><span style="font-size:12.8000001907349px"><br></span></p><p><span style="font-size:12.8000001907349px">      pkt.size = 0;</span></p><p><span style="font-size:12.8000001907349px"><br></span></p><p><span style="font-size:12.8000001907349px">      outFrameYUV->pts = frame_count;</span></p><p><span style="font-size:12.8000001907349px"><br></span></p><p><span style="font-size:12.8000001907349px">      ret = avcodec_encode_video2(outCodecCtx, &pkt, outFrameYUV, &got_output);</span></p><p><span style="font-size:12.8000001907349px"><br></span></p><p><span style="font-size:12.8000001907349px">      if (ret < 0) {</span></p><p><span style="font-size:12.8000001907349px"><br></span></p><p><span style="font-size:12.8000001907349px">        fprintf(stderr, "Error encoding video frame: %s\n", av_err2str(ret));</span></p><p><span style="font-size:12.8000001907349px"><br></span></p><p><span style="font-size:12.8000001907349px">        return -1;</span></p><p><span style="font-size:12.8000001907349px">      }</span></p><p><span style="font-size:12.8000001907349px"><br></span></p><p><span style="font-size:12.8000001907349px">      if (got_output) {</span></p><p><span style="font-size:12.8000001907349px"><br></span></p><p><span style="font-size:12.8000001907349px">        if (stream->codec->coded_frame->key_frame) {</span></p><p><span style="font-size:12.8000001907349px"><br></span></p><p><span style="font-size:12.8000001907349px">          pkt.flags |= AV_PKT_FLAG_KEY;</span></p><p><span style="font-size:12.8000001907349px">        }</span></p><p><span style="font-size:12.8000001907349px"><br></span></p><p><span style="font-size:12.8000001907349px">        pkt.stream_index = stream->index;</span></p><p><span style="font-size:12.8000001907349px"><br></span></p><p><span style="font-size:12.8000001907349px">        if (pkt.pts != AV_NOPTS_VALUE)</span></p><p><span style="font-size:12.8000001907349px"><br></span></p><p><span style="font-size:12.8000001907349px">          pkt.pts = av_rescale_q(pkt.pts, stream->codec->time_base,</span></p><p><span style="font-size:12.8000001907349px">                                 stream->time_base);</span></p><p><span style="font-size:12.8000001907349px"><br></span></p><p><span style="font-size:12.8000001907349px">        if (pkt.dts != AV_NOPTS_VALUE)</span></p><p><span style="font-size:12.8000001907349px"><br></span></p><p><span style="font-size:12.8000001907349px">          pkt.dts = av_rescale_q(pkt.dts, stream->codec->time_base,</span></p><p><span style="font-size:12.8000001907349px">                                 stream->time_base);</span></p><p><span style="font-size:12.8000001907349px"><br></span></p><p><span style="font-size:12.8000001907349px">        if (avio_open_dyn_buf(&outFmtCtx->pb) != 0) {</span></p><p><span style="font-size:12.8000001907349px"><br></span></p><p><span style="font-size:12.8000001907349px">          printf("ERROR: Unable to open dynamic buffer\n");</span></p><p><span style="font-size:12.8000001907349px">        }</span></p><p><span style="font-size:12.8000001907349px"><br></span></p><p><span style="font-size:12.8000001907349px">        ret = av_interleaved_write_frame(outFmtCtx, &pkt);</span></p><p><span style="font-size:12.8000001907349px"><br></span></p><p><span style="font-size:12.8000001907349px">        unsigned char *pb_buffer;</span></p><p><span style="font-size:12.8000001907349px"><br></span></p><p><span style="font-size:12.8000001907349px">        int len =</span></p><p><span style="font-size:12.8000001907349px">            avio_close_dyn_buf(outFmtCtx->pb, (unsigned char **)&pb_buffer);</span></p><p><span style="font-size:12.8000001907349px"><br></span></p><p><span style="font-size:12.8000001907349px">        avio_write(outFmtCtx->pb, (unsigned char *)pb_buffer, len);</span></p><p><span style="font-size:12.8000001907349px"><br></span></p><p><span style="font-size:12.8000001907349px">      } else {</span></p><p><span style="font-size:12.8000001907349px"><br></span></p><p><span style="font-size:12.8000001907349px">        ret = 0;</span></p><p><span style="font-size:12.8000001907349px">      }</span></p><p><span style="font-size:12.8000001907349px"><br></span></p><p><span style="font-size:12.8000001907349px">      if (ret != 0) {</span></p><p><span style="font-size:12.8000001907349px"><br></span></p><p><span style="font-size:12.8000001907349px">        fprintf(stderr, "Error while writing video frame: %s\n",</span></p><p><span style="font-size:12.8000001907349px">                av_err2str(ret));</span></p><p><span style="font-size:12.8000001907349px"><br></span></p><p><span style="font-size:12.8000001907349px">        exit(1);</span></p><p><span style="font-size:12.8000001907349px">      }</span></p><p><span style="font-size:12.8000001907349px"><br></span></p><p><span style="font-size:12.8000001907349px">      fprintf(stderr, "encoded frame #%d\n", frame_count);</span></p><p><span style="font-size:12.8000001907349px"><br></span></p><p><span style="font-size:12.8000001907349px">      frame_count++;</span></p><p><span style="font-size:12.8000001907349px"><br></span></p><p><span style="font-size:12.8000001907349px">      av_free_packet(&pkt);</span></p><p><span style="font-size:12.8000001907349px"><br></span></p><p><span style="font-size:12.8000001907349px">      av_frame_unref(outFrameYUV);</span></p><p><span style="font-size:12.8000001907349px"><br></span></p><p><span style="font-size:12.8000001907349px">      av_free(buffer);</span></p><p><span style="font-size:12.8000001907349px">    }</span></p><p><span style="font-size:12.8000001907349px">  }</span></p><p><span style="font-size:12.8000001907349px"><br></span></p><p><span style="font-size:12.8000001907349px">  av_free_packet(&inPacket);</span></p><p><span style="font-size:12.8000001907349px">}</span></p><p><span style="font-size:12.8000001907349px"><br></span></p><p><span style="font-size:12.8000001907349px">av_write_trailer(outFmtCtx);</span></p><p><span style="font-size:12.8000001907349px"><br></span></p><p style="font-size:12.8000001907349px">Here's my ffmpeg library versions:</p><p style="font-size:12.8000001907349px">  ffmpeg version N-70876-g294bb6c Copyright (c) 2000-2015 the FFmpeg developers</p><p style="font-size:12.8000001907349px">  built with Apple LLVM version 6.0 (clang-600.0.56) (based on LLVM 3.5svn)</p><p style="font-size:12.8000001907349px">  configuration: --prefix=/usr/local --enable-gpl --enable-postproc --enable-pthreads --enable-libmp3lame --enable-libtheora --enable-libx264 --enable-libvorbis --disable-mmx --disable-ssse3 --disable-armv5te --disable-armv6 --disable-neon --enable-shared --disable-static --disable-stripping</p><p style="font-size:12.8000001907349px">  libavutil      54. 20.100 / 54. 20.100</p><p style="font-size:12.8000001907349px">  libavcodec     56. 29.100 / 56. 29.100</p><p style="font-size:12.8000001907349px">  libavformat    56. 26.101 / 56. 26.101</p><p style="font-size:12.8000001907349px">  libavdevice    56.  4.100 / 56.  4.100</p><p style="font-size:12.8000001907349px">  libavfilter     5. 13.101 /  5. 13.101</p><p style="font-size:12.8000001907349px">  libswscale      3.  1.101 /  3.  1.101</p><p style="font-size:12.8000001907349px">  libswresample   1.  1.100 /  1.  1.100</p><p style="font-size:12.8000001907349px">  libpostproc    53.  3.100 / 53.  3.100</p><p style="font-size:12.8000001907349px"></p><p style="font-size:12.8000001907349px">Hyper fast Audio and Video encoder</p><p style="font-size:12.8000001907349px">Thanks,</p><p style="font-size:12.8000001907349px">Praj</p></div></div></div></div></div></div>

</div>