mirror of
https://github.com/OpenMW/openmw.git
synced 2025-01-21 10:53:53 +00:00
Move some methods into their respective class
This commit is contained in:
parent
5221298a7f
commit
26a09ee7ba
2 changed files with 158 additions and 153 deletions
|
@ -11,123 +11,91 @@
|
||||||
namespace MWRender
|
namespace MWRender
|
||||||
{
|
{
|
||||||
|
|
||||||
int OgreResource_Read(void *user_data, uint8_t *buf, int buf_size)
|
void PacketQueue::put(AVPacket *pkt)
|
||||||
|
{
|
||||||
|
AVPacketList *pkt1;
|
||||||
|
if(av_dup_packet(pkt) < 0)
|
||||||
|
throw std::runtime_error("Failed to duplicate packet");
|
||||||
|
|
||||||
|
pkt1 = (AVPacketList*)av_malloc(sizeof(AVPacketList));
|
||||||
|
if(!pkt1) throw std::bad_alloc();
|
||||||
|
pkt1->pkt = *pkt;
|
||||||
|
pkt1->next = NULL;
|
||||||
|
|
||||||
|
this->mutex.lock ();
|
||||||
|
|
||||||
|
if(!last_pkt)
|
||||||
|
this->first_pkt = pkt1;
|
||||||
|
else
|
||||||
|
this->last_pkt->next = pkt1;
|
||||||
|
this->last_pkt = pkt1;
|
||||||
|
this->nb_packets++;
|
||||||
|
this->size += pkt1->pkt.size;
|
||||||
|
this->cond.notify_one();
|
||||||
|
|
||||||
|
this->mutex.unlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
int PacketQueue::get(AVPacket *pkt, VideoState *is, int block)
|
||||||
|
{
|
||||||
|
AVPacketList *pkt1;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
boost::unique_lock<boost::mutex> lock(this->mutex);
|
||||||
|
for(;;)
|
||||||
{
|
{
|
||||||
Ogre::DataStreamPtr stream = static_cast<VideoState*>(user_data)->stream;
|
if(is->quit)
|
||||||
return stream->read(buf, buf_size);
|
|
||||||
}
|
|
||||||
|
|
||||||
int OgreResource_Write(void *user_data, uint8_t *buf, int buf_size)
|
|
||||||
{
|
|
||||||
Ogre::DataStreamPtr stream = static_cast<VideoState*>(user_data)->stream;
|
|
||||||
return stream->write(buf, buf_size);
|
|
||||||
}
|
|
||||||
|
|
||||||
int64_t OgreResource_Seek(void *user_data, int64_t offset, int whence)
|
|
||||||
{
|
|
||||||
Ogre::DataStreamPtr stream = static_cast<VideoState*>(user_data)->stream;
|
|
||||||
|
|
||||||
whence &= ~AVSEEK_FORCE;
|
|
||||||
if(whence == AVSEEK_SIZE)
|
|
||||||
return stream->size();
|
|
||||||
if(whence == SEEK_SET)
|
|
||||||
stream->seek(offset);
|
|
||||||
else if(whence == SEEK_CUR)
|
|
||||||
stream->seek(stream->tell()+offset);
|
|
||||||
else if(whence == SEEK_END)
|
|
||||||
stream->seek(stream->size()+offset);
|
|
||||||
else
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
return stream->tell();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void PacketQueue::put(AVPacket *pkt)
|
|
||||||
{
|
|
||||||
AVPacketList *pkt1;
|
|
||||||
if(av_dup_packet(pkt) < 0)
|
|
||||||
throw std::runtime_error("Failed to duplicate packet");
|
|
||||||
|
|
||||||
pkt1 = (AVPacketList*)av_malloc(sizeof(AVPacketList));
|
|
||||||
if(!pkt1) throw std::bad_alloc();
|
|
||||||
pkt1->pkt = *pkt;
|
|
||||||
pkt1->next = NULL;
|
|
||||||
|
|
||||||
this->mutex.lock ();
|
|
||||||
|
|
||||||
if(!last_pkt)
|
|
||||||
this->first_pkt = pkt1;
|
|
||||||
else
|
|
||||||
this->last_pkt->next = pkt1;
|
|
||||||
this->last_pkt = pkt1;
|
|
||||||
this->nb_packets++;
|
|
||||||
this->size += pkt1->pkt.size;
|
|
||||||
this->cond.notify_one();
|
|
||||||
|
|
||||||
this->mutex.unlock();
|
|
||||||
}
|
|
||||||
|
|
||||||
int PacketQueue::get(AVPacket *pkt, VideoState *is, int block)
|
|
||||||
{
|
|
||||||
AVPacketList *pkt1;
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
boost::unique_lock<boost::mutex> lock(this->mutex);
|
|
||||||
for(;;)
|
|
||||||
{
|
{
|
||||||
if(is->quit)
|
ret = -1;
|
||||||
{
|
break;
|
||||||
ret = -1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
pkt1 = this->first_pkt;
|
|
||||||
if(pkt1)
|
|
||||||
{
|
|
||||||
this->first_pkt = pkt1->next;
|
|
||||||
if(!this->first_pkt)
|
|
||||||
this->last_pkt = NULL;
|
|
||||||
this->nb_packets--;
|
|
||||||
this->size -= pkt1->pkt.size;
|
|
||||||
|
|
||||||
*pkt = pkt1->pkt;
|
|
||||||
av_free(pkt1);
|
|
||||||
|
|
||||||
ret = 1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!block)
|
|
||||||
{
|
|
||||||
ret = 0;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
this->cond.wait(lock);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
pkt1 = this->first_pkt;
|
||||||
}
|
if(pkt1)
|
||||||
|
|
||||||
void PacketQueue::flush()
|
|
||||||
{
|
|
||||||
AVPacketList *pkt, *pkt1;
|
|
||||||
|
|
||||||
this->mutex.lock();
|
|
||||||
for(pkt = this->first_pkt; pkt != NULL; pkt = pkt1)
|
|
||||||
{
|
{
|
||||||
pkt1 = pkt->next;
|
this->first_pkt = pkt1->next;
|
||||||
av_free_packet(&pkt->pkt);
|
if(!this->first_pkt)
|
||||||
av_freep(&pkt);
|
this->last_pkt = NULL;
|
||||||
|
this->nb_packets--;
|
||||||
|
this->size -= pkt1->pkt.size;
|
||||||
|
|
||||||
|
*pkt = pkt1->pkt;
|
||||||
|
av_free(pkt1);
|
||||||
|
|
||||||
|
ret = 1;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
this->last_pkt = NULL;
|
|
||||||
this->first_pkt = NULL;
|
if (!block)
|
||||||
this->nb_packets = 0;
|
{
|
||||||
this->size = 0;
|
ret = 0;
|
||||||
this->mutex.unlock ();
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
this->cond.wait(lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PacketQueue::flush()
|
||||||
|
{
|
||||||
|
AVPacketList *pkt, *pkt1;
|
||||||
|
|
||||||
|
this->mutex.lock();
|
||||||
|
for(pkt = this->first_pkt; pkt != NULL; pkt = pkt1)
|
||||||
|
{
|
||||||
|
pkt1 = pkt->next;
|
||||||
|
av_free_packet(&pkt->pkt);
|
||||||
|
av_freep(&pkt);
|
||||||
|
}
|
||||||
|
this->last_pkt = NULL;
|
||||||
|
this->first_pkt = NULL;
|
||||||
|
this->nb_packets = 0;
|
||||||
|
this->size = 0;
|
||||||
|
this->mutex.unlock ();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
double get_audio_clock(VideoState *is)
|
double get_audio_clock(VideoState *is)
|
||||||
{
|
{
|
||||||
|
@ -411,6 +379,38 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
int VideoState::OgreResource_Read(void *user_data, uint8_t *buf, int buf_size)
|
||||||
|
{
|
||||||
|
Ogre::DataStreamPtr stream = static_cast<VideoState*>(user_data)->stream;
|
||||||
|
return stream->read(buf, buf_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
int VideoState::OgreResource_Write(void *user_data, uint8_t *buf, int buf_size)
|
||||||
|
{
|
||||||
|
Ogre::DataStreamPtr stream = static_cast<VideoState*>(user_data)->stream;
|
||||||
|
return stream->write(buf, buf_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
int64_t VideoState::OgreResource_Seek(void *user_data, int64_t offset, int whence)
|
||||||
|
{
|
||||||
|
Ogre::DataStreamPtr stream = static_cast<VideoState*>(user_data)->stream;
|
||||||
|
|
||||||
|
whence &= ~AVSEEK_FORCE;
|
||||||
|
if(whence == AVSEEK_SIZE)
|
||||||
|
return stream->size();
|
||||||
|
if(whence == SEEK_SET)
|
||||||
|
stream->seek(offset);
|
||||||
|
else if(whence == SEEK_CUR)
|
||||||
|
stream->seek(stream->tell()+offset);
|
||||||
|
else if(whence == SEEK_END)
|
||||||
|
stream->seek(stream->size()+offset);
|
||||||
|
else
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
return stream->tell();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void timer_callback(boost::system_time t, VideoState* is)
|
void timer_callback(boost::system_time t, VideoState* is)
|
||||||
{
|
{
|
||||||
boost::this_thread::sleep(t);
|
boost::this_thread::sleep(t);
|
||||||
|
@ -793,7 +793,7 @@ public:
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void init_state(VideoState *is, const std::string& resourceName)
|
void VideoState::init(const std::string& resourceName)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
@ -801,90 +801,90 @@ public:
|
||||||
int audio_index = -1;
|
int audio_index = -1;
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
|
||||||
is->av_sync_type = DEFAULT_AV_SYNC_TYPE;
|
this->av_sync_type = DEFAULT_AV_SYNC_TYPE;
|
||||||
is->videoStream = -1;
|
this->videoStream = -1;
|
||||||
is->audioStream = -1;
|
this->audioStream = -1;
|
||||||
is->refresh = false;
|
this->refresh = false;
|
||||||
is->quit = 0;
|
this->quit = 0;
|
||||||
|
|
||||||
is->stream = Ogre::ResourceGroupManager::getSingleton ().openResource(resourceName);
|
this->stream = Ogre::ResourceGroupManager::getSingleton().openResource(resourceName);
|
||||||
if(is->stream.isNull())
|
if(this->stream.isNull())
|
||||||
throw std::runtime_error("Failed to open video resource");
|
throw std::runtime_error("Failed to open video resource");
|
||||||
|
|
||||||
is->format_ctx = avformat_alloc_context();
|
this->format_ctx = avformat_alloc_context();
|
||||||
|
this->format_ctx->pb = avio_alloc_context(NULL, 0, 0, this, OgreResource_Read, OgreResource_Write, OgreResource_Seek);
|
||||||
is->format_ctx->pb = avio_alloc_context(NULL, 0, 0, is, OgreResource_Read, OgreResource_Write, OgreResource_Seek);
|
if(!this->format_ctx->pb)
|
||||||
if(!is->format_ctx->pb)
|
|
||||||
{
|
{
|
||||||
avformat_free_context(is->format_ctx);
|
avformat_free_context(this->format_ctx);
|
||||||
throw std::runtime_error("Failed to allocate ioContext ");
|
throw std::runtime_error("Failed to allocate ioContext ");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Open video file
|
// Open video file
|
||||||
/// \todo leak here, ffmpeg or valgrind bug ?
|
/// \todo leak here, ffmpeg or valgrind bug ?
|
||||||
if (avformat_open_input(&is->format_ctx, resourceName.c_str(), NULL, NULL))
|
if (avformat_open_input(&this->format_ctx, resourceName.c_str(), NULL, NULL))
|
||||||
{
|
{
|
||||||
// "Note that a user-supplied AVFormatContext will be freed on failure."
|
// "Note that a user-supplied AVFormatContext will be freed on failure."
|
||||||
is->format_ctx = NULL;
|
this->format_ctx = NULL;
|
||||||
throw std::runtime_error("Failed to open video input");
|
throw std::runtime_error("Failed to open video input");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Retrieve stream information
|
// Retrieve stream information
|
||||||
if(avformat_find_stream_info(is->format_ctx, NULL) < 0)
|
if(avformat_find_stream_info(this->format_ctx, NULL) < 0)
|
||||||
throw std::runtime_error("Failed to retrieve stream information");
|
throw std::runtime_error("Failed to retrieve stream information");
|
||||||
|
|
||||||
// Dump information about file onto standard error
|
// Dump information about file onto standard error
|
||||||
av_dump_format(is->format_ctx, 0, resourceName.c_str(), 0);
|
av_dump_format(this->format_ctx, 0, resourceName.c_str(), 0);
|
||||||
|
|
||||||
for(i = 0;i < is->format_ctx->nb_streams;i++)
|
for(i = 0;i < this->format_ctx->nb_streams;i++)
|
||||||
{
|
{
|
||||||
if(is->format_ctx->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO && video_index < 0)
|
if(this->format_ctx->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO && video_index < 0)
|
||||||
video_index = i;
|
video_index = i;
|
||||||
if(is->format_ctx->streams[i]->codec->codec_type == AVMEDIA_TYPE_AUDIO && audio_index < 0)
|
if(this->format_ctx->streams[i]->codec->codec_type == AVMEDIA_TYPE_AUDIO && audio_index < 0)
|
||||||
audio_index = i;
|
audio_index = i;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(audio_index >= 0)
|
if(audio_index >= 0)
|
||||||
stream_component_open(is, audio_index, is->format_ctx);
|
stream_component_open(this, audio_index, this->format_ctx);
|
||||||
if(video_index >= 0)
|
if(video_index >= 0)
|
||||||
stream_component_open(is, video_index, is->format_ctx);
|
stream_component_open(this, video_index, this->format_ctx);
|
||||||
}
|
}
|
||||||
catch (std::runtime_error& e)
|
catch(std::runtime_error& e)
|
||||||
{
|
{
|
||||||
is->quit = 1;
|
this->quit = 1;
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
catch (Ogre::Exception& e)
|
catch(Ogre::Exception& e)
|
||||||
{
|
{
|
||||||
is->quit = 1;
|
this->quit = 1;
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void deinit_state(VideoState *is)
|
void VideoState::deinit()
|
||||||
{
|
{
|
||||||
is->audioq.cond.notify_one ();
|
this->audioq.cond.notify_one();
|
||||||
is->videoq.cond.notify_one ();
|
this->videoq.cond.notify_one();
|
||||||
|
|
||||||
is->parse_thread.join();
|
this->parse_thread.join();
|
||||||
is->video_thread.join();
|
this->video_thread.join();
|
||||||
|
|
||||||
if(is->audioStream >= 0)
|
if(this->audioStream >= 0)
|
||||||
avcodec_close(is->audio_st->codec);
|
avcodec_close(this->audio_st->codec);
|
||||||
if(is->videoStream >= 0)
|
if(this->videoStream >= 0)
|
||||||
avcodec_close(is->video_st->codec);
|
avcodec_close(this->video_st->codec);
|
||||||
|
|
||||||
if (is->sws_context)
|
if(this->sws_context)
|
||||||
sws_freeContext(is->sws_context);
|
sws_freeContext(this->sws_context);
|
||||||
|
|
||||||
if (is->format_ctx)
|
if(this->format_ctx)
|
||||||
{
|
{
|
||||||
AVIOContext *ioContext = is->format_ctx->pb;
|
AVIOContext *ioContext = this->format_ctx->pb;
|
||||||
avformat_close_input(&is->format_ctx);
|
avformat_close_input(&this->format_ctx);
|
||||||
av_free(ioContext);
|
av_free(ioContext);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
VideoPlayer::VideoPlayer(Ogre::SceneManager* sceneMgr)
|
VideoPlayer::VideoPlayer(Ogre::SceneManager* sceneMgr)
|
||||||
: mState(NULL)
|
: mState(NULL)
|
||||||
, mSceneMgr(sceneMgr)
|
, mSceneMgr(sceneMgr)
|
||||||
|
@ -941,8 +941,7 @@ public:
|
||||||
MWBase::Environment::get().getSoundManager()->pauseAllSounds();
|
MWBase::Environment::get().getSoundManager()->pauseAllSounds();
|
||||||
|
|
||||||
mState = new VideoState;
|
mState = new VideoState;
|
||||||
|
mState->init(resourceName);
|
||||||
init_state(mState, resourceName);
|
|
||||||
|
|
||||||
schedule_refresh(mState, 40);
|
schedule_refresh(mState, 40);
|
||||||
mState->parse_thread = boost::thread(decode_thread, mState);
|
mState->parse_thread = boost::thread(decode_thread, mState);
|
||||||
|
@ -970,7 +969,7 @@ public:
|
||||||
void VideoPlayer::close()
|
void VideoPlayer::close()
|
||||||
{
|
{
|
||||||
mState->quit = 1;
|
mState->quit = 1;
|
||||||
deinit_state(mState);
|
mState->deinit();
|
||||||
|
|
||||||
delete mState;
|
delete mState;
|
||||||
mState = NULL;
|
mState = NULL;
|
||||||
|
|
|
@ -71,7 +71,6 @@ namespace MWRender
|
||||||
pictq_windex(0), quit(false), refresh(0), format_ctx(0), sws_context(NULL), display_ready(0)
|
pictq_windex(0), quit(false), refresh(0), format_ctx(0), sws_context(NULL), display_ready(0)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
|
||||||
~VideoState()
|
~VideoState()
|
||||||
{
|
{
|
||||||
audioq.flush();
|
audioq.flush();
|
||||||
|
@ -81,6 +80,13 @@ namespace MWRender
|
||||||
free(pictq[0].data);
|
free(pictq[0].data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void init(const std::string& resourceName);
|
||||||
|
void deinit();
|
||||||
|
|
||||||
|
static int OgreResource_Read(void *user_data, uint8_t *buf, int buf_size);
|
||||||
|
static int OgreResource_Write(void *user_data, uint8_t *buf, int buf_size);
|
||||||
|
static int64_t OgreResource_Seek(void *user_data, int64_t offset, int whence);
|
||||||
|
|
||||||
int videoStream, audioStream;
|
int videoStream, audioStream;
|
||||||
|
|
||||||
int av_sync_type;
|
int av_sync_type;
|
||||||
|
|
Loading…
Reference in a new issue