Not able to link ffmpeg libs with gstreamer encoder plugin ?

ssshukla26 ssshukla26 at gmail.com
Wed Jan 27 08:03:42 PST 2016


Hi,

As you suggested, for me it doesn't seems to be a ffmpeg problem.

Cause if it was a ffmpeg problem I must have faced the same when running a
stand alone application which uses ffmpeg.

Please help me in this, I am mailing you all the steps which I followed to
make a ffmpeg application. Please help me understand why my plugin is
showing error while my application works totally fine.

1) Installing all required libs of ffmpeg on my system

sudo apt-get install libx264-dev

mkdir ffmpeg
git clone https://github.com/FFmpeg/FFmpeg ffmpeg/
cd ffmpeg
make distclean
./configure --enable-nonfree --enable-pic --enable-shared --enable-gpl
--enable-libx264
make
sudo make install

2) Making a standalone application

#include <math.h>

#include <libavutil/opt.h>
#include <libavcodec/avcodec.h>
#include <libavutil/channel_layout.h>
#include <libavutil/common.h>
#include <libavutil/imgutils.h>
#include <libavutil/mathematics.h>
#include <libavutil/samplefmt.h>

static  AVCodec *codec;
static  AVCodecContext *encoder_context= NULL;
static  int got_output;
static  int total_frames = 0;
static  FILE *outputfile = NULL;
static  FILE *inputfile = NULL;
static  AVFrame *frame;
static  AVPacket pkt;
static  int lumaSize = 0;
static  int chromaSize = 0;
char *currentFrame = NULL;

static int init_enocoder(char * filename,int width,int height)
{
    inputfile = fopen(filename, "rb");
    if (!inputfile) {
        printf("Could not open  %s\n",filename);
        return 1;
    }

    outputfile = fopen("test.h264", "wb");
    if (!outputfile) {
        printf("Could not open test.h264\n");
        return 1;
    }

    codec = avcodec_find_encoder(AV_CODEC_ID_H264);
    if (!codec) {
        printf("H264 Codec not found\n");
        return 1;
    }

    encoder_context = avcodec_alloc_context3(codec);
    if (!encoder_context) {
        printf("Could not allocate video encoder  context\n");
        return 1;
    }

    encoder_context->bit_rate = 400000;
    encoder_context->width = width;
    encoder_context->height = height;
    encoder_context->time_base = (AVRational){1,30};
    encoder_context->gop_size = 29;
    encoder_context->pix_fmt = AV_PIX_FMT_YUV420P;

    av_opt_set(encoder_context->priv_data, "preset", "slow", 0);

    return 0;
}

static int start_encoder(void)
{
    /* open it */
    if (avcodec_open2(encoder_context, codec, NULL) < 0) {
        printf("Could not start encoder\n");
        return 1;
    }

    frame = av_frame_alloc();
    if (!frame) {
        printf("Could not allocate video frame\n");
        return 1;
    }
    frame->format = encoder_context->pix_fmt;
    frame->width  = encoder_context->width;
    frame->height = encoder_context->height;

    /* the image can be allocated by any means and av_image_alloc() is
     * just the most convenient way if av_malloc() is to be used */
    if(av_image_alloc(frame->data, frame->linesize, encoder_context->width,
encoder_context->height, encoder_context->pix_fmt, 32) < 0)
    {
        printf("Could not allocate raw picture buffer\n");
        return 1;
    }

    lumaSize = encoder_context->width * encoder_context->height;
    chromaSize = (encoder_context->width * encoder_context->height)/4;
    currentFrame = (char *) malloc((lumaSize + chromaSize + chromaSize));
    printf("lumasize = %d chromasize = %d\n",lumaSize,chromaSize);

    return 0;
}

static int encode_frame(void *pFrame)
{
    fflush(stdout);
    av_init_packet(&pkt);
    pkt.data = NULL;    // packet data will be allocated by the encoder
    pkt.size = 0;

    memset((void *)frame->data[0],'\0',lumaSize);
    memset((void *)frame->data[1],'\0',chromaSize);
    memset((void *)frame->data[2],'\0',chromaSize);

    memcpy((void *)frame->data[0],pFrame,lumaSize);
    memcpy((void *)frame->data[1],pFrame+lumaSize,chromaSize);
    memcpy((void *)frame->data[2],pFrame+lumaSize+chromaSize,chromaSize);

    frame->pts = total_frames++;

    if(avcodec_encode_video2(encoder_context, &pkt, frame, &got_output) < 0)
    {
        printf("Error encoding frame\n");
        return -1;
    }

    if (got_output)
    {
        printf("Write frame %3d (size=%5d)\r", total_frames, pkt.size);
        fwrite(pkt.data, 1, pkt.size, outputfile);
        av_packet_unref(&pkt);
    }

    return 0;
}

static void flush_frames(void)
{
    /* get the delayed frames */
    total_frames = 0;
    for (got_output = 1; got_output; total_frames++)
    {
        fflush(stdout);

        if(avcodec_encode_video2(encoder_context, &pkt, NULL, &got_output) <
0)
        {
            printf("Error in flusing frames\n");
            exit(1);
        }

        if (got_output)
        {
            fwrite(pkt.data, 1, pkt.size, outputfile);
            av_packet_unref(&pkt);
        }
    }
    printf("\n\n");
}

static void stop_encoder(void)
{
    av_freep(&frame->data[0]);
    av_frame_free(&frame);
    printf("\n");
}

static void deinit_encoder(void)
{
    fclose(outputfile);
    fclose(inputfile);
    avcodec_close(encoder_context);
    av_free(encoder_context);
}

static int isnumeric(char *str)
{
    if(strspn(str, "0123456789") == strlen(str))
    {
        return 1;
    }

    return 0;
}

