add QOI encode/decode

This commit is contained in:
veejay
2023-09-25 01:38:40 +02:00
parent be6eee3cfe
commit 5730455b0b
8 changed files with 67 additions and 5 deletions

View File

@@ -48,6 +48,7 @@ static struct
{
{ "vj20", CODEC_ID_YUV420F },
{ "vj22", CODEC_ID_YUV422F },
{ "qoiy", CODEC_ID_QOI },
{ "mjpg" ,CODEC_ID_MJPEG },
{ "mjpb", CODEC_ID_MJPEGB },
{ "i420", CODEC_ID_YUV420 },

View File

@@ -235,6 +235,11 @@ lav_file_t *lav_open_output_file(char *filename, char format,
veejay_msg(VEEJAY_MSG_DEBUG, "\tWriting output file in AVI LZO (veejay's fourcc)");
sprintf(fourcc, "MLZO" );
break;
case 'o':
case 'O':
veejay_msg(VEEJAY_MSG_DEBUG, "\tWriting output file in AVI QOI");
sprintf(fourcc, "QOIY");
break;
case 'v':
veejay_msg(VEEJAY_MSG_DEBUG, "\tWriting output file in AVI VJ20 (veejay's fourcc)");
sprintf(fourcc,"VJ20");
@@ -399,6 +404,8 @@ long lav_bytes_remain( lav_file_t *lav_file )
case 'l':
case 'd':
case 'H':
case 'o':
case 'O':
return AVI_bytes_remain( lav_file->avi_fd );
default:
return -1;
@@ -435,6 +442,8 @@ int lav_write_frame(lav_file_t *lav_file, uint8_t *buff, long size, long count)
case 'Y':
case 'L':
case 'l':
case 'o':
case 'O':
case 'd':
case 'H':
if(n==0) {
@@ -1261,6 +1270,13 @@ lav_file_t *lav_open_input_file(char *filename, long mmap_size)
return lav_fd;
}
if( strncasecmp( video_comp, "qoiy", 4 ) == 0 )
{
lav_fd->MJPG_chroma = CHROMA422;
lav_fd->interlacing = LAV_NOT_INTERLACED;
return lav_fd;
}
if (strncasecmp(video_comp,"dvsd",4)==0 ||
strncasecmp(video_comp,"dvcp",4) ==0 ||
strncasecmp(video_comp,"dxsd",4) == 0 ||
@@ -1359,6 +1375,8 @@ const char *lav_strerror(void)
case 'M':
case 'P':
case 'L':
case 'o':
case 'O':
case 'D':
case 'H':
return AVI_strerror();

View File

@@ -40,6 +40,8 @@
#include <veejaycore/av.h>
#include <veejaycore/avhelper.h>
#include <veejaycore/avcommon.h>
#define QOI_IMPLEMENTATION 1
#include <libel/qoi.h>
#ifdef STRICT_CHECKING
#include <assert.h>
#endif
@@ -250,7 +252,7 @@ static vj_encoder *vj_avcodec_new_encoder( int id, VJFrame *frame, char *filenam
}
}
if(id != 998 && id != 999 && id != 900 && id != 997 && id != 996 && id != 995 && id != 994)
if(id != 998 && id != 999 && id != 900 && id != 997 && id != 996 && id != 995 && id != 994 && id != 993)
{
#ifdef __FALLBACK_LIBDV
if(id != CODEC_ID_DVVIDEO)
@@ -273,7 +275,7 @@ static vj_encoder *vj_avcodec_new_encoder( int id, VJFrame *frame, char *filenam
}
if( id != 998 && id != 999 && id!= 900 && id != 997 && id != 996 && id != CODEC_ID_DVVIDEO && id != 995 && id != 994 )
if( id != 998 && id != 999 && id!= 900 && id != 997 && id != 996 && id != CODEC_ID_DVVIDEO && id != 995 && id != 994 && id != 993)
{
#ifdef __FALLBACK_LIBDV
if(id != CODEC_ID_DVVIDEO )
@@ -450,6 +452,8 @@ int vj_avcodec_find_codec( int encoder )
return 996;
case ENCODER_LZO:
return 900;
case ENCODER_QOI:
return 993;
case ENCODER_YUV4MPEG:
return 995;
case ENCODER_YUV4MPEG420:
@@ -489,6 +493,8 @@ char vj_avcodec_find_lav( int encoder )
return 'v';
case ENCODER_LZO:
return 'L';
case ENCODER_QOI:
return 'o';
case ENCODER_YUV4MPEG:
case ENCODER_YUV4MPEG420:
return 'S';
@@ -514,6 +520,7 @@ static struct {
{ "YUV 4:2:2 Planar, CCIR 601. 16-235/16-240", ENCODER_YUV422 },
{ "YUV 4:2:0 Planar, CCIR 601, 16-235/16-240", ENCODER_YUV420 },
{ "YUV 4:2:2 Planar, LZO compressed (experimental)", ENCODER_LZO },
{ "QOI grayscale, QOI (experimental)", ENCODER_QOI },
{ "DIVX", ENCODER_DIVX },
{ "Quicktime DV", ENCODER_QUICKTIME_DV },
{ "Quicktime MJPEG", ENCODER_QUICKTIME_MJPEG },
@@ -717,6 +724,19 @@ int vj_avcodec_encode_frame(void *encoder, long nframe,int format, uint8_t *src
{
vj_encoder *av = (vj_encoder*) encoder;
if(format == ENCODER_QOI) {
int res = 0;
qoi_desc d;
d.channels = 1;
d.colorspace = QOI_LINEAR;
d.height = av->height;
d.width = av->width;
qoi_encode( src, &d, &res, buf, buf_len );
return res;
}
if(format == ENCODER_LZO )
return lzo_compress_frame( av->lzo, av->in_frame,src, buf );

View File

@@ -37,7 +37,8 @@
#define ENCODER_YUV4MPEG 13
#define ENCODER_YUV4MPEG420 14
#define ENCODER_HUFFYUV 15
#define NUM_ENCODERS 16
#define ENCODER_QOI 16
#define NUM_ENCODERS 17
typedef struct
{

View File

@@ -51,6 +51,7 @@
#include <libel/av.h>
#include <veejaycore/vj-task.h>
#include <veejaycore/lzo.h>
#include <libel/qoi.h>
#include <math.h>
#include <stdlib.h>
#include <sys/types.h>
@@ -71,6 +72,7 @@
#define CODEC_ID_YUV422 998
#define CODEC_ID_YUV422F 997
#define CODEC_ID_YUV420F 996
#define CODEC_ID_QOI 993
#define CODEC_ID_YUVLZO 900
#define DUMMY_FRAMES 2
#define RUP16(num)(((num)+16)&~16)
@@ -313,7 +315,7 @@ static vj_decoder *_el_new_decoder( void *ctx, int id , int width, int height, f
{
d->lzo_decoder = lzo_new( el_pixel_format_, el_width_, el_height_ , 1);
}
else if ( id == CODEC_ID_YUV422 || id == CODEC_ID_YUV420 || id == CODEC_ID_YUV420F || id == CODEC_ID_YUV422F ) {
else if ( id == CODEC_ID_YUV422 || id == CODEC_ID_YUV420 || id == CODEC_ID_YUV420F || id == CODEC_ID_YUV422F || id == CODEC_ID_QOI ) {
}
else if( ctx )
@@ -884,7 +886,19 @@ int vj_el_get_video_frame(editlist *el, long nframe, uint8_t *dst[4])
break;
case CODEC_ID_YUVLZO:
return lzo_decompress_el( d->lzo_decoder, data,res, dst, el_width_, el_height_, el_pixel_format_);
break;
break;
case CODEC_ID_QOI:
{
qoi_desc d;
d.channels = 1;
d.colorspace = QOI_LINEAR;
d.height = el_height_;
d.width = el_width_;
qoi_decode( data,res, &d, 1, dst, el_out_->len );
return 1;
}
break;
default:
{
int ret = avhelper_decode_video_direct( el->ctx[ N_EL_FILE(n) ], data, res, dst, el_pixel_format_,el_width_,el_height_ );
@@ -979,6 +993,9 @@ int test_video_frame( editlist *el, int n, lav_file_t *lav,int out_pix_fmt)
case CODEC_ID_YUV422F:
ret = PIX_FMT_YUVJ422P;
break;
case CODEC_ID_QOI:
ret = PIX_FMT_GRAY8;
break;
case CODEC_ID_YUV420:
ret = PIX_FMT_YUV420P;
break;

View File

@@ -169,6 +169,8 @@ static int sample_start_encoder(sample_info *si, VJFrame *frame, editlist *el, i
si->encoder_max_size = 2048 + tmp + tmp1 + tmp1;break;
case ENCODER_LZO:
si->encoder_max_size = (tmp * 3 ); break;
case ENCODER_QOI:
si->encoder_max_size = 2048 + tmp; break;
case ENCODER_DVVIDEO:
si->encoder_max_size = ( frame->height == 480 ? 120000: 144000); break;
default:

View File

@@ -1834,6 +1834,8 @@ static int vj_tag_start_encoder(vj_tag *tag, int format, long nframes)
tag->encoder_max_size = 2048 + tmp + (tmp/2) + (tmp/2);break;
case ENCODER_LZO:
tag->encoder_max_size = tmp * 3; break;
case ENCODER_QOI:
tag->encoder_max_size = 2048 + tmp; break;
default:
tag->encoder_max_size = vj_avcodec_get_buf_size(tag->encoder);
break;

View File

@@ -7134,6 +7134,7 @@ static struct {
int id;
} recorder_formats[] = {
{ "mlzo", ENCODER_LZO },
{ "qoiy" , ENCODER_QOI },
{ "y4m422", ENCODER_YUV4MPEG },
{ "y4m420", ENCODER_YUV4MPEG420 },
{ "yv16", ENCODER_YUV422 },