ffmpeg | branch: master | Andreas Rheinhardt <andreas.rheinha...@outlook.com> | Thu Apr 17 08:27:38 2025 +0200| [1ab50cced5a02798bbb7efc3333b1c4a06989317] | committer: Andreas Rheinhardt
avcodec/magicyuvenc: Calculate proper packet size in advance This can be easily done because we have a count of the number of values and the length of the associated codes. This allows to switch to ff_get_encode_buffer() and thereby avoids an implicit intermediate buffer. Signed-off-by: Andreas Rheinhardt <andreas.rheinha...@outlook.com> > http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=1ab50cced5a02798bbb7efc3333b1c4a06989317 --- libavcodec/magicyuvenc.c | 94 +++++++++++++++++++++++------------------------- 1 file changed, 44 insertions(+), 50 deletions(-) diff --git a/libavcodec/magicyuvenc.c b/libavcodec/magicyuvenc.c index 071dce1be3..d29379d3c1 100644 --- a/libavcodec/magicyuvenc.c +++ b/libavcodec/magicyuvenc.c @@ -391,8 +391,8 @@ static int count_plane_slice(AVCodecContext *avctx, int n, int plane) return 0; } -static int encode_table(AVCodecContext *avctx, - PutByteContext *pb, HuffEntry *he, int plane) +static void generate_codes(AVCodecContext *avctx, + HuffEntry *he, int plane) { MagicYUVContext *s = avctx->priv_data; PTable counts[256]; @@ -414,14 +414,15 @@ static int encode_table(AVCodecContext *avctx, magy_huffman_compute_bits(counts, he, codes_counts, 256, 12); calculate_codes(he, codes_counts); +} +static void output_codes(PutByteContext *pb, const HuffEntry he[256]) +{ for (int i = 0; i < 256; i++) { // The seven low bits are len; the top bit means the run of // codes of this length has length one. bytestream2_put_byte(pb, he[i].len); } - - return 0; } static void encode_plane_slice_raw(const uint8_t *src, uint8_t *dst, @@ -547,13 +548,35 @@ static int magy_encode_frame(AVCodecContext *avctx, AVPacket *pkt, const AVFrame *frame, int *got_packet) { MagicYUVContext *s = avctx->priv_data; - const int width = avctx->width, height = avctx->height; - const int slice_height = s->slice_height; PutByteContext pb; - int pos, ret = 0; + int header_size = 32 + (4 + 1) * (s->planes * s->nb_slices + 1) + + 256 * s->planes /* Hufftables */; + int64_t pkt_size = header_size; + int ret; + + avctx->execute2(avctx, predict_slice, (void *)frame, NULL, s->nb_slices); + + for (int i = 0; i < s->planes; i++) + generate_codes(avctx, s->he[i], i); + + for (int i = 0; i < s->nb_slices; ++i) { + for (int j = 0; j < s->planes; ++j) { + Slice *const sl = &s->slices[i * s->planes + j]; + int64_t size = 0; - ret = ff_alloc_packet(avctx, pkt, (256 + 4 * s->nb_slices + width * height) * - s->planes + 256); + for (size_t k = 0; k < FF_ARRAY_ELEMS(sl->counts); ++k) + size += sl->counts[k] * s->he[j][k].len; + size = AV_CEIL_RSHIFT(size, 3); + sl->encode_raw = size >= sl->width * sl->height; + if (sl->encode_raw) + size = sl->width * sl->height; + sl->size = FFALIGN(size + 2, 4); + sl->pos = pkt_size; + pkt_size += sl->size; + } + } + + ret = ff_get_encode_buffer(avctx, pkt, pkt_size, 0); if (ret < 0) return ret; @@ -573,13 +596,17 @@ static int magy_encode_frame(AVCodecContext *avctx, AVPacket *pkt, bytestream2_put_le32(&pb, avctx->width); bytestream2_put_le32(&pb, avctx->height); bytestream2_put_le32(&pb, avctx->width); - bytestream2_put_le32(&pb, slice_height); - bytestream2_put_le32(&pb, 0); + bytestream2_put_le32(&pb, s->slice_height); - for (int i = 0; i < s->planes; i++) { - bytestream2_put_le32(&pb, 0); - for (int j = 1; j < s->nb_slices; j++) - bytestream2_put_le32(&pb, 0); + // Slice position is relative to the current position (i.e. 32) + bytestream2_put_le32(&pb, header_size - 32); + + for (int i = 0; i < s->planes; ++i) { + for (int j = 0; j < s->nb_slices; ++j) { + Slice *const sl = &s->slices[j * s->planes + i]; + bytestream2_put_le32(&pb, sl->pos - 32); + sl->dst = pkt->data + sl->pos; + } } bytestream2_put_byte(&pb, s->planes); @@ -589,44 +616,11 @@ static int magy_encode_frame(AVCodecContext *avctx, AVPacket *pkt, bytestream2_put_byte(&pb, n * s->planes + i); } - avctx->execute2(avctx, predict_slice, (void *)frame, NULL, s->nb_slices); - - for (int i = 0; i < s->planes; i++) - encode_table(avctx, &pb, s->he[i], i); + for (int i = 0; i < s->planes; ++i) + output_codes(&pb, s->he[i]); - for (int i = 0; i < s->nb_slices; ++i) { - for (int j = 0; j < s->planes; ++j) { - Slice *const sl = &s->slices[i * s->planes + j]; - int64_t size = 0; - - for (size_t k = 0; k < FF_ARRAY_ELEMS(sl->counts); ++k) - size += sl->counts[k] * s->he[j][k].len; - size = AV_CEIL_RSHIFT(size, 3); - sl->encode_raw = size >= sl->width * sl->height; - if (sl->encode_raw) - size = sl->width * sl->height; - sl->size = FFALIGN(size + 2, 4); - sl->pos = bytestream2_tell_p(&pb); - sl->dst = pb.buffer; - bytestream2_skip_p(&pb, sl->size); - } - } avctx->execute2(avctx, encode_slice, NULL, NULL, s->nb_slices); - pos = bytestream2_tell_p(&pb); - bytestream2_seek_p(&pb, 32, SEEK_SET); - bytestream2_put_le32(&pb, s->slices[0].pos - 32); - for (int i = 0; i < s->planes; i++) { - for (int n = 0; n < s->nb_slices; n++) { - Slice *sl = &s->slices[n * s->planes + i]; - - bytestream2_put_le32(&pb, sl->pos - 32); - } - } - bytestream2_seek_p(&pb, pos, SEEK_SET); - - pkt->size = bytestream2_tell_p(&pb); - *got_packet = 1; return 0; _______________________________________________ ffmpeg-cvslog mailing list ffmpeg-cvslog@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-cvslog To unsubscribe, visit link above, or email ffmpeg-cvslog-requ...@ffmpeg.org with subject "unsubscribe".