static int read_frame(FILE *fp,void *data,size_t size)
{
    int readbytes = 0;

    if((fp != NULL) || (data != NULL))
    {
        readbytes =  fread(data,1,size,fp);
    }

    return readbytes;
}

int main(int argc, char **argv)
{
    if(argc != 4)
    {
        printf("Usage: ./myh264encoder FileName Width Height\n");
        return 1;
    }

    /* register all the codecs */
    avcodec_register_all();

    if(!isnumeric(argv[2]) || !isnumeric(argv[3]))
    {
        printf("Width and Height must be numeric\n");
        return 1;
    }

    if(0 != init_enocoder(argv[1],atoi(argv[2]),atoi(argv[3])))
        return 1;

    if(0 != start_encoder())
        return 1;

    while(1)
    {
        memset((void *)currentFrame,'\0',(lumaSize + chromaSize +
chromaSize));
        if(read_frame(inputfile,(void *)currentFrame,(lumaSize + chromaSize
+ chromaSize)) == (lumaSize + chromaSize + chromaSize))
        {
            if(0 != encode_frame((void *)currentFrame))
                break;
        }
        else
        {
            printf("\nEOS reached\n");
            break;
        }
    }

    flush_frames();

    stop_encoder();

    deinit_encoder();

    return 0;
}

3) Makefile

CC=gcc
FFMPEG_LIBS=libavdevice libavformat libavfilter libavcodec libswresample
libswscale libavutil
CFLAGS=$(shell pkg-config --cflags $(FFMPEG_LIBS))-c
LDFLAGS=$(shell pkg-config --libs $(FFMPEG_LIBS))-o
EXECUTABLE=myh264encoder
SOURCES=$(wildcard ./*.c)
OBJECTS=$(patsubst %.c,%.o,$(SOURCES))
OUTPUTS=test.h264

$(EXECUTABLE): $(OBJECTS)
    $(CC) $^ $(LDFLAGS) $(EXECUTABLE)

.c.o:
    $(CC) $(CFLAGS) $< -o $@

clean:
    rm -f $(EXECUTABLE) $(OBJECTS) $(OUTPUTS)

4) Compilation

$ make
gcc -I/usr/local/include  -c myh264encoding.c -o myh264encoding.o
gcc myh264encoding.o -L/usr/local/lib -lavdevice -lavformat -lavfilter
-lavcodec -lswresample -lswscale -lavutil  -o myh264encoder

5) execution 

$ ./myh264encoder /home/sunny/Videos/rawvideo_yuv420.yuv 640 480
[libx264 @ 0x1c054c0] using cpu capabilities: MMX2 SSE2Fast SSSE3 SSE4.2 AVX
[libx264 @ 0x1c054c0] profile High, level 3.0
lumasize = 307200 chromasize = 76800
Write frame 1872 (size=54811)
EOS reached



[libx264 @ 0x1c054c0] frame I:67    Avg QP: 5.96  size: 21411
[libx264 @ 0x1c054c0] frame P:598   Avg QP:13.71  size:  2032
[libx264 @ 0x1c054c0] frame B:1207  Avg QP:21.64  size:   456
[libx264 @ 0x1c054c0] consecutive B-frames:  9.6%  8.9% 13.6% 67.9%
[libx264 @ 0x1c054c0] mb I  I16..4: 68.8% 13.0% 18.2%
[libx264 @ 0x1c054c0] mb P  I16..4:  0.9%  1.1%  0.5%  P16..4:  5.2%  2.3% 
2.0%  0.0%  0.0%    skip:88.1%
[libx264 @ 0x1c054c0] mb B  I16..4:  0.0%  0.1%  0.1%  B16..8:  4.9%  1.1% 
0.4%  direct: 0.2%  skip:93.3%  L0:42.4% L1:47.8% BI: 9.8%
[libx264 @ 0x1c054c0] final ratefactor: 14.87
[libx264 @ 0x1c054c0] 8x8 transform intra:19.3% inter:45.6%
[libx264 @ 0x1c054c0] direct mvs  spatial:96.6% temporal:3.4%
[libx264 @ 0x1c054c0] coded y,uvDC,uvAC intra: 27.0% 28.0% 25.1% inter: 1.9%
1.8% 0.9%
[libx264 @ 0x1c054c0] i16 v,h,dc,p: 83% 14%  1%  2%
[libx264 @ 0x1c054c0] i8 v,h,dc,ddl,ddr,vr,hd,vl,hu: 18% 21% 38%  3%  4%  4% 
4%  4%  5%
[libx264 @ 0x1c054c0] i4 v,h,dc,ddl,ddr,vr,hd,vl,hu: 20% 18% 14%  6%  9%  9% 
8%  8%  9%
[libx264 @ 0x1c054c0] i8c dc,h,v,p: 78% 10%  8%  3%
[libx264 @ 0x1c054c0] Weighted P-Frames: Y:0.3% UV:0.2%
[libx264 @ 0x1c054c0] ref P L0: 71.5%  7.4%  9.7%  5.6%  4.6%  1.3%  0.0%
[libx264 @ 0x1c054c0] ref B L0: 81.8% 11.3%  5.4%  1.5%
[libx264 @ 0x1c054c0] ref B L1: 95.5%  4.5%
[libx264 @ 0x1c054c0] kb/s:410.18



--
View this message in context: http://gstreamer-devel.966125.n4.nabble.com/Not-able-to-link-ffmpeg-libs-with-gstreamer-encoder-plugin-tp4675503p4675511.html
Sent from the GStreamer-devel mailing list archive at Nabble.com.


More information about the gstreamer-devel mailing list