Index: /trunk/src/defs/class_id.h
===================================================================
--- /trunk/src/defs/class_id.h	(revision 6730)
+++ /trunk/src/defs/class_id.h	(revision 6731)
@@ -107,4 +107,6 @@
   // SUPER-Modeling
   CL_TEXTURE                    =    0x00c01000,
+  CL_TEXTURE_SEQUENCE           =    0x00004000,
+
   CL_TEXT                       =    0x00c02000,
 
@@ -202,4 +204,5 @@
   CL_NPC_TEST2                  =    0x00000302,
   CL_MOVIE_ENTITY               =    0x00000303,
+  CL_RECORDER                   =    0x00000304,
 
 
@@ -243,5 +246,4 @@
 
   CL_MATERIAL                   =    0x00000804,
-  CL_TEXTURE_SEQUENCE           =    0x00004805,
   CL_OBJ_MODEL                  =    0x00000807,
 
Index: /trunk/src/lib/graphics/importer/media_container.cc
===================================================================
--- /trunk/src/lib/graphics/importer/media_container.cc	(revision 6730)
+++ /trunk/src/lib/graphics/importer/media_container.cc	(revision 6731)
@@ -40,18 +40,7 @@
 
   fps = 0;
-
-  if (filename != NULL)
-  {
-    if(!this->loadMedia(filename))
-      PRINTF(1)("MediaContainer::loadMedia() failed for %s\n", filename);
-  }
-}
-
-MediaContainer::MediaContainer()
-{
-  // set the class id for the base object
-  this->setClassID(CL_MEDIA_CONTAINER, "MediaContainer");
-
-  fps = 0;
+  mediaLoaded = false;
+
+  this->loadMedia(filename);
 }
 
@@ -61,6 +50,20 @@
 MediaContainer::~MediaContainer()
 {
+  this->unloadMedia();
+}
+
+void MediaContainer::unloadMedia()
+{
+  // check whether a movie is already loaded
+  if(!mediaLoaded)
+    return;
+
+  fps = 0;
+
+  // clear texturelist
+  this->clearLists();
+
   if (glIsTexture(texture))
-    glDeleteTextures(1, &texture);
+  glDeleteTextures(1, &texture);
 
   // Free the RGB image
@@ -76,8 +79,22 @@
   // Close the video file
   av_close_input_file(format_context);
+
+  mediaLoaded = false;
+
 }
 
 bool MediaContainer::loadMedia(const char* filename)
 {
+  this->unloadMedia();
+
+  if(filename == NULL)
+    return false;
+  // check whether file exists
+  if(!ResourceManager::isInDataDir(filename))
+  {
+    PRINTF(1)("Could not find %s\n", filename);
+    return false;
+  }
+
   // register all formats and codecs
   av_register_all();
@@ -146,4 +163,5 @@
   // read the frames and save them in a sequence as textures
   this->loadFrames();
+  mediaLoaded = true;
 
   return true;
Index: /trunk/src/lib/graphics/importer/media_container.h
===================================================================
--- /trunk/src/lib/graphics/importer/media_container.h	(revision 6730)
+++ /trunk/src/lib/graphics/importer/media_container.h	(revision 6731)
@@ -40,9 +40,9 @@
   int video_stream;
   double fps;
+  bool mediaLoaded;
 
 public:
 
-  MediaContainer(const char* filename);
-  MediaContainer();
+  MediaContainer(const char* filename = NULL);
   ~MediaContainer();
 
@@ -55,5 +55,5 @@
   
   GLuint getNextFrame();
-
+  void unloadMedia();
 };
 
