RISOLTO Non riesco a compilare in c - errori

Stato
Discussione chiusa ad ulteriori risposte.

gino62

Nuovo Utente
17
0
C:
#include <libavcodec/avcodec.h>
#include <libavformat/avformat.h>
#include <libswscale/swscale.h>

#include <stdio.h>

// compatibility with newer API
#if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(55,28,1)
#define av_frame_alloc avcodec_alloc_frame
#define av_frame_free avcodec_free_frame
#endif

void SaveFrame(AVFrame *pFrame, int width, int height, int iFrame) {
  FILE *pFile;
  char szFilename[32];
  int  y;

  // Open file
  sprintf(szFilename, "frame%d.ppm", iFrame);
  pFile=fopen(szFilename, "wb");
  if(pFile==NULL)
    return;

  // Write header
  fprintf(pFile, "P6\n%d %d\n255\n", width, height);

  // Write pixel data
  for(y=0; y<height; y++)
    fwrite(pFrame->data[0]+y*pFrame->linesize[0], 1, width*3, pFile);

  // Close file
  fclose(pFile);
}

int main(int argc, char *argv[]) {
  // Initalizing these to NULL prevents segfaults!
  AVFormatContext   *pFormatCtx = NULL;
  int               i, videoStream;
  AVCodecContext    *pCodecCtxOrig = NULL;
  AVCodecContext    *pCodecCtx = NULL;
  AVCodec           *pCodec = NULL;
  AVFrame           *pFrame = NULL;
  AVFrame           *pFrameRGB = NULL;
  AVPacket          packet;
  int               frameFinished;
  int               numBytes;
  uint8_t           *buffer = NULL;
  struct SwsContext *sws_ctx = NULL;

  if(argc < 2) {
    printf("Please provide a movie file\n");
    return -1;
  }
  // Register all formats and codecs
  av_register_all();

  // Open video file
  if(avformat_open_input(&pFormatCtx, argv[1], NULL, NULL)!=0)
    return -1; // Couldn't open file

  // Retrieve stream information
  if(avformat_find_stream_info(pFormatCtx, NULL)<0)
    return -1; // Couldn't find stream information

  // Dump information about file onto standard error
  av_dump_format(pFormatCtx, 0, argv[1], 0);

  // Find the first video stream
  videoStream=-1;
  for(i=0; i<pFormatCtx->nb_streams; i++)
    if(pFormatCtx->streams[i]->codec->codec_type==AVMEDIA_TYPE_VIDEO) {
      videoStream=i;
      break;
    }
  if(videoStream==-1)
    return -1; // Didn't find a video stream

  // Get a pointer to the codec context for the video stream
  pCodecCtxOrig=pFormatCtx->streams[videoStream]->codec;
  // Find the decoder for the video stream
  pCodec=avcodec_find_decoder(pCodecCtxOrig->codec_id);
  if(pCodec==NULL) {
    fprintf(stderr, "Unsupported codec!\n");
    return -1; // Codec not found
  }
  // Copy context
  pCodecCtx = avcodec_alloc_context3(pCodec);
  if(avcodec_copy_context(pCodecCtx, pCodecCtxOrig) != 0) {
    fprintf(stderr, "Couldn't copy codec context");
    return -1; // Error copying codec context
  }

  // Open codec
  if(avcodec_open2(pCodecCtx, pCodec, NULL)<0)
    return -1; // Could not open codec

  // Allocate video frame
  pFrame=av_frame_alloc();

  // Allocate an AVFrame structure
  pFrameRGB=av_frame_alloc();
  if(pFrameRGB==NULL)
    return -1;

  // Determine required buffer size and allocate buffer
  numBytes=avpicture_get_size(PIX_FMT_RGB24, pCodecCtx->width,
                  pCodecCtx->height);
  buffer=(uint8_t *)av_malloc(numBytes*sizeof(uint8_t));

  // 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((AVPicture *)pFrameRGB, buffer, PIX_FMT_RGB24,
         pCodecCtx->width, pCodecCtx->height);

  // initialize SWS context for software scaling
  sws_ctx = sws_getContext(pCodecCtx->width,
               pCodecCtx->height,
               pCodecCtx->pix_fmt,
               pCodecCtx->width,
               pCodecCtx->height,
               PIX_FMT_RGB24,
               SWS_BILINEAR,
               NULL,
               NULL,
               NULL
               );

  // Read frames and save first five frames to disk
  i=0;
  while(av_read_frame(pFormatCtx, &packet)>=0) {
    // Is this a packet from the video stream?
    if(packet.stream_index==videoStream) {
      // Decode video frame
      avcodec_decode_video2(pCodecCtx, pFrame, &frameFinished, &packet);
    
      // Did we get a video frame?
      if(frameFinished) {
    // Convert the image from its native format to RGB
    sws_scale(sws_ctx, (uint8_t const * const *)pFrame->data,
          pFrame->linesize, 0, pCodecCtx->height,
          pFrameRGB->data, pFrameRGB->linesize);
  
    // Save the frame to disk
    if(++i<=5)
      SaveFrame(pFrameRGB, pCodecCtx->width, pCodecCtx->height,
            i);
      }
    }
  
    // Free the packet that was allocated by av_read_frame
    av_free_packet(&packet);
  }

  // Free the RGB image
  av_free(buffer);
  av_frame_free(&pFrameRGB);

  // Free the YUV frame
  av_frame_free(&pFrame);

  // Close the codecs
  avcodec_close(pCodecCtx);
  avcodec_close(pCodecCtxOrig);

  // Close the video file
  avformat_close_input(&pFormatCtx);

  return 0;
}

