mirror of
https://github.com/LibreELEC/LibreELEC.tv.git
synced 2025-07-29 05:36:47 +00:00
Merge pull request #7689 from HiassofT/le11-rpi-h264-hi10-fix
[le11] RPi: fix playback of 10bit H264 files
This commit is contained in:
commit
08665f1c32
@ -1,5 +1,5 @@
|
|||||||
diff --git a/configure b/configure
|
diff --git a/configure b/configure
|
||||||
index d7a3f507e8..83383b0317 100755
|
index 4ba72bf84b..f2fc33e89b 100755
|
||||||
--- a/configure
|
--- a/configure
|
||||||
+++ b/configure
|
+++ b/configure
|
||||||
@@ -207,6 +207,7 @@ External library support:
|
@@ -207,6 +207,7 @@ External library support:
|
||||||
@ -104,7 +104,7 @@ index d7a3f507e8..83383b0317 100755
|
|||||||
huffyuv_decoder_select="bswapdsp huffyuvdsp llviddsp"
|
huffyuv_decoder_select="bswapdsp huffyuvdsp llviddsp"
|
||||||
huffyuv_encoder_select="bswapdsp huffman huffyuvencdsp llvidencdsp"
|
huffyuv_encoder_select="bswapdsp huffman huffyuvencdsp llvidencdsp"
|
||||||
hymt_decoder_select="huffyuv_decoder"
|
hymt_decoder_select="huffyuv_decoder"
|
||||||
@@ -2919,6 +2941,7 @@ d3d11va_deps="dxva_h ID3D11VideoDecoder ID3D11VideoContext"
|
@@ -2920,6 +2942,7 @@ d3d11va_deps="dxva_h ID3D11VideoDecoder ID3D11VideoContext"
|
||||||
dxva2_deps="dxva2api_h DXVA2_ConfigPictureDecode ole32 user32"
|
dxva2_deps="dxva2api_h DXVA2_ConfigPictureDecode ole32 user32"
|
||||||
ffnvcodec_deps_any="libdl LoadLibrary"
|
ffnvcodec_deps_any="libdl LoadLibrary"
|
||||||
nvdec_deps="ffnvcodec"
|
nvdec_deps="ffnvcodec"
|
||||||
@ -112,7 +112,7 @@ index d7a3f507e8..83383b0317 100755
|
|||||||
vaapi_x11_deps="xlib"
|
vaapi_x11_deps="xlib"
|
||||||
videotoolbox_hwaccel_deps="videotoolbox pthreads"
|
videotoolbox_hwaccel_deps="videotoolbox pthreads"
|
||||||
videotoolbox_hwaccel_extralibs="-framework QuartzCore"
|
videotoolbox_hwaccel_extralibs="-framework QuartzCore"
|
||||||
@@ -2960,6 +2983,12 @@ hevc_dxva2_hwaccel_deps="dxva2 DXVA_PicParams_HEVC"
|
@@ -2961,6 +2984,12 @@ hevc_dxva2_hwaccel_deps="dxva2 DXVA_PicParams_HEVC"
|
||||||
hevc_dxva2_hwaccel_select="hevc_decoder"
|
hevc_dxva2_hwaccel_select="hevc_decoder"
|
||||||
hevc_nvdec_hwaccel_deps="nvdec"
|
hevc_nvdec_hwaccel_deps="nvdec"
|
||||||
hevc_nvdec_hwaccel_select="hevc_decoder"
|
hevc_nvdec_hwaccel_select="hevc_decoder"
|
||||||
@ -125,7 +125,7 @@ index d7a3f507e8..83383b0317 100755
|
|||||||
hevc_vaapi_hwaccel_deps="vaapi VAPictureParameterBufferHEVC"
|
hevc_vaapi_hwaccel_deps="vaapi VAPictureParameterBufferHEVC"
|
||||||
hevc_vaapi_hwaccel_select="hevc_decoder"
|
hevc_vaapi_hwaccel_select="hevc_decoder"
|
||||||
hevc_vdpau_hwaccel_deps="vdpau VdpPictureInfoHEVC"
|
hevc_vdpau_hwaccel_deps="vdpau VdpPictureInfoHEVC"
|
||||||
@@ -3437,8 +3466,13 @@ sndio_indev_deps="sndio"
|
@@ -3438,8 +3467,13 @@ sndio_indev_deps="sndio"
|
||||||
sndio_outdev_deps="sndio"
|
sndio_outdev_deps="sndio"
|
||||||
v4l2_indev_deps_any="linux_videodev2_h sys_videoio_h"
|
v4l2_indev_deps_any="linux_videodev2_h sys_videoio_h"
|
||||||
v4l2_indev_suggest="libv4l2"
|
v4l2_indev_suggest="libv4l2"
|
||||||
@ -139,7 +139,7 @@ index d7a3f507e8..83383b0317 100755
|
|||||||
vfwcap_indev_deps="vfw32 vfwcap_defines"
|
vfwcap_indev_deps="vfw32 vfwcap_defines"
|
||||||
xcbgrab_indev_deps="libxcb"
|
xcbgrab_indev_deps="libxcb"
|
||||||
xcbgrab_indev_suggest="libxcb_shm libxcb_shape libxcb_xfixes"
|
xcbgrab_indev_suggest="libxcb_shm libxcb_shape libxcb_xfixes"
|
||||||
@@ -3657,6 +3691,7 @@ tonemap_vaapi_filter_deps="vaapi VAProcFilterParameterBufferHDRToneMapping"
|
@@ -3658,6 +3692,7 @@ tonemap_vaapi_filter_deps="vaapi VAProcFilterParameterBufferHDRToneMapping"
|
||||||
tonemap_opencl_filter_deps="opencl const_nan"
|
tonemap_opencl_filter_deps="opencl const_nan"
|
||||||
transpose_opencl_filter_deps="opencl"
|
transpose_opencl_filter_deps="opencl"
|
||||||
transpose_vaapi_filter_deps="vaapi VAProcPipelineCaps_rotation_flags"
|
transpose_vaapi_filter_deps="vaapi VAProcPipelineCaps_rotation_flags"
|
||||||
@ -147,7 +147,7 @@ index d7a3f507e8..83383b0317 100755
|
|||||||
unsharp_opencl_filter_deps="opencl"
|
unsharp_opencl_filter_deps="opencl"
|
||||||
uspp_filter_deps="gpl avcodec"
|
uspp_filter_deps="gpl avcodec"
|
||||||
vaguedenoiser_filter_deps="gpl"
|
vaguedenoiser_filter_deps="gpl"
|
||||||
@@ -6154,6 +6189,12 @@ check_func_headers glob.h glob
|
@@ -6155,6 +6190,12 @@ check_func_headers glob.h glob
|
||||||
enabled xlib &&
|
enabled xlib &&
|
||||||
check_lib xlib "X11/Xlib.h X11/extensions/Xvlib.h" XvGetPortAttribute -lXv -lX11 -lXext
|
check_lib xlib "X11/Xlib.h X11/extensions/Xvlib.h" XvGetPortAttribute -lXv -lX11 -lXext
|
||||||
|
|
||||||
@ -160,7 +160,7 @@ index d7a3f507e8..83383b0317 100755
|
|||||||
check_headers direct.h
|
check_headers direct.h
|
||||||
check_headers dirent.h
|
check_headers dirent.h
|
||||||
check_headers dxgidebug.h
|
check_headers dxgidebug.h
|
||||||
@@ -6491,11 +6532,12 @@ enabled mbedtls && { check_pkg_config mbedtls mbedtls mbedtls/x509_crt
|
@@ -6492,11 +6533,12 @@ enabled mbedtls && { check_pkg_config mbedtls mbedtls mbedtls/x509_crt
|
||||||
check_lib mbedtls mbedtls/ssl.h mbedtls_ssl_init -lmbedtls -lmbedx509 -lmbedcrypto ||
|
check_lib mbedtls mbedtls/ssl.h mbedtls_ssl_init -lmbedtls -lmbedx509 -lmbedcrypto ||
|
||||||
die "ERROR: mbedTLS not found"; }
|
die "ERROR: mbedTLS not found"; }
|
||||||
enabled mediacodec && { enabled jni || die "ERROR: mediacodec requires --enable-jni"; }
|
enabled mediacodec && { enabled jni || die "ERROR: mediacodec requires --enable-jni"; }
|
||||||
@ -175,7 +175,7 @@ index d7a3f507e8..83383b0317 100755
|
|||||||
die "ERROR: mmal not found" &&
|
die "ERROR: mmal not found" &&
|
||||||
check_func_headers interface/mmal/mmal.h "MMAL_PARAMETER_VIDEO_MAX_NUM_CALLBACKS"; }
|
check_func_headers interface/mmal/mmal.h "MMAL_PARAMETER_VIDEO_MAX_NUM_CALLBACKS"; }
|
||||||
enabled openal && { { for al_extralibs in "${OPENAL_LIBS}" "-lopenal" "-lOpenAL32"; do
|
enabled openal && { { for al_extralibs in "${OPENAL_LIBS}" "-lopenal" "-lOpenAL32"; do
|
||||||
@@ -6536,8 +6578,16 @@ enabled rkmpp && { require_pkg_config rkmpp rockchip_mpp rockchip/r
|
@@ -6537,8 +6579,16 @@ enabled rkmpp && { require_pkg_config rkmpp rockchip_mpp rockchip/r
|
||||||
{ enabled libdrm ||
|
{ enabled libdrm ||
|
||||||
die "ERROR: rkmpp requires --enable-libdrm"; }
|
die "ERROR: rkmpp requires --enable-libdrm"; }
|
||||||
}
|
}
|
||||||
@ -192,7 +192,7 @@ index d7a3f507e8..83383b0317 100755
|
|||||||
|
|
||||||
if enabled gcrypt; then
|
if enabled gcrypt; then
|
||||||
GCRYPT_CONFIG="${cross_prefix}libgcrypt-config"
|
GCRYPT_CONFIG="${cross_prefix}libgcrypt-config"
|
||||||
@@ -6617,6 +6667,10 @@ if enabled v4l2_m2m; then
|
@@ -6618,6 +6668,10 @@ if enabled v4l2_m2m; then
|
||||||
check_cc vp9_v4l2_m2m linux/videodev2.h "int i = V4L2_PIX_FMT_VP9;"
|
check_cc vp9_v4l2_m2m linux/videodev2.h "int i = V4L2_PIX_FMT_VP9;"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@ -203,7 +203,7 @@ index d7a3f507e8..83383b0317 100755
|
|||||||
check_headers sys/videoio.h
|
check_headers sys/videoio.h
|
||||||
test_code cc sys/videoio.h "struct v4l2_frmsizeenum vfse; vfse.discrete.width = 0;" && enable_sanitized struct_v4l2_frmivalenum_discrete
|
test_code cc sys/videoio.h "struct v4l2_frmsizeenum vfse; vfse.discrete.width = 0;" && enable_sanitized struct_v4l2_frmivalenum_discrete
|
||||||
|
|
||||||
@@ -7104,6 +7158,9 @@ check_deps $CONFIG_LIST \
|
@@ -7105,6 +7159,9 @@ check_deps $CONFIG_LIST \
|
||||||
enabled threads && ! enabled pthreads && ! enabled atomics_native && die "non pthread threading without atomics not supported, try adding --enable-pthreads or --cpu=i486 or higher if you are on x86"
|
enabled threads && ! enabled pthreads && ! enabled atomics_native && die "non pthread threading without atomics not supported, try adding --enable-pthreads or --cpu=i486 or higher if you are on x86"
|
||||||
enabled avresample && warn "Building with deprecated library libavresample"
|
enabled avresample && warn "Building with deprecated library libavresample"
|
||||||
|
|
||||||
@ -214,10 +214,10 @@ index d7a3f507e8..83383b0317 100755
|
|||||||
haiku)
|
haiku)
|
||||||
disable memalign
|
disable memalign
|
||||||
diff --git a/fftools/ffmpeg.c b/fftools/ffmpeg.c
|
diff --git a/fftools/ffmpeg.c b/fftools/ffmpeg.c
|
||||||
index 46bb014de8..0502ff71b8 100644
|
index dec012a299..8aa13007f9 100644
|
||||||
--- a/fftools/ffmpeg.c
|
--- a/fftools/ffmpeg.c
|
||||||
+++ b/fftools/ffmpeg.c
|
+++ b/fftools/ffmpeg.c
|
||||||
@@ -2186,8 +2186,8 @@ static int ifilter_send_frame(InputFilter *ifilter, AVFrame *frame)
|
@@ -2189,8 +2189,8 @@ static int ifilter_send_frame(InputFilter *ifilter, AVFrame *frame)
|
||||||
ifilter->channel_layout != frame->channel_layout;
|
ifilter->channel_layout != frame->channel_layout;
|
||||||
break;
|
break;
|
||||||
case AVMEDIA_TYPE_VIDEO:
|
case AVMEDIA_TYPE_VIDEO:
|
||||||
@ -228,7 +228,7 @@ index 46bb014de8..0502ff71b8 100644
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2198,6 +2198,9 @@ static int ifilter_send_frame(InputFilter *ifilter, AVFrame *frame)
|
@@ -2201,6 +2201,9 @@ static int ifilter_send_frame(InputFilter *ifilter, AVFrame *frame)
|
||||||
(ifilter->hw_frames_ctx && ifilter->hw_frames_ctx->data != frame->hw_frames_ctx->data))
|
(ifilter->hw_frames_ctx && ifilter->hw_frames_ctx->data != frame->hw_frames_ctx->data))
|
||||||
need_reinit = 1;
|
need_reinit = 1;
|
||||||
|
|
||||||
@ -238,7 +238,7 @@ index 46bb014de8..0502ff71b8 100644
|
|||||||
if (need_reinit) {
|
if (need_reinit) {
|
||||||
ret = ifilter_parameters_from_frame(ifilter, frame);
|
ret = ifilter_parameters_from_frame(ifilter, frame);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
@@ -2466,8 +2469,7 @@ static int decode_video(InputStream *ist, AVPacket *pkt, int *got_output, int64_
|
@@ -2469,8 +2472,7 @@ static int decode_video(InputStream *ist, AVPacket *pkt, int *got_output, int64_
|
||||||
decoded_frame->top_field_first = ist->top_field_first;
|
decoded_frame->top_field_first = ist->top_field_first;
|
||||||
|
|
||||||
ist->frames_decoded++;
|
ist->frames_decoded++;
|
||||||
@ -248,7 +248,7 @@ index 46bb014de8..0502ff71b8 100644
|
|||||||
err = ist->hwaccel_retrieve_data(ist->dec_ctx, decoded_frame);
|
err = ist->hwaccel_retrieve_data(ist->dec_ctx, decoded_frame);
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
goto fail;
|
goto fail;
|
||||||
@@ -2671,7 +2673,12 @@ static int process_input_packet(InputStream *ist, const AVPacket *pkt, int no_eo
|
@@ -2674,7 +2676,12 @@ static int process_input_packet(InputStream *ist, const AVPacket *pkt, int no_eo
|
||||||
case AVMEDIA_TYPE_VIDEO:
|
case AVMEDIA_TYPE_VIDEO:
|
||||||
ret = decode_video (ist, repeating ? NULL : avpkt, &got_output, &duration_pts, !pkt,
|
ret = decode_video (ist, repeating ? NULL : avpkt, &got_output, &duration_pts, !pkt,
|
||||||
&decode_failed);
|
&decode_failed);
|
||||||
@ -262,7 +262,7 @@ index 46bb014de8..0502ff71b8 100644
|
|||||||
if (pkt && pkt->duration) {
|
if (pkt && pkt->duration) {
|
||||||
duration_dts = av_rescale_q(pkt->duration, ist->st->time_base, AV_TIME_BASE_Q);
|
duration_dts = av_rescale_q(pkt->duration, ist->st->time_base, AV_TIME_BASE_Q);
|
||||||
} else if(ist->dec_ctx->framerate.num != 0 && ist->dec_ctx->framerate.den != 0) {
|
} else if(ist->dec_ctx->framerate.num != 0 && ist->dec_ctx->framerate.den != 0) {
|
||||||
@@ -2895,6 +2902,16 @@ static enum AVPixelFormat get_format(AVCodecContext *s, const enum AVPixelFormat
|
@@ -2898,6 +2905,16 @@ static enum AVPixelFormat get_format(AVCodecContext *s, const enum AVPixelFormat
|
||||||
} else {
|
} else {
|
||||||
const HWAccel *hwaccel = NULL;
|
const HWAccel *hwaccel = NULL;
|
||||||
int i;
|
int i;
|
||||||
@ -279,7 +279,7 @@ index 46bb014de8..0502ff71b8 100644
|
|||||||
for (i = 0; hwaccels[i].name; i++) {
|
for (i = 0; hwaccels[i].name; i++) {
|
||||||
if (hwaccels[i].pix_fmt == *p) {
|
if (hwaccels[i].pix_fmt == *p) {
|
||||||
hwaccel = &hwaccels[i];
|
hwaccel = &hwaccels[i];
|
||||||
@@ -2990,6 +3007,15 @@ static int init_input_stream(int ist_index, char *error, int error_len)
|
@@ -2993,6 +3010,15 @@ static int init_input_stream(int ist_index, char *error, int error_len)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -53003,11 +53003,15 @@ index b67b216331..ded1478a49 100644
|
|||||||
+
|
+
|
||||||
#endif /* AVCODEC_V4L2_M2M_H */
|
#endif /* AVCODEC_V4L2_M2M_H */
|
||||||
diff --git a/libavcodec/v4l2_m2m_dec.c b/libavcodec/v4l2_m2m_dec.c
|
diff --git a/libavcodec/v4l2_m2m_dec.c b/libavcodec/v4l2_m2m_dec.c
|
||||||
index ab07c0a24a..2bd113facb 100644
|
index ab07c0a24a..4c5ad55547 100644
|
||||||
--- a/libavcodec/v4l2_m2m_dec.c
|
--- a/libavcodec/v4l2_m2m_dec.c
|
||||||
+++ b/libavcodec/v4l2_m2m_dec.c
|
+++ b/libavcodec/v4l2_m2m_dec.c
|
||||||
@@ -23,6 +23,10 @@
|
@@ -21,8 +21,14 @@
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
+#include "config.h"
|
||||||
|
+
|
||||||
#include <linux/videodev2.h>
|
#include <linux/videodev2.h>
|
||||||
#include <sys/ioctl.h>
|
#include <sys/ioctl.h>
|
||||||
+
|
+
|
||||||
@ -53017,7 +53021,7 @@ index ab07c0a24a..2bd113facb 100644
|
|||||||
#include "libavutil/pixfmt.h"
|
#include "libavutil/pixfmt.h"
|
||||||
#include "libavutil/pixdesc.h"
|
#include "libavutil/pixdesc.h"
|
||||||
#include "libavutil/opt.h"
|
#include "libavutil/opt.h"
|
||||||
@@ -30,75 +34,267 @@
|
@@ -30,75 +36,274 @@
|
||||||
#include "libavcodec/decode.h"
|
#include "libavcodec/decode.h"
|
||||||
#include "libavcodec/internal.h"
|
#include "libavcodec/internal.h"
|
||||||
|
|
||||||
@ -53031,6 +53035,13 @@ index ab07c0a24a..2bd113facb 100644
|
|||||||
+#include "v4l2_req_dmabufs.h"
|
+#include "v4l2_req_dmabufs.h"
|
||||||
|
|
||||||
-static int v4l2_try_start(AVCodecContext *avctx)
|
-static int v4l2_try_start(AVCodecContext *avctx)
|
||||||
|
+#if CONFIG_H264_DECODER
|
||||||
|
+#include "h264_parse.h"
|
||||||
|
+#endif
|
||||||
|
+#if CONFIG_HEVC_DECODER
|
||||||
|
+#include "hevc_parse.h"
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
+// Pick 64 for max last count - that is >1sec at 60fps
|
+// Pick 64 for max last count - that is >1sec at 60fps
|
||||||
+#define STATS_LAST_COUNT_MAX 64
|
+#define STATS_LAST_COUNT_MAX 64
|
||||||
+#define STATS_INTERVAL_MAX (1 << 30)
|
+#define STATS_INTERVAL_MAX (1 << 30)
|
||||||
@ -53090,13 +53101,13 @@ index ab07c0a24a..2bd113facb 100644
|
|||||||
+ for (i = 0; i != 8; ++i) {
|
+ for (i = 0; i != 8; ++i) {
|
||||||
+ *s++ = ' ';
|
+ *s++ = ' ';
|
||||||
+ s = len > i + offset ? hex2(s, *m++) : dash2(s);
|
+ s = len > i + offset ? hex2(s, *m++) : dash2(s);
|
||||||
}
|
+ }
|
||||||
+ *s++ = ' ';
|
+ *s++ = ' ';
|
||||||
+ *s++ = ':';
|
+ *s++ = ':';
|
||||||
+ for (; i != 16; ++i) {
|
+ for (; i != 16; ++i) {
|
||||||
+ *s++ = ' ';
|
+ *s++ = ' ';
|
||||||
+ s = len > i + offset ? hex2(s, *m++) : dash2(s);
|
+ s = len > i + offset ? hex2(s, *m++) : dash2(s);
|
||||||
+ }
|
}
|
||||||
+ *s++ = 0;
|
+ *s++ = 0;
|
||||||
+}
|
+}
|
||||||
|
|
||||||
@ -53333,7 +53344,7 @@ index ab07c0a24a..2bd113facb 100644
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -133,58 +329,548 @@ static int v4l2_prepare_decoder(V4L2m2mContext *s)
|
@@ -133,58 +338,742 @@ static int v4l2_prepare_decoder(V4L2m2mContext *s)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -53541,23 +53552,23 @@ index ab07c0a24a..2bd113facb 100644
|
|||||||
+ }
|
+ }
|
||||||
+ return NQ_DRAINING;
|
+ return NQ_DRAINING;
|
||||||
+ }
|
+ }
|
||||||
|
+
|
||||||
|
+ if (!s->buf_pkt.size)
|
||||||
|
+ return NQ_NONE;
|
||||||
|
+
|
||||||
|
+ if ((ret = check_output_streamon(avctx, s)) != 0)
|
||||||
|
+ return ret;
|
||||||
|
|
||||||
- ret = ff_v4l2_context_enqueue_packet(output, &s->buf_pkt);
|
- ret = ff_v4l2_context_enqueue_packet(output, &s->buf_pkt);
|
||||||
- if (ret < 0 && ret != AVERROR(EAGAIN))
|
- if (ret < 0 && ret != AVERROR(EAGAIN))
|
||||||
- goto fail;
|
- goto fail;
|
||||||
+ if (!s->buf_pkt.size)
|
|
||||||
+ return NQ_NONE;
|
|
||||||
|
|
||||||
- /* if EAGAIN don't unref packet and try to enqueue in the next iteration */
|
|
||||||
- if (ret != AVERROR(EAGAIN))
|
|
||||||
+ if ((ret = check_output_streamon(avctx, s)) != 0)
|
|
||||||
+ return ret;
|
|
||||||
+
|
|
||||||
+ if (s->extdata_sent)
|
+ if (s->extdata_sent)
|
||||||
+ ret = ff_v4l2_context_enqueue_packet(&s->output, &s->buf_pkt, NULL, 0);
|
+ ret = ff_v4l2_context_enqueue_packet(&s->output, &s->buf_pkt, NULL, 0);
|
||||||
+ else
|
+ else
|
||||||
+ ret = ff_v4l2_context_enqueue_packet(&s->output, &s->buf_pkt, s->extdata_data, s->extdata_size);
|
+ ret = ff_v4l2_context_enqueue_packet(&s->output, &s->buf_pkt, s->extdata_data, s->extdata_size);
|
||||||
+
|
|
||||||
|
- /* if EAGAIN don't unref packet and try to enqueue in the next iteration */
|
||||||
|
- if (ret != AVERROR(EAGAIN))
|
||||||
+ if (ret == AVERROR(EAGAIN)) {
|
+ if (ret == AVERROR(EAGAIN)) {
|
||||||
+ // Out of input buffers - keep packet
|
+ // Out of input buffers - keep packet
|
||||||
+ ret = NQ_Q_FULL;
|
+ ret = NQ_Q_FULL;
|
||||||
@ -53576,15 +53587,6 @@ index ab07c0a24a..2bd113facb 100644
|
|||||||
- goto fail;
|
- goto fail;
|
||||||
+ av_log(avctx, AV_LOG_ERROR, "Packet enqueue failure: err=%d\n", ret);
|
+ av_log(avctx, AV_LOG_ERROR, "Packet enqueue failure: err=%d\n", ret);
|
||||||
+ return ret;
|
+ return ret;
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ // Start if we haven't
|
|
||||||
+ {
|
|
||||||
+ const int ret2 = v4l2_try_start(avctx);
|
|
||||||
+ if (ret2) {
|
|
||||||
+ av_log(avctx, AV_LOG_DEBUG, "Start failure: err=%d\n", ret2);
|
|
||||||
+ ret = (ret2 == AVERROR(ENOMEM)) ? ret2 : NQ_DEAD;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -53592,9 +53594,18 @@ index ab07c0a24a..2bd113facb 100644
|
|||||||
- return ff_v4l2_context_dequeue_frame(capture, frame, -1);
|
- return ff_v4l2_context_dequeue_frame(capture, frame, -1);
|
||||||
-fail:
|
-fail:
|
||||||
- av_packet_unref(&s->buf_pkt);
|
- av_packet_unref(&s->buf_pkt);
|
||||||
return ret;
|
+ // Start if we haven't
|
||||||
}
|
+ {
|
||||||
|
+ const int ret2 = v4l2_try_start(avctx);
|
||||||
|
+ if (ret2) {
|
||||||
|
+ av_log(avctx, AV_LOG_DEBUG, "Start failure: err=%d\n", ret2);
|
||||||
|
+ ret = (ret2 == AVERROR(ENOMEM)) ? ret2 : NQ_DEAD;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return ret;
|
||||||
|
+}
|
||||||
|
+
|
||||||
+static int qbuf_wait(AVCodecContext * const avctx, V4L2Context * const ctx)
|
+static int qbuf_wait(AVCodecContext * const avctx, V4L2Context * const ctx)
|
||||||
+{
|
+{
|
||||||
+ int rv = 0;
|
+ int rv = 0;
|
||||||
@ -53751,10 +53762,131 @@ index ab07c0a24a..2bd113facb 100644
|
|||||||
+ ret = v4l2_receive_frame2(avctx, frame);
|
+ ret = v4l2_receive_frame2(avctx, frame);
|
||||||
+ done = us_time();
|
+ done = us_time();
|
||||||
+ av_log(avctx, AV_LOG_TRACE, ">>> %s: rx time=%" PRId64 ", rv=%d\n", __func__, done - now, ret);
|
+ av_log(avctx, AV_LOG_TRACE, ">>> %s: rx time=%" PRId64 ", rv=%d\n", __func__, done - now, ret);
|
||||||
+ return ret;
|
return ret;
|
||||||
+}
|
}
|
||||||
+#endif
|
+#endif
|
||||||
+
|
+
|
||||||
|
+static uint32_t
|
||||||
|
+avprofile_to_v4l2(const enum AVCodecID codec_id, const int avprofile)
|
||||||
|
+{
|
||||||
|
+ switch (codec_id) {
|
||||||
|
+ case AV_CODEC_ID_H264:
|
||||||
|
+ switch (avprofile) {
|
||||||
|
+ case FF_PROFILE_H264_BASELINE:
|
||||||
|
+ return V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE;
|
||||||
|
+ case FF_PROFILE_H264_CONSTRAINED_BASELINE:
|
||||||
|
+ return V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_BASELINE;
|
||||||
|
+ case FF_PROFILE_H264_MAIN:
|
||||||
|
+ return V4L2_MPEG_VIDEO_H264_PROFILE_MAIN;
|
||||||
|
+ case FF_PROFILE_H264_EXTENDED:
|
||||||
|
+ return V4L2_MPEG_VIDEO_H264_PROFILE_EXTENDED;
|
||||||
|
+ case FF_PROFILE_H264_HIGH:
|
||||||
|
+ return V4L2_MPEG_VIDEO_H264_PROFILE_HIGH;
|
||||||
|
+ case FF_PROFILE_H264_HIGH_10:
|
||||||
|
+ return V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_10;
|
||||||
|
+ case FF_PROFILE_H264_HIGH_10_INTRA:
|
||||||
|
+ return V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_10_INTRA;
|
||||||
|
+ case FF_PROFILE_H264_MULTIVIEW_HIGH:
|
||||||
|
+ case FF_PROFILE_H264_HIGH_422:
|
||||||
|
+ return V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_422;
|
||||||
|
+ case FF_PROFILE_H264_HIGH_422_INTRA:
|
||||||
|
+ return V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_422_INTRA;
|
||||||
|
+ case FF_PROFILE_H264_STEREO_HIGH:
|
||||||
|
+ return V4L2_MPEG_VIDEO_H264_PROFILE_STEREO_HIGH;
|
||||||
|
+ case FF_PROFILE_H264_HIGH_444_PREDICTIVE:
|
||||||
|
+ return V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_444_PREDICTIVE;
|
||||||
|
+ case FF_PROFILE_H264_HIGH_444_INTRA:
|
||||||
|
+ return V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_444_INTRA;
|
||||||
|
+ case FF_PROFILE_H264_CAVLC_444:
|
||||||
|
+ return V4L2_MPEG_VIDEO_H264_PROFILE_CAVLC_444_INTRA;
|
||||||
|
+ case FF_PROFILE_H264_HIGH_444:
|
||||||
|
+ default:
|
||||||
|
+ break;
|
||||||
|
+// V4L2_MPEG_VIDEO_H264_PROFILE_SCALABLE_BASELINE = 12,
|
||||||
|
+// V4L2_MPEG_VIDEO_H264_PROFILE_SCALABLE_HIGH = 13,
|
||||||
|
+// V4L2_MPEG_VIDEO_H264_PROFILE_SCALABLE_HIGH_INTRA = 14,
|
||||||
|
+// V4L2_MPEG_VIDEO_H264_PROFILE_MULTIVIEW_HIGH = 16,
|
||||||
|
+// V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_HIGH = 17,
|
||||||
|
+ }
|
||||||
|
+ break;
|
||||||
|
+ case AV_CODEC_ID_MPEG2VIDEO:
|
||||||
|
+ case AV_CODEC_ID_MPEG4:
|
||||||
|
+ case AV_CODEC_ID_VC1:
|
||||||
|
+ case AV_CODEC_ID_VP8:
|
||||||
|
+ case AV_CODEC_ID_VP9:
|
||||||
|
+ case AV_CODEC_ID_AV1:
|
||||||
|
+ // Most profiles are a simple number that matches the V4L2 enum
|
||||||
|
+ return avprofile;
|
||||||
|
+ default:
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+ return ~(uint32_t)0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+// This check mirrors Chrome's profile check by testing to see if the profile
|
||||||
|
+// exists as a possible value for the V4L2 profile control
|
||||||
|
+static int
|
||||||
|
+check_profile(AVCodecContext *const avctx, V4L2m2mContext *const s)
|
||||||
|
+{
|
||||||
|
+ struct v4l2_queryctrl query_ctrl;
|
||||||
|
+ struct v4l2_querymenu query_menu;
|
||||||
|
+ uint32_t profile_id;
|
||||||
|
+
|
||||||
|
+ // An unset profile is almost certainly zero or -99 - do not reject
|
||||||
|
+ if (avctx->profile <= 0) {
|
||||||
|
+ av_log(avctx, AV_LOG_VERBOSE, "Profile <= 0 - check skipped\n");
|
||||||
|
+ return 0;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ memset(&query_ctrl, 0, sizeof(query_ctrl));
|
||||||
|
+ switch (avctx->codec_id) {
|
||||||
|
+ case AV_CODEC_ID_MPEG2VIDEO:
|
||||||
|
+ profile_id = V4L2_CID_MPEG_VIDEO_MPEG2_PROFILE;
|
||||||
|
+ break;
|
||||||
|
+ case AV_CODEC_ID_MPEG4:
|
||||||
|
+ profile_id = V4L2_CID_MPEG_VIDEO_MPEG4_PROFILE;
|
||||||
|
+ break;
|
||||||
|
+ case AV_CODEC_ID_H264:
|
||||||
|
+ profile_id = V4L2_CID_MPEG_VIDEO_H264_PROFILE;
|
||||||
|
+ break;
|
||||||
|
+ case AV_CODEC_ID_VP8:
|
||||||
|
+ profile_id = V4L2_CID_MPEG_VIDEO_VP8_PROFILE;
|
||||||
|
+ break;
|
||||||
|
+ case AV_CODEC_ID_VP9:
|
||||||
|
+ profile_id = V4L2_CID_MPEG_VIDEO_VP9_PROFILE;
|
||||||
|
+ break;
|
||||||
|
+#ifdef V4L2_CID_MPEG_VIDEO_AV1_PROFILE
|
||||||
|
+ case AV_CODEC_ID_AV1:
|
||||||
|
+ profile_id = V4L2_CID_MPEG_VIDEO_AV1_PROFILE;
|
||||||
|
+ break;
|
||||||
|
+#endif
|
||||||
|
+ default:
|
||||||
|
+ av_log(avctx, AV_LOG_VERBOSE, "Can't map profile for codec id %d; profile check skipped\n", avctx->codec_id);
|
||||||
|
+ return 0;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ query_ctrl = (struct v4l2_queryctrl){.id = profile_id};
|
||||||
|
+ if (ioctl(s->fd, VIDIOC_QUERYCTRL, &query_ctrl) != 0) {
|
||||||
|
+ av_log(avctx, AV_LOG_VERBOSE, "Query profile ctrl (%#x) not supported: assume OK\n", query_ctrl.id);
|
||||||
|
+ }
|
||||||
|
+ else {
|
||||||
|
+ av_log(avctx, AV_LOG_DEBUG, "%s: Control supported: %#x\n", __func__, query_ctrl.id);
|
||||||
|
+
|
||||||
|
+ query_menu = (struct v4l2_querymenu){
|
||||||
|
+ .id = query_ctrl.id,
|
||||||
|
+ .index = avprofile_to_v4l2(avctx->codec_id, avctx->profile),
|
||||||
|
+ };
|
||||||
|
+
|
||||||
|
+ if (query_menu.index > query_ctrl.maximum ||
|
||||||
|
+ query_menu.index < query_ctrl.minimum ||
|
||||||
|
+ ioctl(s->fd, VIDIOC_QUERYMENU, &query_menu) != 0) {
|
||||||
|
+ return AVERROR(ENOENT);
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return 0;
|
||||||
|
+};
|
||||||
|
+
|
||||||
+static int
|
+static int
|
||||||
+check_size(AVCodecContext * const avctx, V4L2m2mContext * const s)
|
+check_size(AVCodecContext * const avctx, V4L2m2mContext * const s)
|
||||||
+{
|
+{
|
||||||
@ -53875,6 +54007,78 @@ index ab07c0a24a..2bd113facb 100644
|
|||||||
+ return size + (1 << 16);
|
+ return size + (1 << 16);
|
||||||
+}
|
+}
|
||||||
+
|
+
|
||||||
|
+static void
|
||||||
|
+parse_extradata(AVCodecContext *avctx)
|
||||||
|
+{
|
||||||
|
+ if (!avctx->extradata || !avctx->extradata_size)
|
||||||
|
+ return;
|
||||||
|
+
|
||||||
|
+ switch (avctx->codec_id) {
|
||||||
|
+#if CONFIG_H264_DECODER
|
||||||
|
+ case AV_CODEC_ID_H264:
|
||||||
|
+ {
|
||||||
|
+ H264ParamSets ps = {{NULL}};
|
||||||
|
+ int is_avc = 0;
|
||||||
|
+ int nal_length_size = 0;
|
||||||
|
+ int ret;
|
||||||
|
+
|
||||||
|
+ ret = ff_h264_decode_extradata(avctx->extradata, avctx->extradata_size,
|
||||||
|
+ &ps, &is_avc, &nal_length_size,
|
||||||
|
+ avctx->err_recognition, avctx);
|
||||||
|
+ if (ret > 0) {
|
||||||
|
+ const SPS * sps = NULL;
|
||||||
|
+ unsigned int i;
|
||||||
|
+ for (i = 0; i != MAX_SPS_COUNT; ++i) {
|
||||||
|
+ if (ps.sps_list[i]) {
|
||||||
|
+ sps = (const SPS *)ps.sps_list[i]->data;
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ if (sps) {
|
||||||
|
+ avctx->profile = ff_h264_get_profile(sps);
|
||||||
|
+ avctx->level = sps->level_idc;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ ff_h264_ps_uninit(&ps);
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+#endif
|
||||||
|
+#if CONFIG_HEVC_DECODER
|
||||||
|
+ case AV_CODEC_ID_HEVC:
|
||||||
|
+ {
|
||||||
|
+ HEVCParamSets ps = {{NULL}};
|
||||||
|
+ HEVCSEI sei = {{{{0}}}};
|
||||||
|
+ int is_nalff = 0;
|
||||||
|
+ int nal_length_size = 0;
|
||||||
|
+ int ret;
|
||||||
|
+
|
||||||
|
+ ret = ff_hevc_decode_extradata(avctx->extradata, avctx->extradata_size,
|
||||||
|
+ &ps, &sei, &is_nalff, &nal_length_size,
|
||||||
|
+ avctx->err_recognition, 0, avctx);
|
||||||
|
+ if (ret > 0) {
|
||||||
|
+ const HEVCSPS * sps = NULL;
|
||||||
|
+ unsigned int i;
|
||||||
|
+ for (i = 0; i != HEVC_MAX_SPS_COUNT; ++i) {
|
||||||
|
+ if (ps.sps_list[i]) {
|
||||||
|
+ sps = (const HEVCSPS *)ps.sps_list[i]->data;
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ if (sps) {
|
||||||
|
+ avctx->profile = sps->ptl.general_ptl.profile_idc;
|
||||||
|
+ avctx->level = sps->ptl.general_ptl.level_idc;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ ff_hevc_ps_uninit(&ps);
|
||||||
|
+ ff_hevc_reset_sei(&sei);
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+#endif
|
||||||
|
+ default:
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
|
||||||
static av_cold int v4l2_decode_init(AVCodecContext *avctx)
|
static av_cold int v4l2_decode_init(AVCodecContext *avctx)
|
||||||
{
|
{
|
||||||
V4L2Context *capture, *output;
|
V4L2Context *capture, *output;
|
||||||
@ -53895,7 +54099,8 @@ index ab07c0a24a..2bd113facb 100644
|
|||||||
+ avctx->ticks_per_frame = 2;
|
+ avctx->ticks_per_frame = 2;
|
||||||
+ }
|
+ }
|
||||||
+
|
+
|
||||||
+ av_log(avctx, AV_LOG_INFO, "level=%d\n", avctx->level);
|
+ parse_extradata(avctx);
|
||||||
|
+
|
||||||
ret = ff_v4l2_m2m_create_context(priv, &s);
|
ret = ff_v4l2_m2m_create_context(priv, &s);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return ret;
|
return ret;
|
||||||
@ -53906,7 +54111,7 @@ index ab07c0a24a..2bd113facb 100644
|
|||||||
capture = &s->capture;
|
capture = &s->capture;
|
||||||
output = &s->output;
|
output = &s->output;
|
||||||
|
|
||||||
@@ -192,14 +878,65 @@ static av_cold int v4l2_decode_init(AVCodecContext *avctx)
|
@@ -192,14 +1081,65 @@ static av_cold int v4l2_decode_init(AVCodecContext *avctx)
|
||||||
* by the v4l2 driver; this event will trigger a full pipeline reconfig and
|
* by the v4l2 driver; this event will trigger a full pipeline reconfig and
|
||||||
* the proper values will be retrieved from the kernel driver.
|
* the proper values will be retrieved from the kernel driver.
|
||||||
*/
|
*/
|
||||||
@ -53974,7 +54179,7 @@ index ab07c0a24a..2bd113facb 100644
|
|||||||
|
|
||||||
s->avctx = avctx;
|
s->avctx = avctx;
|
||||||
ret = ff_v4l2_m2m_codec_init(priv);
|
ret = ff_v4l2_m2m_codec_init(priv);
|
||||||
@@ -208,12 +945,84 @@ static av_cold int v4l2_decode_init(AVCodecContext *avctx)
|
@@ -208,12 +1148,88 @@ static av_cold int v4l2_decode_init(AVCodecContext *avctx)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -53997,6 +54202,10 @@ index ab07c0a24a..2bd113facb 100644
|
|||||||
+ if ((ret = check_size(avctx, s)) != 0)
|
+ if ((ret = check_size(avctx, s)) != 0)
|
||||||
+ return ret;
|
+ return ret;
|
||||||
+
|
+
|
||||||
|
+ if ((ret = check_profile(avctx, s)) != 0) {
|
||||||
|
+ av_log(avctx, AV_LOG_WARNING, "Profile %d not supported by decode\n", avctx->profile);
|
||||||
|
+ return ret;
|
||||||
|
+ }
|
||||||
+ return 0;
|
+ return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -54061,7 +54270,7 @@ index ab07c0a24a..2bd113facb 100644
|
|||||||
}
|
}
|
||||||
|
|
||||||
#define OFFSET(x) offsetof(V4L2m2mPriv, x)
|
#define OFFSET(x) offsetof(V4L2m2mPriv, x)
|
||||||
@@ -222,10 +1031,17 @@ static av_cold int v4l2_decode_close(AVCodecContext *avctx)
|
@@ -222,10 +1238,17 @@ static av_cold int v4l2_decode_close(AVCodecContext *avctx)
|
||||||
static const AVOption options[] = {
|
static const AVOption options[] = {
|
||||||
V4L_M2M_DEFAULT_OPTS,
|
V4L_M2M_DEFAULT_OPTS,
|
||||||
{ "num_capture_buffers", "Number of buffers in the capture context",
|
{ "num_capture_buffers", "Number of buffers in the capture context",
|
||||||
@ -54080,7 +54289,7 @@ index ab07c0a24a..2bd113facb 100644
|
|||||||
#define M2MDEC_CLASS(NAME) \
|
#define M2MDEC_CLASS(NAME) \
|
||||||
static const AVClass v4l2_m2m_ ## NAME ## _dec_class = { \
|
static const AVClass v4l2_m2m_ ## NAME ## _dec_class = { \
|
||||||
.class_name = #NAME "_v4l2m2m_decoder", \
|
.class_name = #NAME "_v4l2m2m_decoder", \
|
||||||
@@ -246,9 +1062,15 @@ static const AVOption options[] = {
|
@@ -246,9 +1269,15 @@ static const AVOption options[] = {
|
||||||
.init = v4l2_decode_init, \
|
.init = v4l2_decode_init, \
|
||||||
.receive_frame = v4l2_receive_frame, \
|
.receive_frame = v4l2_receive_frame, \
|
||||||
.close = v4l2_decode_close, \
|
.close = v4l2_decode_close, \
|
||||||
@ -59855,7 +60064,7 @@ index 0000000000..99c90064ea
|
|||||||
+
|
+
|
||||||
+#endif
|
+#endif
|
||||||
diff --git a/libavcodec/vc1dec.c b/libavcodec/vc1dec.c
|
diff --git a/libavcodec/vc1dec.c b/libavcodec/vc1dec.c
|
||||||
index ea93e11588..a9e0c6323e 100644
|
index d4ceb60791..fb7f839c5e 100644
|
||||||
--- a/libavcodec/vc1dec.c
|
--- a/libavcodec/vc1dec.c
|
||||||
+++ b/libavcodec/vc1dec.c
|
+++ b/libavcodec/vc1dec.c
|
||||||
@@ -486,7 +486,7 @@ static av_cold int vc1_decode_init(AVCodecContext *avctx)
|
@@ -486,7 +486,7 @@ static av_cold int vc1_decode_init(AVCodecContext *avctx)
|
||||||
@ -62325,6 +62534,67 @@ index f6b572b3de..44fe8b679c 100644
|
|||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return ret;
|
return ret;
|
||||||
av_log(log_ctx, AV_LOG_ERROR,
|
av_log(log_ctx, AV_LOG_ERROR,
|
||||||
|
diff --git a/libavfilter/buffersink.c b/libavfilter/buffersink.c
|
||||||
|
index 15d897cff6..c134759bbf 100644
|
||||||
|
--- a/libavfilter/buffersink.c
|
||||||
|
+++ b/libavfilter/buffersink.c
|
||||||
|
@@ -58,6 +58,11 @@ typedef struct BufferSinkContext {
|
||||||
|
int sample_rates_size;
|
||||||
|
|
||||||
|
AVFrame *peeked_frame;
|
||||||
|
+
|
||||||
|
+ union {
|
||||||
|
+ av_buffersink_alloc_video_frame * video;
|
||||||
|
+ } alloc_cb;
|
||||||
|
+ void * alloc_v;
|
||||||
|
} BufferSinkContext;
|
||||||
|
|
||||||
|
#define NB_ITEMS(list) (list ## _size / sizeof(*list))
|
||||||
|
@@ -148,6 +153,22 @@ int attribute_align_arg av_buffersink_get_samples(AVFilterContext *ctx,
|
||||||
|
return get_frame_internal(ctx, frame, 0, nb_samples);
|
||||||
|
}
|
||||||
|
|
||||||
|
+static AVFrame * alloc_video_buffer(AVFilterLink *link, int w, int h)
|
||||||
|
+{
|
||||||
|
+ AVFilterContext * const ctx = link->dst;
|
||||||
|
+ BufferSinkContext * const bs = ctx->priv;
|
||||||
|
+ return bs->alloc_cb.video ? bs->alloc_cb.video(ctx, bs->alloc_v, w, h) :
|
||||||
|
+ ff_default_get_video_buffer(link, w, h);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+int av_buffersink_set_alloc_video_frame(AVFilterContext *ctx, av_buffersink_alloc_video_frame * cb, void * v)
|
||||||
|
+{
|
||||||
|
+ BufferSinkContext * const bs = ctx->priv;
|
||||||
|
+ bs->alloc_cb.video = cb;
|
||||||
|
+ bs->alloc_v = v;
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
#if FF_API_BUFFERSINK_ALLOC
|
||||||
|
AVBufferSinkParams *av_buffersink_params_alloc(void)
|
||||||
|
{
|
||||||
|
@@ -331,6 +352,7 @@ static const AVFilterPad avfilter_vsink_buffer_inputs[] = {
|
||||||
|
{
|
||||||
|
.name = "default",
|
||||||
|
.type = AVMEDIA_TYPE_VIDEO,
|
||||||
|
+ .get_video_buffer = alloc_video_buffer,
|
||||||
|
},
|
||||||
|
{ NULL }
|
||||||
|
};
|
||||||
|
diff --git a/libavfilter/buffersink.h b/libavfilter/buffersink.h
|
||||||
|
index 69ed0f29a8..a3aa6fcb3c 100644
|
||||||
|
--- a/libavfilter/buffersink.h
|
||||||
|
+++ b/libavfilter/buffersink.h
|
||||||
|
@@ -198,6 +198,9 @@ int av_buffersink_get_frame(AVFilterContext *ctx, AVFrame *frame);
|
||||||
|
*/
|
||||||
|
int av_buffersink_get_samples(AVFilterContext *ctx, AVFrame *frame, int nb_samples);
|
||||||
|
|
||||||
|
+typedef AVFrame * av_buffersink_alloc_video_frame(AVFilterContext * ctx, void * v, int w, int h);
|
||||||
|
+int av_buffersink_set_alloc_video_frame(AVFilterContext *ctx, av_buffersink_alloc_video_frame * cb, void * v);
|
||||||
|
+
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
diff --git a/libavfilter/buffersrc.c b/libavfilter/buffersrc.c
|
diff --git a/libavfilter/buffersrc.c b/libavfilter/buffersrc.c
|
||||||
index da1cf9941e..c588ed23cb 100644
|
index da1cf9941e..c588ed23cb 100644
|
||||||
--- a/libavfilter/buffersrc.c
|
--- a/libavfilter/buffersrc.c
|
||||||
@ -64695,7 +64965,7 @@ index 0000000000..61c03a385c
|
|||||||
+};
|
+};
|
||||||
+
|
+
|
||||||
diff --git a/libavformat/matroskaenc.c b/libavformat/matroskaenc.c
|
diff --git a/libavformat/matroskaenc.c b/libavformat/matroskaenc.c
|
||||||
index bbf231f2a4..22571c89a3 100644
|
index b4284a8778..692265593c 100644
|
||||||
--- a/libavformat/matroskaenc.c
|
--- a/libavformat/matroskaenc.c
|
||||||
+++ b/libavformat/matroskaenc.c
|
+++ b/libavformat/matroskaenc.c
|
||||||
@@ -58,6 +58,9 @@
|
@@ -58,6 +58,9 @@
|
||||||
@ -64723,7 +64993,7 @@ index bbf231f2a4..22571c89a3 100644
|
|||||||
case AV_CODEC_ID_HEVC:
|
case AV_CODEC_ID_HEVC:
|
||||||
return ff_isom_write_hvcc(dyn_cp, par->extradata,
|
return ff_isom_write_hvcc(dyn_cp, par->extradata,
|
||||||
par->extradata_size, 0);
|
par->extradata_size, 0);
|
||||||
@@ -2258,7 +2265,9 @@ static int mkv_check_new_extra_data(AVFormatContext *s, const AVPacket *pkt)
|
@@ -2259,7 +2266,9 @@ static int mkv_check_new_extra_data(AVFormatContext *s, const AVPacket *pkt)
|
||||||
break;
|
break;
|
||||||
// FIXME: Remove the following once libaom starts propagating extradata during init()
|
// FIXME: Remove the following once libaom starts propagating extradata during init()
|
||||||
// See https://bugs.chromium.org/p/aomedia/issues/detail?id=2012
|
// See https://bugs.chromium.org/p/aomedia/issues/detail?id=2012
|
||||||
@ -64733,7 +65003,7 @@ index bbf231f2a4..22571c89a3 100644
|
|||||||
if (side_data_size && mkv->track.bc && !par->extradata_size) {
|
if (side_data_size && mkv->track.bc && !par->extradata_size) {
|
||||||
AVIOContext *dyn_cp;
|
AVIOContext *dyn_cp;
|
||||||
uint8_t *codecpriv;
|
uint8_t *codecpriv;
|
||||||
@@ -2266,7 +2275,10 @@ static int mkv_check_new_extra_data(AVFormatContext *s, const AVPacket *pkt)
|
@@ -2267,7 +2276,10 @@ static int mkv_check_new_extra_data(AVFormatContext *s, const AVPacket *pkt)
|
||||||
ret = avio_open_dyn_buf(&dyn_cp);
|
ret = avio_open_dyn_buf(&dyn_cp);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return ret;
|
return ret;
|
||||||
@ -64745,7 +65015,7 @@ index bbf231f2a4..22571c89a3 100644
|
|||||||
codecpriv_size = avio_get_dyn_buf(dyn_cp, &codecpriv);
|
codecpriv_size = avio_get_dyn_buf(dyn_cp, &codecpriv);
|
||||||
if ((ret = dyn_cp->error) < 0 ||
|
if ((ret = dyn_cp->error) < 0 ||
|
||||||
!codecpriv_size && (ret = AVERROR_INVALIDDATA)) {
|
!codecpriv_size && (ret = AVERROR_INVALIDDATA)) {
|
||||||
@@ -2274,8 +2286,25 @@ static int mkv_check_new_extra_data(AVFormatContext *s, const AVPacket *pkt)
|
@@ -2275,8 +2287,25 @@ static int mkv_check_new_extra_data(AVFormatContext *s, const AVPacket *pkt)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
avio_seek(mkv->track.bc, track->codecpriv_offset, SEEK_SET);
|
avio_seek(mkv->track.bc, track->codecpriv_offset, SEEK_SET);
|
||||||
@ -64774,10 +65044,10 @@ index bbf231f2a4..22571c89a3 100644
|
|||||||
ret = ff_alloc_extradata(par, side_data_size);
|
ret = ff_alloc_extradata(par, side_data_size);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
diff --git a/libavformat/movenc.c b/libavformat/movenc.c
|
diff --git a/libavformat/movenc.c b/libavformat/movenc.c
|
||||||
index bade57dcea..d23101b23f 100644
|
index 2cd5773dc5..0cbbc094de 100644
|
||||||
--- a/libavformat/movenc.c
|
--- a/libavformat/movenc.c
|
||||||
+++ b/libavformat/movenc.c
|
+++ b/libavformat/movenc.c
|
||||||
@@ -5913,6 +5913,7 @@ static int mov_write_single_packet(AVFormatContext *s, AVPacket *pkt)
|
@@ -5926,6 +5926,7 @@ static int mov_write_single_packet(AVFormatContext *s, AVPacket *pkt)
|
||||||
if (trk->par->codec_id == AV_CODEC_ID_MP4ALS ||
|
if (trk->par->codec_id == AV_CODEC_ID_MP4ALS ||
|
||||||
trk->par->codec_id == AV_CODEC_ID_AAC ||
|
trk->par->codec_id == AV_CODEC_ID_AAC ||
|
||||||
trk->par->codec_id == AV_CODEC_ID_AV1 ||
|
trk->par->codec_id == AV_CODEC_ID_AV1 ||
|
||||||
@ -64786,10 +65056,10 @@ index bade57dcea..d23101b23f 100644
|
|||||||
buffer_size_t side_size;
|
buffer_size_t side_size;
|
||||||
uint8_t *side = av_packet_get_side_data(pkt, AV_PKT_DATA_NEW_EXTRADATA, &side_size);
|
uint8_t *side = av_packet_get_side_data(pkt, AV_PKT_DATA_NEW_EXTRADATA, &side_size);
|
||||||
diff --git a/libavformat/utils.c b/libavformat/utils.c
|
diff --git a/libavformat/utils.c b/libavformat/utils.c
|
||||||
index 1384b56771..27479e3c40 100644
|
index 75e5350a27..e10b493dae 100644
|
||||||
--- a/libavformat/utils.c
|
--- a/libavformat/utils.c
|
||||||
+++ b/libavformat/utils.c
|
+++ b/libavformat/utils.c
|
||||||
@@ -3011,6 +3011,40 @@ static int has_codec_parameters(AVStream *st, const char **errmsg_ptr)
|
@@ -3013,6 +3013,40 @@ static int has_codec_parameters(AVStream *st, const char **errmsg_ptr)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -64830,7 +65100,7 @@ index 1384b56771..27479e3c40 100644
|
|||||||
/* returns 1 or 0 if or if not decoded data was returned, or a negative error */
|
/* returns 1 or 0 if or if not decoded data was returned, or a negative error */
|
||||||
static int try_decode_frame(AVFormatContext *s, AVStream *st,
|
static int try_decode_frame(AVFormatContext *s, AVStream *st,
|
||||||
const AVPacket *avpkt, AVDictionary **options)
|
const AVPacket *avpkt, AVDictionary **options)
|
||||||
@@ -3049,7 +3083,11 @@ static int try_decode_frame(AVFormatContext *s, AVStream *st,
|
@@ -3051,7 +3085,11 @@ static int try_decode_frame(AVFormatContext *s, AVStream *st,
|
||||||
av_dict_set(options ? options : &thread_opt, "lowres", "0", 0);
|
av_dict_set(options ? options : &thread_opt, "lowres", "0", 0);
|
||||||
if (s->codec_whitelist)
|
if (s->codec_whitelist)
|
||||||
av_dict_set(options ? options : &thread_opt, "codec_whitelist", s->codec_whitelist, 0);
|
av_dict_set(options ? options : &thread_opt, "codec_whitelist", s->codec_whitelist, 0);
|
||||||
@ -64843,7 +65113,7 @@ index 1384b56771..27479e3c40 100644
|
|||||||
if (!options)
|
if (!options)
|
||||||
av_dict_free(&thread_opt);
|
av_dict_free(&thread_opt);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
@@ -3080,6 +3118,14 @@ static int try_decode_frame(AVFormatContext *s, AVStream *st,
|
@@ -3082,6 +3120,14 @@ static int try_decode_frame(AVFormatContext *s, AVStream *st,
|
||||||
if (avctx->codec_type == AVMEDIA_TYPE_VIDEO ||
|
if (avctx->codec_type == AVMEDIA_TYPE_VIDEO ||
|
||||||
avctx->codec_type == AVMEDIA_TYPE_AUDIO) {
|
avctx->codec_type == AVMEDIA_TYPE_AUDIO) {
|
||||||
ret = avcodec_send_packet(avctx, &pkt);
|
ret = avcodec_send_packet(avctx, &pkt);
|
||||||
@ -64858,7 +65128,7 @@ index 1384b56771..27479e3c40 100644
|
|||||||
if (ret < 0 && ret != AVERROR(EAGAIN) && ret != AVERROR_EOF)
|
if (ret < 0 && ret != AVERROR(EAGAIN) && ret != AVERROR_EOF)
|
||||||
break;
|
break;
|
||||||
if (ret >= 0)
|
if (ret >= 0)
|
||||||
@@ -3708,9 +3754,20 @@ FF_ENABLE_DEPRECATION_WARNINGS
|
@@ -3710,9 +3756,20 @@ FF_ENABLE_DEPRECATION_WARNINGS
|
||||||
// Try to just open decoders, in case this is enough to get parameters.
|
// Try to just open decoders, in case this is enough to get parameters.
|
||||||
if (!has_codec_parameters(st, NULL) && st->internal->request_probe <= 0) {
|
if (!has_codec_parameters(st, NULL) && st->internal->request_probe <= 0) {
|
||||||
if (codec && !avctx->codec)
|
if (codec && !avctx->codec)
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
From 97d39a46091b65e4355ce7e545bdec46ff2f87de Mon Sep 17 00:00:00 2001
|
From 97d39a46091b65e4355ce7e545bdec46ff2f87de Mon Sep 17 00:00:00 2001
|
||||||
From: popcornmix <popcornmix@gmail.com>
|
From: popcornmix <popcornmix@gmail.com>
|
||||||
Date: Sat, 11 Sep 2021 14:03:05 +0100
|
Date: Sat, 11 Sep 2021 14:03:05 +0100
|
||||||
Subject: [PATCH 1/4] CDVDVideoCodecDRMPRIME: Also support YUV420 buffers
|
Subject: [PATCH 1/7] CDVDVideoCodecDRMPRIME: Also support YUV420 buffers
|
||||||
|
|
||||||
CDVDVideoCodecDRMPRIME: Add support for deinterlace of sw decoded buffers
|
CDVDVideoCodecDRMPRIME: Add support for deinterlace of sw decoded buffers
|
||||||
|
|
||||||
@ -50,5 +50,5 @@ index 20a5c24f53..a36107c515 100644
|
|||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
{
|
{
|
||||||
--
|
--
|
||||||
2.39.0
|
2.39.2
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
From 42b30508bfe5451d4dc2884acfde9e0ec2d58c92 Mon Sep 17 00:00:00 2001
|
From 42b30508bfe5451d4dc2884acfde9e0ec2d58c92 Mon Sep 17 00:00:00 2001
|
||||||
From: Dom Cobley <popcornmix@gmail.com>
|
From: Dom Cobley <popcornmix@gmail.com>
|
||||||
Date: Fri, 3 Dec 2021 16:00:50 +0000
|
Date: Fri, 3 Dec 2021 16:00:50 +0000
|
||||||
Subject: [PATCH 2/4] gbm: Set max bpc for high bit depth videos
|
Subject: [PATCH 2/7] gbm: Set max bpc for high bit depth videos
|
||||||
|
|
||||||
---
|
---
|
||||||
.../HwDecRender/VideoLayerBridgeDRMPRIME.cpp | 16 ++++++++++++++++
|
.../HwDecRender/VideoLayerBridgeDRMPRIME.cpp | 16 ++++++++++++++++
|
||||||
@ -42,5 +42,5 @@ index 4b8ee5afbb..bd6623e8d1 100644
|
|||||||
|
|
||||||
void CVideoLayerBridgeDRMPRIME::SetVideoPlane(CVideoBufferDRMPRIME* buffer, const CRect& destRect)
|
void CVideoLayerBridgeDRMPRIME::SetVideoPlane(CVideoBufferDRMPRIME* buffer, const CRect& destRect)
|
||||||
--
|
--
|
||||||
2.39.0
|
2.39.2
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
From 0b9b204c6560f3aff39697f92616b48102840dfe Mon Sep 17 00:00:00 2001
|
From 0b9b204c6560f3aff39697f92616b48102840dfe Mon Sep 17 00:00:00 2001
|
||||||
From: Lukas Rusak <lorusak@gmail.com>
|
From: Lukas Rusak <lorusak@gmail.com>
|
||||||
Date: Mon, 29 Apr 2019 18:48:45 -0700
|
Date: Mon, 29 Apr 2019 18:48:45 -0700
|
||||||
Subject: [PATCH 3/4] CVideoLayerBridgeDRMPRIME add colourspace connector
|
Subject: [PATCH 3/7] CVideoLayerBridgeDRMPRIME add colourspace connector
|
||||||
property
|
property
|
||||||
|
|
||||||
---
|
---
|
||||||
@ -83,5 +83,5 @@ index bd6623e8d1..a1342595c6 100644
|
|||||||
|
|
||||||
void CVideoLayerBridgeDRMPRIME::SetVideoPlane(CVideoBufferDRMPRIME* buffer, const CRect& destRect)
|
void CVideoLayerBridgeDRMPRIME::SetVideoPlane(CVideoBufferDRMPRIME* buffer, const CRect& destRect)
|
||||||
--
|
--
|
||||||
2.39.0
|
2.39.2
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
From 518d8487d090af854fb72a7d0e5efc075d97228c Mon Sep 17 00:00:00 2001
|
From 518d8487d090af854fb72a7d0e5efc075d97228c Mon Sep 17 00:00:00 2001
|
||||||
From: Dom Cobley <popcornmix@gmail.com>
|
From: Dom Cobley <popcornmix@gmail.com>
|
||||||
Date: Wed, 18 Jan 2023 16:41:00 +0000
|
Date: Wed, 18 Jan 2023 16:41:00 +0000
|
||||||
Subject: [PATCH 4/4] CDVDVideoCodecDRMPRIME: Adjust av formats to match recent
|
Subject: [PATCH 4/7] CDVDVideoCodecDRMPRIME: Adjust av formats to match recent
|
||||||
ffmpeg changes
|
ffmpeg changes
|
||||||
|
|
||||||
---
|
---
|
||||||
@ -45,5 +45,5 @@ index a36107c515..d5b3289680 100644
|
|||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
{
|
{
|
||||||
--
|
--
|
||||||
2.39.0
|
2.39.2
|
||||||
|
|
||||||
|
@ -0,0 +1,93 @@
|
|||||||
|
From a11461db2d442e0648ebb9255a2399a647d8f5be Mon Sep 17 00:00:00 2001
|
||||||
|
From: Dom Cobley <popcornmix@gmail.com>
|
||||||
|
Date: Wed, 25 Jan 2023 18:42:24 +0000
|
||||||
|
Subject: [PATCH 5/7] DVDVideoCodecDRMPRIME: Support YUV422 and YUV444 formats
|
||||||
|
|
||||||
|
See: https://github.com/xbmc/xbmc/issues/20017
|
||||||
|
|
||||||
|
We currently can't play YUV422 and YUV444 videos with drm
|
||||||
|
but they can be made to work with straightforward plumbing
|
||||||
|
---
|
||||||
|
.../Buffers/VideoBufferPoolDMA.cpp | 6 +++++
|
||||||
|
.../DVDCodecs/Video/DVDVideoCodecDRMPRIME.cpp | 27 +++++++++++++++----
|
||||||
|
2 files changed, 28 insertions(+), 5 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/xbmc/cores/VideoPlayer/Buffers/VideoBufferPoolDMA.cpp b/xbmc/cores/VideoPlayer/Buffers/VideoBufferPoolDMA.cpp
|
||||||
|
index fb2dfc6c78..e6b071117e 100644
|
||||||
|
--- a/xbmc/cores/VideoPlayer/Buffers/VideoBufferPoolDMA.cpp
|
||||||
|
+++ b/xbmc/cores/VideoPlayer/Buffers/VideoBufferPoolDMA.cpp
|
||||||
|
@@ -123,6 +123,12 @@ uint32_t CVideoBufferPoolDMA::TranslateFormat(AVPixelFormat format)
|
||||||
|
case AV_PIX_FMT_YUV420P:
|
||||||
|
case AV_PIX_FMT_YUVJ420P:
|
||||||
|
return DRM_FORMAT_YUV420;
|
||||||
|
+ case AV_PIX_FMT_YUV422P:
|
||||||
|
+ case AV_PIX_FMT_YUVJ422P:
|
||||||
|
+ return DRM_FORMAT_YUV422;
|
||||||
|
+ case AV_PIX_FMT_YUV444P:
|
||||||
|
+ case AV_PIX_FMT_YUVJ444P:
|
||||||
|
+ return DRM_FORMAT_YUV444;
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
diff --git a/xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodecDRMPRIME.cpp b/xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodecDRMPRIME.cpp
|
||||||
|
index d5b3289680..4af903ecf5 100644
|
||||||
|
--- a/xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodecDRMPRIME.cpp
|
||||||
|
+++ b/xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodecDRMPRIME.cpp
|
||||||
|
@@ -142,7 +142,8 @@ static bool IsSupportedHwFormat(const enum AVPixelFormat fmt)
|
||||||
|
|
||||||
|
static bool IsSupportedSwFormat(const enum AVPixelFormat fmt)
|
||||||
|
{
|
||||||
|
- return fmt == AV_PIX_FMT_YUV420P || fmt == AV_PIX_FMT_YUVJ420P;
|
||||||
|
+ return fmt == AV_PIX_FMT_YUV420P || fmt == AV_PIX_FMT_YUVJ420P || fmt == AV_PIX_FMT_YUV422P ||
|
||||||
|
+ fmt == AV_PIX_FMT_YUVJ422P || fmt == AV_PIX_FMT_YUV444P || fmt == AV_PIX_FMT_YUVJ444P;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const AVCodecHWConfig* FindHWConfig(const AVCodec* codec)
|
||||||
|
@@ -206,7 +207,14 @@ enum AVPixelFormat CDVDVideoCodecDRMPRIME::GetFormat(struct AVCodecContext* avct
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- CLog::Log(LOGERROR, "CDVDVideoCodecDRMPRIME::{} - unsupported pixel format", __FUNCTION__);
|
||||||
|
+ std::vector<std::string> formats;
|
||||||
|
+ for (int n = 0; fmt[n] != AV_PIX_FMT_NONE; n++)
|
||||||
|
+ {
|
||||||
|
+ formats.emplace_back(av_get_pix_fmt_name(fmt[n]));
|
||||||
|
+ }
|
||||||
|
+ CLog::Log(LOGERROR, "CDVDVideoCodecDRMPRIME::{} - no supported pixel formats: {}", __FUNCTION__,
|
||||||
|
+ StringUtils::Join(formats, ", "));
|
||||||
|
+
|
||||||
|
return AV_PIX_FMT_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -226,6 +234,14 @@ int CDVDVideoCodecDRMPRIME::GetBuffer(struct AVCodecContext* avctx, AVFrame* fra
|
||||||
|
case AV_PIX_FMT_YUVJ420P:
|
||||||
|
size = width * height * 3 / 2;
|
||||||
|
break;
|
||||||
|
+ case AV_PIX_FMT_YUV422P:
|
||||||
|
+ case AV_PIX_FMT_YUVJ422P:
|
||||||
|
+ size = width * height * 2;
|
||||||
|
+ break;
|
||||||
|
+ case AV_PIX_FMT_YUV444P:
|
||||||
|
+ case AV_PIX_FMT_YUVJ444P:
|
||||||
|
+ size = width * height * 3;
|
||||||
|
+ break;
|
||||||
|
default:
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
@@ -512,9 +528,10 @@ bool CDVDVideoCodecDRMPRIME::SetPictureParams(VideoPicture* pVideoPicture)
|
||||||
|
(static_cast<int>(lrint(pVideoPicture->iWidth / aspect_ratio))) & -3;
|
||||||
|
}
|
||||||
|
|
||||||
|
- pVideoPicture->color_range = m_pFrame->color_range == AVCOL_RANGE_JPEG ||
|
||||||
|
- m_pFrame->format == AV_PIX_FMT_YUVJ420P ||
|
||||||
|
- m_hints.colorRange == AVCOL_RANGE_JPEG;
|
||||||
|
+ pVideoPicture->color_range =
|
||||||
|
+ m_pFrame->color_range == AVCOL_RANGE_JPEG || m_pFrame->format == AV_PIX_FMT_YUVJ420P ||
|
||||||
|
+ m_pFrame->format == AV_PIX_FMT_YUVJ422P || m_pFrame->format == AV_PIX_FMT_YUVJ444P ||
|
||||||
|
+ m_hints.colorRange == AVCOL_RANGE_JPEG;
|
||||||
|
pVideoPicture->color_primaries = m_pFrame->color_primaries == AVCOL_PRI_UNSPECIFIED
|
||||||
|
? m_hints.colorPrimaries
|
||||||
|
: m_pFrame->color_primaries;
|
||||||
|
--
|
||||||
|
2.39.2
|
||||||
|
|
@ -0,0 +1,55 @@
|
|||||||
|
From 7b820fa6812e8389613238c6ab3a12fc1dee0276 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Dom Cobley <popcornmix@gmail.com>
|
||||||
|
Date: Tue, 31 Jan 2023 14:13:00 +0000
|
||||||
|
Subject: [PATCH 6/7] VideoBufferDMA: Support exporting YCbCr444 buffers
|
||||||
|
|
||||||
|
The current code assumes chroma is decimated by two, but that is not necessarily the case.
|
||||||
|
DRMPRIME decode with EGL rendering of YCbCr444 video will have corrupted colours.
|
||||||
|
|
||||||
|
Ask ffmpeg what the chroma decimation is.
|
||||||
|
---
|
||||||
|
.../VideoPlayer/Buffers/VideoBufferDMA.cpp | 21 ++++++++++++-------
|
||||||
|
1 file changed, 14 insertions(+), 7 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/xbmc/cores/VideoPlayer/Buffers/VideoBufferDMA.cpp b/xbmc/cores/VideoPlayer/Buffers/VideoBufferDMA.cpp
|
||||||
|
index 2dd7c1341d..3e6bf0dc7a 100644
|
||||||
|
--- a/xbmc/cores/VideoPlayer/Buffers/VideoBufferDMA.cpp
|
||||||
|
+++ b/xbmc/cores/VideoPlayer/Buffers/VideoBufferDMA.cpp
|
||||||
|
@@ -119,20 +119,27 @@ bool CVideoBufferDMA::Alloc()
|
||||||
|
|
||||||
|
void CVideoBufferDMA::Export(AVFrame* frame, uint32_t width, uint32_t height)
|
||||||
|
{
|
||||||
|
- m_planes = av_pix_fmt_count_planes(static_cast<AVPixelFormat>(frame->format));
|
||||||
|
+ AVPixelFormat pix_fmt = static_cast<AVPixelFormat>(frame->format);
|
||||||
|
+ m_planes = av_pix_fmt_count_planes(pix_fmt);
|
||||||
|
+ int h_shift;
|
||||||
|
+ int v_shift;
|
||||||
|
|
||||||
|
- if (m_planes < 2)
|
||||||
|
- throw std::runtime_error(
|
||||||
|
- "non-planar formats not supported: " +
|
||||||
|
- std::string(av_get_pix_fmt_name(static_cast<AVPixelFormat>(frame->format))));
|
||||||
|
+ if (av_pix_fmt_get_chroma_sub_sample(pix_fmt, &h_shift, &v_shift))
|
||||||
|
+ throw std::runtime_error("unable to determine chroma_sub_sample: " +
|
||||||
|
+ std::string(av_get_pix_fmt_name(pix_fmt)));
|
||||||
|
+
|
||||||
|
+ if (m_planes < 2 || m_planes > 3)
|
||||||
|
+ throw std::runtime_error("only 2 or 3 plane formats supported: " +
|
||||||
|
+ std::string(av_get_pix_fmt_name(pix_fmt)));
|
||||||
|
|
||||||
|
for (uint32_t plane = 0; plane < m_planes; plane++)
|
||||||
|
{
|
||||||
|
m_strides[plane] =
|
||||||
|
av_image_get_linesize(static_cast<AVPixelFormat>(frame->format), width, plane);
|
||||||
|
- m_offsets[plane] =
|
||||||
|
- plane == 0 ? 0 : (m_offsets[plane - 1] + m_strides[plane - 1] * (height >> (plane - 1)));
|
||||||
|
}
|
||||||
|
+ m_offsets[0] = 0;
|
||||||
|
+ m_offsets[1] = m_strides[0] * height;
|
||||||
|
+ m_offsets[2] = m_offsets[1] + (m_strides[1] * height >> v_shift);
|
||||||
|
|
||||||
|
if (CServiceBroker::GetLogging().CanLogComponent(LOGVIDEO))
|
||||||
|
{
|
||||||
|
--
|
||||||
|
2.39.2
|
||||||
|
|
@ -0,0 +1,332 @@
|
|||||||
|
From ae91030c1a84693fd0d34b919f9f8434b08e00c9 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Dom Cobley <popcornmix@gmail.com>
|
||||||
|
Date: Mon, 6 Feb 2023 15:19:51 +0000
|
||||||
|
Subject: [PATCH 7/7] DVDVideoCodecDRMPRIME: Add support for arbitrary output
|
||||||
|
pixel formats
|
||||||
|
|
||||||
|
This enables any ffmpeg pixel formats to be supported by DRMPRIME decoder
|
||||||
|
by creating a scale ffmpeg filter to convert it to a supported format.
|
||||||
|
|
||||||
|
This allows formats like h264 Hi10P and hevc 12-bit 444 to be software decoded,
|
||||||
|
converted and displayed through DRM.
|
||||||
|
|
||||||
|
This will be a cheaper path than disabling DRMPRIME, which is also
|
||||||
|
software decode, convert, but then needs convert to texture and display through GL.
|
||||||
|
|
||||||
|
And it happens automatically without requiring user video settings
|
||||||
|
---
|
||||||
|
.../DVDCodecs/Video/DVDVideoCodecDRMPRIME.cpp | 124 +++++++++++-------
|
||||||
|
.../DVDCodecs/Video/DVDVideoCodecDRMPRIME.h | 3 +-
|
||||||
|
2 files changed, 77 insertions(+), 50 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodecDRMPRIME.cpp b/xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodecDRMPRIME.cpp
|
||||||
|
index 4af903ecf5..92a182608d 100644
|
||||||
|
--- a/xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodecDRMPRIME.cpp
|
||||||
|
+++ b/xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodecDRMPRIME.cpp
|
||||||
|
@@ -199,7 +199,7 @@ enum AVPixelFormat CDVDVideoCodecDRMPRIME::GetFormat(struct AVCodecContext* avct
|
||||||
|
{
|
||||||
|
for (int n = 0; fmt[n] != AV_PIX_FMT_NONE; n++)
|
||||||
|
{
|
||||||
|
- if (IsSupportedHwFormat(fmt[n]) || IsSupportedSwFormat(fmt[n]))
|
||||||
|
+ //if (IsSupportedHwFormat(fmt[n]) || IsSupportedSwFormat(fmt[n]))
|
||||||
|
{
|
||||||
|
CDVDVideoCodecDRMPRIME* ctx = static_cast<CDVDVideoCodecDRMPRIME*>(avctx->opaque);
|
||||||
|
ctx->UpdateProcessInfo(avctx, fmt[n]);
|
||||||
|
@@ -220,7 +220,8 @@ enum AVPixelFormat CDVDVideoCodecDRMPRIME::GetFormat(struct AVCodecContext* avct
|
||||||
|
|
||||||
|
int CDVDVideoCodecDRMPRIME::GetBuffer(struct AVCodecContext* avctx, AVFrame* frame, int flags)
|
||||||
|
{
|
||||||
|
- if (IsSupportedSwFormat(static_cast<AVPixelFormat>(frame->format)))
|
||||||
|
+ AVPixelFormat pix_fmt = static_cast<AVPixelFormat>(frame->format);
|
||||||
|
+ if (IsSupportedSwFormat(pix_fmt))
|
||||||
|
{
|
||||||
|
int width = frame->width;
|
||||||
|
int height = frame->height;
|
||||||
|
@@ -228,7 +229,7 @@ int CDVDVideoCodecDRMPRIME::GetBuffer(struct AVCodecContext* avctx, AVFrame* fra
|
||||||
|
AlignedSize(avctx, width, height);
|
||||||
|
|
||||||
|
int size;
|
||||||
|
- switch (avctx->pix_fmt)
|
||||||
|
+ switch (pix_fmt)
|
||||||
|
{
|
||||||
|
case AV_PIX_FMT_YUV420P:
|
||||||
|
case AV_PIX_FMT_YUVJ420P:
|
||||||
|
@@ -248,13 +249,12 @@ int CDVDVideoCodecDRMPRIME::GetBuffer(struct AVCodecContext* avctx, AVFrame* fra
|
||||||
|
|
||||||
|
CDVDVideoCodecDRMPRIME* ctx = static_cast<CDVDVideoCodecDRMPRIME*>(avctx->opaque);
|
||||||
|
auto buffer = dynamic_cast<CVideoBufferDMA*>(
|
||||||
|
- ctx->m_processInfo.GetVideoBufferManager().Get(avctx->pix_fmt, size, nullptr));
|
||||||
|
+ ctx->m_processInfo.GetVideoBufferManager().Get(pix_fmt, size, nullptr));
|
||||||
|
if (!buffer)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
- frame->opaque = static_cast<void*>(buffer);
|
||||||
|
frame->opaque_ref =
|
||||||
|
- av_buffer_create(nullptr, 0, ReleaseBuffer, frame->opaque, AV_BUFFER_FLAG_READONLY);
|
||||||
|
+ av_buffer_create(nullptr, 0, ReleaseBuffer, static_cast<void*>(buffer), AV_BUFFER_FLAG_READONLY);
|
||||||
|
|
||||||
|
buffer->Export(frame, width, height);
|
||||||
|
buffer->SyncStart();
|
||||||
|
@@ -608,9 +608,9 @@ bool CDVDVideoCodecDRMPRIME::SetPictureParams(VideoPicture* pVideoPicture)
|
||||||
|
buffer->SetRef(m_pFrame);
|
||||||
|
pVideoPicture->videoBuffer = buffer;
|
||||||
|
}
|
||||||
|
- else if (m_pFrame->opaque)
|
||||||
|
+ else if (IsSupportedSwFormat(static_cast<AVPixelFormat>(m_pFrame->format)))
|
||||||
|
{
|
||||||
|
- CVideoBufferDMA* buffer = static_cast<CVideoBufferDMA*>(m_pFrame->opaque);
|
||||||
|
+ CVideoBufferDMA* buffer = static_cast<CVideoBufferDMA*>(av_buffer_get_opaque(m_pFrame->buf[0]));
|
||||||
|
buffer->SetPictureParams(*pVideoPicture);
|
||||||
|
buffer->Acquire();
|
||||||
|
buffer->SyncEnd();
|
||||||
|
@@ -644,13 +644,13 @@ void CDVDVideoCodecDRMPRIME::FilterTest()
|
||||||
|
|
||||||
|
if (name.find("deinterlace") != std::string::npos)
|
||||||
|
{
|
||||||
|
- if (FilterOpen(name, true))
|
||||||
|
+ bool ret = FilterOpen(name, false, true);
|
||||||
|
+ FilterClose();
|
||||||
|
+ if (ret)
|
||||||
|
{
|
||||||
|
m_deintFilterName = name;
|
||||||
|
-
|
||||||
|
CLog::Log(LOGDEBUG, "CDVDVideoCodecDRMPRIME::{} - found deinterlacing filter {}",
|
||||||
|
__FUNCTION__, name);
|
||||||
|
-
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@@ -660,14 +660,31 @@ void CDVDVideoCodecDRMPRIME::FilterTest()
|
||||||
|
__FUNCTION__);
|
||||||
|
}
|
||||||
|
|
||||||
|
-bool CDVDVideoCodecDRMPRIME::FilterOpen(const std::string& filters, bool test)
|
||||||
|
+AVFrame *CDVDVideoCodecDRMPRIME::alloc_filter_frame(AVFilterContext * ctx, void * v, int w, int h)
|
||||||
|
+{
|
||||||
|
+ int result;
|
||||||
|
+ CDVDVideoCodecDRMPRIME* me = static_cast<CDVDVideoCodecDRMPRIME*>(v);
|
||||||
|
+ AVFrame *frame = av_frame_alloc();
|
||||||
|
+ frame->width = w;
|
||||||
|
+ frame->height = h;
|
||||||
|
+ frame->format = AV_PIX_FMT_YUV420P;
|
||||||
|
+
|
||||||
|
+ if ((result = CDVDVideoCodecDRMPRIME::GetBuffer(me->m_pCodecContext, frame, 0)) < 0)
|
||||||
|
+ {
|
||||||
|
+ CLog::Log(LOGERROR, "CDVDVideoCodecDRMPRIME::alloc_filter_frame - failed to GetBuffer ({})", result);
|
||||||
|
+ return nullptr;
|
||||||
|
+ }
|
||||||
|
+ return frame;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+bool CDVDVideoCodecDRMPRIME::FilterOpen(const std::string& filters, bool scale, bool test)
|
||||||
|
{
|
||||||
|
int result;
|
||||||
|
|
||||||
|
if (m_pFilterGraph)
|
||||||
|
FilterClose();
|
||||||
|
|
||||||
|
- if (filters.empty())
|
||||||
|
+ if (filters.empty() && !scale)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if (!(m_pFilterGraph = avfilter_graph_alloc()))
|
||||||
|
@@ -678,13 +695,13 @@ bool CDVDVideoCodecDRMPRIME::FilterOpen(const std::string& filters, bool test)
|
||||||
|
|
||||||
|
const AVFilter* srcFilter = avfilter_get_by_name("buffer");
|
||||||
|
const AVFilter* outFilter = avfilter_get_by_name("buffersink");
|
||||||
|
- enum AVPixelFormat pix_fmts[] = { AV_PIX_FMT_DRM_PRIME, AV_PIX_FMT_NONE };
|
||||||
|
+ enum AVPixelFormat pix_fmts[] = { scale ? AV_PIX_FMT_YUV420P : AV_PIX_FMT_DRM_PRIME, AV_PIX_FMT_NONE };
|
||||||
|
|
||||||
|
std::string args = StringUtils::Format("video_size={}x{}:pix_fmt={}:time_base={}/{}:"
|
||||||
|
"pixel_aspect={}/{}",
|
||||||
|
m_pCodecContext->width,
|
||||||
|
m_pCodecContext->height,
|
||||||
|
- AV_PIX_FMT_DRM_PRIME,
|
||||||
|
+ scale ? m_pCodecContext->pix_fmt : AV_PIX_FMT_DRM_PRIME,
|
||||||
|
m_pCodecContext->time_base.num ?
|
||||||
|
m_pCodecContext->time_base.num : 1,
|
||||||
|
m_pCodecContext->time_base.num ?
|
||||||
|
@@ -703,7 +720,6 @@ bool CDVDVideoCodecDRMPRIME::FilterOpen(const std::string& filters, bool test)
|
||||||
|
CLog::Log(LOGERROR,
|
||||||
|
"CDVDVideoCodecDRMPRIME::FilterOpen - avfilter_graph_create_filter: src: {} ({})",
|
||||||
|
err, result);
|
||||||
|
- FilterClose();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -711,7 +727,6 @@ bool CDVDVideoCodecDRMPRIME::FilterOpen(const std::string& filters, bool test)
|
||||||
|
if (!par)
|
||||||
|
{
|
||||||
|
CLog::Log(LOGERROR, "CDVDVideoCodecDRMPRIME::FilterOpen - unable to alloc buffersrc");
|
||||||
|
- FilterClose();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -727,7 +742,6 @@ bool CDVDVideoCodecDRMPRIME::FilterOpen(const std::string& filters, bool test)
|
||||||
|
CLog::Log(LOGERROR,
|
||||||
|
"CDVDVideoCodecDRMPRIME::FilterOpen - av_buffersrc_parameters_set: {} ({})",
|
||||||
|
err, result);
|
||||||
|
- FilterClose();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
av_freep(&par);
|
||||||
|
@@ -741,7 +755,6 @@ bool CDVDVideoCodecDRMPRIME::FilterOpen(const std::string& filters, bool test)
|
||||||
|
CLog::Log(LOGERROR,
|
||||||
|
"CDVDVideoCodecDRMPRIME::FilterOpen - avfilter_graph_create_filter: out: {} ({})",
|
||||||
|
err, result);
|
||||||
|
- FilterClose();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -750,32 +763,46 @@ bool CDVDVideoCodecDRMPRIME::FilterOpen(const std::string& filters, bool test)
|
||||||
|
if (result < 0)
|
||||||
|
{
|
||||||
|
CLog::Log(LOGERROR, "CDVDVideoCodecDRMPRIME::FilterOpen - failed settings pix formats");
|
||||||
|
- FilterClose();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
- AVFilterInOut* outputs = avfilter_inout_alloc();
|
||||||
|
- AVFilterInOut* inputs = avfilter_inout_alloc();
|
||||||
|
+ if (!filters.empty())
|
||||||
|
+ {
|
||||||
|
+ AVFilterInOut* outputs = avfilter_inout_alloc();
|
||||||
|
+ AVFilterInOut* inputs = avfilter_inout_alloc();
|
||||||
|
|
||||||
|
- outputs->name = av_strdup("in");
|
||||||
|
- outputs->filter_ctx = m_pFilterIn;
|
||||||
|
- outputs->pad_idx = 0;
|
||||||
|
- outputs->next = nullptr;
|
||||||
|
+ outputs->name = av_strdup("in");
|
||||||
|
+ outputs->filter_ctx = m_pFilterIn;
|
||||||
|
+ outputs->pad_idx = 0;
|
||||||
|
+ outputs->next = nullptr;
|
||||||
|
|
||||||
|
- inputs->name = av_strdup("out");
|
||||||
|
- inputs->filter_ctx = m_pFilterOut;
|
||||||
|
- inputs->pad_idx = 0;
|
||||||
|
- inputs->next = nullptr;
|
||||||
|
+ inputs->name = av_strdup("out");
|
||||||
|
+ inputs->filter_ctx = m_pFilterOut;
|
||||||
|
+ inputs->pad_idx = 0;
|
||||||
|
+ inputs->next = nullptr;
|
||||||
|
|
||||||
|
- result = avfilter_graph_parse_ptr(m_pFilterGraph, filters.c_str(), &inputs, &outputs, NULL);
|
||||||
|
- avfilter_inout_free(&outputs);
|
||||||
|
- avfilter_inout_free(&inputs);
|
||||||
|
+ result = avfilter_graph_parse_ptr(m_pFilterGraph, filters.c_str(), &inputs, &outputs, NULL);
|
||||||
|
+ avfilter_inout_free(&outputs);
|
||||||
|
+ avfilter_inout_free(&inputs);
|
||||||
|
|
||||||
|
- if (result < 0)
|
||||||
|
+ if (result < 0)
|
||||||
|
+ {
|
||||||
|
+ CLog::Log(LOGERROR, "CDVDVideoCodecDRMPRIME::FilterOpen - avfilter_graph_parse");
|
||||||
|
+ return false;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ else
|
||||||
|
{
|
||||||
|
- CLog::Log(LOGERROR, "CDVDVideoCodecDRMPRIME::FilterOpen - avfilter_graph_parse");
|
||||||
|
- FilterClose();
|
||||||
|
- return false;
|
||||||
|
+ if ((result = av_buffersink_set_alloc_video_frame(m_pFilterOut, alloc_filter_frame, static_cast<void*>(this))) < 0)
|
||||||
|
+ {
|
||||||
|
+ CLog::Log(LOGERROR, "CDVDVideoCodecDRMPRIME::FilterOpen - av_buffersink_set_alloc_video_frame = {}", result);
|
||||||
|
+ return result;
|
||||||
|
+ }
|
||||||
|
+ if ((result = avfilter_link(m_pFilterIn, 0, m_pFilterOut, 0)) < 0)
|
||||||
|
+ {
|
||||||
|
+ CLog::Log(LOGERROR, "CDVDVideoCodecDRMPRIME::FilterOpen - avfilter_link");
|
||||||
|
+ return false;
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((result = avfilter_graph_config(m_pFilterGraph, nullptr)) < 0)
|
||||||
|
@@ -784,15 +811,11 @@ bool CDVDVideoCodecDRMPRIME::FilterOpen(const std::string& filters, bool test)
|
||||||
|
av_strerror(result, err, AV_ERROR_MAX_STRING_SIZE);
|
||||||
|
CLog::Log(LOGERROR, "CDVDVideoCodecDRMPRIME::FilterOpen - avfilter_graph_config: {} ({})",
|
||||||
|
err, result);
|
||||||
|
- FilterClose();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (test)
|
||||||
|
- {
|
||||||
|
- FilterClose();
|
||||||
|
return true;
|
||||||
|
- }
|
||||||
|
|
||||||
|
m_processInfo.SetVideoDeintMethod(filters);
|
||||||
|
|
||||||
|
@@ -827,16 +850,16 @@ void CDVDVideoCodecDRMPRIME::FilterClose()
|
||||||
|
CDVDVideoCodec::VCReturn CDVDVideoCodecDRMPRIME::ProcessFilterIn()
|
||||||
|
{
|
||||||
|
// sw decoded buffers need cache flush and for descripter to be set
|
||||||
|
- if (!IsSupportedHwFormat(static_cast<AVPixelFormat>(m_pFrame->format)) && m_pFrame->opaque != nullptr)
|
||||||
|
+ if (!IsSupportedHwFormat(static_cast<AVPixelFormat>(m_pFrame->format)) && IsSupportedSwFormat(static_cast<AVPixelFormat>(m_pFrame->format)))
|
||||||
|
{
|
||||||
|
- CVideoBufferDMA* buffer = static_cast<CVideoBufferDMA*>(m_pFrame->opaque);
|
||||||
|
+ CVideoBufferDMA* buffer = static_cast<CVideoBufferDMA*>(av_buffer_get_opaque(m_pFrame->buf[0]));
|
||||||
|
buffer->SetDimensions(m_pFrame->width, m_pFrame->height);
|
||||||
|
buffer->SyncEnd();
|
||||||
|
auto descriptor = buffer->GetDescriptor();
|
||||||
|
m_pFrame->data[0] = reinterpret_cast<uint8_t*>(descriptor);
|
||||||
|
+ m_pFrame->format = AV_PIX_FMT_DRM_PRIME;
|
||||||
|
}
|
||||||
|
|
||||||
|
- m_pFrame->format = AV_PIX_FMT_DRM_PRIME;
|
||||||
|
int ret = av_buffersrc_add_frame(m_pFilterIn, m_pFrame);
|
||||||
|
if (ret < 0)
|
||||||
|
{
|
||||||
|
@@ -929,25 +952,28 @@ CDVDVideoCodec::VCReturn CDVDVideoCodecDRMPRIME::GetPicture(VideoPicture* pVideo
|
||||||
|
return VC_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ // we need to scale if the buffer isn't in DRM_PRIME format
|
||||||
|
+ bool need_scale = !IsSupportedSwFormat(static_cast<AVPixelFormat>(m_pFrame->format)) && !IsSupportedHwFormat(static_cast<AVPixelFormat>(m_pFrame->format));
|
||||||
|
+
|
||||||
|
if (!m_processInfo.GetVideoInterlaced() && m_pFrame->interlaced_frame)
|
||||||
|
m_processInfo.SetVideoInterlaced(true);
|
||||||
|
|
||||||
|
std::string filterChain = GetFilterChain(m_pFrame->interlaced_frame);
|
||||||
|
- if (!filterChain.empty())
|
||||||
|
+ if (!filterChain.empty() || need_scale)
|
||||||
|
{
|
||||||
|
bool reopenFilter = false;
|
||||||
|
if (m_filters != filterChain)
|
||||||
|
reopenFilter = true;
|
||||||
|
|
||||||
|
if (m_pFilterGraph &&
|
||||||
|
- (m_pFilterIn->outputs[0]->w != m_pCodecContext->width ||
|
||||||
|
- m_pFilterIn->outputs[0]->h != m_pCodecContext->height))
|
||||||
|
+ (m_pFilterIn->outputs[0]->w != m_pFrame->width ||
|
||||||
|
+ m_pFilterIn->outputs[0]->h != m_pFrame->height))
|
||||||
|
reopenFilter = true;
|
||||||
|
|
||||||
|
- if (reopenFilter)
|
||||||
|
+ if (reopenFilter || (need_scale && m_pFilterGraph == nullptr))
|
||||||
|
{
|
||||||
|
m_filters = filterChain;
|
||||||
|
- if (!FilterOpen(filterChain, false))
|
||||||
|
+ if (!FilterOpen(filterChain, need_scale, false))
|
||||||
|
FilterClose();
|
||||||
|
}
|
||||||
|
|
||||||
|
diff --git a/xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodecDRMPRIME.h b/xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodecDRMPRIME.h
|
||||||
|
index fab3431d40..bb88fde1f9 100644
|
||||||
|
--- a/xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodecDRMPRIME.h
|
||||||
|
+++ b/xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodecDRMPRIME.h
|
||||||
|
@@ -44,7 +44,8 @@ protected:
|
||||||
|
CDVDVideoCodec::VCReturn ProcessFilterOut();
|
||||||
|
static enum AVPixelFormat GetFormat(struct AVCodecContext* avctx, const enum AVPixelFormat* fmt);
|
||||||
|
static int GetBuffer(struct AVCodecContext* avctx, AVFrame* frame, int flags);
|
||||||
|
- bool FilterOpen(const std::string& filters, bool test);
|
||||||
|
+ static AVFrame *alloc_filter_frame(AVFilterContext * ctx, void * v, int w, int h);
|
||||||
|
+ bool FilterOpen(const std::string& filters, bool scale, bool test);
|
||||||
|
void FilterClose();
|
||||||
|
void FilterTest();
|
||||||
|
std::string GetFilterChain(bool interlaced);
|
||||||
|
--
|
||||||
|
2.39.2
|
||||||
|
|
@ -46,7 +46,7 @@ create_patch() {
|
|||||||
;;
|
;;
|
||||||
rpi)
|
rpi)
|
||||||
REPO="https://github.com/jc-kynesim/rpi-ffmpeg"
|
REPO="https://github.com/jc-kynesim/rpi-ffmpeg"
|
||||||
REFSPEC="dev/4.4/rpi_import_1"
|
REFSPEC="test/4.4.1/main"
|
||||||
PATCH_CREATE_DIFF="yes"
|
PATCH_CREATE_DIFF="yes"
|
||||||
;;
|
;;
|
||||||
kodi)
|
kodi)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user