Index: /trunk/src/lib/graphics/importer/movie_player.cc
===================================================================
--- /trunk/src/lib/graphics/importer/movie_player.cc	(revision 6730)
+++ /trunk/src/lib/graphics/importer/movie_player.cc	(revision 6731)
@@ -33,22 +33,28 @@
 MoviePlayer::MoviePlayer(const char* filename)
 {
-  this->init();
-
-  if (filename != NULL)
-  {
-    if(!this->loadMovie(filename))
-      PRINTF(1)("MoviePlayer::loadMovie() failes for %s\n", filename);
-  }
-}
-
-MoviePlayer::MoviePlayer()
-{
-  this->init();
-}
+  // set the class id for the base object
+  this->setClassID(CL_MOVIE_PLAYER, "MoviePlayer");
+
+  status = STOP;
+  timer = 0;
+  frame_number = 0;
+
+  mediaLoaded = false;
+
+  this->loadMovie(filename);
+
+}
+
 
 MoviePlayer::~MoviePlayer()
 {
-  //delete material;
-  //delete model;
+  this->unloadMedia();
+}
+
+void MoviePlayer::unloadMedia()
+{
+  // check whether a movie is already loaded
+  if(!mediaLoaded)
+    return;
 
   if (glIsTexture(texture))
@@ -62,6 +68,4 @@
   av_free(frame);
 
-  avcodec_default_free_buffers(codec_context);
-
   // Close the codec
   avcodec_close(codec_context);
@@ -69,30 +73,27 @@
   // Close the video file
   av_close_input_file(format_context);
-}
-
-void MoviePlayer::init()
-{
-  // set the class id for the base object
-  this->setClassID(CL_MOVIE_PLAYER, "MoviePlayer");
 
   status = STOP;
   timer = 0;
   frame_number = 0;
-  loading = false;
-
-  /*material = new Material;
-  material->setDiffuseMap("maps/radialTransparency.png");
-
-  model = new PrimitiveModel(PRIM_PLANE, 10.0);
-
-  LightManager* lightMan = LightManager::getInstance();
-  lightMan->setAmbientColor(.1,.1,.1);
-  (new Light())->setAbsCoor(5.0, 10.0, 40.0);
-  (new Light())->setAbsCoor(-10, -20, -100);
-  */
-}
+
+  mediaLoaded = false;
+
+}
+
 
 bool MoviePlayer::loadMovie(const char* filename)
 {
+  this->unloadMedia();
+
+  if(filename == NULL)
+    return false;
+  // check whether file exists
+  if(!ResourceManager::isInDataDir(filename))
+  {
+    PRINTF(1)("Could not find %s\n", filename);
+    return false;
+  }
+
   // register all formats and codecs
   av_register_all();
@@ -177,5 +178,5 @@
   glBindTexture(GL_TEXTURE_2D, 0);
 
-  loading = true;
+  mediaLoaded = true;
   return true;
 }
@@ -277,5 +278,5 @@
 bool MoviePlayer::gotoFrame(int frames)
 {
-  if(!loading)
+  if(!mediaLoaded)
   {
     PRINTF(0)("Load first the media file with loadMovie\n");
@@ -344,8 +345,4 @@
     status = PLAY;
     timer = 0;
-
-    this->gotoFrame(start_frame);
-
-    PRINTF(0)("start\n");
   }
 }
@@ -354,8 +351,5 @@
 {
   if(status == PAUSE)
-  {
     status = PLAY;
-    PRINTF(0)("resume\n");
-  }
 }
 
@@ -363,8 +357,5 @@
 {
   if(status == PLAY)
-  {
     status = PAUSE;
-    PRINTF(0)("pause\n");
-  }
 }
 
@@ -372,6 +363,4 @@
 {
   status = STOP;
-
-  PRINTF(0)("stop\n");
 }
 
@@ -389,16 +378,6 @@
         this->skipFrame(actual_frame - frame_number - 1);
     }
-    //PRINTF(0)("frame_number: %i\n", frame_number);
-  }
-}
-
-/*const void MoviePlayer::draw()
-{
-  material->select();
-  glBindTexture(GL_TEXTURE_2D, texture);
-  model->draw();
-
-  LightManager::getInstance()->draw();
-}*/
+  }
+}
 
 GLuint MoviePlayer::getTexture()
