[libav-devel] [PATCH 3/6] cbs: Demote the "decomposition unimplemented" warning
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
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
--- 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
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
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
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
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
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
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
--- 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
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()
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
--- 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()
--- 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
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