History

avcodec/magicyuvenc: Avoid intermediate buffer

Given that we can calculate the size of each slice in advance, we can determine the position in the output packet where it needs to be put and can therefore avoid the intermediate buffer.

Andreas Rheinhardt committed 1 year ago

Commit e8b97b71 parent 6e6e4e01 file · +14 −30Browse files

Unified · Split

libavcodec/magicyuvenc.c+14−30
@@ -60,7 +60,7 @@ typedef struct Slice { · 59 unmodified lines
6060 unsigned pos;
6161 unsigned size;
6262 uint8_t *slice;
63− uint8_t *bitslice;
63+ uint8_t *dst;
6464 int64_t counts[256];
6565 } Slice;
6666
@@ -74,7 +74,6 @@ typedef struct MagicYUVContext { · 7 unmodified lines
7474 int correlate;
7575 int hshift[4];
7676 int vshift[4];
77− unsigned bitslice_size;
7877 uint8_t *decorrelate_buf[2];
7978 Slice *slices;
8079 HuffEntry he[4][256];
@@ -224,7 +223,6 @@ static av_cold int magy_encode_init(AVCodecContext *avctx) · 143 unmodified lines
224223 s->decorrelate_buf[1] = s->decorrelate_buf[0] + (s->nb_slices * s->slice_height) * aligned_width;
225224 }
226225
227− s->bitslice_size = avctx->width * s->slice_height + 2;
228226 for (int n = 0; n < s->nb_slices; n++) {
229227 for (int i = 0; i < s->planes; i++) {
230228 Slice *sl = &s->slices[n * s->planes + i];
@@ -233,10 +231,9 @@ static av_cold int magy_encode_init(AVCodecContext *avctx) · 2 unmodified lines
233231 sl->height = AV_CEIL_RSHIFT(sl->height, s->vshift[i]);
234232 sl->width = AV_CEIL_RSHIFT(avctx->width, s->hshift[i]);
235233
236− sl->bitslice = av_malloc(s->bitslice_size + AV_INPUT_BUFFER_PADDING_SIZE);
237234 sl->slice = av_malloc(avctx->width * (s->slice_height + 2) +
238235 AV_INPUT_BUFFER_PADDING_SIZE);
239− if (!sl->slice || !sl->bitslice) {
236+ if (!sl->slice) {
240237 av_log(avctx, AV_LOG_ERROR, "Cannot allocate temporary buffer.\n");
241238 return AVERROR(ENOMEM);
242239 }
@@ -426,21 +423,16 @@ static int encode_table(AVCodecContext *avctx, · 183 unmodified lines
426423 return 0;
427424 }
428425
429−static int encode_plane_slice_raw(const uint8_t *src, uint8_t *dst,
430− int width, int height, int prediction)
426+static void encode_plane_slice_raw(const uint8_t *src, uint8_t *dst, int dst_size,
427+ int width, int height, int prediction)
431428 {
432429 unsigned count = width * height;
433430
434431 dst[0] = 1;
435432 dst[1] = prediction;
433+ AV_WN32(dst + dst_size - 4, 0);
436434
437435 memcpy(dst + 2, src, count);
438− count += 2;
439− AV_WN32(dst + count, 0);
440− if (count & 3)
441− count += 4 - (count & 3);
442−
443− return count;
444436 }
445437
446438 static void encode_plane_slice(const uint8_t *src, uint8_t *dst, unsigned dst_size,
@@ -482,11 +474,11 @@ static int encode_slice(AVCodecContext *avctx, void *tdata, · 35 unmodified lines
482474 Slice *sl = &s->slices[n * s->planes + i];
483475
484476 if (sl->encode_raw)
485− encode_plane_slice_raw(sl->slice, sl->bitslice,
477+ encode_plane_slice_raw(sl->slice, sl->dst, sl->size,
486478 sl->width, sl->height, s->frame_pred);
487479 else
488480 encode_plane_slice(sl->slice,
489− sl->bitslice,
481+ sl->dst,
490482 sl->size,
491483 sl->width, sl->height,
492484 s->he[i], s->frame_pred);
@@ -612,32 +604,25 @@ static int magy_encode_frame(AVCodecContext *avctx, AVPacket *pkt, · 119 unmodified lines
612604 tables_size = put_bytes_count(&pbit, 1);
613605 bytestream2_skip_p(&pb, tables_size);
614606
615− for (int i = 0; i < s->planes; ++i) {
616− for (int j = 0; j < s->nb_slices; ++j) {
617− Slice *const sl = &s->slices[j * s->planes + i];
607+ for (int i = 0; i < s->nb_slices; ++i) {
608+ for (int j = 0; j < s->planes; ++j) {
609+ Slice *const sl = &s->slices[i * s->planes + j];
618610 int64_t size = 0;
619611
620612 for (size_t k = 0; k < FF_ARRAY_ELEMS(sl->counts); ++k)
621− size += sl->counts[k] * s->he[i][k].len;
613+ size += sl->counts[k] * s->he[j][k].len;
622614 size = AV_CEIL_RSHIFT(size, 3);
623615 sl->encode_raw = size >= sl->width * sl->height;
624616 if (sl->encode_raw)
625617 size = sl->width * sl->height;
626618 sl->size = FFALIGN(size + 2, 4);
619+ sl->pos = bytestream2_tell_p(&pb);
620+ sl->dst = pb.buffer;
621+ bytestream2_skip_p(&pb, sl->size);
627622 }
628623 }
629624 avctx->execute2(avctx, encode_slice, NULL, NULL, s->nb_slices);
630625
631− for (int n = 0; n < s->nb_slices; n++) {
632− for (int i = 0; i < s->planes; i++) {
633− Slice *sl = &s->slices[n * s->planes + i];
634−
635− sl->pos = bytestream2_tell_p(&pb);
636−
637− bytestream2_put_buffer(&pb, sl->bitslice, sl->size);
638− }
639− }
640−
641626 pos = bytestream2_tell_p(&pb);
642627 bytestream2_seek_p(&pb, 32, SEEK_SET);
643628 bytestream2_put_le32(&pb, s->slices[0].pos - 32);
@@ -665,7 +650,6 @@ static av_cold int magy_encode_close(AVCodecContext *avctx) · 21 unmodified lines
665650 Slice *sl = &s->slices[i];
666651
667652 av_freep(&sl->slice);
668− av_freep(&sl->bitslice);
669653 }
670654 av_freep(&s->slices);
671655 av_freep(&s->decorrelate_buf);

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t