Problem with linking FFMPEG's libraries

Discuss the development of new homebrew software, tools and libraries.

Moderators: cheriff, TyRaNiD

Post Reply
The_Fearless
Posts: 2
Joined: Tue Jul 31, 2007 12:25 am

Problem with linking FFMPEG's libraries

Post by The_Fearless »

Hi,
I'm trying to use FFMPEG in a program, but i've got a problem... I can compile the 4 libraries, and i want to use them in this program (that's just the first version, it'll be a video player):

Code: Select all

#include <pspkernel.h>
#include <pspdebug.h>
#include <pspctrl.h>
#include <stdlib.h>
#include <string.h>

#include "../ffmpeg/libavcodec/avcodec.h"
#include "../ffmpeg/libavformat/avformat.h"
#include "../ffmpeg/libavformat/avio.h"
#include "../ffmpeg/libavcodec/opt.h"
#include "../ffmpeg/libavutil/fifo.h"
#include "../ffmpeg/libavutil/avstring.h"


PSP_MODULE_INFO&#40;"CONTROLTEST", 0, 1, 1&#41;;

#define printf	pspDebugScreenPrintf

int done = 0;

int exit_callback&#40;int arg1, int arg2, void *common&#41;
&#123;
	return 0;
&#125;

/* Callback thread */
int CallbackThread&#40;SceSize args, void *argp&#41;
&#123;
	int cbid;

	cbid = sceKernelCreateCallback&#40;"Exit Callback", exit_callback, NULL&#41;;
	sceKernelRegisterExitCallback&#40;cbid&#41;;
	sceKernelSleepThreadCB&#40;&#41;;

	return 0;
&#125;

/* Sets up the callback thread and returns its thread id */
int SetupCallbacks&#40;void&#41;
&#123;
	int thid = 0;

	thid = sceKernelCreateThread&#40;"update_thread", CallbackThread,
				     0x11, 0xFA0, 0, 0&#41;;
	if&#40;thid >= 0&#41;
	&#123;
		sceKernelStartThread&#40;thid, 0, 0&#41;;
	&#125;

	return thid;
&#125;

void SaveFrame&#40;AVFrame *pFrame, int width, int height, int iFrame&#41; &#123;
  FILE *pFile;
  char szFilename&#91;32&#93;;
  int  y;
  
  // Open file
  sprintf&#40;szFilename, "frame%d.ppm", iFrame&#41;;
  pFile=fopen&#40;szFilename, "wb"&#41;;
  if&#40;pFile==NULL&#41;
    return;
  
  // Write header
  fprintf&#40;pFile, "P6\n%d %d\n255\n", width, height&#41;;
  
  // Write pixel data
  for&#40;y=0; y<height; y++&#41;
    fwrite&#40;pFrame->data&#91;0&#93;+y*pFrame->linesize&#91;0&#93;, 1, width*3, pFile&#41;;
  
  // Close file
  fclose&#40;pFile&#41;;
&#125;