@@ -425,5 +404,5 @@
 void MoviePlayer::printInformation()
 {
-  if(!loading)
+  if(!mediaLoaded)
   {
     PRINTF(0)("Load first the media file with loadMovie\n");
Index: /trunk/src/lib/graphics/importer/movie_player.h
===================================================================
--- /trunk/src/lib/graphics/importer/movie_player.h	(revision 6730)
+++ /trunk/src/lib/graphics/importer/movie_player.h	(revision 6731)
@@ -17,9 +17,5 @@
 
 #include "glincl.h"
-
-//#include "light.h"
 #include "texture.h"
-//#include "material.h"
-//#include "primitive_model.h"
 
 // include base_object.h since all classes are derived from this one
@@ -29,6 +25,6 @@
 typedef enum MP_STATUS {
   PLAY,
-        PAUSE,
-        STOP
+  PAUSE,
+  STOP
 };
 
@@ -37,7 +33,4 @@
 
 private:
-
-  //Model* model;
-  //Material* material;
 
   AVFormatContext* format_context;
@@ -61,38 +54,35 @@
   float fps;
   int duration;
-  bool loading;
+  bool mediaLoaded;
 
 public:
 
-  MoviePlayer(const char* filename);
-  MoviePlayer();
+  MoviePlayer(const char* filename = NULL);
   ~MoviePlayer();
 
   bool loadMovie(const char* filename);
 
-        void start(float start_time);
-        void resume();
-        void pause();
-        void stop();
+  void start(float start_time);
+  void resume();
+  void pause();
+  void stop();
 
-        void tick(float dt);
-        //const void draw();
-        GLuint getTexture();
+  void tick(float dt);
+  GLuint getTexture();
 
-        void setFPS(float fps);
-        float getFPS();
-        const MP_STATUS getStatus();
+  void setFPS(float fps);
+  float getFPS();
+  const MP_STATUS getStatus();
   void printInformation();
 
 private:
 
-  void init();
   void getNextFrame();
   void skipFrame(int frames);
   bool gotoFrame(int frames);
 
+  void unloadMedia();
+
 };
 
-
-
 #endif // _MOVIE_PLAYER
Index: /trunk/src/story_entities/movie_loader.cc
===================================================================
--- /trunk/src/story_entities/movie_loader.cc	(revision 6730)
+++ /trunk/src/story_entities/movie_loader.cc	(revision 6731)
@@ -20,5 +20,5 @@
 #include "graphics_engine.h"
 #include "load_param.h"
-#include "resource_manager.h"
+#include "state.h"
 
 
@@ -35,7 +35,7 @@
 }
 
-MovieLoader::~MovieLoader()
+MovieLoader::~MovieLoader() 
 {
-  PRINTF(4)("Deleted MoviePlayer\n");
+  delete this->movie_player;
 }
 
@@ -52,34 +52,20 @@
 {
   movie_player->loadMovie(filename);
-
-  PRINTF(0)("\nloaded Movie %s\n\n", filename);
 }
 
 
-ErrorMessage MovieLoader::init()
-{
-
-}
+ErrorMessage MovieLoader::init() {}
 
 
-ErrorMessage MovieLoader::loadData()
-{
-
-}
+ErrorMessage MovieLoader::loadData() {}
 
 
-ErrorMessage MovieLoader::unloadData()
-{
-
-}
+ErrorMessage MovieLoader::unloadData() {}
 
 bool MovieLoader::start()
 {
-  PRINTF(0)("\nMovieLoader INFO:\n");
-  movie_player->printInformation();
-  PRINTF(0)("\n");
-
+  this->movie_player->start(0);
+  
   this->isRunning = true;
-
   this->run();
 }
@@ -97,12 +83,9 @@
   // first timestamp for t = 0
   this->lastFrame = SDL_GetTicks ();
-  this->movie_player->start(0);
 
   while( this->isRunning)
   {
-
     this->tick();
     this->draw();
-
   }
 }
@@ -121,8 +104,8 @@
 
   glBegin(GL_QUADS);
