On 11/11/2022 9:39 PM, Peter Ross wrote:
+static int lead_decode_frame(AVCodecContext *avctx, AVFrame * frame, + int * got_frame, AVPacket * avpkt) +{ + LeadContext *s = avctx->priv_data; + const uint8_t * buf = avpkt->data; + int ret, format, yuv20p_half = 0, fields = 1, q, size; + GetBitContext gb; + int16_t dc_pred[3] = {0, 0, 0}; + uint16_t dequant[2][64]; + + if (avpkt->size < 8) + return AVERROR_INVALIDDATA; + + format = AV_RL16(buf + 4); + switch(format) { + case 0x1000: + avctx->pix_fmt = AV_PIX_FMT_YUV420P; + break; + case 0x2000: + avctx->pix_fmt = AV_PIX_FMT_YUV444P; + break; + case 0x2006: + avctx->pix_fmt = AV_PIX_FMT_YUV444P; + fields = 2; + break; + case 0x8000: + avctx->pix_fmt = AV_PIX_FMT_YUV420P; + yuv20p_half = 1;
nit: maybe do switch(format) { case 0x8000: yuv20p_half = 1; // fall-through case 0x1000: avctx->pix_fmt = AV_PIX_FMT_YUV420P; break;
+ break; + default: + avpriv_request_sample(avctx, "unsupported format 0x%x", format); + return AVERROR_PATCHWELCOME; + } + + q = AV_RL16(buf + 6); + calc_dequant(dequant[0], ff_mjpeg_std_luminance_quant_tbl, q); + calc_dequant(dequant[1], ff_mjpeg_std_chrominance_quant_tbl, q); + + if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) + return ret; + + frame->key_frame = 1; + frame->pict_type = AV_PICTURE_TYPE_I;
Shouldn't the codec have the prop AV_CODEC_PROP_INTRA_ONLY then? Or do some formats not yet supported have inter frames?
[...]
+ if (yuv20p_half) { + for (int mb_y = 0; mb_y < avctx->height / 16; mb_y++) + for (int mb_x = 0; mb_x < avctx->width / 16; mb_x++) + for (int b = 0; b < 4; b++) { + const VLCElem * dc_vlc = b < 2 ? luma_dc_vlc.table : chroma_dc_vlc.table; + int dc_bits = b < 2 ? LUMA_DC_BITS : CHROMA_DC_BITS; + const VLCElem * ac_vlc = b < 2 ? luma_ac_vlc.table : chroma_ac_vlc.table; + int ac_bits = b < 2 ? LUMA_AC_BITS : CHROMA_AC_BITS; + int plane = b < 2 ? 0 : b - 1; + int x, y; + + if (b < 2) { + y = 16*mb_y + 8*(b >> 1); + x = 16*mb_x + 8*(b & 1); + } else { + y = 8*mb_y; + x = 8*mb_x; + } + + ret = decode_block(s, &gb, dc_vlc, dc_bits, ac_vlc, ac_bits, + dc_pred + plane, dequant[!(b < 4)], + frame->data[plane] + y*frame->linesize[plane] + x, + (b < 2 ? 2 : 1) * frame->linesize[plane]); + if (ret < 0) + return ret; + + if (b < 2) + copy_block8(frame->data[plane] + (y + 1)*frame->linesize[plane] + x, + frame->data[plane] + y*frame->linesize[plane] + x, + 2*frame->linesize[plane], 2*frame->linesize[plane], 8); + } + } else if (avctx->pix_fmt == AV_PIX_FMT_YUV420P) { + for (int mb_y = 0; mb_y < avctx->height / 16; mb_y++) + for (int mb_x = 0; mb_x < avctx->width / 16; mb_x++) + for (int b = 0; b < 6; b++) { + const VLCElem * dc_vlc = b < 4 ? luma_dc_vlc.table : chroma_dc_vlc.table; + int dc_bits = b < 4 ? LUMA_DC_BITS : CHROMA_DC_BITS; + const VLCElem * ac_vlc = b < 4 ? luma_ac_vlc.table : chroma_ac_vlc.table; + int ac_bits = b < 4 ? LUMA_AC_BITS : CHROMA_AC_BITS; + int plane = b < 4 ? 0 : b - 3; + int x, y; + + if (b < 4) { + y = 16*mb_y + 8*(b>>1); + x = 16*mb_x + 8*(b&1); + } else { + y = 8*mb_y; + x = 8*mb_x; + } + + ret = decode_block(s, &gb, dc_vlc, dc_bits, ac_vlc, ac_bits, + dc_pred + plane, dequant[!(b < 4)], + frame->data[plane] + y*frame->linesize[plane] + x, + frame->linesize[plane]); + if (ret < 0) + return ret; + }
You should be able to combine these two blocks, doing things like b < (4 >> yuv20p_half), b - (3 >> yuv20p_half) and such.
_______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".