int main&#40;void&#41; &#123;
	SceCtrlData pad;

	pspDebugScreenInit&#40;&#41;;
	SetupCallbacks&#40;&#41;;

	sceCtrlSetSamplingCycle&#40;0&#41;;
	sceCtrlSetSamplingMode&#40;PSP_CTRL_MODE_ANALOG&#41;;

	printf&#40;"Press X to rip frame"&#41;;

	while&#40;!done&#41;&#123;
		pspDebugScreenSetXY&#40;0, 2&#41;;

    		sceCtrlReadBufferPositive&#40;&pad, 1&#41;; 

		if &#40;pad.Buttons != 0&#41;&#123;
			if &#40;pad.Buttons & PSP_CTRL_CROSS&#41;&#123;
				printf&#40;"Ripping Frame"&#41;;
				//Start of Movie Rip
				av_register_all&#40;&#41;;
				
				AVFormatContext *pFormatCtx;
				// Open video file
				if&#40;av_open_input_file&#40;&pFormatCtx, "prova.avi", NULL, 0, NULL&#41;!=0&#41;
					return -1; // Couldn't open file
				
				// Retrieve stream information
				if&#40;av_find_stream_info&#40;pFormatCtx&#41;<0&#41;
					return -1; // Couldn't find stream information
				
				// Dump information about file onto standard error
				dump_format&#40;pFormatCtx, 0, "prova.avi", 0&#41;;
				
				int i;
				AVCodecContext *pCodecCtx;
				
				// Find the first video stream
				int videoStream = -1;
				 for&#40;i=0; i<pFormatCtx->nb_streams; i++&#41;
			             if&#40;pFormatCtx->streams&#91;i&#93;->codec->codec_type==CODEC_TYPE_VIDEO&#41; &#123;
					  videoStream=i;
					  break;
				     &#125;
				 
				 if&#40;videoStream==-1&#41;
				     return -1; // Didn't find a video stream
				 
				 // Get a pointer to the codec context for the video stream
				 pCodecCtx=pFormatCtx->streams&#91;videoStream&#93;->codec;
				 
				 AVCodec *pCodec;
				 
				 // Find the decoder for the video stream
				 pCodec=avcodec_find_decoder&#40;pCodecCtx->codec_id&#41;;
				 
				 if&#40;pCodec==NULL&#41; &#123;
				     fprintf&#40;stderr, "Unsupported codec!\n"&#41;;
				     return -1; // Codec not found
				    &#125;
				 
				 // Open codec
				 if&#40;avcodec_open&#40;pCodecCtx, pCodec&#41;<0&#41;
				     return -1; // Could not open codec
				 
				 AVFrame *pFrame;
				 AVFrame *pFrameRGB;
				 
				 // Allocate video frame
				 pFrame=avcodec_alloc_frame&#40;&#41;;
				 
				 // Allocate an AVFrame structure
				 pFrameRGB=avcodec_alloc_frame&#40;&#41;;
				 
				 if&#40;pFrameRGB==NULL&#41;
			             return -1;
				 
				 uint8_t *buffer;
				 int numBytes;
				 // Determine required buffer size and allocate buffer
				 numBytes=avpicture_get_size&#40;PIX_FMT_RGB24, pCodecCtx->width,pCodecCtx->height&#41;;
	
				 buffer=&#40;uint8_t *&#41;av_malloc&#40;numBytes*sizeof&#40;uint8_t&#41;&#41;;
				 
				 // Assign appropriate parts of buffer to image planes in pFrameRGB
				 // Note that pFrameRGB is an AVFrame, but AVFrame is a superset
				 // of AVPicture
				 avpicture_fill&#40;&#40;AVPicture *&#41;pFrameRGB, buffer, PIX_FMT_RGB24, 
						 pCodecCtx->width, pCodecCtx->height&#41;;
				 
				 int frameFinished;
				 AVPacket packet;
				 
				 i=0;
				 while&#40;av_read_frame&#40;pFormatCtx, &packet&#41;>=0&#41; &#123;
			            // Is this a packet from the video stream?
				    if&#40;packet.stream_index==videoStream&#41; &#123;
				        // Decode video frame
					avcodec_decode_video&#40;pCodecCtx, pFrame, &frameFinished,
                                                             packet.data, packet.size&#41;;
					
					// Did we get a video frame?
					if&#40;frameFinished&#41; &#123;
					    // Convert the image from its native format to RGB
					    img_convert&#40;&#40;AVPicture *&#41;pFrameRGB, PIX_FMT_RGB24, 
                                                       &#40;AVPicture*&#41;pFrame, pCodecCtx->pix_fmt, 
			                                pCodecCtx->width, pCodecCtx->height&#41;;
					    // Save the frame to disk
					    if&#40;++i<=5&#41;
					       SaveFrame&#40;pFrameRGB, pCodecCtx->width, pCodecCtx->height, i&#41;;
					&#125;
				    &#125;
				    // Free the packet that was allocated by av_read_frame
				    av_free_packet&#40;&packet&#41;;
				 &#125;

                                 // Free the RGB image
				 av_free&#40;buffer&#41;;
				 av_free&#40;pFrameRGB&#41;;
				 
				 // Free the YUV frame
				 av_free&#40;pFrame&#41;;
				 
				 // Close the codec
				 avcodec_close&#40;pCodecCtx&#41;;
				 
				 // Close the video file
				 av_close_input_file&#40;pFormatCtx&#41;;


				 
				 return 0;
			                 &#125;
                  &#125;
           &#125;

        printf&#40;"Finito. Ritorno all'XMB..."&#41;;

    	sceKernelExitGame&#40;&#41;;
	return 0;
