mirror of
https://github.com/nyanmisaka/ffmpeg-rockchip.git
synced 2025-10-19 07:05:53 +08:00
avcodec/dxtory: add support for vertically flipped frames
This commit is contained in:
@@ -32,9 +32,44 @@
|
|||||||
#include "internal.h"
|
#include "internal.h"
|
||||||
#include "unary.h"
|
#include "unary.h"
|
||||||
|
|
||||||
|
static void do_vflip(AVCodecContext *avctx, AVFrame *pic, int vflip)
|
||||||
|
{
|
||||||
|
if (!vflip)
|
||||||
|
return;
|
||||||
|
|
||||||
|
switch (pic->format) {
|
||||||
|
case AV_PIX_FMT_YUV444P:
|
||||||
|
pic->data[1] += (avctx->height - 1) * pic->linesize[1];
|
||||||
|
pic->linesize[1] = -pic->linesize[1];
|
||||||
|
pic->data[2] += (avctx->height - 1) * pic->linesize[2];
|
||||||
|
pic->linesize[2] = -pic->linesize[2];
|
||||||
|
case AV_PIX_FMT_BGR24:
|
||||||
|
case AV_PIX_FMT_RGB24:
|
||||||
|
pic->data[0] += (avctx->height - 1) * pic->linesize[0];
|
||||||
|
pic->linesize[0] = -pic->linesize[0];
|
||||||
|
break;
|
||||||
|
case AV_PIX_FMT_YUV410P:
|
||||||
|
pic->data[0] += (avctx->height - 1) * pic->linesize[0];
|
||||||
|
pic->linesize[0] = -pic->linesize[0];
|
||||||
|
pic->data[1] += ((avctx->height >> 2) - 1) * pic->linesize[1];
|
||||||
|
pic->linesize[1] = -pic->linesize[1];
|
||||||
|
pic->data[2] += ((avctx->height >> 2) - 1) * pic->linesize[2];
|
||||||
|
pic->linesize[2] = -pic->linesize[2];
|
||||||
|
break;
|
||||||
|
case AV_PIX_FMT_YUV420P:
|
||||||
|
pic->data[0] += (avctx->height - 1) * pic->linesize[0];
|
||||||
|
pic->linesize[0] = -pic->linesize[0];
|
||||||
|
pic->data[1] += ((avctx->height >> 1) - 1) * pic->linesize[1];
|
||||||
|
pic->linesize[1] = -pic->linesize[1];
|
||||||
|
pic->data[2] += ((avctx->height >> 1) - 1) * pic->linesize[2];
|
||||||
|
pic->linesize[2] = -pic->linesize[2];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static int dxtory_decode_v1_rgb(AVCodecContext *avctx, AVFrame *pic,
|
static int dxtory_decode_v1_rgb(AVCodecContext *avctx, AVFrame *pic,
|
||||||
const uint8_t *src, int src_size,
|
const uint8_t *src, int src_size,
|
||||||
int id, int bpp)
|
int id, int bpp, uint32_t vflipped)
|
||||||
{
|
{
|
||||||
int h;
|
int h;
|
||||||
uint8_t *dst;
|
uint8_t *dst;
|
||||||
@@ -49,6 +84,8 @@ static int dxtory_decode_v1_rgb(AVCodecContext *avctx, AVFrame *pic,
|
|||||||
if ((ret = ff_get_buffer(avctx, pic, 0)) < 0)
|
if ((ret = ff_get_buffer(avctx, pic, 0)) < 0)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
|
do_vflip(avctx, pic, vflipped);
|
||||||
|
|
||||||
dst = pic->data[0];
|
dst = pic->data[0];
|
||||||
for (h = 0; h < avctx->height; h++) {
|
for (h = 0; h < avctx->height; h++) {
|
||||||
memcpy(dst, src, avctx->width * bpp);
|
memcpy(dst, src, avctx->width * bpp);
|
||||||
@@ -56,11 +93,14 @@ static int dxtory_decode_v1_rgb(AVCodecContext *avctx, AVFrame *pic,
|
|||||||
dst += pic->linesize[0];
|
dst += pic->linesize[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
do_vflip(avctx, pic, vflipped);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int dxtory_decode_v1_410(AVCodecContext *avctx, AVFrame *pic,
|
static int dxtory_decode_v1_410(AVCodecContext *avctx, AVFrame *pic,
|
||||||
const uint8_t *src, int src_size)
|
const uint8_t *src, int src_size,
|
||||||
|
uint32_t vflipped)
|
||||||
{
|
{
|
||||||
int h, w;
|
int h, w;
|
||||||
uint8_t *Y1, *Y2, *Y3, *Y4, *U, *V;
|
uint8_t *Y1, *Y2, *Y3, *Y4, *U, *V;
|
||||||
@@ -75,6 +115,8 @@ static int dxtory_decode_v1_410(AVCodecContext *avctx, AVFrame *pic,
|
|||||||
if ((ret = ff_get_buffer(avctx, pic, 0)) < 0)
|
if ((ret = ff_get_buffer(avctx, pic, 0)) < 0)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
|
do_vflip(avctx, pic, vflipped);
|
||||||
|
|
||||||
Y1 = pic->data[0];
|
Y1 = pic->data[0];
|
||||||
Y2 = pic->data[0] + pic->linesize[0];
|
Y2 = pic->data[0] + pic->linesize[0];
|
||||||
Y3 = pic->data[0] + pic->linesize[0] * 2;
|
Y3 = pic->data[0] + pic->linesize[0] * 2;
|
||||||
@@ -99,11 +141,14 @@ static int dxtory_decode_v1_410(AVCodecContext *avctx, AVFrame *pic,
|
|||||||
V += pic->linesize[2];
|
V += pic->linesize[2];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
do_vflip(avctx, pic, vflipped);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int dxtory_decode_v1_420(AVCodecContext *avctx, AVFrame *pic,
|
static int dxtory_decode_v1_420(AVCodecContext *avctx, AVFrame *pic,
|
||||||
const uint8_t *src, int src_size)
|
const uint8_t *src, int src_size,
|
||||||
|
uint32_t vflipped)
|
||||||
{
|
{
|
||||||
int h, w;
|
int h, w;
|
||||||
uint8_t *Y1, *Y2, *U, *V;
|
uint8_t *Y1, *Y2, *U, *V;
|
||||||
@@ -118,6 +163,8 @@ static int dxtory_decode_v1_420(AVCodecContext *avctx, AVFrame *pic,
|
|||||||
if ((ret = ff_get_buffer(avctx, pic, 0)) < 0)
|
if ((ret = ff_get_buffer(avctx, pic, 0)) < 0)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
|
do_vflip(avctx, pic, vflipped);
|
||||||
|
|
||||||
Y1 = pic->data[0];
|
Y1 = pic->data[0];
|
||||||
Y2 = pic->data[0] + pic->linesize[0];
|
Y2 = pic->data[0] + pic->linesize[0];
|
||||||
U = pic->data[1];
|
U = pic->data[1];
|
||||||
@@ -136,11 +183,14 @@ static int dxtory_decode_v1_420(AVCodecContext *avctx, AVFrame *pic,
|
|||||||
V += pic->linesize[2];
|
V += pic->linesize[2];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
do_vflip(avctx, pic, vflipped);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int dxtory_decode_v1_444(AVCodecContext *avctx, AVFrame *pic,
|
static int dxtory_decode_v1_444(AVCodecContext *avctx, AVFrame *pic,
|
||||||
const uint8_t *src, int src_size)
|
const uint8_t *src, int src_size,
|
||||||
|
uint32_t vflipped)
|
||||||
{
|
{
|
||||||
int h, w;
|
int h, w;
|
||||||
uint8_t *Y, *U, *V;
|
uint8_t *Y, *U, *V;
|
||||||
@@ -155,6 +205,8 @@ static int dxtory_decode_v1_444(AVCodecContext *avctx, AVFrame *pic,
|
|||||||
if ((ret = ff_get_buffer(avctx, pic, 0)) < 0)
|
if ((ret = ff_get_buffer(avctx, pic, 0)) < 0)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
|
do_vflip(avctx, pic, vflipped);
|
||||||
|
|
||||||
Y = pic->data[0];
|
Y = pic->data[0];
|
||||||
U = pic->data[1];
|
U = pic->data[1];
|
||||||
V = pic->data[2];
|
V = pic->data[2];
|
||||||
@@ -169,6 +221,8 @@ static int dxtory_decode_v1_444(AVCodecContext *avctx, AVFrame *pic,
|
|||||||
V += pic->linesize[2];
|
V += pic->linesize[2];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
do_vflip(avctx, pic, vflipped);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -270,7 +324,8 @@ static int dxtory_decode_v2(AVCodecContext *avctx, AVFrame *pic,
|
|||||||
const uint8_t *src, int src_size,
|
const uint8_t *src, int src_size,
|
||||||
decode_slice_func decode_slice,
|
decode_slice_func decode_slice,
|
||||||
setup_lru_func setup_lru,
|
setup_lru_func setup_lru,
|
||||||
enum AVPixelFormat fmt)
|
enum AVPixelFormat fmt,
|
||||||
|
uint32_t vflipped)
|
||||||
{
|
{
|
||||||
GetByteContext gb, gb_check;
|
GetByteContext gb, gb_check;
|
||||||
GetBitContext gb2;
|
GetBitContext gb2;
|
||||||
@@ -301,6 +356,8 @@ static int dxtory_decode_v2(AVCodecContext *avctx, AVFrame *pic,
|
|||||||
if ((ret = ff_get_buffer(avctx, pic, 0)) < 0)
|
if ((ret = ff_get_buffer(avctx, pic, 0)) < 0)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
|
do_vflip(avctx, pic, vflipped);
|
||||||
|
|
||||||
for (slice = 0; slice < nslices; slice++) {
|
for (slice = 0; slice < nslices; slice++) {
|
||||||
slice_size = bytestream2_get_le32(&gb);
|
slice_size = bytestream2_get_le32(&gb);
|
||||||
|
|
||||||
@@ -322,6 +379,8 @@ static int dxtory_decode_v2(AVCodecContext *avctx, AVFrame *pic,
|
|||||||
avpriv_request_sample(avctx, "Not enough slice data available");
|
avpriv_request_sample(avctx, "Not enough slice data available");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
do_vflip(avctx, pic, vflipped);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -379,19 +438,20 @@ static int dx2_decode_slice_565(GetBitContext *gb, AVFrame *frame,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int dxtory_decode_v2_565(AVCodecContext *avctx, AVFrame *pic,
|
static int dxtory_decode_v2_565(AVCodecContext *avctx, AVFrame *pic,
|
||||||
const uint8_t *src, int src_size, int is_565)
|
const uint8_t *src, int src_size, int is_565,
|
||||||
|
uint32_t vflipped)
|
||||||
{
|
{
|
||||||
enum AVPixelFormat fmt = AV_PIX_FMT_RGB24;
|
enum AVPixelFormat fmt = AV_PIX_FMT_RGB24;
|
||||||
if (is_565)
|
if (is_565)
|
||||||
return dxtory_decode_v2(avctx, pic, src, src_size,
|
return dxtory_decode_v2(avctx, pic, src, src_size,
|
||||||
dx2_decode_slice_565,
|
dx2_decode_slice_565,
|
||||||
setup_lru_565,
|
setup_lru_565,
|
||||||
fmt);
|
fmt, vflipped);
|
||||||
else
|
else
|
||||||
return dxtory_decode_v2(avctx, pic, src, src_size,
|
return dxtory_decode_v2(avctx, pic, src, src_size,
|
||||||
dx2_decode_slice_555,
|
dx2_decode_slice_555,
|
||||||
setup_lru_555,
|
setup_lru_555,
|
||||||
fmt);
|
fmt, vflipped);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int dx2_decode_slice_rgb(GetBitContext *gb, AVFrame *frame,
|
static int dx2_decode_slice_rgb(GetBitContext *gb, AVFrame *frame,
|
||||||
@@ -424,12 +484,13 @@ static void default_setup_lru(uint8_t lru[3][8])
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int dxtory_decode_v2_rgb(AVCodecContext *avctx, AVFrame *pic,
|
static int dxtory_decode_v2_rgb(AVCodecContext *avctx, AVFrame *pic,
|
||||||
const uint8_t *src, int src_size)
|
const uint8_t *src, int src_size,
|
||||||
|
uint32_t vflipped)
|
||||||
{
|
{
|
||||||
return dxtory_decode_v2(avctx, pic, src, src_size,
|
return dxtory_decode_v2(avctx, pic, src, src_size,
|
||||||
dx2_decode_slice_rgb,
|
dx2_decode_slice_rgb,
|
||||||
default_setup_lru,
|
default_setup_lru,
|
||||||
AV_PIX_FMT_BGR24);
|
AV_PIX_FMT_BGR24, vflipped);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int dx2_decode_slice_410(GetBitContext *gb, AVFrame *frame,
|
static int dx2_decode_slice_410(GetBitContext *gb, AVFrame *frame,
|
||||||
@@ -466,12 +527,13 @@ static int dx2_decode_slice_410(GetBitContext *gb, AVFrame *frame,
|
|||||||
|
|
||||||
|
|
||||||
static int dxtory_decode_v2_410(AVCodecContext *avctx, AVFrame *pic,
|
static int dxtory_decode_v2_410(AVCodecContext *avctx, AVFrame *pic,
|
||||||
const uint8_t *src, int src_size)
|
const uint8_t *src, int src_size,
|
||||||
|
uint32_t vflipped)
|
||||||
{
|
{
|
||||||
return dxtory_decode_v2(avctx, pic, src, src_size,
|
return dxtory_decode_v2(avctx, pic, src, src_size,
|
||||||
dx2_decode_slice_410,
|
dx2_decode_slice_410,
|
||||||
default_setup_lru,
|
default_setup_lru,
|
||||||
AV_PIX_FMT_YUV410P);
|
AV_PIX_FMT_YUV410P, vflipped);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int dx2_decode_slice_420(GetBitContext *gb, AVFrame *frame,
|
static int dx2_decode_slice_420(GetBitContext *gb, AVFrame *frame,
|
||||||
@@ -510,12 +572,13 @@ static int dx2_decode_slice_420(GetBitContext *gb, AVFrame *frame,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int dxtory_decode_v2_420(AVCodecContext *avctx, AVFrame *pic,
|
static int dxtory_decode_v2_420(AVCodecContext *avctx, AVFrame *pic,
|
||||||
const uint8_t *src, int src_size)
|
const uint8_t *src, int src_size,
|
||||||
|
uint32_t vflipped)
|
||||||
{
|
{
|
||||||
return dxtory_decode_v2(avctx, pic, src, src_size,
|
return dxtory_decode_v2(avctx, pic, src, src_size,
|
||||||
dx2_decode_slice_420,
|
dx2_decode_slice_420,
|
||||||
default_setup_lru,
|
default_setup_lru,
|
||||||
AV_PIX_FMT_YUV420P);
|
AV_PIX_FMT_YUV420P, vflipped);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int dx2_decode_slice_444(GetBitContext *gb, AVFrame *frame,
|
static int dx2_decode_slice_444(GetBitContext *gb, AVFrame *frame,
|
||||||
@@ -550,12 +613,13 @@ static int dx2_decode_slice_444(GetBitContext *gb, AVFrame *frame,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int dxtory_decode_v2_444(AVCodecContext *avctx, AVFrame *pic,
|
static int dxtory_decode_v2_444(AVCodecContext *avctx, AVFrame *pic,
|
||||||
const uint8_t *src, int src_size)
|
const uint8_t *src, int src_size,
|
||||||
|
uint32_t vflipped)
|
||||||
{
|
{
|
||||||
return dxtory_decode_v2(avctx, pic, src, src_size,
|
return dxtory_decode_v2(avctx, pic, src, src_size,
|
||||||
dx2_decode_slice_444,
|
dx2_decode_slice_444,
|
||||||
default_setup_lru,
|
default_setup_lru,
|
||||||
AV_PIX_FMT_YUV444P);
|
AV_PIX_FMT_YUV444P, vflipped);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
|
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,
|
|||||||
{
|
{
|
||||||
AVFrame *pic = data;
|
AVFrame *pic = data;
|
||||||
const uint8_t *src = avpkt->data;
|
const uint8_t *src = avpkt->data;
|
||||||
int ret;
|
uint32_t type;
|
||||||
|
int vflipped, ret;
|
||||||
|
|
||||||
if (avpkt->size < 16) {
|
if (avpkt->size < 16) {
|
||||||
av_log(avctx, AV_LOG_ERROR, "packet too small\n");
|
av_log(avctx, AV_LOG_ERROR, "packet too small\n");
|
||||||
return AVERROR_INVALIDDATA;
|
return AVERROR_INVALIDDATA;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (AV_RB32(src)) {
|
type = AV_RB32(src);
|
||||||
|
vflipped = !!(type & 0x20);
|
||||||
|
|
||||||
|
switch (type) {
|
||||||
|
case 0x01000021:
|
||||||
case 0x01000001:
|
case 0x01000001:
|
||||||
ret = dxtory_decode_v1_rgb(avctx, pic, src + 16, avpkt->size - 16,
|
ret = dxtory_decode_v1_rgb(avctx, pic, src + 16, avpkt->size - 16,
|
||||||
AV_PIX_FMT_BGR24, 3);
|
AV_PIX_FMT_BGR24, 3, vflipped);
|
||||||
break;
|
break;
|
||||||
|
case 0x01000029:
|
||||||
case 0x01000009:
|
case 0x01000009:
|
||||||
ret = dxtory_decode_v2_rgb(avctx, pic, src + 16, avpkt->size - 16);
|
ret = dxtory_decode_v2_rgb(avctx, pic, src + 16, avpkt->size - 16, vflipped);
|
||||||
break;
|
break;
|
||||||
|
case 0x02000021:
|
||||||
case 0x02000001:
|
case 0x02000001:
|
||||||
ret = dxtory_decode_v1_420(avctx, pic, src + 16, avpkt->size - 16);
|
ret = dxtory_decode_v1_420(avctx, pic, src + 16, avpkt->size - 16, vflipped);
|
||||||
break;
|
break;
|
||||||
|
case 0x02000029:
|
||||||
case 0x02000009:
|
case 0x02000009:
|
||||||
ret = dxtory_decode_v2_420(avctx, pic, src + 16, avpkt->size - 16);
|
ret = dxtory_decode_v2_420(avctx, pic, src + 16, avpkt->size - 16, vflipped);
|
||||||
break;
|
break;
|
||||||
|
case 0x03000021:
|
||||||
case 0x03000001:
|
case 0x03000001:
|
||||||
ret = dxtory_decode_v1_410(avctx, pic, src + 16, avpkt->size - 16);
|
ret = dxtory_decode_v1_410(avctx, pic, src + 16, avpkt->size - 16, vflipped);
|
||||||
break;
|
break;
|
||||||
|
case 0x03000029:
|
||||||
case 0x03000009:
|
case 0x03000009:
|
||||||
ret = dxtory_decode_v2_410(avctx, pic, src + 16, avpkt->size - 16);
|
ret = dxtory_decode_v2_410(avctx, pic, src + 16, avpkt->size - 16, vflipped);
|
||||||
break;
|
break;
|
||||||
|
case 0x04000021:
|
||||||
case 0x04000001:
|
case 0x04000001:
|
||||||
ret = dxtory_decode_v1_444(avctx, pic, src + 16, avpkt->size - 16);
|
ret = dxtory_decode_v1_444(avctx, pic, src + 16, avpkt->size - 16, vflipped);
|
||||||
break;
|
break;
|
||||||
|
case 0x04000029:
|
||||||
case 0x04000009:
|
case 0x04000009:
|
||||||
ret = dxtory_decode_v2_444(avctx, pic, src + 16, avpkt->size - 16);
|
ret = dxtory_decode_v2_444(avctx, pic, src + 16, avpkt->size - 16, vflipped);
|
||||||
break;
|
break;
|
||||||
|
case 0x17000021:
|
||||||
case 0x17000001:
|
case 0x17000001:
|
||||||
ret = dxtory_decode_v1_rgb(avctx, pic, src + 16, avpkt->size - 16,
|
ret = dxtory_decode_v1_rgb(avctx, pic, src + 16, avpkt->size - 16,
|
||||||
AV_PIX_FMT_RGB565LE, 2);
|
AV_PIX_FMT_RGB565LE, 2, vflipped);
|
||||||
break;
|
break;
|
||||||
|
case 0x17000029:
|
||||||
case 0x17000009:
|
case 0x17000009:
|
||||||
ret = dxtory_decode_v2_565(avctx, pic, src + 16, avpkt->size - 16, 1);
|
ret = dxtory_decode_v2_565(avctx, pic, src + 16, avpkt->size - 16, 1, vflipped);
|
||||||
break;
|
break;
|
||||||
|
case 0x18000021:
|
||||||
|
case 0x19000021:
|
||||||
case 0x18000001:
|
case 0x18000001:
|
||||||
case 0x19000001:
|
case 0x19000001:
|
||||||
ret = dxtory_decode_v1_rgb(avctx, pic, src + 16, avpkt->size - 16,
|
ret = dxtory_decode_v1_rgb(avctx, pic, src + 16, avpkt->size - 16,
|
||||||
AV_PIX_FMT_RGB555LE, 2);
|
AV_PIX_FMT_RGB555LE, 2, vflipped);
|
||||||
break;
|
break;
|
||||||
|
case 0x18000029:
|
||||||
|
case 0x19000029:
|
||||||
case 0x18000009:
|
case 0x18000009:
|
||||||
case 0x19000009:
|
case 0x19000009:
|
||||||
ret = dxtory_decode_v2_565(avctx, pic, src + 16, avpkt->size - 16, 0);
|
ret = dxtory_decode_v2_565(avctx, pic, src + 16, avpkt->size - 16, 0, vflipped);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
avpriv_request_sample(avctx, "Frame header %"PRIX32, AV_RB32(src));
|
avpriv_request_sample(avctx, "Frame header %"PRIX32, type);
|
||||||
return AVERROR_PATCHWELCOME;
|
return AVERROR_PATCHWELCOME;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user