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
[email protected]
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
[email protected] with subject "unsubscribe".