<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>