-    glTexCoord2f(1.0f, 0.0f); glVertex2f( 0, 0);
-    glTexCoord2f(1.0f, 1.0f); glVertex2f( 0, 100);
-    glTexCoord2f(0.0f, 1.0f); glVertex2f( 100, 100);
-    glTexCoord2f(0.0f, 0.0f); glVertex2f( 100, 0);
+    glTexCoord2f(0.0f, 0.0f); glVertex2f( 0, 0);
+    glTexCoord2f(0.0f, 1.0f); glVertex2f( 0, State::getResY());
+    glTexCoord2f(1.0f, 1.0f); glVertex2f( State::getResX(), State::getResY());
+    glTexCoord2f(1.0f, 0.0f); glVertex2f( State::getResX(), 0);
   glEnd();
 
@@ -139,5 +122,5 @@
 
   // calculate time difference in milliseconds (Uint32)
-  this->dt = currentFrame - this->lastFrame;
+  this->dt = currentFrame - this->lastFrame; 
   // calculate time difference in seconds (float)
   this->dts = (float)this->dt / 1000.0f;
Index: /trunk/src/world_entities/Makefile.am
===================================================================
--- /trunk/src/world_entities/Makefile.am	(revision 6730)
+++ /trunk/src/world_entities/Makefile.am	(revision 6731)
@@ -21,4 +21,5 @@
                   world_entities/satellite.cc \
                   world_entities/movie_entity.cc \
+                  world_entities/recorder.cc \
                   world_entities/character_attributes.cc \
                   world_entities/test_entity.cc \
@@ -74,4 +75,5 @@
                  world_entities/satellite.h \
                  world_entities/movie_entity.h \
+                 world_entities/recorder.h \
                  world_entities/character_attributes.h \
                  world_entities/test_entity.h \
Index: /trunk/src/world_entities/movie_entity.cc
===================================================================
--- /trunk/src/world_entities/movie_entity.cc	(revision 6730)
+++ /trunk/src/world_entities/movie_entity.cc	(revision 6731)
@@ -37,4 +37,5 @@
   height = 20;
   width = 20;
+  mediaLoaded = false;
 
   this->toList(OM_COMMON);
@@ -63,5 +64,5 @@
   LoadParam(root, "name", this, MovieEntity, loadMovie);
   LoadParam(root, "axis", this, MovieEntity, setAxis);
-  LoadParam(root, "rotation", this, MovieEntity, setRotation);
+  //LoadParam(root, "rotation", this, MovieEntity, setRotation);
   LoadParam(root, "size", this, MovieEntity, setSize);
 }
@@ -69,5 +70,8 @@
 void MovieEntity::loadMovie(const char* filename)
 {
-  media_container->loadMedia(filename);
+  if(media_container->loadMedia(filename))
+    mediaLoaded = true;
+  else
+    mediaLoaded = false;
 }
 
