forked from mirror/openmw-tes3mp
fix a bunch of warnings, improved error handling, initialize texture to black
This commit is contained in:
parent
fe384a1600
commit
18d8c767bd
3 changed files with 154 additions and 131 deletions
|
@ -125,21 +125,23 @@ namespace MWRender
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
static void packet_queue_flush(PacketQueue *q) {
|
|
||||||
|
void PacketQueue::flush() {
|
||||||
AVPacketList *pkt, *pkt1;
|
AVPacketList *pkt, *pkt1;
|
||||||
|
|
||||||
q->mutex.lock();
|
this->mutex.lock();
|
||||||
for(pkt = q->first_pkt; pkt != NULL; pkt = pkt1) {
|
for(pkt = this->first_pkt; pkt != NULL; pkt = pkt1) {
|
||||||
pkt1 = pkt->next;
|
pkt1 = pkt->next;
|
||||||
av_free_packet(&pkt->pkt);
|
av_free_packet(&pkt->pkt);
|
||||||
av_freep(&pkt);
|
av_freep(&pkt);
|
||||||
}
|
}
|
||||||
q->last_pkt = NULL;
|
this->last_pkt = NULL;
|
||||||
q->first_pkt = NULL;
|
this->first_pkt = NULL;
|
||||||
q->nb_packets = 0;
|
this->nb_packets = 0;
|
||||||
q->size = 0;
|
this->size = 0;
|
||||||
q->mutex.unlock ();
|
this->mutex.unlock ();
|
||||||
}
|
}
|
||||||
|
|
||||||
double get_audio_clock(VideoState *is) {
|
double get_audio_clock(VideoState *is) {
|
||||||
double pts;
|
double pts;
|
||||||
int hw_buf_size, bytes_per_sec, n;
|
int hw_buf_size, bytes_per_sec, n;
|
||||||
|
@ -279,7 +281,7 @@ namespace MWRender
|
||||||
is->audio_pkt_data = pkt->data;
|
is->audio_pkt_data = pkt->data;
|
||||||
is->audio_pkt_size = pkt->size;
|
is->audio_pkt_size = pkt->size;
|
||||||
/* if update, update the audio clock w/pts */
|
/* if update, update the audio clock w/pts */
|
||||||
if(pkt->pts != AV_NOPTS_VALUE) {
|
if((uint64_t)pkt->pts != AV_NOPTS_VALUE) {
|
||||||
is->audio_clock = av_q2d(is->audio_st->time_base)*pkt->pts;
|
is->audio_clock = av_q2d(is->audio_st->time_base)*pkt->pts;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -349,7 +351,7 @@ namespace MWRender
|
||||||
if (is->video_st->codec->width != 0 && is->video_st->codec->height != 0)
|
if (is->video_st->codec->width != 0 && is->video_st->codec->height != 0)
|
||||||
{
|
{
|
||||||
Ogre::TexturePtr texture = Ogre::TextureManager::getSingleton ().getByName("VideoTexture");
|
Ogre::TexturePtr texture = Ogre::TextureManager::getSingleton ().getByName("VideoTexture");
|
||||||
if (texture.isNull () || texture->getWidth() != is->video_st->codec->width || texture->getHeight() != is->video_st->codec->height)
|
if (texture.isNull () || static_cast<int>(texture->getWidth()) != is->video_st->codec->width || static_cast<int>(texture->getHeight()) != is->video_st->codec->height)
|
||||||
{
|
{
|
||||||
Ogre::TextureManager::getSingleton ().remove ("VideoTexture");
|
Ogre::TextureManager::getSingleton ().remove ("VideoTexture");
|
||||||
texture = Ogre::TextureManager::getSingleton().createManual(
|
texture = Ogre::TextureManager::getSingleton().createManual(
|
||||||
|
@ -364,6 +366,7 @@ namespace MWRender
|
||||||
Ogre::PixelBox pb(is->video_st->codec->width, is->video_st->codec->height, 1, Ogre::PF_BYTE_RGBA, vp->data);
|
Ogre::PixelBox pb(is->video_st->codec->width, is->video_st->codec->height, 1, Ogre::PF_BYTE_RGBA, vp->data);
|
||||||
Ogre::HardwarePixelBufferSharedPtr buffer = texture->getBuffer();
|
Ogre::HardwarePixelBufferSharedPtr buffer = texture->getBuffer();
|
||||||
buffer->blitFromMemory(pb);
|
buffer->blitFromMemory(pb);
|
||||||
|
is->display_ready = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
free(vp->data);
|
free(vp->data);
|
||||||
|
@ -527,7 +530,7 @@ namespace MWRender
|
||||||
int video_thread(void *arg) {
|
int video_thread(void *arg) {
|
||||||
VideoState *is = (VideoState *)arg;
|
VideoState *is = (VideoState *)arg;
|
||||||
AVPacket pkt1, *packet = &pkt1;
|
AVPacket pkt1, *packet = &pkt1;
|
||||||
int len1, frameFinished;
|
int frameFinished;
|
||||||
AVFrame *pFrame;
|
AVFrame *pFrame;
|
||||||
double pts;
|
double pts;
|
||||||
|
|
||||||
|
@ -547,12 +550,15 @@ namespace MWRender
|
||||||
// Save global pts to be stored in pFrame
|
// Save global pts to be stored in pFrame
|
||||||
global_video_pkt_pts = packet->pts;
|
global_video_pkt_pts = packet->pts;
|
||||||
// Decode video frame
|
// Decode video frame
|
||||||
len1 = avcodec_decode_video2(is->video_st->codec, pFrame, &frameFinished,
|
if (avcodec_decode_video2(is->video_st->codec, pFrame, &frameFinished,
|
||||||
packet);
|
packet) < 0)
|
||||||
if(packet->dts == AV_NOPTS_VALUE
|
{
|
||||||
|
throw std::runtime_error("Error decoding video frame");
|
||||||
|
}
|
||||||
|
if((uint64_t)packet->dts == AV_NOPTS_VALUE
|
||||||
&& pFrame->opaque && *(uint64_t*)pFrame->opaque != AV_NOPTS_VALUE) {
|
&& pFrame->opaque && *(uint64_t*)pFrame->opaque != AV_NOPTS_VALUE) {
|
||||||
pts = *(uint64_t *)pFrame->opaque;
|
pts = *(uint64_t *)pFrame->opaque;
|
||||||
} else if(packet->dts != AV_NOPTS_VALUE) {
|
} else if((uint64_t)packet->dts != AV_NOPTS_VALUE) {
|
||||||
pts = packet->dts;
|
pts = packet->dts;
|
||||||
} else {
|
} else {
|
||||||
pts = 0;
|
pts = 0;
|
||||||
|
@ -586,7 +592,7 @@ namespace MWRender
|
||||||
AVCodec *codec;
|
AVCodec *codec;
|
||||||
SDL_AudioSpec wanted_spec, spec;
|
SDL_AudioSpec wanted_spec, spec;
|
||||||
|
|
||||||
if(stream_index < 0 || stream_index >= pFormatCtx->nb_streams) {
|
if(stream_index < 0 || stream_index >= static_cast<int>(pFormatCtx->nb_streams)) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -650,22 +656,24 @@ namespace MWRender
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int decode_interrupt_cb(void) {
|
int decode_interrupt_cb(void) {
|
||||||
return (global_video_state && global_video_state->quit);
|
return (global_video_state && global_video_state->quit);
|
||||||
}
|
}
|
||||||
|
|
||||||
int decode_thread(void *arg) {
|
int decode_thread(void *arg)
|
||||||
|
{
|
||||||
VideoState *is = (VideoState *)arg;
|
VideoState *is = (VideoState *)arg;
|
||||||
|
try
|
||||||
|
{
|
||||||
AVFormatContext *pFormatCtx = avformat_alloc_context ();
|
AVFormatContext *pFormatCtx = avformat_alloc_context ();
|
||||||
AVPacket pkt1, *packet = &pkt1;
|
AVPacket pkt1, *packet = &pkt1;
|
||||||
|
|
||||||
int video_index = -1;
|
int video_index = -1;
|
||||||
int audio_index = -1;
|
int audio_index = -1;
|
||||||
int i;
|
unsigned int i;
|
||||||
|
|
||||||
is->videoStream=-1;
|
is->videoStream=-1;
|
||||||
is->audioStream=-1;
|
is->audioStream=-1;
|
||||||
|
@ -753,6 +761,7 @@ namespace MWRender
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
is->quit = 1;
|
is->quit = 1;
|
||||||
|
|
||||||
is->audioq.cond.notify_one ();
|
is->audioq.cond.notify_one ();
|
||||||
|
@ -767,10 +776,21 @@ namespace MWRender
|
||||||
|
|
||||||
sws_freeContext (is->sws_context);
|
sws_freeContext (is->sws_context);
|
||||||
|
|
||||||
av_close_input_file(pFormatCtx);
|
avformat_close_input(&pFormatCtx);
|
||||||
pFormatCtx = NULL;
|
pFormatCtx = NULL;
|
||||||
|
|
||||||
av_free(ioContext);
|
av_free(ioContext);
|
||||||
|
}
|
||||||
|
catch (std::runtime_error& e)
|
||||||
|
{
|
||||||
|
std::cerr << "An error occured playing the video: " << e.what () << std::endl;
|
||||||
|
is->quit = 1;
|
||||||
|
}
|
||||||
|
catch (Ogre::Exception& e)
|
||||||
|
{
|
||||||
|
std::cerr << "An error occured playing the video: " << e.getFullDescription () << std::endl;
|
||||||
|
is->quit = 1;
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -857,8 +877,10 @@ namespace MWRender
|
||||||
close();
|
close();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!Ogre::TextureManager::getSingleton ().getByName ("VideoTexture").isNull ())
|
if (mState && mState->display_ready && !Ogre::TextureManager::getSingleton ().getByName ("VideoTexture").isNull ())
|
||||||
mVideoMaterial->getTechnique(0)->getPass(0)->getTextureUnitState (0)->setTextureName ("VideoTexture");
|
mVideoMaterial->getTechnique(0)->getPass(0)->getTextureUnitState (0)->setTextureName ("VideoTexture");
|
||||||
|
else
|
||||||
|
mVideoMaterial->getTechnique(0)->getPass(0)->getTextureUnitState (0)->setTextureName ("black.png");
|
||||||
}
|
}
|
||||||
|
|
||||||
void VideoPlayer::close()
|
void VideoPlayer::close()
|
||||||
|
|
|
@ -48,6 +48,8 @@ namespace MWRender
|
||||||
|
|
||||||
boost::mutex mutex;
|
boost::mutex mutex;
|
||||||
boost::condition_variable cond;
|
boost::condition_variable cond;
|
||||||
|
|
||||||
|
void flush ();
|
||||||
};
|
};
|
||||||
struct VideoPicture {
|
struct VideoPicture {
|
||||||
VideoPicture () :
|
VideoPicture () :
|
||||||
|
@ -58,8 +60,6 @@ namespace MWRender
|
||||||
double pts;
|
double pts;
|
||||||
};
|
};
|
||||||
|
|
||||||
static void packet_queue_flush(PacketQueue *q);
|
|
||||||
|
|
||||||
struct VideoState {
|
struct VideoState {
|
||||||
VideoState () :
|
VideoState () :
|
||||||
videoStream(-1), audioStream(-1), av_sync_type(0), external_clock(0),
|
videoStream(-1), audioStream(-1), av_sync_type(0), external_clock(0),
|
||||||
|
@ -67,14 +67,14 @@ namespace MWRender
|
||||||
audio_pkt_data(NULL), audio_pkt_size(0), audio_hw_buf_size(0), audio_diff_cum(0), audio_diff_avg_coef(0),
|
audio_pkt_data(NULL), audio_pkt_size(0), audio_hw_buf_size(0), audio_diff_cum(0), audio_diff_avg_coef(0),
|
||||||
audio_diff_threshold(0), audio_diff_avg_count(0), frame_timer(0), frame_last_pts(0), frame_last_delay(0),
|
audio_diff_threshold(0), audio_diff_avg_count(0), frame_timer(0), frame_last_pts(0), frame_last_delay(0),
|
||||||
video_clock(0), video_current_pts(0), video_current_pts_time(0), video_st(NULL), rgbaFrame(NULL), pictq_size(0),
|
video_clock(0), video_current_pts(0), video_current_pts_time(0), video_st(NULL), rgbaFrame(NULL), pictq_size(0),
|
||||||
pictq_rindex(0), pictq_windex(0), quit(false), refresh(0), sws_context(NULL)
|
pictq_rindex(0), pictq_windex(0), quit(false), refresh(0), sws_context(NULL), display_ready(0)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
|
||||||
~VideoState()
|
~VideoState()
|
||||||
{
|
{
|
||||||
packet_queue_flush (&audioq);
|
audioq.flush ();
|
||||||
packet_queue_flush (&videoq);
|
videoq.flush();
|
||||||
|
|
||||||
if (pictq_size >= 1)
|
if (pictq_size >= 1)
|
||||||
free (pictq[0].data);
|
free (pictq[0].data);
|
||||||
|
@ -126,6 +126,7 @@ namespace MWRender
|
||||||
int quit;
|
int quit;
|
||||||
|
|
||||||
int refresh;
|
int refresh;
|
||||||
|
int display_ready;
|
||||||
};
|
};
|
||||||
enum {
|
enum {
|
||||||
AV_SYNC_AUDIO_MASTER,
|
AV_SYNC_AUDIO_MASTER,
|
||||||
|
|
|
@ -277,7 +277,7 @@ void FFmpeg_Decoder::open(const std::string &fname)
|
||||||
ss << stream->mCodecCtx->codec_id;
|
ss << stream->mCodecCtx->codec_id;
|
||||||
fail(ss.str());
|
fail(ss.str());
|
||||||
}
|
}
|
||||||
if(avcodec_open(stream->mCodecCtx, codec) < 0)
|
if(avcodec_open2(stream->mCodecCtx, codec, NULL) < 0)
|
||||||
fail("Failed to open audio codec " + std::string(codec->long_name));
|
fail("Failed to open audio codec " + std::string(codec->long_name));
|
||||||
|
|
||||||
stream->mDecodedData = (char*)av_malloc(AVCODEC_MAX_AUDIO_FRAME_SIZE);
|
stream->mDecodedData = (char*)av_malloc(AVCODEC_MAX_AUDIO_FRAME_SIZE);
|
||||||
|
@ -293,7 +293,7 @@ void FFmpeg_Decoder::open(const std::string &fname)
|
||||||
}
|
}
|
||||||
catch(std::exception &e)
|
catch(std::exception &e)
|
||||||
{
|
{
|
||||||
av_close_input_file(mFormatCtx);
|
avformat_close_input(&mFormatCtx);
|
||||||
mFormatCtx = NULL;
|
mFormatCtx = NULL;
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
|
@ -317,7 +317,7 @@ void FFmpeg_Decoder::close()
|
||||||
AVIOContext* context = mFormatCtx->pb;
|
AVIOContext* context = mFormatCtx->pb;
|
||||||
av_free(context);
|
av_free(context);
|
||||||
mFormatCtx->pb = NULL;
|
mFormatCtx->pb = NULL;
|
||||||
av_close_input_file(mFormatCtx);
|
avformat_close_input(&mFormatCtx);
|
||||||
}
|
}
|
||||||
mFormatCtx = NULL;
|
mFormatCtx = NULL;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue