Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: [solved] FFMPEG problem  (Read 9154 times)

0 Members and 1 Guest are viewing this topic.

7eventh

  • Newbie
  • *
  • Posts: 9
    • MSN Messenger - jan.keromnes@free.fr
    • View Profile
    • http://7eventh.free.fr
[solved] FFMPEG problem
« on: July 17, 2009, 08:38:17 pm »
Hello.

I'm trying to play a video file with the Graphics component of SFML, so I used this French tutorial : http://www.sfml-dev.org/wiki/fr/tutoriels/integrervideo.

Here is my code (directly copied from the tutorial) :

Code: [Select]
#include <SFML/Graphics.hpp>
extern "C"
{
  #include <libavformat/avformat.h>
  #include <libavcodec/avcodec.h>
}

sf::RenderWindow App;
sf::Image im_video;
sf::Sprite sp_video;
sf::Uint8 *Data;

AVFormatContext *pFormatCtx;
int             videoStream;
int             iFrameSize;
AVCodecContext  *pCodecCtx;
AVFrame         *pFrame;
AVFrame         *pFrameRGB;
uint8_t         *buffer;
AVPacket        packet;

int init_video(char* filename);
void display();
void close_video();


int init_video(char* filename)
{

AVCodec   *pCodec;

av_register_all();
 
  if(av_open_input_file(&pFormatCtx, filename, NULL, 0, NULL)!=0)
  {
    fprintf(stderr, "Unexisting file!\n");
    return -1;
  }
 
  if(av_find_stream_info(pFormatCtx)<0)
  {
    fprintf(stderr, "Couldn't find stream information!\n");
    return -1;
  }
 
  dump_format(pFormatCtx, 0, filename, 0);

  videoStream=-1;
  for(int i=0; i<(pFormatCtx->nb_streams); i++)
  {
    if(pFormatCtx->streams[i]->codec.codec_type==CODEC_TYPE_VIDEO)
    {
      videoStream=i;
      break;
    }
  }
  if(videoStream==-1)
    return -1;
 
  pCodecCtx=&pFormatCtx->streams[videoStream]->codec;

  pCodec=avcodec_find_decoder(pCodecCtx->codec_id);
  if(pCodec==NULL)
  {
    fprintf(stderr, "Unsupported codec!\n");
    return -1;
  }
 
  if(avcodec_open(pCodecCtx, pCodec)<0)
    return -1;
  iFrameSize = pCodecCtx->width * pCodecCtx->height * 3;

  pFrame=avcodec_alloc_frame();
 
  pFrameRGB=avcodec_alloc_frame();
  if(pFrameRGB==NULL)
    return -1;

  int numBytes=avpicture_get_size(PIX_FMT_RGB24, pCodecCtx->width, pCodecCtx->height);
  buffer=(uint8_t *)av_malloc(numBytes*sizeof(uint8_t));
 
  avpicture_fill((AVPicture *)pFrameRGB, buffer, PIX_FMT_RGB24,
                pCodecCtx->width, pCodecCtx->height);

  Data = new sf::Uint8[pCodecCtx->width * pCodecCtx->height * 4];
 
  return 0;
}

void display()
{
  int frameFinished;
 
  if (av_read_packet(pFormatCtx, &packet) < 0)
  {
    close_video();
    //exit(0);
  }
 
  if(packet.stream_index==videoStream)
  {
avcodec_decode_video(pCodecCtx, pFrame, &frameFinished,
                        packet.data, packet.size);
 
    if(frameFinished)
    {
      // Convert the image from its native format to RGB
      img_convert((AVPicture *)pFrameRGB, PIX_FMT_RGB24,
                  (AVPicture*)pFrame, pCodecCtx->pix_fmt, pCodecCtx->width,
                  pCodecCtx->height);
 }

int j = 0;
    for(int i = 0 ; i < (iFrameSize) ; i+=3)
    {
      Data[j] = pFrameRGB->data[0][i];
      Data[j+1] = pFrameRGB->data[0][i+1];
      Data[j+2] = pFrameRGB->data[0][i+2];
      Data[j+3] = 255;
      j+=4;
    }
    im_video.LoadFromPixels(pCodecCtx->width, pCodecCtx->height, Data);

}
  // Dessiner l'image sur le tampon de l'écran
  App.Draw(sp_video);
}

void close_video()
{
  // Libérer le packet alloué par av_read_frame
  av_free_packet(&packet);
  // Libérer l'image RGB
  av_free(buffer);
  av_free(pFrameRGB);
  // Libérer l'image YUV
  av_free(pFrame);
  // Fermer le codec
  avcodec_close(pCodecCtx);
  // Fermer le  fichier video
  av_close_input_file(pFormatCtx);
}

int main()
{
// Notre fonction pour initialiser la video
if ( init_video("test.avi") == 0 )
{
 // Code SFML de base
 App.Create( sf::VideoMode(pCodecCtx->width*2, pCodecCtx->height*2, 32),
                             "Video avec SFML et FFMpeg"
                           );
 
// On crée notre image, en blanc par exemple
 im_video.Create(pCodecCtx->width, pCodecCtx->height, sf::Color(255,255,255,255));
// J'aime bien ne pas mettre le smooth, ça dépend de la qualité de la video :)
 im_video.SetSmooth(false);
// On crée notre sprite
 sp_video.SetImage(im_video);
// Vous pouvez utiliser les fonctionnalité du sprite sur la video,
// comme le scale, de la même manière qu'une simple image fixe
 
 // La boucle principale
 bool Running = true;
 while (Running)
 {
   // Les évènements
   sf::Event Event;
   while (App.GetEvent(Event))
   {
     if (Event.Type == sf::Event::Closed)
       Running = false;
 
     if ((Event.Type == sf::Event::KeyPressed) && (Event.Key.Code == sf::Key::Escape))
       Running = false;
   }
 
// Notre fonction de lecture et dessin de la video
   display();
 
// On affiche tout ça
   App.Display();
   App.SetFramerateLimit(50);
 }
 
// Notre fonction pour fermer la video
 close_video();
 return EXIT_SUCCESS;
}
  return EXIT_FAILURE;
}



I've also correctly added the following libraries : avformat.lib and avcodec.lib. When I'm trying to build, I get this error :


Code: [Select]
1>------ Build started: Project: ffmpeg_test1, Configuration: Release Win32 ------
1>Compiling...
1>main.cpp
1>.\main.cpp(49) : warning C4018: '<' : signed/unsigned mismatch
1>.\main.cpp(51) : error C2228: left of '.codec_type' must have class/struct/union
1>        type is 'AVCodecContext *'
1>        did you intend to use '->' instead?
1>.\main.cpp(60) : error C2440: '=' : cannot convert from 'AVCodecContext **' to 'AVCodecContext *'
1>        Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast
1>.\main.cpp(108) : error C3861: 'img_convert': identifier not found
1>Build log was saved at "file://c:\Projects\vcpp\ffmpeg_test1\ffmpeg_test1\Release\BuildLog.htm"
1>ffmpeg_test1 - 3 error(s), 1 warning(s)
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========


Can anyone please help me there ?

7eventh

  • Newbie
  • *
  • Posts: 9
    • MSN Messenger - jan.keromnes@free.fr
    • View Profile
    • http://7eventh.free.fr
[solved] FFMPEG problem
« Reply #1 on: July 17, 2009, 08:53:26 pm »
Problem solved, sorry for the inconvenience, I hope it'll help others who have the same problem.

Solution :
* Forget about the warning.
* Go to the locations of the errors :
- Replace "codec.codec_type" by "codec->codec_type". Codec is a pointer.
- Replace "pCodecCtx=&pFormatCtx->..." by "pCodecCtx=pFormatCtx->..."
* Use function prototypes in the top of your code.
* Add this function :

Code: [Select]
int img_convert(AVPicture* dst, PixelFormat dst_pix_fmt, AVPicture* src, PixelFormat pix_fmt, int width, int height)
{
   int av_log = av_log_get_level();
   av_log_set_level(AV_LOG_QUIET);
   SwsContext *img_convert_ctx = sws_getContext(width, height, pix_fmt, width, height, dst_pix_fmt, SWS_BICUBIC, NULL, NULL, NULL);
   int result = sws_scale(img_convert_ctx, src->data, src->linesize, 0, height, dst->data, dst->linesize);
   sws_freeContext(img_convert_ctx);
   av_log_set_level(av_log);
   return result;
}

didito

  • Newbie
  • *
  • Posts: 27
    • View Profile
    • http://didito.gpigs.com
[solved] FFMPEG problem
« Reply #2 on: October 20, 2009, 08:35:32 pm »
hello,

i'm glad to have stumbled upon your thread since i am trying to do something similar. although i would like to use live video from a camera.

i will try to get your example to work on my mac though. can you tell me on which platform (os, compiler, ffmpeg version) you have developed this?
and another question regarding the timing? does ffmpeg handle this internally or do you just ignore it for now?

thanks in advance,
didi

core4mac

  • Newbie
  • *
  • Posts: 5
    • View Profile
    • Email
Link problems
« Reply #3 on: January 04, 2010, 02:59:12 am »
I tried to use ffmpeg with my source but the linking fails for the following reason(s):

warning: "In /developer.../usr/local/lib/libabcodec.a, file is not of required architecture"

error: _av_open_input_file
error: _av_find_stream_info
error: _av_register_all

I am using Snow Leopard and have compiled the ffmpeg sources with different --arch configurations, but nothing seems to work.

What is the correct configuration for ffmpeg and xcode to get things running ?