add PacketGuard and move try/catch up

pull/3088/head
Evil Eye 4 years ago
parent 1b61ec979d
commit 3b7cef9e88

@ -37,6 +37,39 @@ namespace
{ {
const int MAX_AUDIOQ_SIZE = (5 * 16 * 1024); const int MAX_AUDIOQ_SIZE = (5 * 16 * 1024);
const int MAX_VIDEOQ_SIZE = (5 * 256 * 1024); const int MAX_VIDEOQ_SIZE = (5 * 256 * 1024);
class PacketGuard
{
AVPacket mPacket;
bool mReleased;
public:
PacketGuard() : mReleased(false)
{
av_init_packet(&mPacket);
}
AVPacket* operator->()
{
return &mPacket;
}
AVPacket* operator*()
{
return &mPacket;
}
AVPacket* release()
{
mReleased = true;
return &mPacket;
}
~PacketGuard()
{
if(!mReleased)
av_packet_unref(&mPacket);
}
};
} }
namespace Video namespace Video
@ -98,7 +131,7 @@ void PacketQueue::put(AVPacket *pkt)
this->last_pkt->next = pkt1.get(); this->last_pkt->next = pkt1.get();
this->last_pkt = pkt1.release(); this->last_pkt = pkt1.release();
this->nb_packets++; this->nb_packets++;
this->size += pkt1->pkt.size; this->size += this->last_pkt->pkt.size;
this->cond.notify_one(); this->cond.notify_one();
} }
@ -383,7 +416,17 @@ class VideoThread
public: public:
VideoThread(VideoState* self) VideoThread(VideoState* self)
: mVideoState(self) : mVideoState(self)
, mThread([this] { run(); }) , mThread([this]
{
try
{
run();
}
catch(std::exception& e)
{
std::cerr << "An error occurred playing the video: " << e.what () << std::endl;
}
})
{ {
} }
@ -395,15 +438,10 @@ public:
void run() void run()
{ {
VideoState* self = mVideoState; VideoState* self = mVideoState;
AVPacket pkt1, *packet = &pkt1; PacketGuard packet;
av_init_packet(packet); std::unique_ptr<AVFrame, VideoPicture::AVFrameDeleter> pFrame{av_frame_alloc()};
AVFrame *pFrame;
pFrame = av_frame_alloc(); while(self->videoq.get(*packet, self) >= 0)
try
{
while(self->videoq.get(packet, self) >= 0)
{ {
if(packet->data == flush_pkt.data) if(packet->data == flush_pkt.data)
{ {
@ -420,36 +458,27 @@ public:
} }
// Decode video frame // Decode video frame
int ret = avcodec_send_packet(self->video_ctx, packet); int ret = avcodec_send_packet(self->video_ctx, *packet);
// EAGAIN is not expected // EAGAIN is not expected
if (ret < 0) if (ret < 0)
throw std::runtime_error("Error decoding video frame"); throw std::runtime_error("Error decoding video frame");
while (!ret) while (!ret)
{ {
ret = avcodec_receive_frame(self->video_ctx, pFrame); ret = avcodec_receive_frame(self->video_ctx, pFrame.get());
if (!ret) if (!ret)
{ {
double pts = pFrame->best_effort_timestamp; double pts = pFrame->best_effort_timestamp;
pts *= av_q2d((*self->video_st)->time_base); pts *= av_q2d((*self->video_st)->time_base);
pts = self->synchronize_video(pFrame, pts); pts = self->synchronize_video(pFrame.get(), pts);
if(self->queue_picture(pFrame, pts) < 0) if(self->queue_picture(pFrame.get(), pts) < 0)
break; break;
} }
} }
} }
} }
catch(std::exception& e)
{
std::cerr << "An error occurred playing the video: " << e.what () << std::endl;
}
av_packet_unref(packet);
av_frame_free(&pFrame);
}
private: private:
VideoState* mVideoState; VideoState* mVideoState;
@ -475,8 +504,7 @@ public:
VideoState* self = mVideoState; VideoState* self = mVideoState;
AVFormatContext *pFormatCtx = self->format_ctx; AVFormatContext *pFormatCtx = self->format_ctx;
AVPacket pkt1, *packet = &pkt1; PacketGuard packet;
av_init_packet(packet);
try try
{ {
@ -559,7 +587,7 @@ public:
continue; continue;
} }
if(av_read_frame(pFormatCtx, packet) < 0) if(av_read_frame(pFormatCtx, *packet) < 0)
{ {
if (self->audioq.nb_packets == 0 && self->videoq.nb_packets == 0 && self->pictq_size == 0) if (self->audioq.nb_packets == 0 && self->videoq.nb_packets == 0 && self->pictq_size == 0)
self->mVideoEnded = true; self->mVideoEnded = true;
@ -570,11 +598,9 @@ public:
// Is this a packet from the video stream? // Is this a packet from the video stream?
if(self->video_st && packet->stream_index == self->video_st-pFormatCtx->streams) if(self->video_st && packet->stream_index == self->video_st-pFormatCtx->streams)
self->videoq.put(packet); self->videoq.put(packet.release());
else if(self->audio_st && packet->stream_index == self->audio_st-pFormatCtx->streams) else if(self->audio_st && packet->stream_index == self->audio_st-pFormatCtx->streams)
self->audioq.put(packet); self->audioq.put(packet.release());
else
av_packet_unref(packet);
} }
} }
catch(std::exception& e) { catch(std::exception& e) {

Loading…
Cancel
Save