History

avcodec/dxtory: add support for vertically flipped frames

Paul B Mahol committed 6 years ago

Commit 2d16b6b1 parent 69e22e21 file · +113 −31Browse files

Unified · Split

libavcodec/dxtory.c+113−31
@@ -32,9 +32,44 @@ · 31 unmodified lines
3232 #include "internal.h"
3333 #include "unary.h"
3434
35+static void do_vflip(AVCodecContext *avctx, AVFrame *pic, int vflip)
36+{
37+ if (!vflip)
38+ return;
39+
40+ switch (pic->format) {
41+ case AV_PIX_FMT_YUV444P:
42+ pic->data[1] += (avctx->height - 1) * pic->linesize[1];
43+ pic->linesize[1] = -pic->linesize[1];
44+ pic->data[2] += (avctx->height - 1) * pic->linesize[2];
45+ pic->linesize[2] = -pic->linesize[2];
46+ case AV_PIX_FMT_BGR24:
47+ case AV_PIX_FMT_RGB24:
48+ pic->data[0] += (avctx->height - 1) * pic->linesize[0];
49+ pic->linesize[0] = -pic->linesize[0];
50+ break;
51+ case AV_PIX_FMT_YUV410P:
52+ pic->data[0] += (avctx->height - 1) * pic->linesize[0];
53+ pic->linesize[0] = -pic->linesize[0];
54+ pic->data[1] += ((avctx->height >> 2) - 1) * pic->linesize[1];
55+ pic->linesize[1] = -pic->linesize[1];
56+ pic->data[2] += ((avctx->height >> 2) - 1) * pic->linesize[2];
57+ pic->linesize[2] = -pic->linesize[2];
58+ break;
59+ case AV_PIX_FMT_YUV420P:
60+ pic->data[0] += (avctx->height - 1) * pic->linesize[0];
61+ pic->linesize[0] = -pic->linesize[0];
62+ pic->data[1] += ((avctx->height >> 1) - 1) * pic->linesize[1];
63+ pic->linesize[1] = -pic->linesize[1];
64+ pic->data[2] += ((avctx->height >> 1) - 1) * pic->linesize[2];
65+ pic->linesize[2] = -pic->linesize[2];
66+ break;
67+ }
68+}
69+
3570 static int dxtory_decode_v1_rgb(AVCodecContext *avctx, AVFrame *pic,
3671 const uint8_t *src, int src_size,
37− int id, int bpp)
72+ int id, int bpp, uint32_t vflipped)
3873 {
3974 int h;
4075 uint8_t *dst;
@@ -49,6 +84,8 @@ static int dxtory_decode_v1_rgb(AVCodecContext *avctx, AVFrame *pic, · 8 unmodified lines
4984 if ((ret = ff_get_buffer(avctx, pic, 0)) < 0)
5085 return ret;
5186
87+ do_vflip(avctx, pic, vflipped);
88+
5289 dst = pic->data[0];
5390 for (h = 0; h < avctx->height; h++) {
5491 memcpy(dst, src, avctx->width * bpp);
@@ -56,11 +93,14 @@ static int dxtory_decode_v1_rgb(AVCodecContext *avctx, AVFrame *pic, · 1 unmodified line
5693 dst += pic->linesize[0];
5794 }
5895
96+ do_vflip(avctx, pic, vflipped);
97+
5998 return 0;
6099 }
61100
62101 static int dxtory_decode_v1_410(AVCodecContext *avctx, AVFrame *pic,
63− const uint8_t *src, int src_size)
102+ const uint8_t *src, int src_size,
103+ uint32_t vflipped)
64104 {
65105 int h, w;
66106 uint8_t *Y1, *Y2, *Y3, *Y4, *U, *V;
@@ -75,6 +115,8 @@ static int dxtory_decode_v1_410(AVCodecContext *avctx, AVFrame *pic, · 8 unmodified lines
75115 if ((ret = ff_get_buffer(avctx, pic, 0)) < 0)
76116 return ret;
77117
118+ do_vflip(avctx, pic, vflipped);
119+
78120 Y1 = pic->data[0];
79121 Y2 = pic->data[0] + pic->linesize[0];
80122 Y3 = pic->data[0] + pic->linesize[0] * 2;
@@ -99,11 +141,14 @@ static int dxtory_decode_v1_410(AVCodecContext *avctx, AVFrame *pic, · 18 unmodified lines
99141 V += pic->linesize[2];
100142 }
101143
144+ do_vflip(avctx, pic, vflipped);
145+
102146 return 0;
103147 }
104148
105149 static int dxtory_decode_v1_420(AVCodecContext *avctx, AVFrame *pic,
106− const uint8_t *src, int src_size)
150+ const uint8_t *src, int src_size,
151+ uint32_t vflipped)
107152 {
108153 int h, w;
109154 uint8_t *Y1, *Y2, *U, *V;
@@ -118,6 +163,8 @@ static int dxtory_decode_v1_420(AVCodecContext *avctx, AVFrame *pic, · 8 unmodified lines
118163 if ((ret = ff_get_buffer(avctx, pic, 0)) < 0)
119164 return ret;
120165
166+ do_vflip(avctx, pic, vflipped);
167+
121168 Y1 = pic->data[0];
122169 Y2 = pic->data[0] + pic->linesize[0];
123170 U = pic->data[1];
@@ -136,11 +183,14 @@ static int dxtory_decode_v1_420(AVCodecContext *avctx, AVFrame *pic, · 12 unmodified lines
136183 V += pic->linesize[2];
137184 }
138185
186+ do_vflip(avctx, pic, vflipped);
187+
139188 return 0;
140189 }
141190
142191 static int dxtory_decode_v1_444(AVCodecContext *avctx, AVFrame *pic,
143− const uint8_t *src, int src_size)
192+ const uint8_t *src, int src_size,
193+ uint32_t vflipped)
144194 {
145195 int h, w;
146196 uint8_t *Y, *U, *V;
@@ -155,6 +205,8 @@ static int dxtory_decode_v1_444(AVCodecContext *avctx, AVFrame *pic, · 8 unmodified lines
155205 if ((ret = ff_get_buffer(avctx, pic, 0)) < 0)
156206 return ret;
157207
208+ do_vflip(avctx, pic, vflipped);
209+
158210 Y = pic->data[0];
159211 U = pic->data[1];
160212 V = pic->data[2];
@@ -169,6 +221,8 @@ static int dxtory_decode_v1_444(AVCodecContext *avctx, AVFrame *pic, · 8 unmodified lines
169221 V += pic->linesize[2];
170222 }
171223
224+ do_vflip(avctx, pic, vflipped);
225+
172226 return 0;
173227 }
174228
@@ -270,7 +324,8 @@ static int dxtory_decode_v2(AVCodecContext *avctx, AVFrame *pic, · 95 unmodified lines
270324 const uint8_t *src, int src_size,
271325 decode_slice_func decode_slice,
272326 setup_lru_func setup_lru,
273− enum AVPixelFormat fmt)
327+ enum AVPixelFormat fmt,
328+ uint32_t vflipped)
274329 {
275330 GetByteContext gb, gb_check;
276331 GetBitContext gb2;
@@ -301,6 +356,8 @@ static int dxtory_decode_v2(AVCodecContext *avctx, AVFrame *pic, · 24 unmodified lines
301356 if ((ret = ff_get_buffer(avctx, pic, 0)) < 0)
302357 return ret;
303358
359+ do_vflip(avctx, pic, vflipped);
360+
304361 for (slice = 0; slice < nslices; slice++) {
305362 slice_size = bytestream2_get_le32(&gb);
306363
@@ -322,6 +379,8 @@ static int dxtory_decode_v2(AVCodecContext *avctx, AVFrame *pic, · 15 unmodified lines
322379 avpriv_request_sample(avctx, "Not enough slice data available");
323380 }
324381
382+ do_vflip(avctx, pic, vflipped);
383+
325384 return 0;
326385 }
327386
@@ -379,19 +438,20 @@ static int dx2_decode_slice_565(GetBitContext *gb, AVFrame *frame, · 51 unmodified lines
379438 }
380439
381440 static int dxtory_decode_v2_565(AVCodecContext *avctx, AVFrame *pic,
382− const uint8_t *src, int src_size, int is_565)
441+ const uint8_t *src, int src_size, int is_565,
442+ uint32_t vflipped)
383443 {
384444 enum AVPixelFormat fmt = AV_PIX_FMT_RGB24;
385445 if (is_565)
386446 return dxtory_decode_v2(avctx, pic, src, src_size,
387447 dx2_decode_slice_565,
388448 setup_lru_565,
389− fmt);
449+ fmt, vflipped);
390450 else
391451 return dxtory_decode_v2(avctx, pic, src, src_size,
392452 dx2_decode_slice_555,
393453 setup_lru_555,
394− fmt);
454+ fmt, vflipped);
395455 }
396456
397457 static int dx2_decode_slice_rgb(GetBitContext *gb, AVFrame *frame,
@@ -424,12 +484,13 @@ static void default_setup_lru(uint8_t lru[3][8]) · 26 unmodified lines
424484 }
425485
426486 static int dxtory_decode_v2_rgb(AVCodecContext *avctx, AVFrame *pic,
427− const uint8_t *src, int src_size)
487+ const uint8_t *src, int src_size,
488+ uint32_t vflipped)
428489 {
429490 return dxtory_decode_v2(avctx, pic, src, src_size,
430491 dx2_decode_slice_rgb,
431492 default_setup_lru,
432− AV_PIX_FMT_BGR24);
493+ AV_PIX_FMT_BGR24, vflipped);
433494 }
434495
435496 static int dx2_decode_slice_410(GetBitContext *gb, AVFrame *frame,
@@ -466,12 +527,13 @@ static int dx2_decode_slice_410(GetBitContext *gb, AVFrame *frame, · 30 unmodified lines
466527
467528
468529 static int dxtory_decode_v2_410(AVCodecContext *avctx, AVFrame *pic,
469− const uint8_t *src, int src_size)
530+ const uint8_t *src, int src_size,
531+ uint32_t vflipped)
470532 {
471533 return dxtory_decode_v2(avctx, pic, src, src_size,
472534 dx2_decode_slice_410,
473535 default_setup_lru,
474− AV_PIX_FMT_YUV410P);
536+ AV_PIX_FMT_YUV410P, vflipped);
475537 }
476538
477539 static int dx2_decode_slice_420(GetBitContext *gb, AVFrame *frame,
@@ -510,12 +572,13 @@ static int dx2_decode_slice_420(GetBitContext *gb, AVFrame *frame, · 32 unmodified lines
510572 }
511573
512574 static int dxtory_decode_v2_420(AVCodecContext *avctx, AVFrame *pic,
513− const uint8_t *src, int src_size)
575+ const uint8_t *src, int src_size,
576+ uint32_t vflipped)
514577 {
515578 return dxtory_decode_v2(avctx, pic, src, src_size,
516579 dx2_decode_slice_420,
517580 default_setup_lru,
518− AV_PIX_FMT_YUV420P);
581+ AV_PIX_FMT_YUV420P, vflipped);
519582 }
520583
521584 static int dx2_decode_slice_444(GetBitContext *gb, AVFrame *frame,
@@ -550,12 +613,13 @@ static int dx2_decode_slice_444(GetBitContext *gb, AVFrame *frame, · 28 unmodified lines
550613 }
551614
552615 static int dxtory_decode_v2_444(AVCodecContext *avctx, AVFrame *pic,
553− const uint8_t *src, int src_size)
616+ const uint8_t *src, int src_size,
617+ uint32_t vflipped)
554618 {
555619 return dxtory_decode_v2(avctx, pic, src, src_size,
556620 dx2_decode_slice_444,
557621 default_setup_lru,
558− AV_PIX_FMT_YUV444P);
622+ AV_PIX_FMT_YUV444P, vflipped);
559623 }
560624
561625 static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
@@ -563,57 +627,75 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, · 1 unmodified line
563627 {
564628 AVFrame *pic = data;
565629 const uint8_t *src = avpkt->data;
566− int ret;
630+ uint32_t type;
631+ int vflipped, ret;
567632
568633 if (avpkt->size < 16) {
569634 av_log(avctx, AV_LOG_ERROR, "packet too small\n");
570635 return AVERROR_INVALIDDATA;
571636 }
572637
573− switch (AV_RB32(src)) {
638+ type = AV_RB32(src);
639+ vflipped = !!(type & 0x20);
640+
641+ switch (type) {
642+ case 0x01000021:
574643 case 0x01000001:
575644 ret = dxtory_decode_v1_rgb(avctx, pic, src + 16, avpkt->size - 16,
576− AV_PIX_FMT_BGR24, 3);
645+ AV_PIX_FMT_BGR24, 3, vflipped);
577646 break;
647+ case 0x01000029:
578648 case 0x01000009:
579− ret = dxtory_decode_v2_rgb(avctx, pic, src + 16, avpkt->size - 16);
649+ ret = dxtory_decode_v2_rgb(avctx, pic, src + 16, avpkt->size - 16, vflipped);
580650 break;
651+ case 0x02000021:
581652 case 0x02000001:
582− ret = dxtory_decode_v1_420(avctx, pic, src + 16, avpkt->size - 16);
653+ ret = dxtory_decode_v1_420(avctx, pic, src + 16, avpkt->size - 16, vflipped);
583654 break;
655+ case 0x02000029:
584656 case 0x02000009:
585− ret = dxtory_decode_v2_420(avctx, pic, src + 16, avpkt->size - 16);
657+ ret = dxtory_decode_v2_420(avctx, pic, src + 16, avpkt->size - 16, vflipped);
586658 break;
659+ case 0x03000021:
587660 case 0x03000001:
588− ret = dxtory_decode_v1_410(avctx, pic, src + 16, avpkt->size - 16);
661+ ret = dxtory_decode_v1_410(avctx, pic, src + 16, avpkt->size - 16, vflipped);
589662 break;
663+ case 0x03000029:
590664 case 0x03000009:
591− ret = dxtory_decode_v2_410(avctx, pic, src + 16, avpkt->size - 16);
665+ ret = dxtory_decode_v2_410(avctx, pic, src + 16, avpkt->size - 16, vflipped);
592666 break;
667+ case 0x04000021:
593668 case 0x04000001:
594− ret = dxtory_decode_v1_444(avctx, pic, src + 16, avpkt->size - 16);
669+ ret = dxtory_decode_v1_444(avctx, pic, src + 16, avpkt->size - 16, vflipped);
595670 break;
671+ case 0x04000029:
596672 case 0x04000009:
597− ret = dxtory_decode_v2_444(avctx, pic, src + 16, avpkt->size - 16);
673+ ret = dxtory_decode_v2_444(avctx, pic, src + 16, avpkt->size - 16, vflipped);
598674 break;
675+ case 0x17000021:
599676 case 0x17000001:
600677 ret = dxtory_decode_v1_rgb(avctx, pic, src + 16, avpkt->size - 16,
601− AV_PIX_FMT_RGB565LE, 2);
678+ AV_PIX_FMT_RGB565LE, 2, vflipped);
602679 break;
680+ case 0x17000029:
603681 case 0x17000009:
604− ret = dxtory_decode_v2_565(avctx, pic, src + 16, avpkt->size - 16, 1);
682+ ret = dxtory_decode_v2_565(avctx, pic, src + 16, avpkt->size - 16, 1, vflipped);
605683 break;
684+ case 0x18000021:
685+ case 0x19000021:
606686 case 0x18000001:
607687 case 0x19000001:
608688 ret = dxtory_decode_v1_rgb(avctx, pic, src + 16, avpkt->size - 16,
609− AV_PIX_FMT_RGB555LE, 2);
689+ AV_PIX_FMT_RGB555LE, 2, vflipped);
610690 break;
691+ case 0x18000029:
692+ case 0x19000029:
611693 case 0x18000009:
612694 case 0x19000009:
613− ret = dxtory_decode_v2_565(avctx, pic, src + 16, avpkt->size - 16, 0);
695+ ret = dxtory_decode_v2_565(avctx, pic, src + 16, avpkt->size - 16, 0, vflipped);
614696 break;
615697 default:
616− avpriv_request_sample(avctx, "Frame header %"PRIX32, AV_RB32(src));
698+ avpriv_request_sample(avctx, "Frame header %"PRIX32, type);
617699 return AVERROR_PATCHWELCOME;
618700 }
619701

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