Come da titolo mi escono degli errori nella compilazione: rinomino il file in .c,
da linux: cc -I ... prova.c -o prova
warning: implicit declaration of function ‘avformat_open_input’ [-Wimplicit-function-declaration]
request for member ‘nb_streams’ in something not a structure or union
for(i=0; i<pFormatCtx->nb_streams; i++) .. ecc
gli errori sono questi:
prova.c: In function ‘main’:
prova.c:60:6: warning: implicit declaration of function ‘avformat_open_input’; did you mean ‘avformat_free_context’? [-Wimplicit-function-declaration]
if(avformat_open_input(&pFormatCtx, argv[1], NULL, NULL)!=0)
^~~~~~~~~~~~~~~~~~~
avformat_free_context
prova.c:64:6: warning: implicit declaration of function ‘avformat_find_stream_info’; did you mean ‘av_find_stream_info’? [-Wimplicit-function-declaration]
if(avformat_find_stream_info(pFormatCtx, NULL)<0)
^~~~~~~~~~~~~~~~~~~~~~~~~
av_find_stream_info
prova.c:96:6: warning: implicit declaration of function ‘avcodec_open2’; did you mean ‘avcodec_open’? [-Wimplicit-function-declaration]
if(avcodec_open2(pCodecCtx, pCodec, NULL)<0)
^~~~~~~~~~~~~
avcodec_open
prova.c:12:23: warning: implicit declaration of function ‘avcodec_free_frame’; did you mean ‘avcodec_parse_frame’? [-Wimplicit-function-declaration]
#define av_frame_free avcodec_free_frame
^~~~~~~~~~~~~~~~~~
prova.c:159:3: note: in expansion of macro ‘av_frame_free’
av_frame_free(&pFrameRGB);
^~~~~~~~~~~~~
prova.c:169:3: warning: implicit declaration of function ‘avformat_close_input’; did you mean ‘avformat_license’? [-Wimplicit-function-declaration]
avformat_close_input(&pFormatCtx);
^~~~~~~~~~~~~~~~~~~~
avformat_license
/usr/bin/ld: /tmp/ccvNkKXf.o: in function `main':
prova.c:(.text+0x142): undefined reference to `av_register_all'
/usr/bin/ld: prova.c:(.text+0x16b): undefined reference to `avformat_open_input'
/usr/bin/ld: prova.c:(.text+0x18f): undefined reference to `avformat_find_stream_info'
/usr/bin/ld: prova.c:(.text+0x1c1): undefined reference to `av_dump_format'
/usr/bin/ld: prova.c:(.text+0x246): undefined reference to `avcodec_find_decoder'
/usr/bin/ld: prova.c:(.text+0x287): undefined reference to `avcodec_alloc_context3'
/usr/bin/ld: prova.c:(.text+0x29e): undefined reference to `avcodec_copy_context'
/usr/bin/ld: prova.c:(.text+0x2e9): undefined reference to `avcodec_open2'
/usr/bin/ld: prova.c:(.text+0x2fc): undefined reference to `avcodec_alloc_frame'
/usr/bin/ld: prova.c:(.text+0x305): undefined reference to `avcodec_alloc_frame'
/usr/bin/ld: prova.c:(.text+0x336): undefined reference to `avpicture_get_size'
/usr/bin/ld: prova.c:(.text+0x343): undefined reference to `av_malloc'
/usr/bin/ld: prova.c:(.text+0x36f): undefined reference to `avpicture_fill'
/usr/bin/ld: prova.c:(.text+0x3aa): undefined reference to `sws_getContext'
/usr/bin/ld: prova.c:(.text+0x3eb): undefined reference to `avcodec_decode_video2'
/usr/bin/ld: prova.c:(.text+0x439): undefined reference to `sws_scale'
/usr/bin/ld: prova.c:(.text+0x473): undefined reference to `av_free_packet'
/usr/bin/ld: prova.c:(.text+0x489): undefined reference to `av_read_frame'
/usr/bin/ld: prova.c:(.text+0x49d): undefined reference to `av_free'
/usr/bin/ld: prova.c:(.text+0x4ae): undefined reference to `avcodec_free_frame'
/usr/bin/ld: prova.c:(.text+0x4bf): undefined reference to `avcodec_free_frame'
/usr/bin/ld: prova.c:(.text+0x4cb): undefined reference to `avcodec_close'
/usr/bin/ld: prova.c:(.text+0x4d7): undefined reference to `avcodec_close'
/usr/bin/ld: prova.c:(.text+0x4e8): undefined reference to `avformat_close_input'
collect2: error: ld returned 1 exit status




dovrei dichiarare le funzioni (per iniziare) ma non sono riuscito
grazie
 
Ultima modifica:

DispatchCode

Utente Attivo
966
594
CPU
Intel i7 6700HQ, 2.60Ghz, 4 core 8 threads
Scheda Madre
Asustek
HDD
Hitachi 7200 rpm, 1TB
RAM
16GB DDR4 (2 slot su 4)
GPU
Nvidia Geforce GTX 960M, 4GB
Audio
Realtek
Net
30Mbps/3Mbps con Eolo
OS
Windows 10 64bit
Pubblica il codice usando il tag CODE per favore...
 

Moffetta88

Moderatore
Staff Forum
Utente Èlite
11,877
7,202
CPU
i5-4690
Dissipatore
DEEPCOOL CAPTAIN 240EX
Scheda Madre
MSI Z97 U3 PLUS
HDD
KINGSTON SSD KC400 240GB
RAM
24GB BALLISTIX SPORT @2133MHz
GPU
STRIX GTX980 DC2OC
Audio
INTEGRATA
Monitor
AOC G2590VXQ
PSU
BEQUIET! System Power 7 500W
Case
DEEPCOOL MATREXX 55
Periferiche
NESSUNA
Net
FTTC FASTWEB
OS
UBUNTU/WINDOWS10
Facciamo prima a fare così: da dove hai copiato il codice? essendo un qualcosa di strano, di sicuro nel GCC ci saranno stati dei parametri da inserire che bellamente hai saltato
 

pabloski

Utente Èlite
2,686
763
Lì si vede chiaramente che mancano sia i file header che le librerie di FFMPEG. Ci saranno dei pacchetti tipo libavformat-dev, libavcodec-dev, ecc... che vanno installati.
 
  • Like
Reactions: Moffetta88

gino62

Nuovo Utente
17
0
Facciamo prima a fare così: da dove hai copiato il codice? essendo un qualcosa di strano, di sicuro nel GCC ci saranno stati dei parametri da inserire che bellamente hai saltato
Post automatically merged:

Lì si vede chiaramente che mancano sia i file header che le librerie di FFMPEG. Ci saranno dei pacchetti tipo libavformat-dev, libavcodec-dev, ecc... che vanno installati.
Le librerie le ho scaricate da qui.
Vorrei andare per ordine e riuscire ad eliminare un errore alla volta, il primo:
warning: implicit declaration of function ‘avformat_open_input’ [-Wimplicit-function-declaration]
request for member ‘nb_streams’ in something not a structure or union
sembra debba essere dichiarata una funzione.
 
Ultima modifica:

pabloski

Utente Èlite
2,686
763
No no no. Sotto Linux la roba non si scarica da siti di dubbia fama. Senza contare che quelli sono i sorgenti ( non ci sono i file .a e .so delle librerie ) e sono pure vecchi ( 2011, 10 anni fa!! ).

Devi installare i pacchetti -dev delle librerie che vuoi usare, utilizzando il package manager della tua distribuzione Linux.
 
  • Like
Reactions: Mursey

gino62

Nuovo Utente
17
0
No no no. Sotto Linux la roba non si scarica da siti di dubbia fama. Senza contare che quelli sono i sorgenti ( non ci sono i file .a e .so delle librerie ) e sono pure vecchi ( 2011, 10 anni fa!! ).

Devi installare i pacchetti -dev delle librerie che vuoi usare, utilizzando il package manager della tua distribuzione Linux.
Non ho installato i pacchetti (sono installati in automatico da ffmpeg). La compilazioni non iniziava perchè i #include non trovavano le librerie, non trovando le librerie le ho scaricate (scompattate, non installate, è un file .zip) e messe nella cartella dove compilo.
Ad ogni modo credo di essere riuscito a dichiarare la prima funzione con:
int avformat_open_input(AVFormatContext **ps, const char *filename, AVInputFormat *fmt, AVDictionary **options)
....
 

pabloski

Utente Èlite
2,686
763
Non ho installato i pacchetti (sono installati in automatico da ffmpeg). La compilazioni non iniziava perchè i #include non trovavano le librerie, non trovando le librerie le ho scaricate (scompattate, non installate, è un file .zip) e messe nella cartella dove compilo.
Ad ogni modo credo di essere riuscito a dichiarare la prima funzione con:
int avformat_open_input(AVFormatContext **ps, const char *filename, AVInputFormat *fmt, AVDictionary **options)
....

No aspè. In Linux ci sono i pacchetti normali che contengono eseguibili, librerie ( se di librerie si tratta ) e risorse ulteriori ( traduzioni, icone, ecc... ). E ci sono i pacchetti -dev, che contengono gli header file ( quelli che servono a te ) e librerie statiche ( i file .a ).

Senza i pacchetti -dev, non puoi usare una libreria all'interno di un programma che stai scrivendo. E non puoi dichiarare, nel tuo programma, le funzioni che dovresti importare tramite gli include.

p.s. quale distribuzione Linux stai usando?
 

gino62

Nuovo Utente
17
0
No aspè. In Linux ci sono i pacchetti normali che contengono eseguibili, librerie ( se di librerie si tratta ) e risorse ulteriori ( traduzioni, icone, ecc... ). E ci sono i pacchetti -dev, che contengono gli header file ( quelli che servono a te ) e librerie statiche ( i file .a ).

Senza i pacchetti -dev, non puoi usare una libreria all'interno di un programma che stai scrivendo. E non puoi dichiarare, nel tuo programma, le funzioni che dovresti importare tramite gli include.

p.s. quale distribuzione Linux stai usando?
Debian 10.7 (Buster)
ffmpeg version 4.1.6-1
con ldd /usr/bin/ffmpeg | grep "libavcodec" --> libavcodec.so.58 (solo questo)
ldd /usr/bin/ffmpeg | grep "libavformat" --> libavformat.so.58 => /lib/x86_64-linux-gnu/libavformat.so.58 (0x00007fddcc177000)
ldd /usr/bin/ffmpeg | grep "libswscale"
libswscale.so.5 => /lib/x86_64-linux-gnu/libswscale.so.5 (0x00007f9ed1ac6000)

ma in /usr/lib/x86_64-linux-gnu c'è il file "libavcodec.so.58"e "libavcodec.so.58.35.100 "libavformat.so.58" e " libavformat.so.58.20.100"
"libswscale ....

ma la direttiva #include dice " quando il preprocessore incontra questa direttiva si comporta in questo modo: cerca il file specificato e NE COPIA IL CONTENUTO (senza interpretarlo) nel file di testo che viene poi passato al compilatore.

apt-cache search libavcodec
libavcodec58 - libreria FFmpeg con de/codificatori per codec audio/video - file runtime
libavcodec-dev - libreria FFmpeg con de/codificatori per codec audio/video - file di sviluppo
libavcodec-extra58 - libreria FFmpeg con codificatori/decodificatori aggiuntivi per codec audio/video
libavcodec-extra - libreria FFmpeg con codec aggiuntivi (metapacchetto)
libavutil56 - libreria FFmpeg con funzioni per semplificare la programmazione - file runtime
libavutil-dev - libreria FFmpeg con funzioni per semplificare la programmazione - file di sviluppo
 
Ultima modifica:

pabloski

Utente Èlite
2,686
763
Tutto giusto, ma include copia il contenuto degli header file, non quello dei file delle librerie dinamiche ( gli .so ). Tu hai installato le librerie e puoi usare i programmi che usano ffmpeg, ma non hai installato i corrispondenti pacchetti dev e quindi non puoi compilare programmi che usano ffmpeg.

A te servono libavcodec-dev, libavformat-dev, libswscale-dev.

p.s. apt-cache cerca tra i pacchetti installati e non, quindi non ti dice se un pacchetto è installato o meno...usa apt search e grep "installato"
 

gino62

Nuovo Utente
17
0
Tutto giusto, ma include copia il contenuto degli header file, non quello dei file delle librerie dinamiche ( gli .so ). Tu hai installato le librerie e puoi usare i programmi che usano ffmpeg, ma non hai installato i corrispondenti pacchetti dev e quindi non puoi compilare programmi che usano ffmpeg.

A te servono libavcodec-dev, libavformat-dev, libswscale-dev.

p.s. apt-cache cerca tra i pacchetti installati e non, quindi non ti dice se un pacchetto è installato o meno...usa apt search e grep "installato"
Grazie, credo di aver capito. ... Ho installato le librerie.
cc -o tutorial01 tutorial01.c -lavformat -lavcodec -lswscale -lz -I/usr/include/x86_64-linux-gnu
da errori diversi questa volta:
tutorial01.c: In function ‘main’:
tutorial01.c:80:3: warning: ‘av_register_all’ is deprecated [-Wdeprecated-declarations]
av_register_all();
^~~~~~~~~~~~~~~
In file included from tutorial01.c:27:
/usr/include/x86_64-linux-gnu/libavformat/avformat.h:2043:6: note: declared here
void av_register_all(void);
^~~~~~~~~~~~~~~
tutorial01.c:96:5: warning: ‘codec’ is deprecated [-Wdeprecated-declarations]
if(pFormatCtx->streams->codec->codec_type==AVMEDIA_TYPE_VIDEO) {
^~
In file included from tutorial01.c:27:
/usr/include/x86_64-linux-gnu/libavformat/avformat.h:878:21: note: declared here
AVCodecContext *codec;
^~~~~
tutorial01.c:104:3: warning: ‘codec’ is deprecated [-Wdeprecated-declarations]
pCodecCtxOrig=pFormatCtx->streams[videoStream]->codec;
^~~~~~~~~~~~~
In file included from tutorial01.c:27:
/usr/include/x86_64-linux-gnu/libavformat/avformat.h:878:21: note: declared here
AVCodecContext *codec;
^~~~~
tutorial01.c:113:3: warning: ‘avcodec_copy_context’ is deprecated [-Wdeprecated-declarations]
if(avcodec_copy_context(pCodecCtx, pCodecCtxOrig) != 0) {
^~
In file included from tutorial01.c:26:
/usr/include/x86_64-linux-gnu/libavcodec/avcodec.h:4178:5: note: declared here
int avcodec_copy_context(AVCodecContext *dest, const AVCodecContext *src);
^~~~~~~~~~~~~~~~~~~~
tutorial01.c:131:3: warning: ‘avpicture_get_size’ is deprecated [-Wdeprecated-declarations]
numBytes=avpicture_get_size(PIX_FMT_RGB24, pCodecCtx->width,
^~~~~~~~
In file included from tutorial01.c:26:
/usr/include/x86_64-linux-gnu/libavcodec/avcodec.h:5450:5: note: declared here
int avpicture_get_size(enum AVPixelFormat pix_fmt, int width, int height);
^~~~~~~~~~~~~~~~~~
tutorial01.c:131:31: error: ‘PIX_FMT_RGB24’ undeclared (first use in this function); did you mean ‘AV_PIX_FMT_RGB24’?
numBytes=avpicture_get_size(PIX_FMT_RGB24, pCodecCtx->width,
^~~~~~~~~~~~~
AV_PIX_FMT_RGB24
tutorial01.c:131:31: note: each undeclared identifier is reported only once for each function it appears in
tutorial01.c:138:3: warning: ‘avpicture_fill’ is deprecated [-Wdeprecated-declarations]
avpicture_fill((AVPicture *)pFrameRGB, buffer, PIX_FMT_RGB24,
^~~~~~~~~~~~~~
In file included from tutorial01.c:26:
/usr/include/x86_64-linux-gnu/libavcodec/avcodec.h:5435:5: note: declared here
int avpicture_fill(AVPicture *picture, const uint8_t *ptr,
^~~~~~~~~~~~~~
tutorial01.c:160:7: warning: ‘avcodec_decode_video2’ is deprecated [-Wdeprecated-declarations]
avcodec_decode_video2(pCodecCtx, pFrame, &frameFinished, &packet);
^~~~~~~~~~~~~~~~~~~~~
In file included from tutorial01.c:26:
/usr/include/x86_64-linux-gnu/libavcodec/avcodec.h:4771:5: note: declared here
int avcodec_decode_video2(AVCodecContext *avctx, AVFrame *picture,
^~~~~~~~~~~~~~~~~~~~~
tutorial01.c:177:5: warning: ‘av_free_packet’ is deprecated [-Wdeprecated-declarations]
av_free_packet(&packet);
^~~~~~~~~~~~~~
In file included from tutorial01.c:26:
/usr/include/x86_64-linux-gnu/libavcodec/avcodec.h:4416:6: note: declared here
void av_free_packet(AVPacket *pkt);
 

bigendian

Utente Attivo
310
147
OS
Linux forever, freedom
LA maggior parte sono warning che indicano che stai usando funzioni vecchie e deprecate per le librerie installate che invece sono piu recenti.
Sempre leggere cosa dicono gli warning.
I warning deprecated si possono ingnorare, per ora, ma unic oerrore

tutorial01.c:131:31: error: ‘PIX_FMT_RGB24’ undeclared (first use in this function); did you mean ‘AV_PIX_FMT_RGB24’?
numBytes=avpicture_get_size(PIX_FMT_RGB24, pCodecCtx->width,


Al posto di PIX_FMT_RGB24 devi usare AV_PIX_FMT_RGB24


Poi forse gia compila.
 

pabloski

Utente Èlite
2,686
763
Allora, ho provato a compilare quel codice sull'ultima ubuntu e ho dovuto:

1. installare libavcodec-dev, libavformat-dev, libswscale-dev
2. sostituire PIX_FMT_RGB24 con AV_PIX_FMT_RGB24
3. compilare con
➜ ~ cc -o a a.c -lavformat -lavcodec -lswscale -lavutil
 
  • Like
Reactions: Moffetta88
Stato
Discussione chiusa ad ulteriori risposte.

Entra

oppure Accedi utilizzando

Hot: PS5 VS XBOX X/S?

  • Playstation 5

    Voti: 584 63.9%
  • XBOX Series X/S

    Voti: 330 36.1%

Discussioni Simili