PageRenderTime 10ms CodeModel.GetById 16ms app.highlight 113ms RepoModel.GetById 1ms app.codeStats 1ms

/core/Decoder.cpp

https://bitbucket.org/jwalraven/fobs-mac-64x
C++ | 1623 lines | 1321 code | 150 blank | 152 comment | 307 complexity | 859380510549307d14973e13495ffb0a MD5 | raw file
   1/******************************************************************************
   2* FOBS C++ wrapper code 
   3* Copyright (c) 2004 Omnividea Multimedia S.L
   4* Coded by Jos´┐Ż San Pedro Wandelmer
   5*
   6*    This file is part of FOBS.
   7*
   8*    FOBS is free software; you can redistribute it and/or modify
   9*    it under the terms of the GNU Lesser General Public License as
  10*    published by the Free Software Foundation; either version 2.1 
  11*    of the License, or (at your option) any later version.
  12*
  13*    FOBS is distributed in the hope that it will be useful,
  14*    but WITHOUT ANY WARRANTY; without even the implied warranty of
  15*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  16*    GNU Lesser General Public License for more details.
  17*
  18*    You should have received a copy of the GNU Lesser General Public
  19*    License along with FOBS; if not, write to the Free Software
  20*    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  21******************************************************************************/
  22
  23
  24extern "C"
  25{
  26#include "libavformat/avformat.h"
  27#include "libavdevice/avdevice.h"
  28#include "libswscale/swscale.h"
  29#include "libavcodec/opt.h"
  30#include "libavutil/fifo.h"
  31#include "libavutil/avstring.h"
  32}
  33
  34#include "Decoder.h"
  35#include <iostream>
  36#include "PacketBuffer.h"
  37
  38using namespace std;
  39using namespace omnividea::fobs;
  40
  41class _AVInit
  42{
  43   public:
  44   _AVInit()
  45   {
  46	  avcodec_register_all();
  47	  //avdevice_register_all();
  48      av_register_all();
  49   }
  50   ~_AVInit()
  51   {
  52      //av_free_static();
  53   }
  54};
  55static _AVInit __singleton;
  56
  57static enum CodecID find_codec(const char *name, int type, int encoder)
  58{
  59    const char *codec_string = encoder ? "encoder" : "decoder";
  60    AVCodec *codec;
  61	
  62    if(!name)
  63        return CODEC_ID_NONE;
  64    codec = encoder ?
  65	avcodec_find_encoder_by_name(name) :
  66	avcodec_find_decoder_by_name(name);
  67    if(!codec) {
  68		return CODEC_ID_NONE;
  69    }
  70    if(codec->type != type) {
  71		return CODEC_ID_NONE;
  72    }
  73    return codec->id;
  74}
  75
  76void Decoder::setAudioResampleFlag(bool flag)
  77{
  78	this->audioResampleFlag = flag;
  79}
  80
  81
  82FrameIndex Decoder::frameIndexFromTimeStamp(TimeStamp t)
  83{
  84    return (FrameIndex)(t / FOBS_TIMESTAMP_UNITS_D * getFrameRate());
  85}
  86TimeStamp Decoder::timeStampFromFrameIndex(FrameIndex f)
  87{
  88    return (TimeStamp)((double)f / (double)getFrameRate() * FOBS_TIMESTAMP_UNITS_D);
  89}
  90
  91bool Decoder::compareTimeStamps(TimeStamp t1, TimeStamp t2)
  92{
  93    bool res =  false;
  94    if(isVideoPresent()) res = ::abs(t2-t1) <= 1000.0/getFrameRate();
  95    else res = ::abs(t2-t1) <= 1000.0/getAudioSampleRate();
  96    //cout << "T1: " << t1 << " == T2: " << t2 << " : " << res << endl;
  97    return res;
  98}
  99
 100TimeStamp Decoder::pts2TimeStamp(int64_t pts, AVRational *pts_timebase) {
 101	//cout << "(Pts) " << pts << "* (Base Num)" << pts_timebase->num << "/ (double)(Base Den)"<<pts_timebase->den<<"*"<<FOBS_TIMESTAMP_UNITS_D<<endl;
 102	TimeStamp t= (TimeStamp)(pts*pts_timebase->num/(double)pts_timebase->den*FOBS_TIMESTAMP_UNITS_D);
 103	//cout << "Result: " << t <<endl;
 104	return t;
 105   }
 106int64_t Decoder::timeStamp2pts(TimeStamp ts, AVRational *pts_timebase) {
 107	return (int64_t)(ts * (double)pts_timebase->den / pts_timebase->num / FOBS_TIMESTAMP_UNITS_D);
 108   }
 109
 110ReturnCode Decoder::testOpen()
 111{
 112   ReturnCode error = opened?OkCode:NotInitializedError;
 113   return error;
 114}
 115ReturnCode Decoder::testClose()
 116{
 117   ReturnCode error = (!opened)?OkCode:AlreadyInitializedError;
 118   return error;
 119}
 120
 121Decoder::Decoder(const char *filename)
 122{
 123   strcpy(this->filename,filename);
 124   audioEnabledFlag = false;
 125   audioResampleFlag = false;
 126   incorrectPts = false;
 127   
 128   //derived from static members 
 129   yuvPicture = new AVPicture();
 130   rgbPicture = new AVPicture();
 131   rgbaPicture = new AVPicture();
 132   decodedPicture = new AVPicture();
 133   transitionPicture = new AVPicture();
 134   transitionPictureRgb = new AVPicture();   
 135   videoBuffer = new PacketBuffer();
 136   audioBuffer = new PacketBuffer();
 137
 138    reset();
 139}
 140Decoder::~Decoder()
 141{
 142   close();
 143   
 144   delete yuvPicture;
 145   delete rgbPicture;
 146   delete rgbaPicture;
 147   delete decodedPicture;
 148   delete transitionPicture;
 149   delete transitionPictureRgb;
 150   delete videoBuffer;
 151   delete audioBuffer;
 152}
 153
 154void Decoder::reset()
 155{
 156   rgbBuf = NULL;
 157   rgbaBuf = NULL;
 158   yuvBuf = NULL;
 159   yuvBytes = NULL;
 160   opened = false;
 161
 162   img_resample_ctx = NULL;
 163   audioResampler = NULL;
 164   inputFile = NULL;
 165   inputFileFormat = NULL;
 166   transitionPictureBuf = NULL;
 167   transitionPictureBufRgb = NULL;
 168   currentYuv = currentRgb = currentRgba = 0;
 169   currentYuvFlag = false;
 170   currentRgbFlag = false;
 171   currentRgbaFlag = false;
 172   position = 0;
 173   positionAudio = 0;
 174   frameFlag = false;
 175
 176
 177   videoStreamIndex = -1; 
 178   audioStreamIndex = -1;
 179   
 180   videoBuffer->clear();
 181   audioBuffer->clear();
 182
 183
 184}
 185ReturnCode Decoder::close()
 186{
 187   ReturnCode error = testOpen();
 188   if(isOk(error))
 189   {
 190      av_free(rgbBuf);
 191      av_free(rgbaBuf);
 192      av_free(yuvBuf);
 193      delete []yuvBytes;
 194   
 195      if(videoStreamIndex >= 0 && inputFile->streams[videoStreamIndex] != NULL)
 196      {
 197        avcodec_close(inputFile->streams[videoStreamIndex]->codec);
 198         //av_free(inputStream.st);
 199      }
 200      if(audioStreamIndex >= 0 && inputFile->streams[audioStreamIndex] != NULL)
 201      {
 202        avcodec_close(inputFile->streams[audioStreamIndex]->codec);
 203      }
 204      av_close_input_file(inputFile);
 205      av_free(inputFileFormat);
 206      av_free(transitionPictureBuf);
 207      av_free(transitionPictureBufRgb);
 208      //if(img_resample_ctx)img_resample_close(img_resample_ctx);
 209      if(img_resample_ctx)sws_freeContext(img_resample_ctx);
 210      if(audioResampler)audio_resample_close(audioResampler);
 211      reset();
 212   }
 213
 214
 215   return error;
 216}
 217
 218
 219ReturnCode Decoder::_open()
 220{
 221	int ret;
 222
 223	
 224	
 225   AVFormatParameters params, *ap = &params;
 226   ReturnCode error = testClose();
 227
 228   if(isOk(error))
 229   {
 230	   /* get default parameters  */
 231	   int audio_sample_rate = 44100;
 232	   int audio_channels = 1;
 233	   AVRational frame_rate = (AVRational) {0,0};
 234	   int frame_width  = 0;
 235	   int frame_height = 0;
 236	   int frame_padtop  = 0;
 237	   int frame_padbottom = 0;
 238	   int frame_padleft  = 0;
 239	   int frame_padright = 0;
 240	   enum PixelFormat frame_pix_fmt = PIX_FMT_NONE;
 241	   int  video_channel = 0;
 242	   char  *audio_codec_name = NULL;
 243	   char  *video_codec_name = NULL;
 244	   
 245	   
 246	   inputFile = av_alloc_format_context();
 247	   
 248	   memset(ap, 0, sizeof(*ap));
 249	   ap->prealloced_context = 1;
 250	   ap->sample_rate = audio_sample_rate;
 251	   ap->channels = audio_channels;
 252	   ap->time_base.den = frame_rate.num;
 253	   ap->time_base.num = frame_rate.den;
 254	   ap->width = frame_width + frame_padleft + frame_padright;
 255	   ap->height = frame_height + frame_padtop + frame_padbottom;
 256	   ap->pix_fmt = frame_pix_fmt;
 257	   ap->channel = video_channel;
 258	   ap->video_codec_id = find_codec(video_codec_name, CODEC_TYPE_VIDEO, 0);
 259	   ap->audio_codec_id = find_codec(audio_codec_name, CODEC_TYPE_AUDIO, 0);
 260
 261	   //AVFormatContext *avformat_opts = av_alloc_format_context();
 262	   //set_context_opts(inputFile, avformat_opts, AV_OPT_FLAG_DECODING_PARAM);
 263	   
 264	   inputFile->video_codec_id   = find_codec(video_codec_name   , CODEC_TYPE_VIDEO   , 0);
 265	   inputFile->audio_codec_id   = find_codec(audio_codec_name   , CODEC_TYPE_AUDIO   , 0);
 266	   
 267      /* open the input file with generic libav function */
 268      ret = av_open_input_file(&inputFile, filename, inputFileFormat, 0, ap);
 269      if (ret < 0) 
 270      {
 271         error = FileOpenError;
 272      }
 273   }
 274   if(isOk(error))
 275   {
 276      /* If not enough info to get the stream parameters, we decode the
 277       first frames to get it. (used in mpeg case for example) */
 278      ret = av_find_stream_info(inputFile);
 279      if (ret < 0) {
 280         error = FormatUnsupportedError;
 281      }
 282   }
 283
 284   /*
 285   if(isOk(error))
 286   {
 287      dump_format(inputFile, 1, filename.c_str(), 0);
 288   }
 289   */
 290   
 291   if(isOk(error))
 292   {
 293      //eofReachedFlag = false;
 294      
 295      int discard = 1;
 296      //Get just two streams...First Video & First Audio
 297      for(int i=0; i < inputFile->nb_streams; i++) 
 298      {
 299         if(inputFile->streams[i]->codec->codec_type == CODEC_TYPE_VIDEO && videoStreamIndex == -1)
 300         {
 301            discard = 0;
 302            videoStreamIndex = i;
 303         }
 304         else if(inputFile->streams[i]->codec->codec_type == CODEC_TYPE_AUDIO && audioStreamIndex == -1)
 305         {
 306            discard = 0;
 307            audioStreamIndex = i;
 308         }
 309
 310      }
 311      if(discard == 1)
 312      {
 313         error = VideoStreamMissingError;
 314      }
 315   }
 316
 317   if(isOk(error))
 318   {
 319      //test initialization of variables
 320      if(isVideoPresent() && (_getWidth()==0 || _getHeight() == 0))
 321      {
 322        error = FormatUnsupportedError;
 323      }
 324   }
 325
 326	if(isOk(error) && isAudioPresent())
 327	{
 328		//cout << "Audio Resample Flag: "<<audioResampleFlag<<endl;
 329		if(inputFile->streams[audioStreamIndex]->codec->channels > 2 && audioResampleFlag)
 330		{
 331			inputFile->streams[audioStreamIndex]->codec->channels = 2;
 332			inputFile->streams[audioStreamIndex]->codec->request_channels=2;
 333			//audioResampler = audio_resample_init(2, inputFile->streams[audioStreamIndex]->codec->channels, getAudioSampleRate(), getAudioSampleRate());
 334			//cout << "AudioResampler will be needed: " << audioResampler << endl;
 335		}
 336	}
 337	
 338   if(isOk(error))
 339   {
 340     AVCodec *codec;
 341     if(videoStreamIndex >= 0)
 342     {
 343       codec = avcodec_find_decoder(inputFile->streams[videoStreamIndex]->codec->codec_id);
 344       if (!codec) 
 345       {
 346           error = CodecUnsupportedError;
 347       }
 348       else if (avcodec_open(inputFile->streams[videoStreamIndex]->codec, codec) < 0) 
 349       {
 350           error = CodecUnsupportedError;
 351       }
 352     }
 353     if(audioStreamIndex >= 0)
 354     {
 355       codec = avcodec_find_decoder(inputFile->streams[audioStreamIndex]->codec->codec_id);
 356       if (!codec) 
 357       {
 358           //error = CodecUnsupportedError;
 359           audioStreamIndex = -1;
 360           cout << "Audio codec unsupported!\n";
 361       }
 362       else if (avcodec_open(inputFile->streams[audioStreamIndex]->codec, codec) < 0) 
 363       {
 364           //error = CodecUnsupportedError;
 365           audioStreamIndex = -1;
 366           cout << "Audio codec unsupported!\n";
 367       }
 368     }
 369   }
 370
 371   if(isOk(error) && isVideoPresent())
 372   {
 373      yuvBytes = new char[_getWidth()*_getHeight()];
 374      if(yuvBytes == NULL)
 375      {
 376         error = MemoryError;
 377      }
 378   }
 379   if(isOk(error))
 380   {
 381	   if(firstVideoPositionFlag == false)
 382	   {
 383		   firstVideoPosition = 0;
 384		   firstVideoFramePosition = -1;
 385	   }
 386   	   if(firstAudioPositionFlag == false)
 387	   {
 388		   firstAudioPosition = 0;
 389		   firstAudioFramePosition = -1;
 390	   }
 391      opened = true;
 392   }
 393   
 394   return error;
 395}
 396ReturnCode Decoder::open()
 397{
 398   ReturnCode error = testClose();
 399   if(isError(error)) return error;
 400   
 401   reset();
 402   firstVideoPositionFlag = false;
 403   firstAudioPositionFlag = false;
 404  
 405   error = _open();
 406
 407   //find first video frame
 408   if(isVideoPresent())
 409   {
 410       while((isOk(error)|| error == NoFrameError) && firstVideoFramePosition == -1) error = nextFrame();
 411   }
 412   else
 413   {
 414       while((isOk(error)|| error == NoFrameError) && firstAudioFramePosition == -1) error = nextAudioFrame();
 415   }
 416
 417   if(isOk(error))
 418   {
 419      if(inputFile->duration == (TimeStamp)AV_NOPTS_VALUE) 
 420      {
 421        if(isVideoPresent())
 422        {
 423            while(placeAtNextFrame(true) == 0)
 424            {
 425              videoBuffer->deleteNext();
 426              duration =  position;
 427            }
 428            if(duration == 0)
 429            {
 430               error = FormatUnsupportedError;
 431            }
 432        }
 433        else
 434        {
 435            while(placeAtNextFrame(false) == 0)
 436            {
 437              audioBuffer->deleteNext();
 438              duration =  positionAudio;
 439            }
 440            if(duration == 0)
 441            {
 442               error = FormatUnsupportedError;
 443            }            
 444        }
 445      }
 446      else
 447      {
 448          cout << ((double)inputFile->duration/(double)AV_TIME_BASE);
 449          duration = (TimeStamp) ((double)inputFile->duration*FOBS_TIMESTAMP_UNITS_D/(double)AV_TIME_BASE);
 450      }
 451
 452
 453      cout << "First Position: " << firstVideoPosition << ", " << firstVideoFramePosition << " Duration: " << duration << endl;
 454      if(isVideoPresent())cout << "Frame Rate: " << getFrameRate() << endl;
 455   }
 456
 457   close();
 458   
 459   if(isOk(error))
 460   {
 461      return _open();
 462   }
 463      
 464   return error;
 465}
 466
 467double Decoder::getFirstFrameTime()
 468{
 469  return firstVideoFramePosition / FOBS_TIMESTAMP_UNITS_D;
 470}
 471double Decoder::getFirstAudioSampleTime()
 472{
 473  return firstAudioFramePosition / FOBS_TIMESTAMP_UNITS_D;
 474}
 475
 476omnividea::fobs::uint Decoder::getWidth()
 477{
 478   ReturnCode error = testOpen();
 479   if(isOk(error))
 480   {
 481      return _getWidth();
 482   }
 483   else
 484   {
 485      return 0;
 486   }
 487}
 488omnividea::fobs::uint Decoder::_getWidth()
 489{
 490   return inputFile->streams[videoStreamIndex]->codec->width;
 491}
 492omnividea::fobs::uint Decoder::getHeight()
 493{
 494   ReturnCode error = testOpen();
 495   if(isOk(error))
 496   {
 497      return _getHeight();
 498   }
 499   else
 500   {
 501      return 0;
 502   }
 503}
 504omnividea::fobs::uint Decoder::_getHeight()
 505{
 506   return inputFile->streams[videoStreamIndex]->codec->height;
 507}
 508int Decoder::getBitRate()
 509{
 510   ReturnCode error = testOpen();
 511   if(isOk(error))
 512   {
 513      int res = inputFile->streams[videoStreamIndex]->codec->bit_rate / 1000;
 514      if(res == 0) res = inputFile->bit_rate / 1000;
 515      return res;
 516   }
 517   else
 518   {
 519      return 0;
 520   }
 521}
 522double Decoder::getFrameRate()
 523{
 524   ReturnCode error = testOpen();
 525   if(isOk(error))
 526   {
 527      //return (double)inputStream.st->codec.frame_rate / DEFAULT_FRAME_RATE_BASE; //For ffmpeg-0.4.6
 528      //cout << "FR: " << inputFile->streams[videoStreamIndex]->codec.frame_rate << " - Base: " << inputFile->streams[videoStreamIndex]->codec.frame_rate_base << endl;
 529      
 530      //return (double)inputFile->streams[videoStreamIndex]->codec->time_base.den / (double)inputFile->streams[videoStreamIndex]->codec->time_base.num; //For ffmpeg-0.4.8
 531      return (double)inputFile->streams[videoStreamIndex]->r_frame_rate.num / (double)inputFile->streams[videoStreamIndex]->r_frame_rate.den;
 532   }
 533   else
 534   {
 535      return -1;
 536   }
 537}
 538TimeStamp Decoder::getDurationMilliseconds()
 539{
 540   return duration;
 541}
 542double Decoder::getDurationSeconds()
 543{
 544   return duration/FOBS_TIMESTAMP_UNITS_D;
 545}
 546
 547byte Decoder::getCrFactor()
 548{
 549   return 2;
 550}
 551byte Decoder::getCbFactor()
 552{
 553   return 2;
 554}
 555
 556byte *Decoder::getLuminance()
 557{
 558   if(testOpen() != 0) return NULL;
 559   int ret;
 560   AVPicture *tmpPicture;
 561   enum PixelFormat pix_fmt=PIX_FMT_YUV420P;
 562   AVCodecContext *dec = inputFile->streams[videoStreamIndex]->codec;
 563
 564   if(currentYuvFlag && compareTimeStamps(position, currentYuv))
 565   {
 566      return (byte *)yuvBytes;
 567   }
 568   
 569   /* convert pixel format if needed */
 570   if(pix_fmt == dec->pix_fmt) 
 571   {
 572      tmpPicture = decodedPicture;
 573   }
 574   else
 575   {
 576      /* create temporary picture */
 577      if(yuvPicture->data[0] == NULL)
 578      {
 579         int size = avpicture_get_size(pix_fmt, dec->width, dec->height);
 580         yuvBuf = (uint8_t *)av_malloc(size);
 581         if (!yuvBuf)
 582         {
 583            return NULL;
 584         }
 585         avpicture_fill(yuvPicture, yuvBuf, pix_fmt, dec->width, dec->height);
 586      }
 587     
 588      ret = img_convert(yuvPicture, pix_fmt, 
 589                       decodedPicture, dec->pix_fmt, 
 590                       dec->width, dec->height);
 591      if(ret < 0) 
 592      {
 593         return NULL;
 594      }
 595      tmpPicture = yuvPicture;
 596   }
 597
 598   unsigned long offset = 0, srcOffset = 0;
 599   for(unsigned i = 0; i < _getHeight(); i++)
 600   {
 601      memcpy(yuvBytes+offset, tmpPicture->data[0]+srcOffset, getWidth());
 602      offset+=getWidth();
 603      srcOffset += decodedPicture->linesize[0];
 604   }
 605   currentYuv = position;
 606   currentYuvFlag = true;
 607   return (byte *)yuvBytes;
 608}
 609
 610byte *Decoder::getCr()
 611{
 612   if(testOpen() != 0) return NULL;
 613   AVCodecContext *dec = inputFile->streams[videoStreamIndex]->codec;
 614   enum PixelFormat pix_fmt=PIX_FMT_YUV420P;
 615   getLuminance();
 616   if(pix_fmt == dec->pix_fmt) 
 617   {
 618      return (byte *)(decodedPicture->data[1]);
 619   }
 620   else
 621   {
 622      return (byte *)(yuvPicture->data[1]);
 623   }
 624}
 625byte *Decoder::getCb()
 626{
 627   if(testOpen() != 0) return NULL;
 628   AVCodecContext *dec = inputFile->streams[videoStreamIndex]->codec;
 629   enum PixelFormat pix_fmt=PIX_FMT_YUV420P;
 630   getLuminance();
 631   if(pix_fmt == dec->pix_fmt) 
 632   {
 633      return (byte *)(decodedPicture->data[2]);
 634   }
 635   else
 636   {
 637      return (byte *)(yuvPicture->data[2]);
 638   }
 639}
 640
 641ReturnCode Decoder::reallocTransitionPicture(int newWidth, int newHeight)
 642{
 643   ReturnCode error = OkCode;
 644   AVCodecContext *dec = inputFile->streams[videoStreamIndex]->codec;
 645   enum PixelFormat pix_fmt = dec->pix_fmt;
 646   if(transitionPictureBuf == NULL || 
 647      transitionPictureWidth != newWidth || 
 648      transitionPictureHeight != newHeight)
 649   {
 650      av_free(transitionPictureBuf);
 651      av_free(transitionPictureBufRgb);
 652      transitionPictureBuf = NULL;
 653      transitionPictureBufRgb = NULL;
 654      if(img_resample_ctx) sws_freeContext(img_resample_ctx);
 655      //if(img_resample_ctx)img_resample_close(img_resample_ctx);
 656      img_resample_ctx = NULL;
 657      int size = avpicture_get_size(pix_fmt, newWidth, newHeight);
 658      int sizeRgb = avpicture_get_size(PIX_FMT_RGB24, newWidth, newHeight);
 659      //cerr << "Decoder Transition: size=" << size << " sizeRgb=" << sizeRgb << " W=" << newWidth << " H=" << newHeight << endl;
 660      transitionPictureBuf = (uint8_t*)av_malloc(size);
 661      if (!transitionPictureBuf)
 662      {
 663         error = MemoryError;
 664      }
 665      if(isOk(error))
 666      {
 667         transitionPictureBufRgb = (uint8_t*)av_malloc(sizeRgb);
 668         if (!transitionPictureBufRgb)
 669         {
 670            error = MemoryError;
 671         }
 672      }
 673      if(isOk(error))
 674      {
 675         enum PixelFormat pix_fmt;
 676         AVPicture *pict;
 677         error = getRawFrame(&pict, (int *)&pix_fmt);
 678         if(isOk(error))
 679         {
 680            img_resample_ctx = sws_getContext(
 681                            this->_getWidth(), this->_getHeight(), pix_fmt,
 682                            newWidth, newHeight, pix_fmt,
 683                            0, NULL, NULL, NULL);
 684            //img_resample_ctx = img_resample_init( newWidth, newHeight, this->_getWidth(), this->_getHeight());
 685            if(img_resample_ctx == NULL)
 686            {
 687                error = MemoryError;
 688            }
 689        }
 690      }
 691      if(isOk(error))
 692      {
 693         avpicture_fill(transitionPicture, transitionPictureBuf, pix_fmt, newWidth, newHeight);
 694         avpicture_fill(transitionPictureRgb, transitionPictureBufRgb, PIX_FMT_RGB24, newWidth, newHeight);
 695         transitionPictureWidth = newWidth;
 696         transitionPictureHeight = newHeight;
 697      }
 698   }
 699   return error;
 700}
 701
 702byte *Decoder::getRGB(int width, int height)
 703{
 704   AVPicture *pict;
 705   enum PixelFormat pix_fmt;
 706   ReturnCode error = getRawFrame(&pict, (int *)&pix_fmt);
 707   if(isError(error)) return NULL;
 708
 709   enum PixelFormat dst_pix_fmt=PIX_FMT_RGB24;
 710
 711   if(reallocTransitionPicture(width, height) == 0)
 712   {
 713      //img_resample(img_resample_ctx, transitionPicture, decodedPicture);
 714      sws_scale(img_resample_ctx, decodedPicture->data, decodedPicture->linesize, 0, transitionPictureHeight/*?*/, transitionPicture->data, transitionPicture->linesize);
 715      if(img_convert(transitionPictureRgb, dst_pix_fmt,transitionPicture, pix_fmt, width, height) < 0)
 716      {
 717         return NULL;
 718      }
 719   }
 720   else
 721   {
 722      return NULL;
 723   }
 724   return (byte *)transitionPictureRgb->data[0];
 725}
 726
 727byte *Decoder::getRGB()
 728{
 729   if(testOpen() != 0) return NULL;
 730   int ret;
 731   AVPicture *tmpPicture;
 732   enum PixelFormat pix_fmt=PIX_FMT_RGB24;
 733   AVCodecContext *dec = inputFile->streams[videoStreamIndex]->codec;
 734   
 735   if(currentRgbFlag && compareTimeStamps(position, currentRgb))
 736   {
 737      if(pix_fmt == dec->pix_fmt) 
 738      {
 739         return (byte *)decodedPicture->data[0];
 740      }
 741      else
 742      {
 743         return (byte *)rgbPicture->data[0];
 744      }
 745   }
 746
 747
 748   /* convert pixel format if needed */
 749   if(pix_fmt == dec->pix_fmt) 
 750   {
 751      tmpPicture = decodedPicture;
 752   }
 753   else
 754   {
 755      /* create temporary picture */
 756      if(rgbBuf == NULL)
 757      {
 758         int size = avpicture_get_size(pix_fmt, dec->width, dec->height);
 759         rgbBuf = (uint8_t *)av_malloc(size);
 760         if (!rgbBuf)
 761         {
 762            return NULL;
 763         }
 764         avpicture_fill(rgbPicture, rgbBuf, pix_fmt, dec->width, dec->height);
 765      }
 766     
 767      ret = img_convert(rgbPicture, pix_fmt, 
 768                       decodedPicture, dec->pix_fmt, 
 769                       dec->width, dec->height);
 770      if(ret < 0) 
 771      {
 772         return NULL;
 773      }
 774      tmpPicture = rgbPicture;
 775   }
 776   currentRgb = position;
 777   currentRgbFlag = true;
 778   return (byte *)tmpPicture->data[0];
 779}
 780
 781byte *Decoder::getRGBA()
 782{
 783   if(testOpen() != 0) return NULL;
 784   int ret;
 785   AVPicture *tmpPicture;
 786   enum PixelFormat pix_fmt=PIX_FMT_RGBA32;
 787   AVCodecContext *dec = inputFile->streams[videoStreamIndex]->codec;
 788   
 789   if(currentRgbaFlag && compareTimeStamps(position, currentRgba))
 790   {
 791      if(pix_fmt == dec->pix_fmt) 
 792      {
 793         return (byte *)decodedPicture->data[0];
 794      }
 795      else
 796      {
 797         return (byte *)rgbaPicture->data[0];
 798      }
 799   }
 800
 801
 802   /* convert pixel format if needed */
 803   if(pix_fmt == dec->pix_fmt) 
 804   {
 805      tmpPicture = decodedPicture;
 806   }
 807   else
 808   {
 809      /* create temporary picture */
 810      if(rgbaBuf == NULL)
 811      {
 812         int size = avpicture_get_size(pix_fmt, dec->width, dec->height);
 813         rgbaBuf = (uint8_t *)av_malloc(size);
 814         if (!rgbaBuf)
 815         {
 816            return NULL;
 817         }
 818         avpicture_fill(rgbaPicture, rgbaBuf, pix_fmt, dec->width, dec->height);
 819      }
 820     
 821      ret = img_convert(rgbaPicture, pix_fmt, 
 822                       decodedPicture, dec->pix_fmt, 
 823                       dec->width, dec->height);
 824      if(ret < 0) 
 825      {
 826         return NULL;
 827      }
 828      tmpPicture = rgbaPicture;
 829   }
 830   currentRgba = position;
 831   currentRgbaFlag = true;
 832   return (byte *)tmpPicture->data[0];
 833}
 834
 835byte *Decoder::getRGBA(char *buf)
 836{
 837   if(testOpen() != 0) return NULL;
 838   int ret;
 839   enum PixelFormat pix_fmt=PIX_FMT_RGBA32;
 840   AVCodecContext *dec = inputFile->streams[videoStreamIndex]->codec;
 841   
 842   {
 843      AVPicture tmpPicture;
 844      avpicture_fill(&tmpPicture, (uint8_t *)buf, pix_fmt, dec->width, dec->height);    
 845      ret = img_convert(&tmpPicture, pix_fmt, 
 846                       decodedPicture, dec->pix_fmt, 
 847                       dec->width, dec->height);
 848      if(ret < 0) 
 849      {
 850         return NULL;
 851      }
 852   }
 853   return (byte *)buf;
 854}
 855
 856ReturnCode Decoder::getRawFrame(AVPicture** pict, int* pix_fmt)
 857{
 858   ReturnCode error = testOpen();
 859   if(isOk(error))
 860   {
 861      AVCodecContext *dec = inputFile->streams[videoStreamIndex]->codec;
 862      *pix_fmt = (int)dec->pix_fmt;
 863      *pict = decodedPicture;
 864   }
 865
 866   return error;
 867}
 868
 869uint8_t* Decoder::getAudioSamples()
 870{
 871  //cout << "Requesting audio frame. Size="<<decodedAudioFrameSize;
 872  //cout << " which should be about "<<(double)decodedAudioFrameSize/getAudioChannelNumber()/2.0/getAudioSampleRate()*1000.0<<"ms"<<endl;
 873	return decodedAudioFrame;
 874}
 875int Decoder::getAudioSamplesSize()
 876{
 877  return decodedAudioFrameSize;
 878}
 879
 880char* Decoder::getFileName()
 881{
 882   return filename;
 883}
 884
 885/*bool Decoder::moreFrames()
 886{
 887   return !(eofReachedFlag);
 888}*/
 889
 890
 891FrameIndex Decoder::getFrameIndex()
 892{
 893    return frameIndexFromTimeStamp(position);
 894   //return (FrameIndex)((position - firstVideoFramePosition) * getFrameRate() + 0.5);
 895}
 896
 897
 898double Decoder::getFrameTime()
 899{
 900   return (position - firstVideoFramePosition)/FOBS_TIMESTAMP_UNITS_D;
 901}
 902
 903double Decoder::getNextFrameTime()
 904{
 905   return getFrameTime() + 1.0/getFrameRate();
 906}
 907
 908ReturnCode Decoder::readNextFrame()
 909{
 910   static unsigned counter = 0;
 911   AVPacket pkt;
 912   int frameReady = false;
 913   ReturnCode error = testOpen();
 914   /*if(isOk(error))
 915   {
 916      if(eofReachedFlag) error = VideoEndError;
 917   }*/
 918   while(isOk(error) && !frameReady)
 919   {
 920     /* read a packet from it and output it in the fifo */
 921     if (av_read_frame(inputFile, &pkt) < 0) 
 922     {
 923        //eofReachedFlag = true;
 924        error = VideoEndError;
 925        continue;
 926     }
 927
 928     if(pkt.stream_index == videoStreamIndex)
 929     {
 930       videoBuffer->append(&pkt);
 931     }
 932     else if(pkt.stream_index == audioStreamIndex)
 933     {
 934        audioBuffer->append(&pkt);
 935     }
 936     else
 937     {
 938        av_free_packet(&pkt);
 939        continue;
 940     }
 941
 942     frameReady = true;
 943  }
 944  return error;
 945}
 946
 947
 948ReturnCode Decoder::placeAtNextFrame(bool videoFrame)
 949{
 950   ReturnCode error = testOpen();
 951   PacketBuffer *buffer = videoFrame?videoBuffer:audioBuffer;
 952   /*if(isOk(error))
 953   {
 954      if(eofReachedFlag) error = VideoEndError;
 955   }*/
 956   while(isOk(error) && buffer->count() <= 0)
 957   {
 958     error = readNextFrame();
 959   }
 960   if(isOk(error))
 961   {
 962     AVPacket *pkt = buffer->readNext();
 963     //if(pkt != NULL) cout << "-DTS " << (videoFrame?"Video":"Audio") << ": "<< pkt->dts << " size:" << pkt->size << endl;
 964     if(pkt == NULL)
 965     {
 966        error = VideoPacketBufferEmptyError;
 967     }
 968     else if(pkt->size > 0) 
 969     {
 970        if(videoFrame)
 971        {
 972            AVRational vTimeBase = inputFile->streams[videoStreamIndex]->time_base;
 973
 974            if(pkt->dts == (TimeStamp)AV_NOPTS_VALUE)
 975            {
 976               position += (TimeStamp)(FOBS_TIMESTAMP_UNITS_D/getFrameRate());
 977			   //cout << "PosNew=" << position <<endl;
 978               if(firstVideoPositionFlag == false)
 979               {
 980                firstVideoPosition = position;
 981                firstVideoPositionFlag = true;
 982               }
 983               else
 984               {
 985                 if(position < firstVideoPosition) firstVideoPosition = position;
 986               }
 987            }
 988            else
 989            {
 990               //position += (TimeStamp)(FOBS_TIMESTAMP_UNITS_D/getFrameRate());
 991			   
 992               if(firstVideoPositionFlag == false || ( pts2TimeStamp(pkt->dts, &vTimeBase) < firstVideoPosition ) )
 993               {
 994                firstVideoPosition = pts2TimeStamp(pkt->dts, &vTimeBase);
 995                firstVideoPositionFlag = true;
 996               }
 997               position = pts2TimeStamp(pkt->dts - timeStamp2pts(firstVideoPosition, &vTimeBase), &vTimeBase);
 998               //cout << "VIDEO PosNew=" << position << "   DTS="<<pkt->dts<<"   PTS=" << pkt->pts << "  DEN=" << vTimeBase.den << "   NUM=" << vTimeBase.num << " FVideoDTS	: " << timeStamp2pts(firstVideoPosition, &vTimeBase) << endl;
 999			   AVStream *s = (inputFile->streams[videoStreamIndex]);
1000            }
1001            frameFlag = true;
1002	    }
1003        else
1004        {
1005            AVRational aTimeBase = inputFile->streams[audioStreamIndex]->time_base;
1006            int aDen = aTimeBase.den;
1007
1008            if((videoStreamIndex < 0 && firstAudioPositionFlag != -1 && pkt->dts == 0 && pkt->pts == 0)||incorrectPts)
1009            {
1010                pkt->dts = (TimeStamp)AV_NOPTS_VALUE;
1011                incorrectPts = true;
1012                //cout << "Incorrect Time Values detected\n";
1013            }
1014            if(pkt->dts == (TimeStamp)AV_NOPTS_VALUE)
1015            {
1016                positionAudio += (TimeStamp)((double)FOBS_TIMESTAMP_UNITS_D*(double)getAudioSamplesSize()/getAudioChannelNumber()/2/getAudioSampleRate());
1017                //cout << "FiguringOut Audio Position: "<< positionAudio << endl;
1018               if(firstAudioPositionFlag == false)
1019               {
1020                firstAudioPosition = position;
1021                firstAudioPositionFlag = true;
1022               }
1023               else
1024               {
1025                 if(positionAudio < firstAudioPosition) firstAudioPosition = positionAudio;
1026               }
1027            }
1028            else
1029            {
1030               //cout << "DTS" << pkt->pts <<endl;
1031               if(firstAudioPositionFlag == false || pts2TimeStamp(pkt->dts, &aTimeBase) < firstAudioPosition )
1032               {
1033				   //cout << "Changing first audio" << endl;
1034			    firstAudioPosition = pts2TimeStamp(pkt->dts, &aTimeBase);
1035                firstAudioPositionFlag = true;
1036               }
1037               positionAudio = pts2TimeStamp(pkt->dts - timeStamp2pts(firstAudioPosition, &aTimeBase), &aTimeBase);
1038            }
1039               //cout << "AUDIO PosNew=" << positionAudio << "   DTS="<<pkt->dts<<"   PTS=" << pkt->pts << "  DEN=" << aTimeBase.den << "   NUM=" << aTimeBase.num << " FAudioDTS	: " << timeStamp2pts(firstAudioPosition, &aTimeBase)<<endl;
1040        }
1041     }
1042     else
1043     {
1044        frameFlag = false;
1045     }
1046   }
1047     /*
1048     cout << "PTS: ";
1049     if(pkt.pts == AV_NOPTS_VALUE) cout << "UNKNOWN ";
1050     else cout << ((double)pkt.pts/(double)AV_TIME_BASE);
1051     cout << endl;
1052     
1053     cout << "DTS: ";
1054     if(pkt.dts == AV_NOPTS_VALUE) cout << "UNKNOWN ";
1055     else cout << ((double)pkt.dts/(double)AV_TIME_BASE);
1056     cout << endl;
1057     */
1058   
1059   return error;
1060}
1061
1062ReturnCode Decoder::decodeFrame()
1063{
1064   ReturnCode error = testOpen();
1065   int got_picture = 0;
1066   AVPacket *pkt = videoBuffer->extractNext();
1067   if(pkt == NULL)
1068   {
1069     error = VideoPacketBufferEmptyError;
1070   }
1071   if(isOk(error))
1072   {
1073      if(pkt->size == 0) 
1074      {
1075        error = BadParamsError;
1076      }
1077   }
1078   if(isOk(error))
1079   {
1080    //cout << "Decode Video: " << pkt->dts << endl;
1081    if (inputFile->streams[videoStreamIndex]->codec->codec_id == CODEC_ID_RAWVIDEO) 
1082    {
1083       int size;
1084       size = (_getWidth() * _getHeight());
1085       avpicture_fill(decodedPicture, pkt->data, 
1086                    inputFile->streams[videoStreamIndex]->codec->pix_fmt,
1087                    inputFile->streams[videoStreamIndex]->codec->width,
1088                    inputFile->streams[videoStreamIndex]->codec->height);
1089    } 
1090    else 
1091    {
1092       AVFrame big_picture;
1093    
1094       int ret = avcodec_decode_video(inputFile->streams[videoStreamIndex]->codec, 
1095                                  &big_picture, &got_picture, pkt->data, pkt->size);
1096
1097       *decodedPicture= *(AVPicture*)&big_picture;
1098       inputFile->streams[videoStreamIndex]->quality= big_picture.quality;
1099       if (ret < 0 || !got_picture) 
1100       {
1101          error = NoFrameError;
1102       }
1103       else if(firstVideoFramePosition == -1)
1104       {
1105        firstVideoFramePosition = position;
1106       }
1107    }
1108    av_free_packet(pkt);
1109  }
1110  return error;
1111}
1112
1113ReturnCode Decoder::decodeAudioFrame()
1114{
1115   ReturnCode error = testOpen();
1116   int data_size = 0;
1117   //short samples[AVCODEC_MAX_AUDIO_FRAME_SIZE / 2];
1118   uint8_t *samples = decodedAudioFrame;
1119   
1120   AVPacket *pkt = audioBuffer->extractNext();
1121
1122
1123   if(pkt == NULL)
1124   {
1125     error = VideoPacketBufferEmptyError;
1126   }
1127   if(isOk(error))
1128   {
1129      if(pkt->size == 0) 
1130      {
1131        error = BadParamsError;
1132        av_free_packet(pkt);
1133      }
1134   }
1135   uint64_t ts;
1136   int ret;
1137   uint8_t *ptr;
1138   int len;
1139   if(isOk(error))
1140   {
1141    ts = pkt->dts;
1142    ptr = pkt->data;
1143    len = pkt->size;
1144
1145    ret = avcodec_decode_audio(inputFile->streams[audioStreamIndex]->codec, (short*) samples, &data_size, ptr, len);
1146    
1147    if(ret < 0)
1148    {
1149       error = GenericError;
1150    }
1151    else if(ret == len)
1152    {
1153        av_free_packet(pkt);
1154    }
1155   }
1156   if(isOk(error))
1157   {
1158    /* Some bug in mpeg audio decoder gives */
1159    /* data_size < 0, it seems they are overflows */
1160
1161    if (data_size <= 0) {
1162        //no audio frame
1163        decodedAudioFrameSize = 0;
1164        //cout << "No Audio Frame!!" << endl;
1165    }
1166    else
1167    {
1168        /* Only used if setAudioResampleFlag 
1169        if(audioResampler)
1170        {
1171            //Resampling needed
1172            int nSamples = data_size / _getAudioChannelNumber()/2;
1173            audio_resample(audioResampler, (short *)resampledAudioBuffer, (short *)samples, nSamples);
1174            data_size = nSamples * getAudioChannelNumber() * 2;
1175            //memcpy(samples, resampled, data_size);
1176        } */
1177      //cout << "Audio Decoded - DTS="<<((double)ts/(double)AV_TIME_BASE)<<" Size=" << data_size << " Max=" << AVCODEC_MAX_AUDIO_FRAME_SIZE << endl;
1178      //audioTime = ((double)ts/(double)AV_TIME_BASE);
1179      //memcpy(decodedAudioFrame, samples, data_size);
1180      if(firstAudioFramePosition == -1)
1181      {
1182        firstAudioFramePosition = positionAudio;
1183      }
1184      decodedAudioFrameSize = data_size;
1185      //cout << "OK!!" << endl;
1186	  //cout << "Audio decode ret=" << ret<< " len="<<len<<" data_size="<<data_size<<endl;
1187      if(ret != len)
1188      {
1189          //Some pkt data was not processed... include it again in the packet list
1190          //cout << "Ret="<<ret<<" - Len="<<len<<endl;
1191          if(pkt->size > 0) //Strange audio processing behaviour...
1192          {
1193              if(ret == 0)
1194              {
1195                  audioBuffer->prepend(pkt);
1196              }
1197              else
1198              {
1199                  AVPacket newPkt;
1200                  av_new_packet(&newPkt, pkt->size - ret);
1201                  memcpy(newPkt.data, pkt->data + ret, pkt->size - ret);
1202                  av_free_packet(pkt);
1203                  audioBuffer->prepend(&newPkt);
1204              }
1205         }
1206      }
1207
1208    }
1209   }
1210   return error;
1211}
1212
1213ReturnCode Decoder::nextFrame()
1214{
1215   //cout << "Next Video Frame Time: " << getNextFrameTime() << endl;
1216   ReturnCode error = placeAtNextFrame(true);
1217   
1218   if(isOk(error))
1219   {
1220      AVPacket *pkt = videoBuffer->readNext();
1221      if(pkt == NULL)
1222      {
1223        error = VideoPacketBufferEmptyError;
1224      }
1225      else if(pkt->size == 0) 
1226      {
1227        videoBuffer->deleteNext();
1228        return nextFrame();
1229      }
1230      else 
1231      {
1232        error = decodeFrame();
1233      }
1234   }
1235
1236    if(error == NoFrameError) return nextFrame();
1237    return error;
1238}
1239
1240ReturnCode Decoder::nextAudioFrame()
1241{
1242
1243   ReturnCode error = placeAtNextFrame(false);
1244   if(isOk(error))
1245   {
1246      AVPacket *pkt = audioBuffer->readNext();
1247      if(pkt == NULL)
1248      {
1249        error = VideoPacketBufferEmptyError;
1250      }
1251      else if(pkt->size == 0)
1252      {
1253        audioBuffer->deleteNext();
1254        return nextAudioFrame();
1255      }
1256      else 
1257      {
1258        //cout << "Decoder AUDIO Time: " << pkt->dts << endl;
1259        
1260        error = decodeAudioFrame();
1261        if(isOk(error))
1262        {
1263		  //cout << "New Audio Sample Set" << endl;
1264          if(getAudioSamplesSize() <= 0)
1265          {
1266              return nextAudioFrame();
1267          }
1268        }
1269      }
1270   }
1271
1272   return error;
1273}
1274
1275ReturnCode Decoder::prevFrame()
1276{
1277   return setFrame(frameIndexFromTimeStamp(position) - 1);
1278}
1279
1280
1281TimeStamp Decoder::getAVPosition()
1282{
1283    if(isVideoPresent())
1284    {
1285        return position;
1286    }
1287    if(isAudioPresent())
1288    {
1289        return positionAudio;
1290    }
1291}
1292
1293ReturnCode Decoder::_setFrame(TimeStamp newPosition)
1294{
1295    ReturnCode error = testOpen();
1296    if(isOk(error))
1297    {
1298      if(isVideoPresent() && firstVideoFramePosition == -1)
1299      {
1300        error = nextFrame();
1301          error = nextAudioFrame();		  
1302      }
1303      else if(isAudioPresent() && firstAudioFramePosition == -1)
1304      {
1305          error = nextFrame();
1306          error = nextAudioFrame();
1307      }
1308    }
1309    if(isOk(error))
1310    {
1311       if(newPosition > getDurationMilliseconds()) error = BadParamsError;
1312    }
1313    
1314    TimeStamp currentPosition=isVideoPresent()?position:positionAudio;
1315    TimeStamp firstPosition=isVideoPresent()?firstVideoFramePosition:firstAudioFramePosition;
1316    if(isOk(error) && !compareTimeStamps(currentPosition, newPosition))
1317    {
1318       videoBuffer->clear();
1319       audioBuffer->clear();
1320       TimeStamp newPos = newPosition - 1000;
1321       if(newPos < firstPosition) newPos = 0;
1322       if(newPosition < firstPosition) newPosition = firstPosition;
1323       int64_t realPos = newPos * 1000;
1324       cout << "Seeking pos: " << newPosition << " - Real: " << realPos << endl;
1325       
1326       int res = -1;
1327       
1328       if(!incorrectPts)
1329       {
1330           res = av_seek_frame(inputFile, -1, realPos, AVSEEK_FLAG_BACKWARD);
1331       }
1332       if(isVideoPresent())
1333       {
1334          if(res < 0)
1335          {
1336              error = setFrameClassic(newPosition);
1337          }
1338          else
1339          {
1340              error = setFrameFast(newPosition);
1341          }
1342       }
1343       else
1344       {
1345           cout << "Performing Audio seek: " << res << endl;
1346           if(res < 0)
1347           {
1348               error = setAudioClassic(newPosition);
1349           }
1350           else
1351           {
1352               error = setAudioFast(newPosition);
1353           }
1354       }
1355       audioBuffer->clear();
1356    }
1357    return error;
1358}
1359
1360/*ReturnCode Decoder::setAudioFast(TimeStamp newPosition)
1361{
1362   ReturnCode error = OkCode;
1363   for(error = nextAudioFrame(); isOk(error);error = nextAudioFrame())
1364   {
1365      if(compareTimeStamps(positionAudio, newPosition)) break;
1366      if(positionAudio > newPosition) break;
1367   }
1368   return error;
1369}*/
1370ReturnCode Decoder::setAudioFast(TimeStamp newPosition)
1371{
1372   ReturnCode error = OkCode;
1373   for(error = placeAtNextFrame(false); isOk(error);error = placeAtNextFrame(false))
1374   {
1375      if(compareTimeStamps(positionAudio, newPosition)) break;
1376      if(positionAudio > newPosition) break;
1377      AVPacket *pkt = audioBuffer->extractNext();
1378      av_free_packet(pkt);
1379   }
1380   return error;
1381}
1382ReturnCode Decoder::setAudioClassic(TimeStamp newPosition)
1383{
1384   ReturnCode error = testOpen();
1385   cout << "SetAudioClassic Called... Use another format!\n";
1386
1387   if(isOk(error))
1388   {
1389      if(newPosition > duration) error = BadParamsError;
1390   }
1391   if(isOk(error))
1392   {
1393      if(compareTimeStamps(positionAudio, newPosition))
1394      {
1395         error = OkCode;
1396      }
1397      else if(newPosition > position)
1398      {
1399          setAudioFast(newPosition);
1400      }
1401      else
1402      {
1403         error = close();
1404         if(isOk(error))
1405         {
1406            error = _open();
1407         }
1408         if(isOk(error))
1409         {
1410            error = setFrameByTime(newPosition);
1411         }
1412      }
1413
1414   }
1415
1416   return error;
1417}
1418
1419
1420
1421ReturnCode Decoder::setFrameFast(TimeStamp newPosition)
1422{
1423   ReturnCode error = OkCode;
1424   bool keyFrame = false;
1425   for(error = placeAtNextFrame(true); isOk(error);)
1426   {
1427      AVPacket *pkt = videoBuffer->readNext();
1428      if(keyFrame == false && pkt->flags & PKT_FLAG_KEY)
1429      {
1430         keyFrame = true;
1431         error = decodeFrame();
1432      }
1433      else
1434      {
1435         if(keyFrame) error = nextFrame();
1436         else 
1437         {
1438            AVPacket *pkt = videoBuffer->extractNext();
1439            av_free_packet(pkt);
1440            error = placeAtNextFrame(true);
1441          }
1442      }
1443
1444      //cout << "P: " << position << endl;
1445      if(compareTimeStamps(position, newPosition) || newPosition <= position) break;
1446   }
1447   
1448   //Workaround to sync a/v after a seek op
1449	//audioBuffer->clear();
1450	positionAudio = firstAudioPosition;
1451   while(audioBuffer->count()>0 && position>positionAudio && isOk(error))
1452   {
1453	   error = placeAtNextFrame(false);
1454	   error = decodeAudioFrame();
1455	   /*
1456    AVPacket *pkt = audioBuffer->readNext();
1457    AVRational aTimeBase = inputFile->streams[audioStreamIndex]->time_base;
1458    if(position +1000 < pts2TimeStamp(pkt->dts, &aTimeBase)) break;
1459    pkt = audioBuffer->extractNext();
1460    cout << "Extracting one audio packet to sync - VidPos: "<<position<<" and packet was: "<< pts2TimeStamp(pkt->pts, &aTimeBase) << endl;
1461    av_free_packet(pkt);
1462		*/
1463   }
1464   
1465   return error;
1466}
1467
1468ReturnCode Decoder::setFrameClassic(TimeStamp newPosition)
1469{
1470   ReturnCode error = testOpen();
1471   cout << "SetFrameClassic Called... Use another video format!\n";
1472   //FrameIndex frameIndex = frameIndexFromTimeStamp(newPosition);
1473   if(isOk(error))
1474   {
1475      if(newPosition > duration) error = BadParamsError;
1476   }
1477   if(isOk(error))
1478   {
1479      if(compareTimeStamps(position, newPosition) && frameFlag)
1480      {
1481         error = OkCode;
1482      }
1483      else if(newPosition > position || !frameFlag)
1484      {
1485         bool keyFrame = false;
1486         for(error = placeAtNextFrame(true); isOk(error) || !frameFlag;)
1487         {
1488            AVPacket *pkt = videoBuffer->readNext();
1489            if((keyFrame == false) && (((pkt->flags & PKT_FLAG_KEY) && (newPosition - position < 5000)) || (newPosition - position < 3500)))
1490            {
1491               keyFrame = true;
1492               error = decodeFrame();
1493            }
1494            else
1495            {
1496               if(keyFrame) error = nextFrame();
1497               else
1498               {
1499                 AVPacket *pkt = videoBuffer->extractNext();
1500                 av_free_packet(pkt);
1501                 error = placeAtNextFrame(true);
1502               }
1503            }
1504            
1505            if(compareTimeStamps(position, newPosition)  || newPosition <= position) break;
1506            //if(newPosition <= position) break;
1507            /*
1508            error = nextFrame();
1509            if(position > newPosition) break;
1510            */
1511         }
1512      }
1513      else
1514      {
1515        cout << "Begin reading video again" << endl;
1516         error = close();
1517         if(isOk(error))
1518         {
1519            error = _open();
1520         }
1521         if(isOk(error))
1522         {
1523            error = setFrameByTime(newPosition);
1524         }
1525      }
1526
1527   }
1528
1529   return error;
1530}
1531ReturnCode Decoder::setFrame(FrameIndex frameIndex)
1532{
1533    return _setFrame(timeStampFromFrameIndex(frameIndex));
1534}
1535ReturnCode Decoder::setFrameByTime(double seconds)
1536{
1537   ReturnCode error = OkCode;
1538   error = _setFrame((TimeStamp)(seconds * FOBS_TIMESTAMP_UNITS_D));
1539   return error;
1540}
1541ReturnCode Decoder::setFrameByTime(TimeStamp milliseconds) 
1542{
1543   return _setFrame(milliseconds);
1544}
1545
1546ReturnCode Decoder::setPosition(TimeStamp milliseconds)
1547{
1548    if(isVideoPresent())
1549    {
1550        return setFrameByTime(milliseconds);
1551    }
1552}
1553
1554bool Decoder::isVideoPresent()
1555{
1556  return videoStreamIndex >= 0;
1557}
1558
1559bool Decoder::isAudioPresent()
1560{
1561  return audioStreamIndex >= 0;
1562}
1563void Decoder::enableAudio(bool flag)
1564{
1565  audioEnabledFlag = flag;
1566}
1567
1568omnividea::fobs::uint Decoder::getAudioSampleRate()
1569{
1570  uint res = 0;
1571  if(isAudioPresent())
1572  {
1573    res = inputFile->streams[audioStreamIndex]->codec->sample_rate;
1574  }
1575  return res;
1576}
1577omnividea::fobs::uint Decoder::getAudioBitRate()
1578{
1579  uint res = 0;
1580  if(isAudioPresent())
1581  {
1582    res = inputFile->streams[audioStreamIndex]->codec->bit_rate / 1000;
1583  }
1584  return res;
1585}
1586
1587
1588omnividea::fobs::uint Decoder::getAudioChannelNumber()
1589{
1590  uint res = 0;
1591  if(isAudioPresent())
1592  {
1593	  res = inputFile->streams[audioStreamIndex]->codec->channels;
1594  }
1595	return res;// > 2?2:res;
1596}
1597
1598double Decoder::getAudioTime()
1599{
1600  return (positionAudio - firstAudioFramePosition)/FOBS_TIMESTAMP_UNITS_D;
1601}
1602
1603double Decoder::getTime()
1604{
1605    if(isVideoPresent())
1606    {
1607        return getFrameTime();//*FOBS_TIMESTAMP_UNITS_D;
1608    }
1609    else
1610    {
1611        return getAudioTime();//*FOBS_TIMESTAMP_UNITS_D;
1612    }
1613}
1614
1615AVCodecContext *Decoder::getAudioCodec()
1616{
1617  if(isAudioPresent()) return inputFile->streams[audioStreamIndex]->codec;
1618  return NULL;
1619}
1620AVCodecContext *Decoder::getVideoCodec()
1621{
1622  if(videoStreamIndex >= 0) return inputFile->streams[videoStreamIndex]->codec;
1623}