@ -1,6 +1,7 @@
# include "videostate.hpp"
# include <iostream>
# include <stdexcept>
# include <osg/Texture2D>
@ -102,14 +103,14 @@ void PacketQueue::put(AVPacket *pkt)
this - > last_pkt = pkt1 ;
this - > nb_packets + + ;
this - > size + = pkt1 - > pkt . size ;
this - > cond . notify_one ( ) ;
this - > cond . signal ( ) ;
this - > mutex . unlock ( ) ;
}
int PacketQueue : : get ( AVPacket * pkt , VideoState * is )
{
boost: : unique_lock < boost : : m utex> lock ( this - > mutex ) ;
OpenThreads: : ScopedLock < OpenThreads : : M utex> lock ( this - > mutex ) ;
while ( ! is - > mQuit )
{
AVPacketList * pkt1 = this - > first_pkt ;
@ -129,7 +130,7 @@ int PacketQueue::get(AVPacket *pkt, VideoState *is)
if ( this - > flushing )
break ;
this - > cond . wait ( lock ) ;
this - > cond . wait ( & this - > mutex ) ;
}
return - 1 ;
@ -138,7 +139,7 @@ int PacketQueue::get(AVPacket *pkt, VideoState *is)
void PacketQueue : : flush ( )
{
this - > flushing = true ;
this - > cond . notify_one ( ) ;
this - > cond . signal ( ) ;
}
void PacketQueue : : clear ( )
@ -233,7 +234,7 @@ void VideoState::video_display(VideoPicture *vp)
void VideoState : : video_refresh ( )
{
boost: : mutex : : scoped_lock lock ( this - > pictq_mutex ) ;
OpenThreads: : ScopedLock < OpenThreads : : Mutex > lock ( this - > pictq_mutex ) ;
if ( this - > pictq_size = = 0 )
return ;
@ -245,7 +246,7 @@ void VideoState::video_refresh()
this - > pictq_rindex = ( pictq_rindex + 1 ) % VIDEO_PICTURE_ARRAY_SIZE ;
this - > frame_last_pts = vp - > pts ;
this - > pictq_size - - ;
this - > pictq_cond . notify_one ( ) ;
this - > pictq_cond . signal ( ) ;
}
else
{
@ -275,7 +276,7 @@ void VideoState::video_refresh()
// update queue for next picture
this - > pictq_size - - ;
this - > pictq_rindex = ( this - > pictq_rindex + 1 ) % VIDEO_PICTURE_ARRAY_SIZE ;
this - > pictq_cond . notify_one ( ) ;
this - > pictq_cond . signal ( ) ;
}
}
@ -286,9 +287,9 @@ int VideoState::queue_picture(AVFrame *pFrame, double pts)
/* wait until we have a new pic */
{
boost: : unique_lock < boost : : m utex> lock ( this - > pictq_mutex ) ;
OpenThreads: : ScopedLock < OpenThreads : : M utex> lock ( this - > pictq_mutex ) ;
while ( this - > pictq_size > = VIDEO_PICTURE_QUEUE_SIZE & & ! this - > mQuit )
this - > pictq_cond . timed_wait( lock , boost : : posix_time : : milliseconds ( 1 ) ) ;
this - > pictq_cond . wait( & this - > pictq_mutex , 1 ) ;
}
if ( this - > mQuit )
return - 1 ;
@ -371,9 +372,18 @@ static void our_free_buffer(void *opaque, uint8_t *data)
av_free ( data ) ;
}
class VideoThread : public OpenThreads : : Thread
{
public :
VideoThread ( VideoState * self )
: mVideoState ( self )
{
start ( ) ;
}
void VideoState : : video_thread_loop ( VideoState * self )
virtual void run ( )
{
VideoState * self = mVideoState ;
AVPacket pkt1 , * packet = & pkt1 ;
int frameFinished ;
AVFrame * pFrame ;
@ -430,8 +440,23 @@ void VideoState::video_thread_loop(VideoState *self)
av_free ( self - > rgbaFrame ) ;
}
void VideoState : : decode_thread_loop ( VideoState * self )
private :
VideoState * mVideoState ;
} ;
class ParseThread : public OpenThreads : : Thread
{
public :
ParseThread ( VideoState * self )
: mVideoState ( self )
{
start ( ) ;
}
virtual void run ( )
{
VideoState * self = mVideoState ;
AVFormatContext * pFormatCtx = self - > format_ctx ;
AVPacket pkt1 , * packet = & pkt1 ;
@ -505,7 +530,7 @@ void VideoState::decode_thread_loop(VideoState *self)
if ( ( self - > audio_st & & self - > audioq . size > MAX_AUDIOQ_SIZE ) | |
( self - > video_st & & self - > videoq . size > MAX_VIDEOQ_SIZE ) )
{
boost : : this_thread : : sleep ( boost : : posix_time : : milliseconds ( 10 ) ) ;
OpenThreads : : Thread : : microSleep ( 10 * 1000 ) ;
continue ;
}
@ -534,6 +559,10 @@ void VideoState::decode_thread_loop(VideoState *self)
self - > mQuit = true ;
}
private :
VideoState * mVideoState ;
} ;
bool VideoState : : update ( )
{
@ -587,7 +616,7 @@ int VideoState::stream_open(int stream_index, AVFormatContext *pFormatCtx)
this - > video_st = pFormatCtx - > streams + stream_index ;
codecCtx - > get_buffer2 = our_get_buffer ;
this - > video_thread = boost : : thread ( video_thread_loop , this ) ;
this - > video_thread . reset ( new VideoThread ( this ) ) ;
break ;
default :
@ -669,7 +698,7 @@ void VideoState::init(boost::shared_ptr<std::istream> inputstream, const std::st
}
this - > parse_thread = boost : : thread ( decode_thread_loop , this ) ;
this - > parse_thread . reset ( new ParseThread ( this ) ) ;
}
void VideoState : : deinit ( )
@ -681,10 +710,16 @@ void VideoState::deinit()
mAudioDecoder . reset ( ) ;
if ( this - > parse_thread . joinable ( ) )
this - > parse_thread . join ( ) ;
if ( this - > video_thread . joinable ( ) )
this - > video_thread . join ( ) ;
if ( this - > parse_thread . get ( ) )
{
this - > parse_thread - > join ( ) ;
this - > parse_thread . reset ( ) ;
}
if ( this - > video_thread . get ( ) )
{
this - > video_thread - > join ( ) ;
this - > video_thread . reset ( ) ;
}
if ( this - > audio_st )
avcodec_close ( ( * this - > audio_st ) - > codec ) ;
@ -779,7 +814,7 @@ ExternalClock::ExternalClock()
void ExternalClock : : setPaused ( bool paused )
{
boost: : mutex : : scoped_lock lock ( mMutex ) ;
OpenThreads: : ScopedLock < OpenThreads : : Mutex > lock ( mMutex ) ;
if ( mPaused = = paused )
return ;
if ( paused )
@ -793,7 +828,7 @@ void ExternalClock::setPaused(bool paused)
uint64_t ExternalClock : : get ( )
{
boost: : mutex : : scoped_lock lock ( mMutex ) ;
OpenThreads: : ScopedLock < OpenThreads : : Mutex > lock ( mMutex ) ;
if ( mPaused )
return mPausedAt ;
else
@ -802,7 +837,7 @@ uint64_t ExternalClock::get()
void ExternalClock : : set ( uint64_t time )
{
boost: : mutex : : scoped_lock lock ( mMutex ) ;
OpenThreads: : ScopedLock < OpenThreads : : Mutex > lock ( mMutex ) ;
mTimeBase = av_gettime ( ) - time ;
mPausedAt = time ;
}