[FFmpeg-devel] [PATCH] avcodec: add SMC encoder
James Almer
jamrial at gmail.com
Sun Aug 15 00:41:56 EEST 2021
On 8/14/2021 1:55 PM, Paul B Mahol wrote:
> +static int smc_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
> + const AVFrame *frame, int *got_packet)
> +{
> + SMCContext *s = avctx->priv_data;
> + const AVFrame *pict = frame;
> + uint8_t *pal;
> + int ret;
> +
> + ret = ff_alloc_packet(avctx, pkt, 8LL * avctx->height * avctx->width);
> + if (ret < 0)
> + return ret;
> +
> + if (avctx->gop_size == 0 || !s->prev_frame->data[0] ||
> + (avctx->frame_number % avctx->gop_size) == 0) {
> + s->key_frame = 1;
> + } else {
> + s->key_frame = 0;
> + }
> +
> + bytestream2_init_writer(&s->pb, pkt->data, pkt->size);
> +
> + bytestream2_put_be32(&s->pb, 0x00);
> +
> + if (!s->prev_frame->data[0]) {
> + s->first_frame = 1;
> + s->prev_frame->format = pict->format;
> + s->prev_frame->width = pict->width;
> + s->prev_frame->height = pict->height;
> + ret = av_frame_get_buffer(s->prev_frame, 0);
This is unnecessary. You're allocating a buffer you'll not use just so
for the next frame the !s->prev_frame->data[0] check above will evaluate
to false.
Get rid of s->first_frame and just look for s->prev_frame->data[0] in
smc_encode_stream() to know if you need to use a previous frame or not.
When you process the second one you'll have called av_frame_ref() on
s->prev_frame at the end of the first, so it will be populated.
> + if (ret < 0)
> + return ret;
> + } else {
> + s->first_frame = 0;
> + }
> +
> + pal = av_packet_new_side_data(pkt, AV_PKT_DATA_PALETTE, AVPALETTE_SIZE);
> + memcpy(pal, frame->data[1], AVPALETTE_SIZE);
> +
> + smc_encode_stream(s, pict);
> +
> + av_shrink_packet(pkt, bytestream2_tell_p(&s->pb));
> +
> + pkt->data[0] = 0x0;
> +
> + // write chunk length
> + AV_WB24(pkt->data + 1, pkt->size);
> +
> + av_frame_unref(s->prev_frame);
> + ret = av_frame_ref(s->prev_frame, frame);
> + if (ret < 0) {
> + av_log(avctx, AV_LOG_ERROR, "cannot add reference\n");
> + return ret;
> + }
> +
> + if (s->key_frame)
> + pkt->flags |= AV_PKT_FLAG_KEY;
> +
> + *got_packet = 1;
> +
> + return 0;
> +}
> +
More information about the ffmpeg-devel
mailing list