Show
Ignore:
Timestamp:
11/20/09 15:31:11 (4 years ago)
Author:
robert
Message:

From Rafa Gaitan, "Current ffmpeg plugin didn't support pause and seek, I have added this
functionality and I also modified osgmovie example to support "seek"."

Note from Robert Osfield, changes osgmovie to use '>' for the seek as '+' was already used in a separate submission that had been merged.

Files:
1 modified

Legend:

Unmodified
Added
Removed
  • OpenSceneGraph/trunk/src/osgPlugins/ffmpeg/FFmpegDecoder.cpp

    r10422 r10809  
    167167        return readNextPacketNormal(); 
    168168 
     169    case PAUSE: 
     170        return false; 
     171 
    169172    case END_OF_STREAM: 
    170173        return readNextPacketEndOfStream(); 
     
    172175    case REWINDING: 
    173176        return readNextPacketRewinding(); 
     177 
     178    case SEEKING: 
     179        return readNextPacketSeeking(); 
    174180 
    175181    default: 
     
    190196} 
    191197 
    192  
    193  
     198void FFmpegDecoder::seek(double time)  
     199{ 
     200    m_pending_packet.clear(); 
     201 
     202    flushAudioQueue(); 
     203    flushVideoQueue(); 
     204    seekButDontFlushQueues(time); 
     205} 
     206 
     207void FFmpegDecoder::pause()  
     208{ 
     209    m_pending_packet.clear(); 
     210 
     211    flushAudioQueue(); 
     212    flushVideoQueue(); 
     213    m_state = PAUSE; 
     214} 
     215 
     216void FFmpegDecoder::resume()  
     217{ 
     218    m_pending_packet.clear(); 
     219 
     220    flushAudioQueue(); 
     221    flushVideoQueue(); 
     222    m_state = NORMAL; 
     223} 
    194224 
    195225void FFmpegDecoder::findAudioStream() 
     
    347377} 
    348378 
     379bool FFmpegDecoder::readNextPacketSeeking()  
     380{ 
     381    const FFmpegPacket packet(FFmpegPacket::PACKET_FLUSH); 
     382 
     383    if (m_audio_queue.timedPush(packet, 10) && m_video_queue.timedPush(packet, 10)) 
     384        m_state = NORMAL; 
     385 
     386    return false;     
     387} 
     388 
     389void FFmpegDecoder::seekButDontFlushQueues(double time) 
     390{ 
     391    const AVRational AvTimeBaseQ = { 1, AV_TIME_BASE }; // = AV_TIME_BASE_Q 
     392 
     393    const int64_t pos = int64_t(m_clocks.getStartTime()+time * double(AV_TIME_BASE)); 
     394    const int64_t seek_target = av_rescale_q(pos, AvTimeBaseQ, m_video_stream->time_base); 
     395 
     396    if (av_seek_frame(m_format_context.get(), m_video_index, seek_target, 0/*AVSEEK_FLAG_BYTE |*/ /*AVSEEK_FLAG_BACKWARD*/) < 0) 
     397        throw std::runtime_error("av_seek_frame failed()"); 
     398 
     399    m_state = SEEKING;     
     400} 
     401 
    349402 
    350403