&#125;
But when i try to compile the code it displays this:

Code: Select all

XP@xp- ~/PSP_Video_Player
$ make
psp-gcc -I. -I/usr/local/pspdev/psp/sdk/include -O2 -G0 -Wall -lavutil -lavforma
t -lavcodec -lz -lavutil -lm -D_PSP_FW_VERSION=150   -c -o main.o main.c
main.c&#58; In function 'main'&#58;
main.c&#58;187&#58; warning&#58; 'img_convert' is deprecated &#40;declared at ../ffmpeg/libavcod
ec/avcodec.h&#58;2395&#41;
psp-gcc&#58; -lavutil&#58; linker input file unused because linking not done
psp-gcc&#58; -lavformat&#58; linker input file unused because linking not done
psp-gcc&#58; -lavcodec&#58; linker input file unused because linking not done
psp-gcc&#58; -lz&#58; linker input file unused because linking not done
psp-gcc&#58; -lavutil&#58; linker input file unused because linking not done
psp-gcc&#58; -lm&#58; linker input file unused because linking not done
psp-gcc -I. -I/usr/local/pspdev/psp/sdk/include -O2 -G0 -Wall -lavutil -lavforma
t -lavcodec -lz -lavutil -lm -D_PSP_FW_VERSION=150  -L. -L/usr/local/pspdev/psp/
sdk/lib   main.o -lavutil -lavformat -lavcodec -lz -lavutil -lm -lpspdebug -lpsp
display -lpspge -lpspctrl -lpspsdk -lc -lpspnet -lpspnet_inet -lpspnet_apctl -lp
spnet_resolver -lpsputility -lpspuser -lpspkernel -o main.elf
main.o&#58; In function `main'&#58;
main.c&#58;&#40;.text+0x218&#41;&#58; undefined reference to `av_register_all'
main.c&#58;&#40;.text+0x230&#41;&#58; undefined reference to `av_open_input_file'
main.c&#58;&#40;.text+0x2ac&#41;&#58; undefined reference to `av_find_stream_info'
main.c&#58;&#40;.text+0x2c8&#41;&#58; undefined reference to `dump_format'
main.c&#58;&#40;.text+0x2f4&#41;&#58; undefined reference to `avcodec_find_decoder'
main.c&#58;&#40;.text+0x304&#41;&#58; undefined reference to `avcodec_open'
main.c&#58;&#40;.text+0x314&#41;&#58; undefined reference to `avcodec_alloc_frame'
main.c&#58;&#40;.text+0x31c&#41;&#58; undefined reference to `avcodec_alloc_frame'
main.c&#58;&#40;.text+0x338&#41;&#58; undefined reference to `avpicture_get_size'
main.c&#58;&#40;.text+0x340&#41;&#58; undefined reference to `av_malloc'
main.c&#58;&#40;.text+0x360&#41;&#58; undefined reference to `avpicture_fill'
main.c&#58;&#40;.text+0x36c&#41;&#58; undefined reference to `av_read_frame'
main.c&#58;&#40;.text+0x3d0&#41;&#58; undefined reference to `avcodec_decode_video'
main.c&#58;&#40;.text+0x3f8&#41;&#58; undefined reference to `img_convert'
main.c&#58;&#40;.text+0x438&#41;&#58; undefined reference to `av_free'
main.c&#58;&#40;.text+0x440&#41;&#58; undefined reference to `av_free'
main.c&#58;&#40;.text+0x448&#41;&#58; undefined reference to `av_free'
main.c&#58;&#40;.text+0x450&#41;&#58; undefined reference to `avcodec_close'
main.c&#58;&#40;.text+0x458&#41;&#58; undefined reference to `av_close_input_file'
collect2&#58; ld returned 1 exit status
make&#58; *** &#91;main.elf&#93; Error 1
I understand that it's a problem with the linking of the libs, but i don't know how to fix it... Please help me XD
chp
Posts: 313
Joined: Wed Jun 23, 2004 7:16 am

Post by chp »

