Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

Changeset 6353 in orxonox.OLD for branches/avi_play/src/lib/graphics/importer


Ignore:
Timestamp:
Dec 30, 2005, 8:34:22 PM (19 years ago)
Author:
hdavid
Message:

branches\avi_play: MoviePlayer works again

Location:
branches/avi_play/src/lib/graphics/importer
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • branches/avi_play/src/lib/graphics/importer/media_container.cc

    r6350 r6353  
    125125  buffer=new uint8_t[num_bytes];
    126126
    127   // Assign appropriate parts of buffer to image planes in pFrameRGB
     127  // Assign appropriate parts of buffer to image planes in RGB_frame
    128128  avpicture_fill((AVPicture *)RGB_frame, buffer, PIX_FMT_RGB24, codec_context->width, codec_context->height);
    129129
     
    155155GLuint MediaContainer::getNextFrame()
    156156{
    157   //if (glIsTexture(texture))
    158   //  glDeleteTextures(1, &texture);
    159157
    160158  // get next frame
     
    189187                 ((AVPicture*)RGB_frame)->linesize[0],
    190188                  codec_context->width*sizeof(uint8_t)*3);
     189
     190        //avcodec_flush_buffers(codec_context);
    191191
    192192        surface = SDL_CreateRGBSurfaceFrom(data, codec_context->width,
     
    228228                        GL_UNSIGNED_BYTE,
    229229                        surface->pixels);
    230         glBindTexture(GL_TEXTURE_2D, 0);
     230        glBindTexture(GL_TEXTURE_2D, 0);     
    231231       
    232232        return texture;
     
    235235      {
    236236        av_free_packet(&packet);
    237         this->getNextFrame();
     237        return this->getNextFrame();
    238238      }
    239239    }
     
    241241    {
    242242      av_free_packet(&packet);
    243       this->getNextFrame();
     243      return this->getNextFrame();
    244244    }
    245245  }
  • branches/avi_play/src/lib/graphics/importer/movie_player.cc

    r6339 r6353  
    1818/* this is for debug output. It just says, that all calls to PRINT() belong to the DEBUG_MODULE_MEDIA module
    1919   For more information refere to https://www.orxonox.net/cgi-bin/trac.cgi/wiki/DebugOutput
    20 *//*
     20*/
    2121#define DEBUG_MODULE_MEDIA
    2222
     
    2929
    3030
    31 //
    32 // Default constructor
    33 //
    3431MoviePlayer::MoviePlayer(const char* filename)
    3532{
    36   media_container = new MediaContainer(filename);
    37 
    3833  this->init();
     34
     35  if (filename != NULL)
     36    this->loadMovie(filename);
    3937}
    4038
    4139MoviePlayer::MoviePlayer()
    4240{
    43   media_container = new MediaContainer();
    44 
    4541  this->init();
    4642}
     
    4844MoviePlayer::~MoviePlayer()
    4945{
    50   delete media_container;
     46  delete material;
     47  delete model;
     48
     49  if (glIsTexture(texture))
     50    glDeleteTextures(1, &texture);
     51  SDL_FreeSurface(surface);
     52
     53  // Free the RGB image
     54  delete [] buffer;
     55  av_free(RGB_frame);
     56
     57  // Free the frame
     58  av_free(frame);
     59
     60  // Close the codec
     61  avcodec_close(codec_context);
     62
     63  // Close the video file
     64  av_close_input_file(format_context);
    5165}
    5266
    5367void MoviePlayer::init()
    5468{
     69  // set the class id for the base object
     70  this->setClassID(CL_MOVIE_PLAYER, "MoviePlayer");
     71
    5572  status = STOP;
    5673  timer = 0;
     74  frame_number = 0;
    5775  speed = 1;
    5876
    5977  material = new Material;
    60 
    6178  material->setDiffuseMap("maps/radialTransparency.png");
    6279
     
    7188void MoviePlayer::loadMovie(const char* filename)
    7289{
    73   media_container->loadMedia(filename);
    74 }
    75 
    76 void MoviePlayer::printInformation()
    77 {
    78   media_container->printMediaInformation();
     90  // register all formats and codecs
     91  av_register_all();
     92
     93  // Open video file
     94  if (av_open_input_file(&format_context, filename, NULL, 0, NULL) !=0 )
     95    PRINTF(1)("Could not open %s\n", filename);
     96
     97  // Retrieve stream information
     98  if (av_find_stream_info(format_context) < 0)
     99    PRINTF(1)("Could not find stream information in %s\n", filename);
     100
     101  // Find the first video stream and take it
     102  video_stream = -1;
     103  for(int i = 0; i < format_context->nb_streams; i++)
     104  {
     105    // NOTE: different code for the 0.4.9-pre1 release of ffmpeg (tardis)
     106    // if(format_context->streams[i]->codec.codec_type == CODEC_TYPE_VIDEO)
     107    if(format_context->streams[i]->codec->codec_type == CODEC_TYPE_VIDEO)
     108    {
     109      video_stream = i;
     110      break;
     111    }
     112  }
     113
     114  if(video_stream == -1)
     115    PRINTF(1)("Could not find a video stream in %s\n", filename);
     116
     117  // Get a pointer to the codec context for the video stream
     118  // NOTE: different code for the 0.4.9-pre1 release of ffmpeg (tardis)
     119  // codec_context = &format_context->streams[video_stream]->codec;
     120  codec_context = format_context->streams[video_stream]->codec;
     121
     122  // Find the decoder for the video stream
     123  codec = avcodec_find_decoder(codec_context->codec_id);
     124  if (codec == NULL)
     125    PRINTF(1)("Could not find codec\n");
     126
     127  // Open codec
     128  if (avcodec_open(codec_context, codec) < 0)
     129    PRINTF(1)("Could not open codec\n");
     130
     131  // Allocate video frame
     132  frame = avcodec_alloc_frame();
     133  RGB_frame = avcodec_alloc_frame();
     134
     135  // Determine required buffer size and allocate buffer
     136  num_bytes = avpicture_get_size(PIX_FMT_RGB24, codec_context->width, codec_context->height);
     137  buffer=new uint8_t[num_bytes];
     138
     139  // Assign appropriate parts of buffer to image planes in RGB_frame
     140  avpicture_fill((AVPicture *)RGB_frame, buffer, PIX_FMT_RGB24, codec_context->width, codec_context->height);
     141
     142  // Calculate fps
     143  fps = av_q2d(format_context->streams[video_stream]->r_frame_rate);
     144
     145  // duration
     146  duration = format_context->duration / 1000000LL;
     147
     148  // create texture
     149  glGenTextures(1, &texture);
     150  glBindTexture(GL_TEXTURE_2D, texture);
     151  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
     152  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
     153  glTexImage2D(GL_TEXTURE_2D,
     154              0,
     155              GL_RGB,
     156              0, 0,
     157              0,
     158              GL_RGB,
     159              GL_UNSIGNED_BYTE,
     160              NULL);
     161  glBindTexture(GL_TEXTURE_2D, 0);
     162}
     163
     164void MoviePlayer::getNextFrame()
     165{
     166  // get next frame
     167  if(av_read_frame(format_context, &packet) >= 0)
     168  {
     169    // Is this a packet from the video stream?
     170    if(packet.stream_index == video_stream)
     171    {
     172      int frame_finished;
     173      // Decode video frame
     174      avcodec_decode_video(codec_context, frame, &frame_finished,
     175                           packet.data, packet.size);
     176
     177      // Free the packet that was allocated by av_read_frame
     178      av_free_packet(&packet);
     179     
     180      // Did we get a video frame?
     181      if(frame_finished)
     182      {
     183        frame_number++;
     184        //PRINTF(0)("frame_number: %i\n", frame_number);
     185        // Conversion from YUV to RGB
     186        // Most codecs return images in YUV 420 format
     187        // (one luminance and two chrominance channels, with the chrominance
     188        // channels samples at half the spatial resolution of the luminance channel)
     189        img_convert((AVPicture*)RGB_frame, PIX_FMT_RGB24, (AVPicture*)frame,
     190                    codec_context->pix_fmt, codec_context->width, codec_context->height);
     191
     192        data = 0;
     193        data = new uint8_t[codec_context->width*codec_context->height*3*sizeof(uint8_t)];
     194        for(int i = 0; i < codec_context->height; i++)
     195          memcpy(&data[i*codec_context->width*3], ((AVPicture*)RGB_frame)->data[0]+i *
     196                 ((AVPicture*)RGB_frame)->linesize[0],
     197                 codec_context->width*sizeof(uint8_t)*3);
     198
     199//avcodec_flush_buffers(codec_context);
     200
     201        surface = SDL_CreateRGBSurfaceFrom(data, codec_context->width,
     202                                           codec_context->height,24,
     203                                           codec_context->width*sizeof(uint8_t)*3,
     204#if SDL_BYTEORDER == SDL_LIL_ENDIAN // OpenGL RGBA masks
     205                                           0x000000FF,
     206                                           0x0000FF00,
     207                                           0x00FF0000,
     208                                           0
     209#else
     210                                           0xFF000000,
     211                                           0x00FF0000,
     212                                           0x0000FF00,
     213                                           0
     214#endif
     215                                            );
     216
     217        glBindTexture(GL_TEXTURE_2D, texture);
     218        // update the texture
     219        glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0,
     220                          surface->w, surface->h,
     221                          GL_RGB, GL_UNSIGNED_BYTE,
     222                          surface->pixels);
     223        // build the MipMaps
     224        gluBuild2DMipmaps(GL_TEXTURE_2D,
     225                        GL_RGB,
     226                        surface->w,
     227                        surface->h,
     228                        GL_RGB,
     229                        GL_UNSIGNED_BYTE,
     230                        surface->pixels);
     231        glBindTexture(GL_TEXTURE_2D, 0);
     232      }
     233      else
     234      {
     235        av_free_packet(&packet);
     236        this->getNextFrame();
     237      }
     238    }
     239    else
     240    {
     241      av_free_packet(&packet);
     242      this->getNextFrame();
     243    }
     244  }
     245  else
     246    this->stop();
     247}
     248
     249void MoviePlayer::skipFrame(int frames)
     250{
     251 
     252  while(frames != 0)
     253  {
     254    if(av_read_frame(format_context, &packet) < 0)
     255      break;
     256    if(packet.stream_index == video_stream)
     257    {
     258      int frame_finished;
     259      // We have to decode the frame to not get ugly fragments
     260      avcodec_decode_video(codec_context, frame, &frame_finished,
     261                            packet.data, packet.size);
     262       
     263      // Did we get a video frame?
     264      if(frame_finished)
     265      {
     266        frames--;
     267        frame_number++;
     268      }
     269    }
     270    av_free_packet(&packet);
     271  }
     272 
     273  this->getNextFrame();
     274
     275}
     276
     277void MoviePlayer::gotoFrame(int frames)
     278{
     279  // seek doesnt work for the first two frames
     280  // you will get ugly fragments
     281  if(frames < 2)
     282  {
     283    // go to the begin of the video
     284    av_seek_frame(format_context, video_stream, 0, AVSEEK_FLAG_BACKWARD);
     285    frame_number = 0;
     286  }
     287  else
     288  {
     289    // seeks to the nearest keyframe
     290    // NOTE: there is only about every 5s a keyframe!
     291    av_seek_frame(format_context, video_stream, frames, AVSEEK_FLAG_BACKWARD);
     292   
     293    // go from the keyframe to the exact position
     294    codec_context->hurry_up = 1;
     295    do {
     296      av_read_frame(format_context, &packet);
     297      if(packet.pts >= frames-1)
     298        break;
     299      int frame_finished;
     300      avcodec_decode_video(codec_context, frame, &frame_finished, packet.data, packet.size);
     301      av_free_packet(&packet);
     302    } while(1);
     303    codec_context->hurry_up = 0;
     304 
     305    frame_number = frames;
     306  }
    79307}
    80308
     
    83311  status = PLAY;
    84312  timer = 0;
    85   fps = media_container->getFPS();
    86 
    87   media_container->gotoFrame(start_time * fps);
    88 
    89    PRINTF(0)("start (start_time: %0.2f)\n", start_time * fps);
     313
     314  this->gotoFrame(start_time * fps);
     315
     316   PRINTF(0)("start\n");
    90317}
    91318
     
    111338{
    112339  status = STOP;
    113   texture = NULL;
    114340
    115341  PRINTF(0)("stop\n");
     
    120346  if(status == PLAY)
    121347  {
    122     current_frame = media_container->getFrameNumber();
    123348    timer += dt;
    124349    actual_frame = timer * fps * speed;
    125350
    126     if(actual_frame != current_frame)
     351    if(actual_frame != frame_number)
    127352    {
    128       if(actual_frame - current_frame == 1)
    129         texture = media_container->getNextFrame();
     353      if(actual_frame - frame_number == 1)
     354        this->getNextFrame();
    130355      else
    131         texture = media_container->skipFrame(actual_frame - current_frame - 1);
     356        this->skipFrame(actual_frame - frame_number - 1);
    132357    }   
    133     //PRINTF(0)("frame_number: %i\n", media_container->getFrameNumber());
    134 
    135     if(texture == NULL && current_frame != 0)
    136       this->stop();
     358    //PRINTF(0)("frame_number: %i\n", frame_number);
    137359  }
    138360}
     
    162384  return this->status;
    163385}
    164 */
     386
     387void MoviePlayer::printInformation()
     388{
     389  PRINTF(0)("========================\n");
     390  PRINTF(0)("========================\n");
     391  PRINTF(0)("=    MEDIACONTAINER    =\n");
     392  PRINTF(0)("========================\n");
     393  PRINTF(0)("========================\n");
     394  PRINTF(0)("=    AVFormatContext   =\n");
     395  PRINTF(0)("========================\n");
     396  PRINTF(0)("filename: %s\n", format_context->filename);
     397  PRINTF(0)("nb_streams: %i\n", format_context->nb_streams);
     398  PRINTF(0)("duration: (%02d:%02d:%02d)\n", duration/3600, (duration%3600)/60, duration%60);
     399  PRINTF(0)("file_size: %ikb\n", format_context->file_size/1024);
     400  PRINTF(0)("bit_rate: %ikb/s\n", format_context->bit_rate/1000);
     401  PRINTF(0)("nb_frames: %i\n", format_context->streams[video_stream]->nb_frames);
     402  PRINTF(0)("r_frame_rate: %i\n", format_context->streams[video_stream]->r_frame_rate.num);
     403  PRINTF(0)("fps: %0.2f\n", av_q2d(format_context->streams[video_stream]->r_frame_rate));
     404  PRINTF(0)("========================\n");
     405  PRINTF(0)("=    AVCodecContext    =\n");
     406  PRINTF(0)("========================\n");
     407  PRINTF(0)("width: %i\n", codec_context->width);
     408  PRINTF(0)("height: %i\n", codec_context->height);
     409  PRINTF(0)("time_base.den: %i\n", codec_context->time_base.den);
     410  PRINTF(0)("time_base.num: %i\n", codec_context->time_base.num);
     411  PRINTF(0)("========================\n");
     412  PRINTF(0)("=       AVCodec        =\n");
     413  PRINTF(0)("========================\n");
     414  PRINTF(0)("codec name: %s\n", codec->name);
     415  PRINTF(0)("========================\n");
     416  PRINTF(0)("========================\n");
     417}
  • branches/avi_play/src/lib/graphics/importer/movie_player.h

    r6339 r6353  
    44
    55*/
    6 /*
     6
    77#ifndef _MOVIE_PLAYER
    88#define _MOVIE_PLAYER
    99
     10#include <SDL.h>
     11
     12#ifdef HAVE_AVFORMAT_H
     13  #include <avformat.h>
     14#else
     15  #include <ffmpeg/avformat.h>
     16#endif
     17
    1018#include "glincl.h"
    11 //#include "sdlincl.h"
    1219
    13 #include "media_container.h"
    1420#include "light.h"
    1521#include "texture.h"
     
    3238private:
    3339
    34   MediaContainer* media_container;
    3540  Model* model;
    3641  Material* material;
    3742
     43  AVFormatContext* format_context;
     44  AVCodecContext* codec_context;
     45  AVCodec* codec;
     46  AVFrame* frame;
     47  AVPacket packet;
     48  AVFrame* RGB_frame;
     49
     50  SDL_Surface* surface;
    3851  GLuint texture;
     52  uint8_t* data;
     53  uint8_t* buffer;
     54  int num_bytes;
     55  int video_stream;
    3956
    4057  MP_STATUS status;     
     
    4259  float timer;
    4360  int actual_frame;
    44   int current_frame;
    45   float fps; 
     61  int frame_number;
     62  float fps;
     63  int duration; 
    4664
    4765public:
     
    5169  ~MoviePlayer();
    5270
    53   void init();
    5471  void loadMovie(const char* filename);
    5572
     
    6784  void printInformation();
    6885
     86private:
     87 
     88  void init();
     89  void getNextFrame();
     90  void skipFrame(int frames);
     91  void gotoFrame(int frame);
     92
    6993};
    7094
     
    7296
    7397#endif // _MOVIE_PLAYER
    74 */
Note: See TracChangeset for help on using the changeset viewer.