From: "jianfeng.zheng" <ggjogh@gmail.com> To: ffmpeg-devel@ffmpeg.org Cc: "jianfeng.zheng" <jianfeng.zheng@mthreads.com> Subject: [FFmpeg-devel] [vaapi-cavs 5/7] cavs: decode wqm and slice weighting for future usage Date: Sun, 21 Jan 2024 22:18:44 +0800 Message-ID: <20240121141846.4077778-5-jianfeng.zheng@mthreads.com> (raw) In-Reply-To: <20240121141846.4077778-1-jianfeng.zheng@mthreads.com> Signed-off-by: jianfeng.zheng <jianfeng.zheng@mthreads.com> --- libavcodec/cavs.h | 26 +++++++- libavcodec/cavsdec.c | 142 +++++++++++++++++++++++++++++++++++++------ 2 files changed, 147 insertions(+), 21 deletions(-) diff --git a/libavcodec/cavs.h b/libavcodec/cavs.h index f490657959..33ef10e850 100644 --- a/libavcodec/cavs.h +++ b/libavcodec/cavs.h @@ -186,12 +186,36 @@ typedef struct AVSContext { int mb_width, mb_height; int width, height; int stream_revision; ///<0 for samples from 2006, 1 for rm52j encoder - int progressive; + int progressive_seq; + int progressive_frame; int pic_structure; int skip_mode_flag; ///< select between skip_count or one skip_flag per MB int loop_filter_disable; int alpha_offset, beta_offset; int ref_flag; + + /** \defgroup guangdian profile + * @{ + */ + int aec_flag; + int weight_quant_flag; + int chroma_quant_param_delta_cb; + int chroma_quant_param_delta_cr; + uint8_t wqm_8x8[64]; + /**@}*/ + + /** \defgroup slice weighting + * FFmpeg don't support slice weighting natively, but maybe needed for HWaccel. + * @{ + */ + uint32_t slice_weight_pred_flag : 1; + uint32_t mb_weight_pred_flag : 1; + uint8_t luma_scale[4]; + int8_t luma_shift[4]; + uint8_t chroma_scale[4]; + int8_t chroma_shift[4]; + /**@}*/ + int mbx, mby, mbidx; ///< macroblock coordinates int flags; ///< availability flags of neighbouring macroblocks int stc; ///< last start code diff --git a/libavcodec/cavsdec.c b/libavcodec/cavsdec.c index 6f462d861c..8d3ba530a6 100644 --- a/libavcodec/cavsdec.c +++ b/libavcodec/cavsdec.c @@ -30,6 +30,7 @@ #include "avcodec.h" #include "get_bits.h" #include "golomb.h" +#include "profiles.h" #include "cavs.h" #include "codec_internal.h" #include "decode.h" @@ -37,6 +38,43 @@ #include "mpeg12data.h" #include "startcode.h" +static const uint8_t default_wq_param[4][6] = { + {128, 98, 106, 116, 116, 128}, + {135, 143, 143, 160, 160, 213}, + {128, 98, 106, 116, 116, 128}, + {128, 128, 128, 128, 128, 128}, +}; +static const uint8_t wq_model_2_param[4][64] = { + { + 0, 0, 0, 4, 4, 4, 5, 5, + 0, 0, 3, 3, 3, 3, 5, 5, + 0, 3, 2, 2, 1, 1, 5, 5, + 4, 3, 2, 2, 1, 5, 5, 5, + 4, 3, 1, 1, 5, 5, 5, 5, + 4, 3, 1, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, + }, { + 0, 0, 0, 4, 4, 4, 5, 5, + 0, 0, 4, 4, 4, 4, 5, 5, + 0, 3, 2, 2, 2, 1, 5, 5, + 3, 3, 2, 2, 1, 5, 5, 5, + 3, 3, 2, 1, 5, 5, 5, 5, + 3, 3, 1, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, + }, { + 0, 0, 0, 4, 4, 3, 5, 5, + 0, 0, 4, 4, 3, 2, 5, 5, + 0, 4, 4, 3, 2, 1, 5, 5, + 4, 4, 3, 2, 1, 5, 5, 5, + 4, 3, 2, 1, 5, 5, 5, 5, + 3, 2, 1, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, + } +}; + static const uint8_t mv_scan[4] = { MV_FWD_X0, MV_FWD_X1, MV_FWD_X2, MV_FWD_X3 @@ -927,7 +965,11 @@ static int decode_mb_b(AVSContext *h, enum cavs_mb mb_type) static inline int decode_slice_header(AVSContext *h, GetBitContext *gb) { - if (h->stc > 0xAF) + int i, nref; + + av_log(h->avctx, AV_LOG_TRACE, "slice start code 0x%02x\n", h->stc); + + if (h->stc > SLICE_MAX_START_CODE) av_log(h->avctx, AV_LOG_ERROR, "unexpected start code 0x%02x\n", h->stc); if (h->stc >= h->mb_height) { @@ -946,11 +988,29 @@ static inline int decode_slice_header(AVSContext *h, GetBitContext *gb) } /* inter frame or second slice can have weighting params */ if ((h->cur.f->pict_type != AV_PICTURE_TYPE_I) || - (!h->pic_structure && h->mby >= h->mb_width / 2)) - if (get_bits1(gb)) { //slice_weighting_flag + (!h->pic_structure && h->mby >= h->mb_height / 2)) { + h->slice_weight_pred_flag = get_bits1(gb); + if (h->slice_weight_pred_flag) { + nref = h->cur.f->pict_type == AV_PICTURE_TYPE_I ? 1 : (h->pic_structure ? 2 : 4); + for (i = 0; i < nref; i++) { + h->luma_scale[i] = get_bits(gb, 8); + h->luma_shift[i] = get_sbits(gb, 8); + skip_bits1(gb); + h->chroma_scale[i] = get_bits(gb, 8); + h->chroma_shift[i] = get_sbits(gb, 8); + skip_bits1(gb); + } + h->mb_weight_pred_flag = get_bits1(gb); + if (!h->avctx->hwaccel) { av_log(h->avctx, AV_LOG_ERROR, "weighted prediction not yet supported\n"); } + } + } + if (h->aec_flag) { + align_get_bits(gb); + } + return 0; } @@ -1108,7 +1168,11 @@ static int decode_pic(AVSContext *h) cavs_frame_unref(&h->cur); - skip_bits(&h->gb, 16);//bbv_dwlay + skip_bits(&h->gb, 16);//bbv_delay + if (h->profile == AV_PROFILE_CAVS_GUANGDIAN) { + skip_bits(&h->gb, 8);//bbv_dwlay_extension + } + if (h->stc == PIC_PB_START_CODE) { h->cur.f->pict_type = get_bits(&h->gb, 2) + AV_PICTURE_TYPE_I; if (h->cur.f->pict_type > AV_PICTURE_TYPE_B) { @@ -1192,9 +1256,9 @@ static int decode_pic(AVSContext *h) if (h->low_delay) get_ue_golomb(&h->gb); //bbv_check_times - h->progressive = get_bits1(&h->gb); + h->progressive_frame = get_bits1(&h->gb); h->pic_structure = 1; - if (!h->progressive) + if (!h->progressive_frame) h->pic_structure = get_bits1(&h->gb); if (!h->pic_structure && h->stc == PIC_PB_START_CODE) skip_bits1(&h->gb); //advanced_pred_mode_disable @@ -1203,9 +1267,11 @@ static int decode_pic(AVSContext *h) h->pic_qp_fixed = h->qp_fixed = get_bits1(&h->gb); h->qp = get_bits(&h->gb, 6); + h->skip_mode_flag = 0; + h->ref_flag = 0; if (h->cur.f->pict_type == AV_PICTURE_TYPE_I) { - if (!h->progressive && !h->pic_structure) - skip_bits1(&h->gb);//what is this? + if (!h->progressive_frame && !h->pic_structure) + h->skip_mode_flag = get_bits1(&h->gb); skip_bits(&h->gb, 4); //reserved bits } else { if (!(h->cur.f->pict_type == AV_PICTURE_TYPE_B && h->pic_structure == 1)) @@ -1220,12 +1286,46 @@ static int decode_pic(AVSContext *h) if ( h->alpha_offset < -64 || h->alpha_offset > 64 || h-> beta_offset < -64 || h-> beta_offset > 64) { h->alpha_offset = h->beta_offset = 0; + av_log(h->avctx, AV_LOG_ERROR, "invalid loop filter params\n"); return AVERROR_INVALIDDATA; } } else { h->alpha_offset = h->beta_offset = 0; } + h->weight_quant_flag = 0; + if (h->profile == AV_PROFILE_CAVS_GUANGDIAN) { + h->weight_quant_flag = get_bits1(&h->gb); + if (h->weight_quant_flag) { + int wq_param[6] = {128, 128, 128, 128, 128, 128}; + int i, wqp_index, wq_model; + const uint8_t *m2p; + + skip_bits1(&h->gb); + if (!get_bits1(&h->gb)) { + h->chroma_quant_param_delta_cb = get_se_golomb(&h->gb); + h->chroma_quant_param_delta_cr = get_se_golomb(&h->gb); + } + wqp_index = get_bits(&h->gb, 2); + wq_model = get_bits(&h->gb, 2); + m2p = wq_model_2_param[wq_model]; + + for (i = 0; i < 6; i++) { + int delta = (wqp_index == 1 || wqp_index == 2) ? get_se_golomb(&h->gb) : 0; + wq_param[i] = default_wq_param[wqp_index][i] + delta; + av_log(h->avctx, AV_LOG_DEBUG, "wqp[%d]=%d\n", i, wq_param[i]); + } + for (i = 0; i < 64; i++) { + h->wqm_8x8[i] = wq_param[ m2p[i] ]; + } + } else { + memset(h->wqm_8x8, 128, sizeof(h->wqm_8x8)); + } + h->aec_flag = get_bits1(&h->gb); + av_log(h->avctx, AV_LOG_DEBUG, "wq_flag=%d, aec_flag=%d\n", + h->weight_quant_flag, h->aec_flag); + } + if (h->stream_revision > 0) { skip_stuffing_bits(h); skip_extension_and_user_data(h); @@ -1311,13 +1411,8 @@ static int decode_seq_header(AVSContext *h) int ret; h->profile = get_bits(&h->gb, 8); - if (h->profile != 0x20) { - avpriv_report_missing_feature(h->avctx, - "only supprt JiZhun profile"); - return AVERROR_PATCHWELCOME; - } h->level = get_bits(&h->gb, 8); - skip_bits1(&h->gb); //progressive sequence + h->progressive_seq = get_bits1(&h->gb); width = get_bits(&h->gb, 14); height = get_bits(&h->gb, 14); @@ -1344,6 +1439,9 @@ static int decode_seq_header(AVSContext *h) skip_bits1(&h->gb); //marker_bit skip_bits(&h->gb, 12); //bit_rate_upper h->low_delay = get_bits1(&h->gb); + av_log(h->avctx, AV_LOG_DEBUG, + "seq: profile=0x%02x, level=0x%02x, size=%dx%d, low_delay=%d\n", + h->profile, h->level, width, height, h->low_delay); ret = ff_set_dimensions(h->avctx, width, height); if (ret < 0) @@ -1369,8 +1467,6 @@ static int cavs_decode_frame(AVCodecContext *avctx, AVFrame *rframe, int *got_frame, AVPacket *avpkt) { AVSContext *h = avctx->priv_data; - const uint8_t *buf = avpkt->data; - int buf_size = avpkt->size; uint32_t stc = -1; int input_size, ret; const uint8_t *buf_end; @@ -1388,16 +1484,18 @@ static int cavs_decode_frame(AVCodecContext *avctx, AVFrame *rframe, h->stc = 0; - buf_ptr = buf; - buf_end = buf + buf_size; - for(;;) { + buf_ptr = avpkt->data; + buf_end = avpkt->data + avpkt->size; + for(; buf_ptr < buf_end;) { buf_ptr = avpriv_find_start_code(buf_ptr, buf_end, &stc); if ((stc & 0xFFFFFE00) || buf_ptr == buf_end) { if (!h->stc) av_log(h->avctx, AV_LOG_WARNING, "no frame decoded\n"); - return FFMAX(0, buf_ptr - buf); + return FFMAX(0, buf_ptr - avpkt->data); } input_size = (buf_end - buf_ptr) * 8; + av_log(h->avctx, AV_LOG_TRACE, "Found start code 0x%04x, sz=%d\n", + stc, input_size / 8); switch (stc) { case CAVS_START_CODE: init_get_bits(&h->gb, buf_ptr, input_size); @@ -1464,12 +1562,16 @@ static int cavs_decode_frame(AVCodecContext *avctx, AVFrame *rframe, break; default: if (stc <= SLICE_MAX_START_CODE) { + h->stc = stc & 0xff; init_get_bits(&h->gb, buf_ptr, input_size); decode_slice_header(h, &h->gb); + } else { + av_log(h->avctx, AV_LOG_WARNING, "Skip unsupported start code 0x%04X\n", stc); } break; } } + return (buf_ptr - avpkt->data); } const FFCodec ff_cavs_decoder = { -- 2.25.1 _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
next prev parent reply other threads:[~2024-01-21 14:19 UTC|newest] Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top 2024-01-21 14:18 [FFmpeg-devel] [vaapi-cavs 1/7] cavs: add cavs profile defs jianfeng.zheng 2024-01-21 14:18 ` [FFmpeg-devel] [vaapi-cavs 2/7] cavs: skip bits between pic header and slc header jianfeng.zheng 2024-01-21 14:18 ` [FFmpeg-devel] [vaapi-cavs 3/7] cavs: time code debug jianfeng.zheng 2024-01-21 14:18 ` [FFmpeg-devel] [vaapi-cavs 4/7] cavs: fix dpb reorder issues when 'low_delay' is varied jianfeng.zheng 2024-01-21 14:18 ` jianfeng.zheng [this message] 2024-01-21 14:18 ` [FFmpeg-devel] [vaapi-cavs 6/7] cavs: set profile & level for AVCodecContext jianfeng.zheng 2024-01-21 14:18 ` [FFmpeg-devel] [vaapi-cavs 7/7] cavs: support vaapi hwaccel decoding jianfeng.zheng 2024-01-22 21:24 ` Mark Thompson
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=20240121141846.4077778-5-jianfeng.zheng@mthreads.com \ --to=ggjogh@gmail.com \ --cc=ffmpeg-devel@ffmpeg.org \ --cc=jianfeng.zheng@mthreads.com \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: link
Git Inbox Mirror of the ffmpeg-devel mailing list - see https://ffmpeg.org/mailman/listinfo/ffmpeg-devel This inbox may be cloned and mirrored by anyone: git clone --mirror https://master.gitmailbox.com/ffmpegdev/0 ffmpegdev/git/0.git # If you have public-inbox 1.1+ installed, you may # initialize and index your mirror using the following commands: public-inbox-init -V2 ffmpegdev ffmpegdev/ https://master.gitmailbox.com/ffmpegdev \ ffmpegdev@gitmailbox.com public-inbox-index ffmpegdev Example config snippet for mirrors. AGPL code for this site: git clone https://public-inbox.org/public-inbox.git