Either order your libraries properly (gcc ld will only find symbols imported from libs earlier in the linking process, so -la -lb isn't the same as -lb -la), or you can group all your libs like this:

gcc -o executable.elf -Wl,--start-group -lone -ltwo -lthree -Wl,--end-group

That will tell the linker to continue looking for symbols if it cannot find them in the currently available ones (more like how it works on other compilers).
GE Dominator
The_Fearless
Posts: 2
Joined: Tue Jul 31, 2007 12:25 am

Post by The_Fearless »

mmm...

I'm using this makefile to build my program:

Code: Select all

TARGET = main
OBJS = main.o

INCDIR = 

CFLAGS = -O2 -G0 -Wall

CXXFLAGS = $&#40;CFLAGS&#41; -fno-exceptions -fno-rtti

ASFLAGS = $&#40;CFLAGS&#41;


LIBDIR =
LIBS = -lavcodec -lavformat -lavutil -lz -lavutil -lm

PSPSDK=$&#40;shell psp-config --pspsdk-path&#41;

LDFLAGS =

EXTRA_TARGETS = EBOOT.PBP

PSP_EBOOT_TITLE = Basic PSP Movie Player


include $&#40;PSPSDK&#41;/lib/build.mak
and it now gives this error:

Code: Select all

$ make
psp-gcc -I. -I/usr/local/pspdev/psp/sdk/include -O2 -G0 -Wall -D_PSP_FW_VERSION=
150   -c -o main.o main.c
main.c&#58; In function 'main'&#58;
main.c&#58;187&#58; warning&#58; 'img_convert' is deprecated &#40;declared at ../ffmpeg/libavcod
ec/avcodec.h&#58;2395&#41;
psp-gcc -I. -I/usr/local/pspdev/psp/sdk/include -O2 -G0 -Wall -D_PSP_FW_VERSION=
150  -L. -L/usr/local/pspdev/psp/sdk/lib   main.o -lavcodec -lavformat -lavutil
-lz -lavutil -lm -lpspdebug -lpspdisplay -lpspge -lpspctrl -lpspsdk -lc -lpspnet
 -lpspnet_inet -lpspnet_apctl -lpspnet_resolver -lpsputility -lpspuser -lpspkern
el -o main.elf
main.o&#58; In function `main'&#58;
main.c&#58;&#40;.text+0x218&#41;&#58; undefined reference to `av_register_all'
main.c&#58;&#40;.text+0x230&#41;&#58; undefined reference to `av_open_input_file'
main.c&#58;&#40;.text+0x2ac&#41;&#58; undefined reference to `av_find_stream_info'
main.c&#58;&#40;.text+0x2c8&#41;&#58; undefined reference to `dump_format'
main.c&#58;&#40;.text+0x2f4&#41;&#58; undefined reference to `avcodec_find_decoder'
main.c&#58;&#40;.text+0x304&#41;&#58; undefined reference to `avcodec_open'
main.c&#58;&#40;.text+0x314&#41;&#58; undefined reference to `avcodec_alloc_frame'
main.c&#58;&#40;.text+0x31c&#41;&#58; undefined reference to `avcodec_alloc_frame'
main.c&#58;&#40;.text+0x338&#41;&#58; undefined reference to `avpicture_get_size'
main.c&#58;&#40;.text+0x340&#41;&#58; undefined reference to `av_malloc'
main.c&#58;&#40;.text+0x360&#41;&#58; undefined reference to `avpicture_fill'
main.c&#58;&#40;.text+0x36c&#41;&#58; undefined reference to `av_read_frame'
main.c&#58;&#40;.text+0x3d0&#41;&#58; undefined reference to `avcodec_decode_video'
main.c&#58;&#40;.text+0x3f8&#41;&#58; undefined reference to `img_convert'
main.c&#58;&#40;.text+0x438&#41;&#58; undefined reference to `av_free'
main.c&#58;&#40;.text+0x440&#41;&#58; undefined reference to `av_free'
main.c&#58;&#40;.text+0x448&#41;&#58; undefined reference to `av_free'
main.c&#58;&#40;.text+0x450&#41;&#58; undefined reference to `avcodec_close'
main.c&#58;&#40;.text+0x458&#41;&#58; undefined reference to `av_close_input_file'
collect2&#58; ld returned 1 exit status
make&#58; *** &#91;main.elf&#93; Error 1
There's still the undefined reference error...

EDIT: Is there any way to know if a lib is compiled the right way?
Post Reply