Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/branches/avi_play/src/lib/graphics/importer/media_container.cc @ 6350

Last change on this file since 6350 was 6350, checked in by hdavid, 18 years ago

branches\avi_play

File size: 7.2 KB
RevLine 
[5937]1/*
2   orxonox - the future of 3D-vertical-scrollers
3
4   Copyright (C) 2004 orx
5
6   This program is free software; you can redistribute it and/or modify
7   it under the terms of the GNU General Public License as published by
8   the Free Software Foundation; either version 2, or (at your option)
9   any later version.
10
11### File Specific:
12   main-programmer: David Hasenfratz, Stephan Lienhard
13   co-programmer:
14*/
15
16
17
18/* this is for debug output. It just says, that all calls to PRINT() belong to the DEBUG_MODULE_MEDIA module
19   For more information refere to https://www.orxonox.net/cgi-bin/trac.cgi/wiki/DebugOutput
20*/
21#define DEBUG_MODULE_MEDIA
22
23
24/* include your own header */
25#include "media_container.h"
26
27/* header for debug output */
28#include "debug.h"
29
30
31/**
32 * Default constructor
33 */
[5939]34MediaContainer::MediaContainer(const char* filename)
[5937]35{
[6339]36  // set the class id for the base object
37  this->setClassID(CL_MEDIA_CONTAINER, "MediaContainer");
[5975]38
[6339]39  fps = 0;
40
[5975]41  if (filename != NULL)
[5962]42    this->loadMedia(filename);
[6289]43}
[5962]44
[6289]45MediaContainer::MediaContainer()
46{
[6339]47  // set the class id for the base object
48  this->setClassID(CL_MEDIA_CONTAINER, "MediaContainer");
49
50  fps = 0;
[5937]51}
52
53/**
54 * Default destructor
55 */
56MediaContainer::~MediaContainer()
57{
[6339]58  if (glIsTexture(texture))
59    glDeleteTextures(1, &texture);
[6163]60  SDL_FreeSurface(surface);
[6149]61
[6068]62  // Free the RGB image
63  delete [] buffer;
64  av_free(RGB_frame);
[5937]65
[6339]66  // Free the frame
[6003]67  av_free(frame);
68
[6339]69  // Close the codec
[6003]70  avcodec_close(codec_context);
71
[6339]72  // Close the video file
[6003]73  av_close_input_file(format_context);
[5937]74}
75
[6339]76void MediaContainer::loadMedia(const char* filename)
[6290]77{
[6339]78  // register all formats and codecs
[6290]79  av_register_all();
80
[6339]81  // Open video file
82  if (av_open_input_file(&format_context, filename, NULL, 0, NULL) !=0 )
83    PRINTF(1)("Could not open %s\n", filename);
[6290]84
[6339]85  // Retrieve stream information
86  if (av_find_stream_info(format_context) < 0)
87    PRINTF(1)("Could not find stream information in %s\n", filename);
88
89  // Find the first video stream and take it
90  video_stream = -1;
91  for(int i = 0; i < format_context->nb_streams; i++)
[6323]92  {
[6339]93    // NOTE: different code for the 0.4.9-pre1 release of ffmpeg (tardis)
94    // if(format_context->streams[i]->codec.codec_type == CODEC_TYPE_VIDEO)
95    if(format_context->streams[i]->codec->codec_type == CODEC_TYPE_VIDEO)
96    {
97      video_stream = i;
98      break;
99    }
[6323]100  }
[6339]101
102  if(video_stream == -1)
103    PRINTF(1)("Could not find a video stream in %s\n", filename);
104
105  // Get a pointer to the codec context for the video stream
106  // NOTE: different code for the 0.4.9-pre1 release of ffmpeg (tardis)
107  // codec_context = &format_context->streams[video_stream]->codec;
108  codec_context = format_context->streams[video_stream]->codec;
109
110  // Find the decoder for the video stream
111  codec = avcodec_find_decoder(codec_context->codec_id);
112  if (codec == NULL)
113    PRINTF(1)("Could not find codec\n");
114
115  // Open codec
116  if (avcodec_open(codec_context, codec) < 0)
117    PRINTF(1)("Could not open codec\n");
118
119  // Allocate video frame
120  frame = avcodec_alloc_frame();
121  RGB_frame = avcodec_alloc_frame();
122
123  // Determine required buffer size and allocate buffer
124  num_bytes = avpicture_get_size(PIX_FMT_RGB24, codec_context->width, codec_context->height);
125  buffer=new uint8_t[num_bytes];
126
127  // Assign appropriate parts of buffer to image planes in pFrameRGB
128  avpicture_fill((AVPicture *)RGB_frame, buffer, PIX_FMT_RGB24, codec_context->width, codec_context->height);
129
130  // Calculate fps
131  fps = av_q2d(format_context->streams[video_stream]->r_frame_rate);
132
133  // read the frames and save them in a sequence as textures
134  this->loadFrames();
[5937]135}
136
[6339]137double MediaContainer::getFPS()
138{
139  return this->fps;
140}
141
142void MediaContainer::loadFrames()
143{
[6350]144  // empty texture list
145  this->clearLists();
146
[6339]147  // go to the begin of the video
148  av_seek_frame(format_context, video_stream, 0, AVSEEK_FLAG_BACKWARD);
149
150  // get all the frames and save them in the sequence
151  while(this->addFrame(this->getNextFrame()) != NULL);
152}
153
154
[6317]155GLuint MediaContainer::getNextFrame()
[5937]156{
[6350]157  //if (glIsTexture(texture))
158  //  glDeleteTextures(1, &texture);
159
[6339]160  // get next frame
[6068]161  if(av_read_frame(format_context, &packet) >= 0)
162  {
[6339]163    // Is this a packet from the video stream?
[6068]164    if(packet.stream_index == video_stream)
165    {
166      int frame_finished;
167      // Decode video frame
[6163]168      avcodec_decode_video(codec_context, frame, &frame_finished,
169                           packet.data, packet.size);
[6003]170
[6317]171      // Free the packet that was allocated by av_read_frame
172      av_free_packet(&packet);
173     
[6068]174      // Did we get a video frame?
175      if(frame_finished)
176      {
[6149]177        // Conversion from YUV to RGB
178        // Most codecs return images in YUV 420 format
179        // (one luminance and two chrominance channels, with the chrominance
180        // channels samples at half the spatial resolution of the luminance channel)
[6163]181        img_convert((AVPicture*)RGB_frame, PIX_FMT_RGB24, (AVPicture*)frame,
182                    codec_context->pix_fmt, codec_context->width, codec_context->height);
[6094]183
[6112]184        data = 0;
185        data = new uint8_t[codec_context->width*codec_context->height*3*sizeof(uint8_t)];
186        for(int i = 0; i < codec_context->height; i++)
[6339]187          memcpy(&data[i*codec_context->width*3],
188                 ((AVPicture*)RGB_frame)->data[0]+i *
189                 ((AVPicture*)RGB_frame)->linesize[0], 
190                  codec_context->width*sizeof(uint8_t)*3);
[6112]191
[6163]192        surface = SDL_CreateRGBSurfaceFrom(data, codec_context->width,
193                                           codec_context->height,24,
194                                           codec_context->width*sizeof(uint8_t)*3,
[6339]195#if SDL_BYTEORDER == SDL_LIL_ENDIAN // OpenGL RGBA masks
[6163]196                                           0x000000FF,
197                                           0x0000FF00,
198                                           0x00FF0000,
199                                           0
200#else
201                                           0xFF000000,
202                                           0x00FF0000,
203                                           0x0000FF00,
204                                           0
205#endif
206                                            );
[6112]207
[6339]208        // Create an OpenGL texture from the surface
209        glGenTextures(1, &texture);
210        glBindTexture(GL_TEXTURE_2D, texture);
211        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
212        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
213        // create the texture
214        glTexImage2D(GL_TEXTURE_2D,
215                    0,
216                    GL_RGB,
217                    surface->w, surface->h,
218                    0,
219                    GL_RGB,
220                    GL_UNSIGNED_BYTE,
221                    surface->pixels);
222        // build the MipMaps
223        gluBuild2DMipmaps(GL_TEXTURE_2D,
224                        GL_RGB,
225                        surface->w,
226                        surface->h,
227                        GL_RGB,
228                        GL_UNSIGNED_BYTE,
229                        surface->pixels);
230        glBindTexture(GL_TEXTURE_2D, 0);
231       
[6317]232        return texture;
[6068]233      }
[6339]234      else
235      {
236        av_free_packet(&packet);
237        this->getNextFrame();
238      }
[6068]239    }
[6317]240    else
241    {
242      av_free_packet(&packet);
243      this->getNextFrame();
244    }
[6068]245  }
246  else
247    return NULL;
248}
Note: See TracBrowser for help on using the repository browser.