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