Tag Archives: video processing

ffmpeg: libavformat, libavcodec and x264

ffmpeg is great tool for almost all your video processing playing need. For general purpose it has everything given as command line. Most of the time you only need to find the correct command for your specific requirement.
Rarely you need more control on your video like encoding in different library and then muxing using ffmpeg. Or say you are streaming on network and it is not of any particular format. You don’t want the overhead of coding to make it of some format and then stream and decode via ffmpeg. In those scenario you have to get away with ffmpeg wrapper and just want to do it in your own way by using core API’s.

ffmpeg is easy in that way also once you get the feel of it. There are just couple of functionality which you need to achieve all this. Sometime you don’t even need all ffmpeg and just getaway with libavcodec swscale etc.

If you have the input file for processing you can just check out the sample code provided. You just have to set the input file for reading and you are done. If your requirement is providing your own input and also getting output in code and not in a file or stream.
I wrote my own wrapper on ffmpeg for windows to get acess to core API I needed.

Once you have the wrapper say ffmpeg_wrapper.c just compile it like

gcc -I. -c -o ffmpeg_wrapper.o ffmpeg_wrapper.c
gcc -shared -o ffmpeg_wrapper.dll ffmpeg_wrapper.o -L. -lavformat -lavcodec -lavutil -lWs2_32 -liconv

any other library you need.

Include are done like this:

#include "libavformat/avformat.h"
#include "libavutil/opt.h"
#include "libavutil/mathematics.h"
#include "libavutil/timestamp.h"
#include "libswscale/swscale.h"
#include "libswresample/swresample.h"

#define DLLEXPORT __declspec(dllexport)
#define CDECL __cdecl

I faced a problem while I was doing encoding via separate h264 dll and then passing the input for muxing via ffmpeg. The problem was with timing I know there are some option in h264 to set the timing info but it was not working out. So I generated the timing using ffmpeg itself.

static int write_frame(AVFormatContext *fmt_ctx, const AVRational *time_base, AVStream *st, AVPacket *pkt)
/* rescale output packet timestamp values from codec to stream timebase */
pkt->pts = av_rescale_q_rnd(pkt->pts, *time_base, st->time_base, AV_ROUND_NEAR_INF|AV_ROUND_PASS_MINMAX);
pkt->dts = av_rescale_q_rnd(pkt->dts, *time_base, st->time_base, AV_ROUND_NEAR_INF|AV_ROUND_PASS_MINMAX);
pkt->duration = av_rescale_q(pkt->duration, *time_base, st->time_base);
pkt->stream_index = st->index;</code>

/* Write the compressed frame to the media file. */
log_packet(fmt_ctx, pkt);
return av_interleaved_write_frame(fmt_ctx, pkt);