@@ -97,4 +101,7 @@
 void MovieEntity::tick(float time)
 {
+  if(!mediaLoaded)
+    return;
+
   timer += time;
 
@@ -122,4 +129,6 @@
 void MovieEntity::draw() const
 {
+  if(!mediaLoaded)
+    false;
 
   glPushMatrix();
Index: /trunk/src/world_entities/movie_entity.h
===================================================================
--- /trunk/src/world_entities/movie_entity.h	(revision 6730)
+++ /trunk/src/world_entities/movie_entity.h	(revision 6731)
@@ -26,4 +26,6 @@
     float width;
 
+    bool mediaLoaded;
+
   public:
     MovieEntity (const TiXmlElement* root = NULL);
Index: /trunk/src/world_entities/recorder.cc
===================================================================
--- /trunk/src/world_entities/recorder.cc	(revision 6731)
+++ /trunk/src/world_entities/recorder.cc	(revision 6731)
@@ -0,0 +1,368 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2006 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+### File Specific:
+   main-programmer: David Hasenfratz
+   co-programmer:
+*/
+
+#include "recorder.h"
+
+#include "load_param.h"
+#include "factory.h"
+#include "resource_manager.h"
+#include "state.h"
+
+using namespace std;
+
+CREATE_FACTORY(Recorder, CL_RECORDER);
+
+
+Recorder::Recorder (const TiXmlElement* root)
+{
+  this->setClassID(CL_RECORDER, "Recorder");
+
+  // initialize libavcodec, and register all codecs and formats
+  av_register_all();
+
+  // Default values
+  stream_duration = 10;
+  stream_frame_rate = 20;
+
+  this->loadParams(root);
+
+  this->toList(OM_COMMON);
+}
+
+
+Recorder::~Recorder ()
+{
+
+}
+
+
+void Recorder::loadParams(const TiXmlElement* root)
+{
+  WorldEntity::loadParams(root);
+
+  LoadParam(root, "duration", this, Recorder, setStreamDuration);
+  LoadParam(root, "fps", this, Recorder, setFPS);
+  LoadParam(root, "name", this, Recorder, initVideo);
+}
+
+
+void Recorder::setStreamDuration(float duration)
+{
+  this->stream_duration = duration;
+}
+
+
+void Recorder::setFPS(float fps)
+{
+  this->stream_frame_rate = fps;
+}
+
+
+void Recorder::initVideo(const char* filename)
+{
+  frame_count = 0;
+  time = 0;
+  stream_nb_frames = (int)(stream_duration * stream_frame_rate);
+
+  // auto detect the output format from the name, default is mpeg
+  output_format = guess_format(NULL, filename, NULL);
+  if (!output_format)
+  {
+      PRINTF(0)("Could not deduce output format from file extension: using MPEG.\n");
+      output_format = guess_format("mpeg", NULL, NULL);
+  }
+  if (!output_format)
+    PRINTF(1)("Could not find suitable output format\n");
+
+  // allocate the output media context
+  format_context = av_alloc_format_context();
+  if (!format_context)
+    PRINTF(1)("Memory error\n");
+
+  format_context->oformat = output_format;
+  snprintf(format_context->filename, sizeof(format_context->filename), "%s", filename);
+
+  // add video stream using the default format codec and initialize the codec
+  if (output_format->video_codec != CODEC_ID_NONE)
+      this->addVideoStream();
+
+  // set the output parameters (must be done even if no parameters)
+  if (av_set_parameters(format_context, NULL) < 0)
+    PRINTF(1)("Invalid output format parameters\n");
+
+  // print some information
+  dump_format(format_context, 0, filename, 1);
+
+  // now that all the parameters are set, we can open the
+  // video codec and allocate the necessary encode buffer
+  if(video_stream)
+    this->openVideo();
+  
+  // open the output file, if needed
+  if(!(output_format->flags & AVFMT_NOFILE))
+  {
+    if(url_fopen(&format_context->pb, filename, URL_WRONLY) < 0)
+      PRINTF(1)("Could not open %s\n", filename);
+  }
+
+  // write the stream header, if any
+  av_write_header(format_context); 
+}
+
+void Recorder::closeVideo()
+{
+  avcodec_close(video_stream->codec);
+  av_free(picture->data[0]);
+  av_free(picture);
+  av_free(buffer);
+
+  // write the trailer, if any 
+  av_write_trailer(format_context);
+  
+  // free the streams
+  for(int i = 0; i < format_context->nb_streams; i++)
+    av_freep(&format_context->streams[i]);
+
+  // close the output file
+  if (!(output_format->flags & AVFMT_NOFILE))
+    url_fclose(&format_context->pb);
+
+  // free the stream
+  av_free(format_context);
+}
+
+
+void Recorder::openVideo()
+{
+  codec_context = video_stream->codec;
+
+  // find the video encoder
+  codec = avcodec_find_encoder(codec_context->codec_id);
+  if(!codec)
+    PRINTF(1)("codec not found\n");
+
+  // open the codec
+  if(avcodec_open(codec_context, codec) < 0)
+    PRINTF(1)("could not open codec\n");
+
+  buffer = NULL;
+  if(!(format_context->oformat->flags & AVFMT_RAWPICTURE))
+  {
+      // allocate output buffer
+      // XXX: API change will be done
+      buffer_size = 200000;
+      buffer = new uint8_t[buffer_size];
+  }
+
+  // allocate the encoded raw picture
+  this->allocPicture();
+  if(!picture)
+    PRINTF(0)("Could not allocate picture\n");
+}
+
+
+void Recorder::allocPicture()
+{ 
+  picture = avcodec_alloc_frame();
+  if(!picture)
+  {
+    picture = NULL;
+    return;
+  }
+  size = avpicture_get_size(codec_context->pix_fmt, width, height);
+  picture_buf = new uint8_t[size];
+  if(!picture_buf)
+  {
+      av_free(picture);
+      return;
+  }
+  avpicture_fill((AVPicture *)picture, picture_buf, 
+                  codec_context->pix_fmt, width, height);
+
+
+
+  RGB_frame = avcodec_alloc_frame();
+
+  // Determine required buffer size and allocate buffer
+  size = avpicture_get_size(PIX_FMT_RGB24, width, height);
+  picture_buf = new uint8_t[size];
+
+  // Assign appropriate parts of buffer to image planes in RGB_frame
+  avpicture_fill((AVPicture *)RGB_frame, picture_buf, PIX_FMT_RGB24, width, height);
+}
+
+
+// add a video output stream
+void Recorder::addVideoStream()
+{
+  video_stream = av_new_stream(format_context, 0);
+  if (!video_stream)
+    PRINTF(1)("Could not alloc stream\n");
+  
+  codec_context = video_stream->codec;
+  codec_context->codec_id = output_format->video_codec;
+  codec_context->codec_type = CODEC_TYPE_VIDEO;
+
+  // put sample parameters
+  codec_context->bit_rate = 400000;
+  // resolution must be a multiple of two
+  codec_context->width = State::getResX();  
+  codec_context->height = State::getResY();
+
+  this->width = codec_context->width;
+  this->height = codec_context->height;
+
+  // time base: this is the fundamental unit of time (in seconds) in terms
+  // of which frame timestamps are represented. for fixed-fps content,
+  // timebase should be 1/framerate and timestamp increments should be
+  // identically 1
+  codec_context->time_base.den = (int)stream_frame_rate;  
+  codec_context->time_base.num = 1;
+  codec_context->gop_size = 12;  // emit one intra frame every twelve frames at most
+  codec_context->pix_fmt = PIX_FMT_YUV420P;
+
+  if (codec_context->codec_id == CODEC_ID_MPEG1VIDEO)
+      // needed to avoid using macroblocks in which some coeffs overflow 
+      // this doesnt happen with normal video, it just happens here as the 
+      // motion of the chroma plane doesnt match the luma plane
+      codec_context->mb_decision=2;
+
+  // some formats want stream headers to be seperate
+  if(!strcmp(format_context->oformat->name, "mp4") ||
+     !strcmp(format_context->oformat->name, "mov") ||
+     !strcmp(format_context->oformat->name, "3gp"))
+    format_context->flags |= CODEC_FLAG_GLOBAL_HEADER;
+}
+
+
+void Recorder::tick(float dt)
+{
+  time += dt;
+  if(time < 1/stream_frame_rate)
+    return;
+  else
+    time = 0;
+
+  // compute current video time
+  if (video_stream)
+      video_pts = (double)video_stream->pts.val * video_stream->time_base.num / video_stream->time_base.den;
+  else
+      video_pts = 0.0;
+
+  if (!video_stream || video_pts >= stream_duration)
+  {
+    this->toList(OM_DEAD);
+    this->closeVideo();
+  }
+  else
+    // write video frame
+    this->writeVideoFrame();
+}
+
+void Recorder::writeVideoFrame()
+{
+  int out_size, err;
+  
+  codec_context = video_stream->codec;
+  
+  if(frame_count >= stream_nb_frames)
+  {
+    /* no more frame to compress. The codec has a latency of a few
+        frames if using B frames, so we get the last frames by
+        passing the same picture again */
+  }
+  else
+    this->fillYuvImage();
+
+  
+  if(format_context->oformat->flags & AVFMT_RAWPICTURE)
+  {
+    // raw video case. The API will change slightly in the near
+    // futur for that
+    av_init_packet(&packet);
+    
+    packet.flags |= PKT_FLAG_KEY;
+    packet.stream_index= video_stream->index;
+    packet.data= (uint8_t *)picture;
+    packet.size= sizeof(AVPicture);
+    
+    err = av_write_frame(format_context, &packet);
+  }
+  else
+  {
+    // encode the image
+    out_size = avcodec_encode_video(codec_context, buffer, buffer_size, picture);
+    // if zero size, it means the image was buffered
+    if (out_size > 0)
+    {
+      av_init_packet(&packet);
+      
+      packet.pts= av_rescale_q(codec_context->coded_frame->pts, codec_context->time_base, video_stream->time_base);
+      if(codec_context->coded_frame->key_frame)
+        packet.flags |= PKT_FLAG_KEY;
+      packet.stream_index = video_stream->index;
+      packet.data= buffer;
+      packet.size= out_size;
+      
+      // write the compressed frame in the media file
+      err = av_write_frame(format_context, &packet);
+    }
+    else
+      err = 0;
+  }
+
+  if(err != 0)
+    PRINTF(1)("Error while writing video frame\n");
+
+  frame_count++;
+}
+
+
+void Recorder::fillYuvImage()
+{
+  unsigned char *outputImage = 0;
+
+  // Allocate the neccessary memory.
+  outputImage = (unsigned char*)malloc(width * height * 3);
+
+  // Clear the variable.
+  memset(outputImage, 0, width * height * 3);
+
+  // You use the glReadPixels() to read every pixel on the screen
+  // that you specify.  You must use one less than each size.
+  glReadPixels(0, 0, width, height, GL_RGB, GL_UNSIGNED_BYTE, outputImage);
+
+  int i = 0;
+  for(int y=height-1;y>=0;y--)
+  {
+    for(int x=0;x<width*3;x++)
+    {
+      RGB_frame->data[0][y*width*3+x] = outputImage[i];
+      i++;
+    }
+  }
+
+
+  img_convert((AVPicture*)picture, PIX_FMT_YUV420P, (AVPicture*)RGB_frame,
+              PIX_FMT_RGB24, width, height);
+
+  // Clear the allocated memory.
+  free(outputImage);
+}
+
+
+void Recorder::draw() const
+{
+}
Index: /trunk/src/world_entities/recorder.h
===================================================================
--- /trunk/src/world_entities/recorder.h	(revision 6731)
+++ /trunk/src/world_entities/recorder.h	(revision 6731)
@@ -0,0 +1,70 @@
+/*!
+ * @file recorder.h
+ * 
+ */
+
+#ifndef _RECORDER_H
+#define _RECORDER_H
+
+#include <SDL.h>
+
+#ifdef HAVE_AVFORMAT_H
+  #include <avformat.h>
+#else
+  #include <ffmpeg/avformat.h>
+#endif
+
+#include "glincl.h"
+#include "world_entity.h"
+
+class Recorder : public WorldEntity
+{
+  private:
+    AVFrame* picture;
+    uint8_t* buffer;
+    int frame_count;
+    int buffer_size;
+
+    AVOutputFormat* output_format;
+    AVFormatContext* format_context;
+    AVCodecContext* codec_context;
+    AVCodec *codec;
+    AVStream* video_stream;
+    AVPacket packet;
+    double video_pts;
+    
+    uint8_t *picture_buf;
+    int size;
+
+    int height;
+    int width;
+    float time;
+
+    float stream_duration;
+    float stream_frame_rate;
+    int stream_nb_frames;
+
+AVFrame* RGB_frame;
+  public:
+    Recorder (const TiXmlElement* root = NULL);
+    ~Recorder ();
+
+    virtual void draw () const;
+    virtual void tick (float dt);
+
+    virtual void loadParams(const TiXmlElement* root);
+
+  private:
+    void initVideo(const char* filename);
+    void addVideoStream();
+    void openVideo();
+    void closeVideo();
+    void allocPicture();
+    void writeVideoFrame();
+    void fillYuvImage();
+
+    void setStreamDuration(float duration);
+    void setFPS(float fps);
+};
+
+#endif /* _RECORDER_H */
