[libav-devel] [PATCH 3/6] cbs: Demote the "decomposition unimplemented" warning

2017-12-10 Thread Mark Thompson
This is harmless and should not be a warning - unknown units are passed
through to the write functions unchanged, and no other code will interact
with them.
---
 libavcodec/cbs.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/libavcodec/cbs.c b/libavcodec/cbs.c
index 3baa31a4d..283e2cc59 100644
--- a/libavcodec/cbs.c
+++ b/libavcodec/cbs.c
@@ -121,7 +121,7 @@ static int cbs_read_fragment_content(CodedBitstreamContext 
*ctx,
 
 err = ctx->codec->read_unit(ctx, >units[i]);
 if (err == AVERROR(ENOSYS)) {
-av_log(ctx->log_ctx, AV_LOG_WARNING,
+av_log(ctx->log_ctx, AV_LOG_VERBOSE,
"Decomposition unimplemented for unit %d "
"(type %d).\n", i, frag->units[i].type);
 } else if (err < 0) {
-- 
2.11.0

___
libav-devel mailing list
libav-devel@libav.org
https://lists.libav.org/mailman/listinfo/libav-devel

[libav-devel] [PATCH 6/6] h264_metadata: Add ability to delete filler data

2017-12-10 Thread Mark Thompson
Deletes both filler NAL units and filler SEI messages.
---
 libavcodec/h264_metadata_bsf.c | 44 ++
 1 file changed, 44 insertions(+)

diff --git a/libavcodec/h264_metadata_bsf.c b/libavcodec/h264_metadata_bsf.c
index ac0b9823b..58d598e6d 100644
--- a/libavcodec/h264_metadata_bsf.c
+++ b/libavcodec/h264_metadata_bsf.c
@@ -62,6 +62,8 @@ typedef struct H264MetadataContext {
 int crop_bottom;
 
 const char *sei_user_data;
+
+int delete_filler;
 } H264MetadataContext;
 
 
@@ -278,6 +280,45 @@ static int h264_metadata_filter(AVBSFContext *bsf, 
AVPacket *out)
 }
 }
 
+if (ctx->delete_filler) {
+for (i = 0; i < au->nb_units; i++) {
+int delete_unit = 0;
+if (au->units[i].type == H264_NAL_FILLER_DATA) {
+// Filler NAL units.
+delete_unit = 1;
+}
+if (au->units[i].type == H264_NAL_SEI) {
+// Filler SEI messages.
+H264RawSEI *sei = au->units[i].content;
+
+for (j = 0; j < sei->payload_count; j++) {
+if (sei->payload[j].payload_type ==
+H264_SEI_TYPE_FILLER_PAYLOAD) {
+if (j + 1 < sei->payload_count) {
+memmove(>payload[j],
+>payload[j + 1],
+(sei->payload_count - (j + 1)) *
+sizeof(*sei->payload));
+}
+--j;
+--sei->payload_count;
+}
+}
+if (sei->payload_count == 0)
+delete_unit = 1;
+}
+if (delete_unit) {
+err = ff_cbs_delete_unit(>cbc, au, i);
+if (err < 0) {
+av_log(bsf, AV_LOG_ERROR, "Failed to delete "
+   "filler NAL.\n");
+goto fail;
+}
+--i;
+}
+}
+}
+
 has_sps = 0;
 for (i = 0; i < au->nb_units; i++) {
 if (au->units[i].type == H264_NAL_SPS) {
@@ -495,6 +536,9 @@ static const AVOption h264_metadata_options[] = {
 { "sei_user_data", "Insert SEI user data (UUID+string)",
 OFFSET(sei_user_data), AV_OPT_TYPE_STRING, { .str = NULL } },
 
+{ "delete_filler", "Delete all filler (both NAL and SEI)",
+OFFSET(delete_filler), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1 },
+
 { NULL }
 };
 
-- 
2.11.0

___
libav-devel mailing list
libav-devel@libav.org
https://lists.libav.org/mailman/listinfo/libav-devel

[libav-devel] [PATCH 4/6] cbs_h2645: Remove active ps references when it is replaced

2017-12-10 Thread Mark Thompson
---
 libavcodec/cbs_h2645.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/libavcodec/cbs_h2645.c b/libavcodec/cbs_h2645.c
index 00eed0f28..1e7854584 100644
--- a/libavcodec/cbs_h2645.c
+++ b/libavcodec/cbs_h2645.c
@@ -674,6 +674,8 @@ static int cbs_h26 ## h26n ## _replace_ ## 
ps_var(CodedBitstreamContext *ctx, \
" id : %d.\n", id); \
 return AVERROR_INVALIDDATA; \
 } \
+if (priv->ps_var[id] == priv->active_ ## ps_var) \
+priv->active_ ## ps_var = NULL ; \
 av_freep(>ps_var[id]); \
 priv->ps_var[id] = av_malloc(sizeof(*ps_var)); \
 if (!priv->ps_var[id]) \
-- 
2.11.0

___
libav-devel mailing list
libav-devel@libav.org
https://lists.libav.org/mailman/listinfo/libav-devel

[libav-devel] [PATCH 5/6] cbs_h264: Add hack for pic_timing with no active SPS

2017-12-10 Thread Mark Thompson
If there is exactly one possible SPS but it is not yet active then just
assume that it should be the active one.
---
 libavcodec/cbs_h264_syntax_template.c | 16 
 1 file changed, 16 insertions(+)

diff --git a/libavcodec/cbs_h264_syntax_template.c 
b/libavcodec/cbs_h264_syntax_template.c
index 0fe18441c..c2fd54682 100644
--- a/libavcodec/cbs_h264_syntax_template.c
+++ b/libavcodec/cbs_h264_syntax_template.c
@@ -561,6 +561,22 @@ static int FUNC(sei_pic_timing)(CodedBitstreamContext 
*ctx, RWContext *rw,
 
 sps = h264->active_sps;
 if (!sps) {
+// If there is exactly one possible SPS but it is not yet active
+// then just assume that it should be the active one.
+int i, k = -1;
+for (i = 0; i < H264_MAX_SPS_COUNT; i++) {
+if (h264->sps[i]) {
+if (k >= 0) {
+k = -1;
+break;
+}
+k = i;
+}
+}
+if (k >= 0)
+sps = h264->sps[k];
+}
+if (!sps) {
 av_log(ctx->log_ctx, AV_LOG_ERROR,
"No active SPS for pic_timing.\n");
 return AVERROR_INVALIDDATA;
-- 
2.11.0

___
libav-devel mailing list
libav-devel@libav.org
https://lists.libav.org/mailman/listinfo/libav-devel

[libav-devel] [PATCH 2/6] hevc: Remove unused hevc_ps_enc.c

2017-12-10 Thread Mark Thompson
Replaced with more complete implementation via coded bitstream infrastructure.
---
 libavcodec/hevc_ps.h |   3 --
 libavcodec/hevc_ps_enc.c | 118 ---
 2 files changed, 121 deletions(-)
 delete mode 100644 libavcodec/hevc_ps_enc.c

diff --git a/libavcodec/hevc_ps.h b/libavcodec/hevc_ps.h
index 6e2b52777..7f88b42e1 100644
--- a/libavcodec/hevc_ps.h
+++ b/libavcodec/hevc_ps.h
@@ -312,7 +312,4 @@ int ff_hevc_decode_nal_pps(GetBitContext *gb, 
AVCodecContext *avctx,
 int ff_hevc_decode_short_term_rps(GetBitContext *gb, AVCodecContext *avctx,
   ShortTermRPS *rps, const HEVCSPS *sps, int 
is_slice_header);
 
-int ff_hevc_encode_nal_vps(HEVCVPS *vps, unsigned int id,
-   uint8_t *buf, int buf_size);
-
 #endif /* AVCODEC_HEVC_PS_H */
diff --git a/libavcodec/hevc_ps_enc.c b/libavcodec/hevc_ps_enc.c
deleted file mode 100644
index 1fb93b302..0
--- a/libavcodec/hevc_ps_enc.c
+++ /dev/null
@@ -1,118 +0,0 @@
-/*
- * HEVC Parameter Set encoding
- *
- * This file is part of Libav.
- *
- * Libav is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * Libav is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#include "golomb_legacy.h"
-#include "hevc_ps.h"
-#include "put_bits.h"
-
-static void write_ptl_layer(PutBitContext *pb, PTLCommon *ptl)
-{
-int i;
-
-put_bits(pb, 2, ptl->profile_space);
-put_bits(pb, 1, ptl->tier_flag);
-put_bits(pb, 5, ptl->profile_idc);
-for (i = 0; i < 32; i++)
-put_bits(pb, 1, ptl->profile_compatibility_flag[i]);
-put_bits(pb, 1, ptl->progressive_source_flag);
-put_bits(pb, 1, ptl->interlaced_source_flag);
-put_bits(pb, 1, ptl->non_packed_constraint_flag);
-put_bits(pb, 1, ptl->frame_only_constraint_flag);
-put_bits32(pb, 0);   // reserved
-put_bits(pb, 12, 0); // reserved
-}
-
-static void write_ptl(PutBitContext *pb, PTL *ptl, int max_num_sub_layers)
-{
-int i;
-
-write_ptl_layer(pb, >general_ptl);
-put_bits(pb, 8, ptl->general_ptl.level_idc);
-
-for (i = 0; i < max_num_sub_layers - 1; i++) {
-put_bits(pb, 1, ptl->sub_layer_profile_present_flag[i]);
-put_bits(pb, 1, ptl->sub_layer_level_present_flag[i]);
-}
-
-if (max_num_sub_layers > 1)
-for (i = max_num_sub_layers - 1; i < 8; i++)
-put_bits(pb, 2, 0); // reserved
-
-for (i = 0; i < max_num_sub_layers - 1; i++) {
-if (ptl->sub_layer_profile_present_flag[i])
-write_ptl_layer(pb, >sub_layer_ptl[i]);
-if (ptl->sub_layer_level_present_flag[i])
-put_bits(pb, 8, ptl->sub_layer_ptl[i].level_idc);
-}
-}
-
-int ff_hevc_encode_nal_vps(HEVCVPS *vps, unsigned int id,
-   uint8_t *buf, int buf_size)
-{
-PutBitContext pb;
-int i;
-
-init_put_bits(, buf, buf_size);
-put_bits(,  4, id);
-put_bits(,  2, 3);   // reserved
-put_bits(,  6, vps->vps_max_layers - 1);
-put_bits(,  3, vps->vps_max_sub_layers - 1);
-put_bits(,  1, vps->vps_temporal_id_nesting_flag);
-put_bits(, 16, 0x);  // reserved
-
-write_ptl(, >ptl, vps->vps_max_sub_layers);
-
-put_bits(, 1, vps->vps_sub_layer_ordering_info_present_flag);
-for (i = vps->vps_sub_layer_ordering_info_present_flag ? 0 : 
vps->vps_max_layers - 1;
- i < vps->vps_max_sub_layers; i++) {
-set_ue_golomb(, vps->vps_max_dec_pic_buffering[i] - 1);
-set_ue_golomb(, vps->vps_num_reorder_pics[i]);
-set_ue_golomb(, vps->vps_max_latency_increase[i] + 1);
-}
-
-put_bits(, 6, vps->vps_max_layer_id);
-set_ue_golomb(, vps->vps_num_layer_sets - 1);
-
-if (vps->vps_num_layer_sets > 1) {
-avpriv_report_missing_feature(NULL, "Writing layer_id_included_flag");
-return AVERROR_PATCHWELCOME;
-}
-
-put_bits(, 1, vps->vps_timing_info_present_flag);
-if (vps->vps_timing_info_present_flag) {
-put_bits32(, vps->vps_num_units_in_tick);
-put_bits32(, vps->vps_time_scale);
-put_bits(, 1, vps->vps_poc_proportional_to_timing_flag);
-if (vps->vps_poc_proportional_to_timing_flag)
-set_ue_golomb(, vps->vps_num_ticks_poc_diff_one - 1);
-
-if (vps->vps_num_hrd_parameters) {
-avpriv_report_missing_feature(NULL, "Writing HRD 

[libav-devel] [PATCH 1/6] qsvenc_hevc: Replace ad-hoc VPS writing with CBS implementation

2017-12-10 Thread Mark Thompson
This copies more information which should be present from the SPS.
It also fixes the value of vps_temporal_id_nesting_flag, which was
previously incorrect for a single-layer stream (the standard states
that it must be 1, and the reference decoder barfs if it isn't).
---
 configure|   2 +-
 libavcodec/Makefile  |   3 +-
 libavcodec/qsvenc_hevc.c | 190 +++
 3 files changed, 111 insertions(+), 84 deletions(-)

diff --git a/configure b/configure
index 7f320fee1..3aa61abb8 100755
--- a/configure
+++ b/configure
@@ -2267,7 +2267,7 @@ h264_vaapi_encoder_deps="VAEncPictureParameterBufferH264"
 h264_vaapi_encoder_select="cbs_h264 vaapi_encode"
 hevc_nvenc_encoder_deps="nvenc"
 hevc_qsv_decoder_select="hevc_mp4toannexb_bsf hevc_parser hevc_qsv_hwaccel 
qsvdec"
-hevc_qsv_encoder_select="hevcparse qsvenc"
+hevc_qsv_encoder_select="cbs_h265 qsvenc"
 hevc_vaapi_encoder_deps="VAEncPictureParameterBufferHEVC"
 hevc_vaapi_encoder_select="cbs_h265 vaapi_encode"
 mjpeg_qsv_encoder_deps="libmfx"
diff --git a/libavcodec/Makefile b/libavcodec/Makefile
index d04902be0..9a1a6fec6 100644
--- a/libavcodec/Makefile
+++ b/libavcodec/Makefile
@@ -284,8 +284,7 @@ OBJS-$(CONFIG_HEVC_DECODER)+= hevcdec.o 
hevc_mvs.o hevc_sei.o \
   hevcdsp.o hevc_filter.o hevc_data.o
 OBJS-$(CONFIG_HEVC_NVENC_ENCODER)  += nvenc_hevc.o
 OBJS-$(CONFIG_HEVC_QSV_DECODER)+= qsvdec_h2645.o
-OBJS-$(CONFIG_HEVC_QSV_ENCODER)+= qsvenc_hevc.o hevc_ps_enc.o   \
-  hevc_data.o
+OBJS-$(CONFIG_HEVC_QSV_ENCODER)+= qsvenc_hevc.o
 OBJS-$(CONFIG_HEVC_VAAPI_ENCODER)  += vaapi_encode_h265.o
 OBJS-$(CONFIG_HNM4_VIDEO_DECODER)  += hnm4video.o
 OBJS-$(CONFIG_HQ_HQA_DECODER)  += hq_hqa.o hq_hqadata.o hq_hqadsp.o \
diff --git a/libavcodec/qsvenc_hevc.c b/libavcodec/qsvenc_hevc.c
index dbb55e2f1..92066dcb7 100644
--- a/libavcodec/qsvenc_hevc.c
+++ b/libavcodec/qsvenc_hevc.c
@@ -28,11 +28,11 @@
 #include "libavutil/opt.h"
 
 #include "avcodec.h"
-#include "bytestream.h"
+#include "cbs.h"
+#include "cbs_h265.h"
 #include "get_bits.h"
 #include "hevc.h"
 #include "hevcdec.h"
-#include "h2645_parse.h"
 #include "internal.h"
 #include "qsv.h"
 #include "qsv_internal.h"
@@ -52,107 +52,135 @@ typedef struct QSVHEVCEncContext {
 
 static int generate_fake_vps(QSVEncContext *q, AVCodecContext *avctx)
 {
-GetByteContext gbc;
-PutByteContext pbc;
-
-GetBitContext gb;
-H2645NAL sps_nal = { NULL };
-HEVCSPS sps = { 0 };
-HEVCVPS vps = { 0 };
-uint8_t vps_buf[128], vps_rbsp_buf[128];
-uint8_t *new_extradata;
-unsigned int sps_id;
-int ret, i, type, vps_size;
+CodedBitstreamContext cbc;
+CodedBitstreamFragment ps;
+const H265RawSPS *sps;
+H265RawVPS vps;
+uint8_t *data = NULL;
+size_t data_size;
+int err, sps_pos, i;
 
 if (!avctx->extradata_size) {
-av_log(avctx, AV_LOG_ERROR, "No extradata returned from libmfx\n");
+av_log(avctx, AV_LOG_ERROR,
+   "No parameter sets returned by libmfx.\n");
 return AVERROR_UNKNOWN;
 }
 
-/* parse the SPS */
-ret = ff_h2645_extract_rbsp(avctx->extradata + 4, avctx->extradata_size - 
4, _nal);
-if (ret < 0) {
-av_log(avctx, AV_LOG_ERROR, "Error unescaping the SPS buffer\n");
-return ret;
-}
+err = ff_cbs_init(, AV_CODEC_ID_HEVC, avctx);
+if (err < 0)
+return err;
 
-ret = init_get_bits8(, sps_nal.data, sps_nal.size);
-if (ret < 0) {
-av_freep(_nal.rbsp_buffer);
-return ret;
+err = ff_cbs_read(, , avctx->extradata, avctx->extradata_size);
+if (err < 0) {
+av_log(avctx, AV_LOG_ERROR,
+   "Error reading parameter sets returned by libmfx.\n");
+ff_cbs_close();
+return err;
 }
 
-get_bits(, 1);
-type = get_bits(, 6);
-if (type != HEVC_NAL_SPS) {
-av_log(avctx, AV_LOG_ERROR, "Unexpected NAL type in the extradata: 
%d\n",
-   type);
-av_freep(_nal.rbsp_buffer);
-return AVERROR_INVALIDDATA;
+sps = NULL;
+for (sps_pos = 0; sps_pos < ps.nb_units; sps_pos++) {
+if (ps.units[sps_pos].type == HEVC_NAL_SPS) {
+sps = ps.units[sps_pos].content;
+break;
+}
 }
-get_bits(, 9);
-
-ret = ff_hevc_parse_sps(, , _id, 0, NULL, avctx);
-av_freep(_nal.rbsp_buffer);
-if (ret < 0) {
-av_log(avctx, AV_LOG_ERROR, "Error parsing the SPS\n");
-return ret;
+if (!sps) {
+av_log(avctx, AV_LOG_ERROR, "No SPS returned by libmfx.\n");
+goto fail;
 }
 
-/* generate the VPS */
-vps.vps_max_layers = 1;
-vps.vps_max_sub_layers = sps.max_sub_layers;
-memcpy(, , sizeof(vps.ptl));
-vps.vps_sub_layer_ordering_info_present_flag = 1;
+vps = (H265RawVPS) {
+.nal_unit_header = {
+

[libav-devel] [PATCH 6/9] lavc: Remove register mechanism for hwaccels

2017-12-10 Thread Mark Thompson
There is no longer any need for a list of them at runtime, because
decoders now carry the pointers to their associated hwaccels internally.
The file containing external declarations is now used to make the list
of hwaccels for configure.
---
 configure  |  2 +-
 libavcodec/allcodecs.c | 51 --
 2 files changed, 1 insertion(+), 52 deletions(-)

diff --git a/configure b/configure
index 7f320fee1..d0e1980dc 100755
--- a/configure
+++ b/configure
@@ -2704,7 +2704,6 @@ find_things(){
 
 ENCODER_LIST=$(find_things  encoder  ENC  libavcodec/allcodecs.c)
 DECODER_LIST=$(find_things  decoder  DEC  libavcodec/allcodecs.c)
-HWACCEL_LIST=$(find_things  hwaccel  HWACCEL  libavcodec/allcodecs.c)
 PARSER_LIST=$(find_things   parser   PARSER   libavcodec/allcodecs.c)
 MUXER_LIST=$(find_thingsmuxer_MUX libavformat/allformats.c)
 DEMUXER_LIST=$(find_things  demuxer  DEMUXlibavformat/allformats.c)
@@ -2719,6 +2718,7 @@ find_things_extern(){
 }
 
 BSF_LIST=$(find_things_extern bsf AVBitStreamFilter 
libavcodec/bitstream_filters.c)
+HWACCEL_LIST=$(find_things_extern hwaccel AVHWAccel libavcodec/hwaccels.h)
 PROTOCOL_LIST=$(find_things_extern protocol URLProtocol 
libavformat/protocols.c)
 
 AVCODEC_COMPONENTS_LIST="
diff --git a/libavcodec/allcodecs.c b/libavcodec/allcodecs.c
index 4ece4307a..50a87493e 100644
--- a/libavcodec/allcodecs.c
+++ b/libavcodec/allcodecs.c
@@ -28,13 +28,6 @@
 #include "avcodec.h"
 #include "version.h"
 
-#define REGISTER_HWACCEL(X, x)  \
-{   \
-extern AVHWAccel ff_##x##_hwaccel;  \
-if (CONFIG_##X##_HWACCEL)   \
-av_register_hwaccel(_##x##_hwaccel); \
-}
-
 #define REGISTER_ENCODER(X, x)  \
 {   \
 extern AVCodec ff_##x##_encoder;\
@@ -66,50 +59,6 @@ void avcodec_register_all(void)
 return;
 initialized = 1;
 
-/* hardware accelerators */
-REGISTER_HWACCEL(H263_VAAPI,h263_vaapi);
-REGISTER_HWACCEL(H264_CUVID,h264_cuvid);
-REGISTER_HWACCEL(H264_D3D11VA,  h264_d3d11va);
-REGISTER_HWACCEL(H264_D3D11VA2, h264_d3d11va2);
-REGISTER_HWACCEL(H264_DXVA2,h264_dxva2);
-REGISTER_HWACCEL(H264_MMAL, h264_mmal);
-REGISTER_HWACCEL(H264_QSV,  h264_qsv);
-REGISTER_HWACCEL(H264_VAAPI,h264_vaapi);
-REGISTER_HWACCEL(H264_VDA,  h264_vda);
-REGISTER_HWACCEL(H264_VDA_OLD,  h264_vda_old);
-REGISTER_HWACCEL(H264_VDPAU,h264_vdpau);
-REGISTER_HWACCEL(HEVC_CUVID,hevc_cuvid);
-REGISTER_HWACCEL(HEVC_D3D11VA,  hevc_d3d11va);
-REGISTER_HWACCEL(HEVC_D3D11VA2, hevc_d3d11va2);
-REGISTER_HWACCEL(HEVC_DXVA2,hevc_dxva2);
-REGISTER_HWACCEL(HEVC_QSV,  hevc_qsv);
-REGISTER_HWACCEL(HEVC_VAAPI,hevc_vaapi);
-REGISTER_HWACCEL(HEVC_VDPAU,hevc_vdpau);
-REGISTER_HWACCEL(MPEG1_VDPAU,   mpeg1_vdpau);
-REGISTER_HWACCEL(MPEG2_D3D11VA, mpeg2_d3d11va);
-REGISTER_HWACCEL(MPEG2_D3D11VA2,mpeg2_d3d11va2);
-REGISTER_HWACCEL(MPEG2_DXVA2,   mpeg2_dxva2);
-REGISTER_HWACCEL(MPEG2_MMAL,mpeg2_mmal);
-REGISTER_HWACCEL(MPEG2_QSV, mpeg2_qsv);
-REGISTER_HWACCEL(MPEG2_VAAPI,   mpeg2_vaapi);
-REGISTER_HWACCEL(MPEG2_VDPAU,   mpeg2_vdpau);
-REGISTER_HWACCEL(MPEG4_VAAPI,   mpeg4_vaapi);
-REGISTER_HWACCEL(MPEG4_VDPAU,   mpeg4_vdpau);
-REGISTER_HWACCEL(VC1_D3D11VA,   vc1_d3d11va);
-REGISTER_HWACCEL(VC1_D3D11VA2,  vc1_d3d11va2);
-REGISTER_HWACCEL(VC1_DXVA2, vc1_dxva2);
-REGISTER_HWACCEL(VC1_QSV,   vc1_qsv);
-REGISTER_HWACCEL(VC1_VAAPI, vc1_vaapi);
-REGISTER_HWACCEL(VC1_VDPAU, vc1_vdpau);
-REGISTER_HWACCEL(VC1_MMAL,  vc1_mmal);
-REGISTER_HWACCEL(VP8_QSV,   vp8_qsv);
-REGISTER_HWACCEL(VP8_VAAPI, vp8_vaapi);
-REGISTER_HWACCEL(WMV3_D3D11VA,  wmv3_d3d11va);
-REGISTER_HWACCEL(WMV3_D3D11VA2, wmv3_d3d11va2);
-REGISTER_HWACCEL(WMV3_DXVA2,wmv3_dxva2);
-REGISTER_HWACCEL(WMV3_VAAPI,wmv3_vaapi);
-REGISTER_HWACCEL(WMV3_VDPAU,wmv3_vdpau);
-
 /* video codecs */
 REGISTER_ENCODER(A64MULTI,  a64multi);
 REGISTER_ENCODER(A64MULTI5, a64multi5);
-- 
2.11.0

___
libav-devel mailing list
libav-devel@libav.org
https://lists.libav.org/mailman/listinfo/libav-devel

[libav-devel] [PATCH 7/9] lavc: Delete all fake hwaccels

2017-12-10 Thread Mark Thompson
They are now unused.
---
 configure | 18 +-
 libavcodec/mmaldec.c  | 21 -
 libavcodec/qsvdec_h2645.c | 18 --
 libavcodec/qsvdec_other.c | 27 ---
 4 files changed, 5 insertions(+), 79 deletions(-)

diff --git a/configure b/configure
index d0e1980dc..d31cb5658 100755
--- a/configure
+++ b/configure
@@ -2183,8 +2183,6 @@ h264_d3d11va2_hwaccel_deps="d3d11va"
 h264_d3d11va2_hwaccel_select="h264_decoder"
 h264_dxva2_hwaccel_deps="dxva2"
 h264_dxva2_hwaccel_select="h264_decoder"
-h264_mmal_hwaccel_deps="mmal"
-h264_qsv_hwaccel_deps="libmfx"
 h264_vaapi_hwaccel_deps="vaapi"
 h264_vaapi_hwaccel_select="h264_decoder"
 h264_vda_hwaccel_deps="vda"
@@ -2201,7 +2199,6 @@ hevc_d3d11va2_hwaccel_deps="d3d11va DXVA_PicParams_HEVC"
 hevc_d3d11va2_hwaccel_select="hevc_decoder"
 hevc_dxva2_hwaccel_deps="dxva2 DXVA_PicParams_HEVC"
 hevc_dxva2_hwaccel_select="hevc_decoder"
-hevc_qsv_hwaccel_deps="libmfx"
 hevc_vaapi_hwaccel_deps="vaapi VAPictureParameterBufferHEVC"
 hevc_vaapi_hwaccel_select="hevc_decoder"
 hevc_vdpau_hwaccel_deps="vdpau VdpPictureInfoHEVC"
@@ -2214,8 +2211,6 @@ mpeg2_d3d11va2_hwaccel_deps="d3d11va"
 mpeg2_d3d11va2_hwaccel_select="mpeg2video_decoder"
 mpeg2_dxva2_hwaccel_deps="dxva2"
 mpeg2_dxva2_hwaccel_select="mpeg2video_decoder"
-mpeg2_mmal_hwaccel_deps="mmal"
-mpeg2_qsv_hwaccel_deps="libmfx"
 mpeg2_vaapi_hwaccel_deps="vaapi"
 mpeg2_vaapi_hwaccel_select="mpeg2video_decoder"
 mpeg2_vdpau_hwaccel_deps="vdpau"
@@ -2230,13 +2225,10 @@ vc1_d3d11va2_hwaccel_deps="d3d11va"
 vc1_d3d11va2_hwaccel_select="vc1_decoder"
 vc1_dxva2_hwaccel_deps="dxva2"
 vc1_dxva2_hwaccel_select="vc1_decoder"
-vc1_mmal_hwaccel_deps="mmal"
-vc1_qsv_hwaccel_deps="libmfx"
 vc1_vaapi_hwaccel_deps="vaapi"
 vc1_vaapi_hwaccel_select="vc1_decoder"
 vc1_vdpau_hwaccel_deps="vdpau"
 vc1_vdpau_hwaccel_select="vc1_decoder"
-vp8_qsv_hwaccel_deps="libmfx"
 vp8_vaapi_hwaccel_deps="vaapi VAPictureParameterBufferVP8"
 vp8_vaapi_hwaccel_select="vp8_decoder"
 wmv3_d3d11va_hwaccel_select="vc1_d3d11va_hwaccel"
@@ -2261,12 +2253,12 @@ scale_npp_filter_deps="cuda libnpp"
 h264_mmal_decoder_deps="mmal"
 h264_nvenc_encoder_deps="nvenc"
 h264_omx_encoder_deps="omx"
-h264_qsv_decoder_select="h264_mp4toannexb_bsf h264_parser qsvdec 
h264_qsv_hwaccel"
+h264_qsv_decoder_select="h264_mp4toannexb_bsf h264_parser qsvdec"
 h264_qsv_encoder_select="qsvenc"
 h264_vaapi_encoder_deps="VAEncPictureParameterBufferH264"
 h264_vaapi_encoder_select="cbs_h264 vaapi_encode"
 hevc_nvenc_encoder_deps="nvenc"
-hevc_qsv_decoder_select="hevc_mp4toannexb_bsf hevc_parser hevc_qsv_hwaccel 
qsvdec"
+hevc_qsv_decoder_select="hevc_mp4toannexb_bsf hevc_parser qsvdec"
 hevc_qsv_encoder_select="hevcparse qsvenc"
 hevc_vaapi_encoder_deps="VAEncPictureParameterBufferHEVC"
 hevc_vaapi_encoder_select="cbs_h265 vaapi_encode"
@@ -2275,14 +2267,14 @@ mjpeg_qsv_encoder_select="qsvenc"
 mjpeg_vaapi_encoder_deps="VAEncPictureParameterBufferJPEG"
 mjpeg_vaapi_encoder_select="vaapi_encode jpegtables"
 mpeg2_mmal_decoder_deps="mmal"
-mpeg2_qsv_decoder_select="qsvdec mpeg2_qsv_hwaccel mpegvideo_parser"
+mpeg2_qsv_decoder_select="qsvdec mpegvideo_parser"
 mpeg2_qsv_encoder_select="qsvenc"
 mpeg2_vaapi_encoder_deps="VAEncPictureParameterBufferMPEG2"
 mpeg2_vaapi_encoder_select="cbs_mpeg2 vaapi_encode"
 mpeg4_omx_encoder_deps="omx"
 vc1_mmal_decoder_deps="mmal"
-vc1_qsv_decoder_select="qsvdec vc1_qsv_hwaccel vc1_parser"
-vp8_qsv_decoder_select="qsvdec vp8_qsv_hwaccel vp8_parser"
+vc1_qsv_decoder_select="qsvdec vc1_parser"
+vp8_qsv_decoder_select="qsvdec vp8_parser"
 vp8_vaapi_encoder_deps="VAEncPictureParameterBufferVP8"
 vp8_vaapi_encoder_select="vaapi_encode"
 vp9_vaapi_encoder_deps="VAEncPictureParameterBufferVP9"
diff --git a/libavcodec/mmaldec.c b/libavcodec/mmaldec.c
index 9d92ee715..b158e24cb 100644
--- a/libavcodec/mmaldec.c
+++ b/libavcodec/mmaldec.c
@@ -788,27 +788,6 @@ static int ffmmal_decode(AVCodecContext *avctx, void 
*data, int *got_frame,
 return ret;
 }
 
-AVHWAccel ff_h264_mmal_hwaccel = {
-.name   = "h264_mmal",
-.type   = AVMEDIA_TYPE_VIDEO,
-.id = AV_CODEC_ID_H264,
-.pix_fmt= AV_PIX_FMT_MMAL,
-};
-
-AVHWAccel ff_mpeg2_mmal_hwaccel = {
-.name   = "mpeg2_mmal",
-.type   = AVMEDIA_TYPE_VIDEO,
-.id = AV_CODEC_ID_MPEG2VIDEO,
-.pix_fmt= AV_PIX_FMT_MMAL,
-};
-
-AVHWAccel ff_vc1_mmal_hwaccel = {
-.name   = "vc1_mmal",
-.type   = AVMEDIA_TYPE_VIDEO,
-.id = AV_CODEC_ID_VC1,
-.pix_fmt= AV_PIX_FMT_MMAL,
-};
-
 static const AVCodecHWConfigInternal *mmal_hw_configs = {
 HW_CONFIG_INTERNAL(MMAL),
 NULL
diff --git a/libavcodec/qsvdec_h2645.c b/libavcodec/qsvdec_h2645.c
index 2fabe38c5..a87e81679 100644
--- a/libavcodec/qsvdec_h2645.c
+++ b/libavcodec/qsvdec_h2645.c
@@ -180,15 +180,6 @@ static void qsv_decode_flush(AVCodecContext *avctx)
 #define OFFSET(x) offsetof(QSVH2645Context, x)
 #define VD 

[libav-devel] [PATCH 9/9] avconv: Use codec hardware config to configure hwaccels

2017-12-10 Thread Mark Thompson
Removes specific support for all hwaccels supported by the generic code
(CUVID, DXVA2, D3D11VA, VAAPI and VDPAU).
---
 avtools/avconv.c |  76 +++-
 avtools/avconv.h |   9 +-
 avtools/avconv_hw.c  | 249 ++-
 avtools/avconv_opt.c |  47 +-
 4 files changed, 246 insertions(+), 135 deletions(-)

diff --git a/avtools/avconv.c b/avtools/avconv.c
index cee7a7b45..ac15464a8 100644
--- a/avtools/avconv.c
+++ b/avtools/avconv.c
@@ -1631,44 +1631,77 @@ static void print_sdp(void)
 av_freep();
 }
 
-static const HWAccel *get_hwaccel(enum AVPixelFormat pix_fmt)
-{
-int i;
-for (i = 0; hwaccels[i].name; i++)
-if (hwaccels[i].pix_fmt == pix_fmt)
-return [i];
-return NULL;
-}
-
 static enum AVPixelFormat get_format(AVCodecContext *s, const enum 
AVPixelFormat *pix_fmts)
 {
 InputStream *ist = s->opaque;
 const enum AVPixelFormat *p;
 int ret;
 
-for (p = pix_fmts; *p != -1; p++) {
+for (p = pix_fmts; *p != AV_PIX_FMT_NONE; p++) {
 const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(*p);
-const HWAccel *hwaccel;
+const AVCodecHWConfig  *config = NULL;
+int i;
 
 if (!(desc->flags & AV_PIX_FMT_FLAG_HWACCEL))
 break;
 
-hwaccel = get_hwaccel(*p);
-if (!hwaccel ||
-(ist->active_hwaccel_id && ist->active_hwaccel_id != hwaccel->id) 
||
-(ist->hwaccel_id != HWACCEL_AUTO && ist->hwaccel_id != 
hwaccel->id))
-continue;
+if (ist->hwaccel_id == HWACCEL_GENERIC ||
+ist->hwaccel_id == HWACCEL_AUTO) {
+for (i = 0;; i++) {
+config = avcodec_get_hw_config(s->codec, i);
+if (!config)
+break;
+if (!(config->methods &
+  AV_CODEC_HW_CONFIG_METHOD_HW_DEVICE_CTX))
+continue;
+if (config->pix_fmt == *p)
+break;
+}
+}
+if (config) {
+if (config->device_type != ist->hwaccel_device_type) {
+// Different hwaccel offered, ignore.
+continue;
+}
 
-ret = hwaccel->init(s);
-if (ret < 0) {
-if (ist->hwaccel_id == hwaccel->id) {
+ret = hwaccel_decode_init(s);
+if (ret < 0) {
+if (ist->hwaccel_id == HWACCEL_GENERIC) {
+av_log(NULL, AV_LOG_FATAL,
+   "%s hwaccel requested for input stream #%d:%d, "
+   "but cannot be initialized.\n",
+   av_hwdevice_get_type_name(config->device_type),
+   ist->file_index, ist->st->index);
+return AV_PIX_FMT_NONE;
+}
+continue;
+}
+} else {
+const HWAccel *hwaccel = NULL;
+int i;
+for (i = 0; hwaccels[i].name; i++) {
+if (hwaccels[i].pix_fmt == *p) {
+hwaccel = [i];
+break;
+}
+}
+if (!hwaccel) {
+// No hwaccel supporting this pixfmt.
+continue;
+}
+if (hwaccel->id != ist->hwaccel_id) {
+// Does not match requested hwaccel.
+continue;
+}
+
+ret = hwaccel->init(s);
+if (ret < 0) {
 av_log(NULL, AV_LOG_FATAL,
"%s hwaccel requested for input stream #%d:%d, "
"but cannot be initialized.\n", hwaccel->name,
ist->file_index, ist->st->index);
 return AV_PIX_FMT_NONE;
 }
-continue;
 }
 
 if (ist->hw_frames_ctx) {
@@ -1677,8 +1710,7 @@ static enum AVPixelFormat get_format(AVCodecContext *s, 
const enum AVPixelFormat
 return AV_PIX_FMT_NONE;
 }
 
-ist->active_hwaccel_id = hwaccel->id;
-ist->hwaccel_pix_fmt   = *p;
+ist->hwaccel_pix_fmt = *p;
 break;
 }
 
diff --git a/avtools/avconv.h b/avtools/avconv.h
index b5843fbc0..0d24c71a7 100644
--- a/avtools/avconv.h
+++ b/avtools/avconv.h
@@ -52,13 +52,9 @@
 enum HWAccelID {
 HWACCEL_NONE = 0,
 HWACCEL_AUTO,
-HWACCEL_VDPAU,
-HWACCEL_DXVA2,
+HWACCEL_GENERIC,
 HWACCEL_VDA,
 HWACCEL_QSV,
-HWACCEL_VAAPI,
-HWACCEL_D3D11VA,
-HWACCEL_CUVID,
 };
 
 typedef struct HWAccel {
@@ -66,7 +62,6 @@ typedef struct HWAccel {
 int (*init)(AVCodecContext *s);
 enum HWAccelID id;
 enum AVPixelFormat pix_fmt;
-enum AVHWDeviceType device_type;
 } HWAccel;
 
 typedef struct HWDevice {
@@ -301,11 +296,11 @@ typedef struct InputStream {
 
 /* hwaccel options */
 enum HWAccelID hwaccel_id;
+enum AVHWDeviceType hwaccel_device_type;
 char  *hwaccel_device;

[libav-devel] [PATCH 1/9] lavc: Add codec metadata to indicate hardware support

2017-12-10 Thread Mark Thompson
---
 doc/APIchanges   |  3 +++
 libavcodec/avcodec.h | 74 
 libavcodec/hwaccel.h | 18 +
 libavcodec/utils.c   | 12 +
 4 files changed, 107 insertions(+)

diff --git a/doc/APIchanges b/doc/APIchanges
index a7ecbcdaa..9d8c7725e 100644
--- a/doc/APIchanges
+++ b/doc/APIchanges
@@ -13,6 +13,9 @@ libavutil: 2017-03-23
 
 API changes, most recent first:
 
+2017-xx-xx - xxx - lavc 58.x+1.0 - avcodec.h
+  Add AVCodecHWConfig and avcodec_get_hw_config().
+
 2017-xx-xx - xxx - lavu 56.7.0 - stereo3d.h
   Add view field to AVStereo3D structure and AVStereo3DView enum.
 
diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h
index 562483502..5d7b3459c 100644
--- a/libavcodec/avcodec.h
+++ b/libavcodec/avcodec.h
@@ -35,6 +35,7 @@
 #include "libavutil/cpu.h"
 #include "libavutil/dict.h"
 #include "libavutil/frame.h"
+#include "libavutil/hwcontext.h"
 #include "libavutil/log.h"
 #include "libavutil/pixfmt.h"
 #include "libavutil/rational.h"
@@ -2735,6 +2736,61 @@ typedef struct AVProfile {
 const char *name; ///< short name for the profile
 } AVProfile;
 
+enum {
+/**
+ * The codec supports this format via the hw_device_ctx interface.
+ *
+ * When selecting this format, AVCodecContext.hw_device_ctx should
+ * have been set to a device of the specified type before calling
+ * avcodec_open2().
+ */
+AV_CODEC_HW_CONFIG_METHOD_HW_DEVICE_CTX = 0x01,
+/**
+ * The codec supports this format via the hw_frames_ctx interface.
+ *
+ * When selecting this format for a decoder,
+ * AVCodecContext.hw_frames_ctx should be set to a suitable frames
+ * context inside the get_format() callback.  The frames context
+ * must have been created on a device of the specified type.
+ */
+AV_CODEC_HW_CONFIG_METHOD_HW_FRAMES_CTX = 0x02,
+/**
+ * The codec supports this format by some internal method.
+ *
+ * This format can be selected without any additional configuration -
+ * no device or frames context is required.
+ */
+AV_CODEC_HW_CONFIG_METHOD_INTERNAL  = 0x04,
+/**
+ * The codec supports this format by some ad-hoc method.
+ *
+ * Additional settings and/or function calls are required.  See the
+ * codec-specific documentation for details.  (Methods requiring
+ * this sort of configuration are deprecated and others should be
+ * used in preference.)
+ */
+AV_CODEC_HW_CONFIG_METHOD_AD_HOC= 0x08,
+};
+
+typedef struct AVCodecHWConfig {
+/**
+ * A hardware pixel format which the codec can use.
+ */
+enum AVPixelFormat pix_fmt;
+/**
+ * Bit set of AV_CODEC_HW_CONFIG_METHOD_* flags, describing the possible
+ * setup methods which can be used with this configuration.
+ */
+int methods;
+/**
+ * The device type associated with the configuration.
+ *
+ * Must be set for AV_CODEC_HW_CONFIG_METHOD_HW_DEVICE_CTX and
+ * AV_CODEC_HW_CONFIG_METHOD_HW_FRAMES_CTX, otherwise unused.
+ */
+enum AVHWDeviceType device_type;
+} AVCodecHWConfig;
+
 typedef struct AVCodecDefault AVCodecDefault;
 
 struct AVSubtitle;
@@ -2859,9 +2915,27 @@ typedef struct AVCodec {
  * packets before decoding.
  */
 const char *bsfs;
+
+/**
+ * Array of pointers to hardware configurations supported by the codec,
+ * or NULL if no hardware supported.  The array is terminated by a NULL
+ * pointer.
+ *
+ * The user can only access this field via avcodec_get_hw_config().
+ */
+const struct AVCodecHWConfigInternal **hw_configs;
 } AVCodec;
 
 /**
+ * Retrieve supported hardware configurations for a codec.
+ *
+ * Values of index from zero to some maximum return the indexed configuration
+ * descriptor; all other values return NULL.  If the codec does not support
+ * any hardware configurations then it will always return NULL.
+ */
+const AVCodecHWConfig *avcodec_get_hw_config(const AVCodec *codec, int index);
+
+/**
  * @defgroup lavc_hwaccel AVHWAccel
  * @{
  */
diff --git a/libavcodec/hwaccel.h b/libavcodec/hwaccel.h
index 60dbe81c8..b6d566248 100644
--- a/libavcodec/hwaccel.h
+++ b/libavcodec/hwaccel.h
@@ -19,6 +19,24 @@
 #ifndef AVCODEC_HWACCEL_H
 #define AVCODEC_HWACCEL_H
 
+#include "avcodec.h"
+
+
 #define HWACCEL_CAP_ASYNC_SAFE  (1 << 0)
 
+
+typedef struct AVCodecHWConfigInternal {
+/**
+ * This is the structure which will be returned to the user by
+ * avcodec_get_hw_config().
+ */
+AVCodecHWConfig public;
+/**
+ * If this configuration uses a hwaccel, a pointer to it.
+ * If not, NULL.
+ */
+const AVHWAccel *hwaccel;
+} AVCodecHWConfigInternal;
+
+
 #endif /* AVCODEC_HWACCEL_H */
diff --git a/libavcodec/utils.c b/libavcodec/utils.c
index bc421f67f..3d6b35fa4 100644
--- a/libavcodec/utils.c
+++ b/libavcodec/utils.c
@@ -41,6 +41,7 @@
 #include "libavutil/dict.h"
 #include "avcodec.h"
 

[libav-devel] [PATCH 2/9] lavc: Add hardware config metadata for decoders supporting hardware output

2017-12-10 Thread Mark Thompson
This includes a pointer to the associated hwaccel for decoders using
hwaccels - these will be used later to implement the hwaccel setup
without needing a global list.

Also added is a new file listing all hwaccels as external declarations -
this will be used later to generate the hwaccel list at configure time.
---
 libavcodec/h263dec.c   | 10 
 libavcodec/h264dec.c   | 28 ++
 libavcodec/hevcdec.c   | 22 +
 libavcodec/hwaccel.h   | 38 +
 libavcodec/hwaccels.h  | 59 ++
 libavcodec/mmaldec.c   |  7 ++
 libavcodec/mpeg12dec.c | 27 -
 libavcodec/mpeg4videodec.c | 10 
 libavcodec/qsvdec.c| 13 ++
 libavcodec/qsvdec.h|  3 +++
 libavcodec/qsvdec_h2645.c  |  2 ++
 libavcodec/qsvdec_other.c  |  3 +++
 libavcodec/vc1dec.c| 37 +
 libavcodec/vp8.c   |  7 ++
 14 files changed, 265 insertions(+), 1 deletion(-)
 create mode 100644 libavcodec/hwaccels.h

diff --git a/libavcodec/h263dec.c b/libavcodec/h263dec.c
index 921ff5fb9..b883c 100644
--- a/libavcodec/h263dec.c
+++ b/libavcodec/h263dec.c
@@ -31,6 +31,7 @@
 #include "flv.h"
 #include "h263.h"
 #include "h263_parser.h"
+#include "hwaccel.h"
 #include "internal.h"
 #include "mpeg_er.h"
 #include "mpeg4video.h"
@@ -677,4 +678,13 @@ AVCodec ff_h263_decoder = {
   AV_CODEC_CAP_TRUNCATED | AV_CODEC_CAP_DELAY,
 .flush  = ff_mpeg_flush,
 .pix_fmts   = ff_h263_hwaccel_pixfmt_list_420,
+.hw_configs = (const AVCodecHWConfigInternal*[]) {
+#if CONFIG_H263_VAAPI_HWACCEL
+HWACCEL_VAAPI(h263),
+#endif
+#if CONFIG_MPEG4_VDPAU_HWACCEL
+HWACCEL_VDPAU(mpeg4),
+#endif
+NULL
+},
 };
diff --git a/libavcodec/h264dec.c b/libavcodec/h264dec.c
index 7a8293efa..4bfd78962 100644
--- a/libavcodec/h264dec.c
+++ b/libavcodec/h264dec.c
@@ -44,6 +44,7 @@
 #include "h264chroma.h"
 #include "h264_mvpred.h"
 #include "h264_ps.h"
+#include "hwaccel.h"
 #include "mathops.h"
 #include "me_cmp.h"
 #include "mpegutils.h"
@@ -786,6 +787,33 @@ AVCodec ff_h264_decoder = {
 .capabilities  = /*AV_CODEC_CAP_DRAW_HORIZ_BAND |*/ 
AV_CODEC_CAP_DR1 |
  AV_CODEC_CAP_DELAY | AV_CODEC_CAP_SLICE_THREADS |
  AV_CODEC_CAP_FRAME_THREADS,
+.hw_configs= (const AVCodecHWConfigInternal*[]) {
+#if CONFIG_H264_CUVID_HWACCEL
+   HWACCEL_CUVID(h264),
+#endif
+#if CONFIG_H264_DXVA2_HWACCEL
+   HWACCEL_DXVA2(h264),
+#endif
+#if CONFIG_H264_D3D11VA_HWACCEL
+   HWACCEL_D3D11VA(h264),
+#endif
+#if CONFIG_H264_D3D11VA2_HWACCEL
+   HWACCEL_D3D11VA2(h264),
+#endif
+#if CONFIG_H264_VAAPI_HWACCEL
+   HWACCEL_VAAPI(h264),
+#endif
+#if CONFIG_H264_VDPAU_HWACCEL
+   HWACCEL_VDPAU(h264),
+#endif
+#if CONFIG_H264_VDA_HWACCEL
+   HW_CONFIG_HWACCEL(0, 0, 1, VDA, NONE, 
ff_h264_vda_hwaccel),
+#endif
+#if CONFIG_H264_VDA_OLD_HWACCEL
+   HW_CONFIG_HWACCEL(0, 0, 1, VDA_VLD, NONE, 
ff_h264_vda_old_hwaccel),
+#endif
+   NULL
+   },
 .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | 
FF_CODEC_CAP_EXPORTS_CROPPING,
 .flush = flush_dpb,
 .init_thread_copy  = ONLY_IF_THREADS_ENABLED(decode_init_thread_copy),
diff --git a/libavcodec/hevcdec.c b/libavcodec/hevcdec.c
index f1d1c7749..130b99f77 100644
--- a/libavcodec/hevcdec.c
+++ b/libavcodec/hevcdec.c
@@ -39,6 +39,7 @@
 #include "hevc.h"
 #include "hevc_data.h"
 #include "hevcdec.h"
+#include "hwaccel.h"
 #include "profiles.h"
 
 const uint8_t ff_hevc_qpel_extra_before[4] = { 0, 3, 3, 3 };
@@ -3120,4 +3121,25 @@ AVCodec ff_hevc_decoder = {
  AV_CODEC_CAP_FRAME_THREADS,
 .profiles  = NULL_IF_CONFIG_SMALL(ff_hevc_profiles),
 .caps_internal = FF_CODEC_CAP_EXPORTS_CROPPING | 
FF_CODEC_CAP_INIT_THREADSAFE,
+.hw_configs= (const AVCodecHWConfigInternal*[]) {
+#if CONFIG_HEVC_CUVID_HWACCEL
+   HWACCEL_CUVID(hevc),
+#endif
+#if CONFIG_HEVC_DXVA2_HWACCEL
+   HWACCEL_DXVA2(hevc),
+#endif
+#if CONFIG_HEVC_D3D11VA_HWACCEL
+   HWACCEL_D3D11VA(hevc),
+#endif
+#if CONFIG_HEVC_D3D11VA2_HWACCEL
+   HWACCEL_D3D11VA2(hevc),
+#endif
+#if CONFIG_HEVC_VAAPI_HWACCEL
+   HWACCEL_VAAPI(hevc),
+#endif
+#if CONFIG_HEVC_VDPAU_HWACCEL
+   HWACCEL_VDPAU(hevc),
+#endif
+   NULL
+  

[libav-devel] [PATCH 4/9] lavc: Use hardware config information in ff_get_format()

2017-12-10 Thread Mark Thompson
This removes the dependency that hardware pixel formats previously had on
AVHWAccel instances, meaning only those which actually do something need
exist after this patch.

Also updates avcodec_default_get_format() to be able to choose hardware
formats if either a matching device has been supplied or no additional
external configuration is required, and avcodec_get_hw_frames_parameters()
to use the hardware config rather than searching the old hwaccel list.
---
 libavcodec/decode.c   | 281 --
 libavcodec/internal.h |   6 ++
 2 files changed, 210 insertions(+), 77 deletions(-)

diff --git a/libavcodec/decode.c b/libavcodec/decode.c
index 27f75d73e..bc2208a3f 100644
--- a/libavcodec/decode.c
+++ b/libavcodec/decode.c
@@ -34,6 +34,7 @@
 #include "avcodec.h"
 #include "bytestream.h"
 #include "decode.h"
+#include "hwaccel.h"
 #include "internal.h"
 #include "thread.h"
 
@@ -644,29 +645,67 @@ int avcodec_decode_subtitle2(AVCodecContext *avctx, 
AVSubtitle *sub,
 return ret;
 }
 
-static int is_hwaccel_pix_fmt(enum AVPixelFormat pix_fmt)
+enum AVPixelFormat avcodec_default_get_format(struct AVCodecContext *avctx,
+  const enum AVPixelFormat *fmt)
 {
-const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pix_fmt);
-return desc->flags & AV_PIX_FMT_FLAG_HWACCEL;
-}
-
-enum AVPixelFormat avcodec_default_get_format(struct AVCodecContext *s, const 
enum AVPixelFormat *fmt)
-{
-while (*fmt != AV_PIX_FMT_NONE && is_hwaccel_pix_fmt(*fmt))
-++fmt;
-return fmt[0];
-}
-
-static AVHWAccel *find_hwaccel(enum AVCodecID codec_id,
-   enum AVPixelFormat pix_fmt)
-{
-AVHWAccel *hwaccel = NULL;
+const AVPixFmtDescriptor *desc;
+const AVCodecHWConfig *config;
+int i, n;
+
+// If a device was supplied when the codec was opened, assume that the
+// user wants to use it.
+if (avctx->hw_device_ctx && avctx->codec->hw_configs) {
+AVHWDeviceContext *device_ctx =
+(AVHWDeviceContext*)avctx->hw_device_ctx->data;
+for (i = 0;; i++) {
+config = >codec->hw_configs[i]->public;
+if (!config)
+break;
+if (!(config->methods &
+  AV_CODEC_HW_CONFIG_METHOD_HW_DEVICE_CTX))
+continue;
+if (device_ctx->type != config->device_type)
+continue;
+for (n = 0; fmt[n] != AV_PIX_FMT_NONE; n++) {
+if (config->pix_fmt == fmt[n])
+return fmt[n];
+}
+}
+}
+// No device or other setup, so we have to choose from things which
+// don't any other external information.
+
+// If the last element of the list is a software format, choose it
+// (this should be best software format if any exist).
+for (n = 0; fmt[n] != AV_PIX_FMT_NONE; n++);
+desc = av_pix_fmt_desc_get(fmt[n - 1]);
+if (!(desc->flags & AV_PIX_FMT_FLAG_HWACCEL))
+return fmt[n - 1];
+
+// Finally, traverse the list in order and choose the first entry
+// with no external dependencies (if there is no hardware configuration
+// information available then this just picks the first entry).
+for (n = 0; fmt[n] != AV_PIX_FMT_NONE; n++) {
+for (i = 0;; i++) {
+config = avcodec_get_hw_config(avctx->codec, i);
+if (!config)
+break;
+if (config->pix_fmt == fmt[n])
+break;
+}
+if (!config) {
+// No specific config available, so the decoder must be able
+// to handle this format without any additional setup.
+return fmt[n];
+}
+if (config->methods & AV_CODEC_HW_CONFIG_METHOD_INTERNAL) {
+// Usable with only internal setup.
+return fmt[n];
+}
+}
 
-while ((hwaccel = av_hwaccel_next(hwaccel)))
-if (hwaccel->id == codec_id
-&& hwaccel->pix_fmt == pix_fmt)
-return hwaccel;
-return NULL;
+// Nothing is usable, give up.
+return AV_PIX_FMT_NONE;
 }
 
 int ff_decode_get_hw_frames_ctx(AVCodecContext *avctx,
@@ -730,9 +769,19 @@ int avcodec_get_hw_frames_parameters(AVCodecContext *avctx,
  AVBufferRef **out_frames_ref)
 {
 AVBufferRef *frames_ref = NULL;
-AVHWAccel *hwa = find_hwaccel(avctx->codec_id, hw_pix_fmt);
-int ret;
+const AVCodecHWConfigInternal *hw_config;
+const AVHWAccel *hwa;
+int i, ret;
+
+for (i = 0;; i++) {
+hw_config = avctx->codec->hw_configs[i];
+if (!hw_config)
+return AVERROR(ENOENT);
+if (hw_config->public.pix_fmt == hw_pix_fmt)
+break;
+}
 
+hwa = hw_config->hwaccel;
 if (!hwa || !hwa->frame_params)
 return AVERROR(ENOENT);
 
@@ -749,52 +798,66 @@ int avcodec_get_hw_frames_parameters(AVCodecContext 
*avctx,
 return 

[libav-devel] [PATCH 8/9] lavc: Mark all AVHWAccel structures as const

2017-12-10 Thread Mark Thompson
---
 libavcodec/avcodec.h  |  2 +-
 libavcodec/cuvid_h264.c   |  2 +-
 libavcodec/cuvid_hevc.c   |  2 +-
 libavcodec/decode.c   |  2 +-
 libavcodec/dxva2_h264.c   |  6 ++---
 libavcodec/dxva2_hevc.c   |  6 ++---
 libavcodec/dxva2_mpeg2.c  |  6 ++---
 libavcodec/dxva2_vc1.c| 12 -
 libavcodec/hwaccels.h | 68 +++
 libavcodec/vaapi_h264.c   |  2 +-
 libavcodec/vaapi_hevc.c   |  2 +-
 libavcodec/vaapi_mpeg2.c  |  2 +-
 libavcodec/vaapi_mpeg4.c  |  4 +--
 libavcodec/vaapi_vc1.c|  4 +--
 libavcodec/vaapi_vp8.c|  2 +-
 libavcodec/vda_h264.c |  4 +--
 libavcodec/vdpau_h264.c   |  2 +-
 libavcodec/vdpau_hevc.c   |  2 +-
 libavcodec/vdpau_mpeg12.c |  4 +--
 libavcodec/vdpau_mpeg4.c  |  2 +-
 libavcodec/vdpau_vc1.c|  4 +--
 21 files changed, 70 insertions(+), 70 deletions(-)

diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h
index f81a48e47..531ffad6a 100644
--- a/libavcodec/avcodec.h
+++ b/libavcodec/avcodec.h
@@ -2294,7 +2294,7 @@ typedef struct AVCodecContext {
  * - encoding: unused.
  * - decoding: Set by libavcodec
  */
-struct AVHWAccel *hwaccel;
+const struct AVHWAccel *hwaccel;
 
 /**
  * Hardware accelerator context.
diff --git a/libavcodec/cuvid_h264.c b/libavcodec/cuvid_h264.c
index a83e4ffba..4f36e922b 100644
--- a/libavcodec/cuvid_h264.c
+++ b/libavcodec/cuvid_h264.c
@@ -163,7 +163,7 @@ static int cuvid_h264_decode_init(AVCodecContext *avctx)
 return ff_cuvid_decode_init(avctx, sps->ref_frame_count + 
sps->num_reorder_frames);
 }
 
-AVHWAccel ff_h264_cuvid_hwaccel = {
+const AVHWAccel ff_h264_cuvid_hwaccel = {
 .name = "h264_cuvid",
 .type = AVMEDIA_TYPE_VIDEO,
 .id   = AV_CODEC_ID_H264,
diff --git a/libavcodec/cuvid_hevc.c b/libavcodec/cuvid_hevc.c
index 5de9bca48..fcf20bbcf 100644
--- a/libavcodec/cuvid_hevc.c
+++ b/libavcodec/cuvid_hevc.c
@@ -266,7 +266,7 @@ static int cuvid_hevc_decode_init(AVCodecContext *avctx)
 return ff_cuvid_decode_init(avctx, sps->temporal_layer[sps->max_sub_layers 
- 1].max_dec_pic_buffering + 1);
 }
 
-AVHWAccel ff_hevc_cuvid_hwaccel = {
+const AVHWAccel ff_hevc_cuvid_hwaccel = {
 .name = "hevc_cuvid",
 .type = AVMEDIA_TYPE_VIDEO,
 .id   = AV_CODEC_ID_HEVC,
diff --git a/libavcodec/decode.c b/libavcodec/decode.c
index bc2208a3f..12a95d422 100644
--- a/libavcodec/decode.c
+++ b/libavcodec/decode.c
@@ -812,7 +812,7 @@ static int hwaccel_init(AVCodecContext *avctx,
 return AVERROR(ENOMEM);
 }
 
-avctx->hwaccel = (AVHWAccel*)hwaccel;
+avctx->hwaccel = hwaccel;
 err = hwaccel->init(avctx);
 if (err < 0) {
 av_log(avctx, AV_LOG_ERROR, "Failed setup for format %s: "
diff --git a/libavcodec/dxva2_h264.c b/libavcodec/dxva2_h264.c
index 8ce8c358c..50e7863bf 100644
--- a/libavcodec/dxva2_h264.c
+++ b/libavcodec/dxva2_h264.c
@@ -513,7 +513,7 @@ static int dxva2_h264_end_frame(AVCodecContext *avctx)
 }
 
 #if CONFIG_H264_DXVA2_HWACCEL
-AVHWAccel ff_h264_dxva2_hwaccel = {
+const AVHWAccel ff_h264_dxva2_hwaccel = {
 .name   = "h264_dxva2",
 .type   = AVMEDIA_TYPE_VIDEO,
 .id = AV_CODEC_ID_H264,
@@ -530,7 +530,7 @@ AVHWAccel ff_h264_dxva2_hwaccel = {
 #endif
 
 #if CONFIG_H264_D3D11VA_HWACCEL
-AVHWAccel ff_h264_d3d11va_hwaccel = {
+const AVHWAccel ff_h264_d3d11va_hwaccel = {
 .name   = "h264_d3d11va",
 .type   = AVMEDIA_TYPE_VIDEO,
 .id = AV_CODEC_ID_H264,
@@ -547,7 +547,7 @@ AVHWAccel ff_h264_d3d11va_hwaccel = {
 #endif
 
 #if CONFIG_H264_D3D11VA2_HWACCEL
-AVHWAccel ff_h264_d3d11va2_hwaccel = {
+const AVHWAccel ff_h264_d3d11va2_hwaccel = {
 .name   = "h264_d3d11va2",
 .type   = AVMEDIA_TYPE_VIDEO,
 .id = AV_CODEC_ID_H264,
diff --git a/libavcodec/dxva2_hevc.c b/libavcodec/dxva2_hevc.c
index 1d665f07d..02d3b9b15 100644
--- a/libavcodec/dxva2_hevc.c
+++ b/libavcodec/dxva2_hevc.c
@@ -422,7 +422,7 @@ static int dxva2_hevc_end_frame(AVCodecContext *avctx)
 }
 
 #if CONFIG_HEVC_DXVA2_HWACCEL
-AVHWAccel ff_hevc_dxva2_hwaccel = {
+const AVHWAccel ff_hevc_dxva2_hwaccel = {
 .name   = "hevc_dxva2",
 .type   = AVMEDIA_TYPE_VIDEO,
 .id = AV_CODEC_ID_HEVC,
@@ -439,7 +439,7 @@ AVHWAccel ff_hevc_dxva2_hwaccel = {
 #endif
 
 #if CONFIG_HEVC_D3D11VA_HWACCEL
-AVHWAccel ff_hevc_d3d11va_hwaccel = {
+const AVHWAccel ff_hevc_d3d11va_hwaccel = {
 .name   = "hevc_d3d11va",
 .type   = AVMEDIA_TYPE_VIDEO,
 .id = AV_CODEC_ID_HEVC,
@@ -456,7 +456,7 @@ AVHWAccel ff_hevc_d3d11va_hwaccel = {
 #endif
 
 #if CONFIG_HEVC_D3D11VA2_HWACCEL
-AVHWAccel ff_hevc_d3d11va2_hwaccel = {
+const AVHWAccel ff_hevc_d3d11va2_hwaccel = {
 .name   = "hevc_d3d11va2",
 .type   = AVMEDIA_TYPE_VIDEO,
 .id = AV_CODEC_ID_HEVC,

[libav-devel] [PATCH 5/9] lavc: Deprecate av_hwaccel_next() and av_register_hwaccel()

2017-12-10 Thread Mark Thompson
---
 doc/APIchanges   |  4 
 libavcodec/avcodec.h | 13 +
 libavcodec/utils.c   | 15 +--
 libavcodec/version.h |  3 +++
 4 files changed, 25 insertions(+), 10 deletions(-)

diff --git a/doc/APIchanges b/doc/APIchanges
index 9d8c7725e..a1abcffaa 100644
--- a/doc/APIchanges
+++ b/doc/APIchanges
@@ -14,6 +14,10 @@ libavutil: 2017-03-23
 API changes, most recent first:
 
 2017-xx-xx - xxx - lavc 58.x+1.0 - avcodec.h
+  Deprecate user visibility of the AVHWAccel structure and the functions
+  av_register_hwaccel() and av_hwaccel_next().
+
+2017-xx-xx - xxx - lavc 58.x+1.0 - avcodec.h
   Add AVCodecHWConfig and avcodec_get_hw_config().
 
 2017-xx-xx - xxx - lavu 56.7.0 - stereo3d.h
diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h
index 5d7b3459c..f81a48e47 100644
--- a/libavcodec/avcodec.h
+++ b/libavcodec/avcodec.h
@@ -2937,6 +2937,10 @@ const AVCodecHWConfig *avcodec_get_hw_config(const 
AVCodec *codec, int index);
 
 /**
  * @defgroup lavc_hwaccel AVHWAccel
+ *
+ * @note  Nothing in this structure should be accessed by the user.  At some
+ *point in future it will not be externally visible at all.
+ *
  * @{
  */
 typedef struct AVHWAccel {
@@ -5015,17 +5019,26 @@ void av_fast_padded_malloc(void *ptr, unsigned int 
*size, size_t min_size);
  */
 unsigned int av_xiphlacing(unsigned char *s, unsigned int v);
 
+#if FF_API_USER_VISIBLE_AVHWACCEL
 /**
  * Register the hardware accelerator hwaccel.
+ *
+ * @deprecated  This function doesn't do anything.
  */
+attribute_deprecated
 void av_register_hwaccel(AVHWAccel *hwaccel);
 
 /**
  * If hwaccel is NULL, returns the first registered hardware accelerator,
  * if hwaccel is non-NULL, returns the next registered hardware accelerator
  * after hwaccel, or NULL if hwaccel is the last one.
+ *
+ * @deprecated  AVHWaccel structures contain no user-serviceable parts, so
+ *  this function should not be used.
  */
+attribute_deprecated
 AVHWAccel *av_hwaccel_next(const AVHWAccel *hwaccel);
+#endif
 
 
 /**
diff --git a/libavcodec/utils.c b/libavcodec/utils.c
index 3d6b35fa4..ba3457664 100644
--- a/libavcodec/utils.c
+++ b/libavcodec/utils.c
@@ -1347,21 +1347,16 @@ const AVCodecHWConfig *avcodec_get_hw_config(const 
AVCodec *codec, int index)
 return >hw_configs[index]->public;
 }
 
-static AVHWAccel *first_hwaccel = NULL;
-
-void av_register_hwaccel(AVHWAccel *hwaccel)
+#if FF_API_USER_VISIBLE_AVHWACCEL
+AVHWAccel *av_hwaccel_next(const AVHWAccel *hwaccel)
 {
-AVHWAccel **p = _hwaccel;
-while (*p)
-p = &(*p)->next;
-*p = hwaccel;
-hwaccel->next = NULL;
+return NULL;
 }
 
-AVHWAccel *av_hwaccel_next(const AVHWAccel *hwaccel)
+void av_register_hwaccel(AVHWAccel *hwaccel)
 {
-return hwaccel ? hwaccel->next : first_hwaccel;
 }
+#endif
 
 int av_lockmgr_register(int (*cb)(void **mutex, enum AVLockOp op))
 {
diff --git a/libavcodec/version.h b/libavcodec/version.h
index aa6cdcd6b..09e03328d 100644
--- a/libavcodec/version.h
+++ b/libavcodec/version.h
@@ -95,5 +95,8 @@
 #ifndef FF_API_VAAPI_CONTEXT
 #define FF_API_VAAPI_CONTEXT(LIBAVCODEC_VERSION_MAJOR < 59)
 #endif
+#ifndef FF_API_USER_VISIBLE_AVHWACCEL
+#define FF_API_USER_VISIBLE_AVHWACCEL (LIBAVCODEC_VERSION_MAJOR < 60)
+#endif
 
 #endif /* AVCODEC_VERSION_H */
-- 
2.11.0

___
libav-devel mailing list
libav-devel@libav.org
https://lists.libav.org/mailman/listinfo/libav-devel

[libav-devel] [PATCH 3/9] webp: Fix alpha initialisation

2017-12-10 Thread Mark Thompson
ff_get_format() in the next patch will reject formats which aren't in the
offered list, so the hack in 7cb9296db872c4221453e5411f242ebcfca62664 is
no longer valid.  Change the hack by adding a new field in the VP8 decoder
context to indicate that it's actually WebP and don't call ff_get_format()
at all in that case.
---
 libavcodec/vp8.c  |  4 +++-
 libavcodec/vp8.h  |  1 +
 libavcodec/webp.c | 16 +---
 3 files changed, 9 insertions(+), 12 deletions(-)

diff --git a/libavcodec/vp8.c b/libavcodec/vp8.c
index 6d1a39930..5c0b4749a 100644
--- a/libavcodec/vp8.c
+++ b/libavcodec/vp8.c
@@ -2515,7 +2515,9 @@ int vp78_decode_frame(AVCodecContext *avctx, void *data, 
int *got_frame,
 if (ret < 0)
 goto err;
 
-if (!is_vp7 && s->pix_fmt == AV_PIX_FMT_NONE) {
+if (s->actually_webp) {
+// avctx->pix_fmt already set in caller.
+} else if (!is_vp7 && s->pix_fmt == AV_PIX_FMT_NONE) {
 enum AVPixelFormat pix_fmts[] = {
 #if CONFIG_VP8_VAAPI_HWACCEL
 AV_PIX_FMT_VAAPI,
diff --git a/libavcodec/vp8.h b/libavcodec/vp8.h
index 1870705ad..1bf7561d0 100644
--- a/libavcodec/vp8.h
+++ b/libavcodec/vp8.h
@@ -140,6 +140,7 @@ typedef struct VP8Context {
 VP8ThreadData *thread_data;
 AVCodecContext *avctx;
 enum AVPixelFormat pix_fmt;
+int actually_webp;
 
 VP8Frame *framep[4];
 VP8Frame *next_framep[4];
diff --git a/libavcodec/webp.c b/libavcodec/webp.c
index 18d68e914..0e769c307 100644
--- a/libavcodec/webp.c
+++ b/libavcodec/webp.c
@@ -1288,16 +1288,6 @@ static int vp8_lossy_decode_alpha(AVCodecContext *avctx, 
AVFrame *p,
 return 0;
 }
 
-static enum AVPixelFormat webp_get_format(AVCodecContext *avctx,
-  const enum AVPixelFormat *formats)
-{
-WebPContext *s = avctx->priv_data;
-if (s->has_alpha)
-return AV_PIX_FMT_YUVA420P;
-else
-return AV_PIX_FMT_YUV420P;
-}
-
 static int vp8_lossy_decode_frame(AVCodecContext *avctx, AVFrame *p,
   int *got_frame, uint8_t *data_start,
   unsigned int data_size)
@@ -1309,7 +1299,11 @@ static int vp8_lossy_decode_frame(AVCodecContext *avctx, 
AVFrame *p,
 if (!s->initialized) {
 ff_vp8_decode_init(avctx);
 s->initialized = 1;
-avctx->get_format = webp_get_format;
+s->v.actually_webp = 1;
+if (s->has_alpha)
+avctx->pix_fmt = AV_PIX_FMT_YUVA420P;
+else
+avctx->pix_fmt = AV_PIX_FMT_YUV420P;
 }
 s->lossless = 0;
 
-- 
2.11.0

___
libav-devel mailing list
libav-devel@libav.org
https://lists.libav.org/mailman/listinfo/libav-devel