mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-01 01:07:51 -04:00
ffmpeg-global-lock
This commit is contained in:
parent
5d00998747
commit
f6a0af6f8d
@ -58,6 +58,16 @@ ConfigVariableBool ffmpeg_support_seek
|
|||||||
"which can be much slower. Set this false only if you suspect "
|
"which can be much slower. Set this false only if you suspect "
|
||||||
"a problem with av_seek_frame()."));
|
"a problem with av_seek_frame()."));
|
||||||
|
|
||||||
|
ConfigVariableBool ffmpeg_global_lock
|
||||||
|
("ffmpeg-global-lock", false,
|
||||||
|
PRC_DESC("Set this true to enable a single global mutex across *all* ffmpeg "
|
||||||
|
"operations. Leave this false to use the mutex only for "
|
||||||
|
"the ffmpeg operations that are generally known to be "
|
||||||
|
"not thread-safe. This will negatively affect ffmpeg performance, "
|
||||||
|
"especially when decoding multiple videos at once (including the "
|
||||||
|
"left and right channels of a stereo video). Set this true only "
|
||||||
|
"if you suspect a problem with ffmpeg's own thread-safe nature."));
|
||||||
|
|
||||||
ConfigVariableEnum<ThreadPriority> ffmpeg_thread_priority
|
ConfigVariableEnum<ThreadPriority> ffmpeg_thread_priority
|
||||||
("ffmpeg-thread-priority", TP_normal,
|
("ffmpeg-thread-priority", TP_normal,
|
||||||
PRC_DESC("The default thread priority at which to start ffmpeg decoder "
|
PRC_DESC("The default thread priority at which to start ffmpeg decoder "
|
||||||
|
@ -29,6 +29,7 @@ NotifyCategoryDecl(ffmpeg, EXPCL_PANDA_MOVIES, EXPTP_PANDA_MOVIES);
|
|||||||
|
|
||||||
extern ConfigVariableInt ffmpeg_max_readahead_frames;
|
extern ConfigVariableInt ffmpeg_max_readahead_frames;
|
||||||
extern ConfigVariableBool ffmpeg_support_seek;
|
extern ConfigVariableBool ffmpeg_support_seek;
|
||||||
|
extern ConfigVariableBool ffmpeg_global_lock;
|
||||||
extern ConfigVariableEnum<ThreadPriority> ffmpeg_thread_priority;
|
extern ConfigVariableEnum<ThreadPriority> ffmpeg_thread_priority;
|
||||||
|
|
||||||
extern EXPCL_PANDA_MOVIES void init_libmovies();
|
extern EXPCL_PANDA_MOVIES void init_libmovies();
|
||||||
|
@ -827,6 +827,22 @@ do_recycle_all_frames() {
|
|||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
bool FfmpegVideoCursor::
|
bool FfmpegVideoCursor::
|
||||||
fetch_packet(int default_frame) {
|
fetch_packet(int default_frame) {
|
||||||
|
if (ffmpeg_global_lock) {
|
||||||
|
ReMutexHolder av_holder(_av_lock);
|
||||||
|
return do_fetch_packet(default_frame);
|
||||||
|
} else {
|
||||||
|
return do_fetch_packet(default_frame);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: FfmpegVideoCursor::do_fetch_packet
|
||||||
|
// Access: Private
|
||||||
|
// Description: As above, with the ffmpeg global lock held (if
|
||||||
|
// configured on).
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
bool FfmpegVideoCursor::
|
||||||
|
do_fetch_packet(int default_frame) {
|
||||||
if (_packet0->data) {
|
if (_packet0->data) {
|
||||||
av_free_packet(_packet0);
|
av_free_packet(_packet0);
|
||||||
}
|
}
|
||||||
@ -906,12 +922,7 @@ fetch_frame(int frame) {
|
|||||||
PStatTimer timer(seek_pcollector);
|
PStatTimer timer(seek_pcollector);
|
||||||
|
|
||||||
// Decode and discard the previous packet.
|
// Decode and discard the previous packet.
|
||||||
#if LIBAVCODEC_VERSION_INT < 3414272
|
decode_frame(finished, _packet1);
|
||||||
avcodec_decode_video(_video_ctx, _frame,
|
|
||||||
&finished, _packet1->data, _packet1->size);
|
|
||||||
#else
|
|
||||||
avcodec_decode_video2(_video_ctx, _frame, &finished, _packet1);
|
|
||||||
#endif
|
|
||||||
flip_packets();
|
flip_packets();
|
||||||
_begin_frame = _packet_frame;
|
_begin_frame = _packet_frame;
|
||||||
if (fetch_packet(frame)) {
|
if (fetch_packet(frame)) {
|
||||||
@ -925,23 +936,13 @@ fetch_frame(int frame) {
|
|||||||
// At this point, _packet0 contains the *next* packet to be
|
// At this point, _packet0 contains the *next* packet to be
|
||||||
// decoded next frame, and _packet1 contains the packet to decode
|
// decoded next frame, and _packet1 contains the packet to decode
|
||||||
// for this frame.
|
// for this frame.
|
||||||
#if LIBAVCODEC_VERSION_INT < 3414272
|
decode_frame(finished, _packet1);
|
||||||
avcodec_decode_video(_video_ctx, _frame,
|
|
||||||
&finished, _packet1->data, _packet1->size);
|
|
||||||
#else
|
|
||||||
avcodec_decode_video2(_video_ctx, _frame, &finished, _packet1);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
// Just get the next frame.
|
// Just get the next frame.
|
||||||
finished = 0;
|
finished = 0;
|
||||||
while (!finished && _packet0->data) {
|
while (!finished && _packet0->data) {
|
||||||
#if LIBAVCODEC_VERSION_INT < 3414272
|
decode_frame(finished, _packet0);
|
||||||
avcodec_decode_video(_video_ctx, _frame,
|
|
||||||
&finished, _packet0->data, _packet0->size);
|
|
||||||
#else
|
|
||||||
avcodec_decode_video2(_video_ctx, _frame, &finished, _packet0);
|
|
||||||
#endif
|
|
||||||
_begin_frame = _packet_frame;
|
_begin_frame = _packet_frame;
|
||||||
fetch_packet(_begin_frame + 1);
|
fetch_packet(_begin_frame + 1);
|
||||||
}
|
}
|
||||||
@ -951,6 +952,38 @@ fetch_frame(int frame) {
|
|||||||
_frame_ready = true;
|
_frame_ready = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: FfmpegVideoCursor::decode_frame
|
||||||
|
// Access: Private
|
||||||
|
// Description: Called within the sub-thread. Decodes the data in
|
||||||
|
// the specified packet into _frame.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void FfmpegVideoCursor::
|
||||||
|
decode_frame(int &finished, AVPacket *packet) {
|
||||||
|
if (ffmpeg_global_lock) {
|
||||||
|
ReMutexHolder av_holder(_av_lock);
|
||||||
|
do_decode_frame(finished, packet);
|
||||||
|
} else {
|
||||||
|
do_decode_frame(finished, packet);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: FfmpegVideoCursor::do_decode_frame
|
||||||
|
// Access: Private
|
||||||
|
// Description: As above, with the ffmpeg global lock held (if
|
||||||
|
// configured on).
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void FfmpegVideoCursor::
|
||||||
|
do_decode_frame(int &finished, AVPacket *packet) {
|
||||||
|
#if LIBAVCODEC_VERSION_INT < 3414272
|
||||||
|
avcodec_decode_video(_video_ctx, _frame,
|
||||||
|
&finished, packet->data, packet->size);
|
||||||
|
#else
|
||||||
|
avcodec_decode_video2(_video_ctx, _frame, &finished, packet);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: FfmpegVideoCursor::seek
|
// Function: FfmpegVideoCursor::seek
|
||||||
// Access: Private
|
// Access: Private
|
||||||
@ -1182,13 +1215,25 @@ export_frame(FfmpegBuffer *buffer) {
|
|||||||
_frame_out->linesize[0] = _size_x * -3;
|
_frame_out->linesize[0] = _size_x * -3;
|
||||||
buffer->_begin_frame = _begin_frame;
|
buffer->_begin_frame = _begin_frame;
|
||||||
buffer->_end_frame = _end_frame;
|
buffer->_end_frame = _end_frame;
|
||||||
|
|
||||||
|
if (ffmpeg_global_lock) {
|
||||||
|
ReMutexHolder av_holder(_av_lock);
|
||||||
#ifdef HAVE_SWSCALE
|
#ifdef HAVE_SWSCALE
|
||||||
nassertv(_convert_ctx != NULL && _frame != NULL && _frame_out != NULL);
|
nassertv(_convert_ctx != NULL && _frame != NULL && _frame_out != NULL);
|
||||||
sws_scale(_convert_ctx, _frame->data, _frame->linesize, 0, _size_y, _frame_out->data, _frame_out->linesize);
|
sws_scale(_convert_ctx, _frame->data, _frame->linesize, 0, _size_y, _frame_out->data, _frame_out->linesize);
|
||||||
#else
|
#else
|
||||||
img_convert((AVPicture *)_frame_out, PIX_FMT_BGR24,
|
img_convert((AVPicture *)_frame_out, PIX_FMT_BGR24,
|
||||||
(AVPicture *)_frame, _video_ctx->pix_fmt, _size_x, _size_y);
|
(AVPicture *)_frame, _video_ctx->pix_fmt, _size_x, _size_y);
|
||||||
#endif
|
#endif
|
||||||
|
} else {
|
||||||
|
#ifdef HAVE_SWSCALE
|
||||||
|
nassertv(_convert_ctx != NULL && _frame != NULL && _frame_out != NULL);
|
||||||
|
sws_scale(_convert_ctx, _frame->data, _frame->linesize, 0, _size_y, _frame_out->data, _frame_out->linesize);
|
||||||
|
#else
|
||||||
|
img_convert((AVPicture *)_frame_out, PIX_FMT_BGR24,
|
||||||
|
(AVPicture *)_frame, _video_ctx->pix_fmt, _size_x, _size_y);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
|
@ -124,8 +124,11 @@ private:
|
|||||||
void do_recycle_all_frames();
|
void do_recycle_all_frames();
|
||||||
|
|
||||||
bool fetch_packet(int default_frame);
|
bool fetch_packet(int default_frame);
|
||||||
|
bool do_fetch_packet(int default_frame);
|
||||||
void flip_packets();
|
void flip_packets();
|
||||||
void fetch_frame(int frame);
|
void fetch_frame(int frame);
|
||||||
|
void decode_frame(int &finished, AVPacket *packet);
|
||||||
|
void do_decode_frame(int &finished, AVPacket *packet);
|
||||||
void seek(int frame, bool backward);
|
void seek(int frame, bool backward);
|
||||||
int binary_seek(int min_frame, int max_frame, int target_frame, int num_iterations);
|
int binary_seek(int min_frame, int max_frame, int target_frame, int num_iterations);
|
||||||
void advance_to_frame(int frame);
|
void advance_to_frame(int frame);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user