From 806496d191c338441828decad32e75d662274889 Mon Sep 17 00:00:00 2001 From: rdb Date: Fri, 23 Aug 2019 10:50:40 +0200 Subject: [PATCH] ffmpeg: proper fallback when compiling without libswscale Compiling with libswscale isn't really optional if you want to play most video files, but if you know what you are doing and all your videos already have a supported pixel formats, it is now possible. Fixes #711 --- panda/src/ffmpeg/ffmpegVideoCursor.cxx | 38 ++++++++++++++++++-------- 1 file changed, 26 insertions(+), 12 deletions(-) diff --git a/panda/src/ffmpeg/ffmpegVideoCursor.cxx b/panda/src/ffmpeg/ffmpegVideoCursor.cxx index 23314561e9..8b700d2342 100644 --- a/panda/src/ffmpeg/ffmpegVideoCursor.cxx +++ b/panda/src/ffmpeg/ffmpegVideoCursor.cxx @@ -138,6 +138,15 @@ init_from(FfmpegVideo *source) { _convert_ctx = sws_getContext(_size_x, _size_y, _video_ctx->pix_fmt, _size_x, _size_y, (AVPixelFormat)_pixel_format, SWS_BILINEAR | SWS_PRINT_INFO, nullptr, nullptr, nullptr); +#else + if (_video_ctx->pix_fmt != _pixel_format) { + const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(_video_ctx->pix_fmt); + ffmpeg_cat.error() + << "Video with pixel format " << (desc ? desc->name : "?") + << " needs conversion, but libswscale support is not enabled.\n"; + cleanup(); + return; + } #endif // HAVE_SWSCALE #ifdef HAVE_THREADS @@ -1164,24 +1173,29 @@ export_frame(FfmpegBuffer *buffer) { buffer->_begin_frame = _begin_frame; buffer->_end_frame = _end_frame; +#ifdef HAVE_SWSCALE + nassertv(_convert_ctx != nullptr && _frame != nullptr); if (ffmpeg_global_lock) { ReMutexHolder av_holder(_av_lock); -#ifdef HAVE_SWSCALE - nassertv(_convert_ctx != nullptr && _frame != nullptr && _frame_out != nullptr); sws_scale(_convert_ctx, _frame->data, _frame->linesize, 0, _size_y, _frame_out->data, _frame_out->linesize); -#else - img_convert((AVPicture *)_frame_out, (AVPixelFormat)_pixel_format, - (AVPicture *)_frame, _video_ctx->pix_fmt, _size_x, _size_y); -#endif } else { -#ifdef HAVE_SWSCALE - nassertv(_convert_ctx != nullptr && _frame != nullptr && _frame_out != nullptr); sws_scale(_convert_ctx, _frame->data, _frame->linesize, 0, _size_y, _frame_out->data, _frame_out->linesize); -#else - img_convert((AVPicture *)_frame_out, (AVPixelFormat)_pixel_format, - (AVPicture *)_frame, _video_ctx->pix_fmt, _size_x, _size_y); -#endif } +#else + nassertv(_frame != nullptr); + uint8_t const *src = _frame->data[0]; + uint8_t *dst = _frame_out->data[0]; + int src_stride = _frame->linesize[0]; + int dst_stride = _frame_out->linesize[0]; + size_t copy_size = _size_x * _num_components; + nassertv(copy_size <= (size_t)std::abs(src_stride)); + + for (int y = 0; y < _size_y; ++y) { + memcpy(dst, src, copy_size); + src += src_stride; + dst += dst_stride; + } +#endif } /**