Add support for h264:yuv444p video format

This commit is contained in:
Alexander Guryanov
2021-09-17 13:52:05 +07:00
parent e82d3145d3
commit 3a13a9b78b
13 changed files with 129 additions and 192 deletions

View File

@@ -41,7 +41,7 @@ jobs:
--enable-swscale
--enable-zlib
--enable-demuxer=avi,rawvideo
--enable-decoder=png,rawvideo
--enable-decoder=png,rawvideo,h264
--enable-parser=png
--enable-protocol=file
--disable-d3d11va

View File

@@ -40,7 +40,7 @@ jobs:
--enable-swscale
--enable-zlib
--enable-demuxer=avi,rawvideo
--enable-decoder=png,rawvideo
--enable-decoder=png,rawvideo,h264
--enable-parser=png
--enable-protocol=file
--disable-d3d11va

View File

@@ -40,7 +40,7 @@ jobs:
--enable-swscale
--enable-zlib
--enable-demuxer=avi,rawvideo
--enable-decoder=png,rawvideo
--enable-decoder=png,rawvideo,h264
--enable-parser=png
--enable-protocol=file
--disable-d3d11va

View File

@@ -115,6 +115,7 @@ XGR_Screen::XGR_Screen(void)
XGR_ScreenSurface = NULL;
XGR_ScreenSurface2D = NULL;
XGR_ScreenSurface2DRgba = NULL;
XGR32_ScreenSurface = NULL;
sdlWindow = NULL;
sdlRenderer = NULL;
@@ -210,11 +211,9 @@ int XGR_Screen::init(int x,int y,int flags_in)
}
void XGR_Screen::create_surfaces(int width, int height) {
std::cout<<"XGR_ScreenSurface = SDL_CreateRGBSurface"<<std::endl;
XGR_ScreenSurface = new uint8_t[width * height] {0};
std::cout<<"XGR_ScreenSurface2D = SDL_CreateRGBSurface"<<std::endl;
XGR_ScreenSurface2D = new uint8_t[width * height] {0};
XGR_ScreenSurface2DRgba = new uint32_t[width * height] {0};
std::cout<<"XGR32_ScreenSurface = SDL_CreateRGBSurface"<<std::endl;
XGR32_ScreenSurface = SDL_CreateRGBSurface(0, width, height, 32, 0, 0, 0, 0);
@@ -286,12 +285,14 @@ void XGR_Screen::destroy_surfaces() {
delete[] XGR_ScreenSurface;
delete[] XGR_ScreenSurface2D;
delete[] XGR_ScreenSurface2DRgba;
SDL_FreeSurface(XGR32_ScreenSurface);
sdlTexture = nullptr;
HDBackgroundTexture = nullptr;
XGR_ScreenSurface = nullptr;
XGR_ScreenSurface2D = nullptr;
XGR_ScreenSurface2DRgba = nullptr;
XGR32_ScreenSurface = nullptr;
}
@@ -829,16 +830,23 @@ void XGR_Screen::close(void)
int UI_OR_GAME=1;
void XGR_Screen::blitRGBA(uint32_t *dst, uint8_t *screenPixels, uint8_t *overlayPixels) {
int x, y;
SDL_Color color;
void XGR_Screen::blitRgba(uint32_t *dstRgba, uint8_t *screenIndexes, uint32_t *screen2DRgba, uint8_t *screen2DIndexes) {
int x, y;
for (y = xgrScreenSizeY; y > 0; --y) {
for (x = xgrScreenSizeX; x > 0; --x) {
uint8_t colorIndex = *overlayPixels == 0 ? *screenPixels : *overlayPixels;
*(dst++) = XGR32_PaletteCache[colorIndex];
screenPixels++;
overlayPixels++;
if (*screen2DIndexes != 0) {
*dstRgba = XGR32_PaletteCache[*screen2DIndexes];
} else if (((uint8_t*)screen2DRgba)[3] != 0) {
*dstRgba = *screen2DRgba;
} else {
*dstRgba = XGR32_PaletteCache[*screenIndexes];
}
++dstRgba;
++screenIndexes;
++screen2DIndexes;
++screen2DRgba;
}
}
}
@@ -856,6 +864,10 @@ uint8_t* XGR_Screen::get_2d_render_buffer() {
return XGR_ScreenSurface2D;
}
uint32_t* XGR_Screen::get_2d_rgba_render_buffer() {
return XGR_ScreenSurface2DRgba;
}
void XGR_Screen::set_active_render_buffer(uint8_t *buf) {
ScreenBuf = (unsigned char*)buf;
}
@@ -908,7 +920,7 @@ void XGR_Screen::flip()
void *pixels;
int pitch;
SDL_LockTexture(sdlTexture, NULL, &pixels, &pitch);
blitRGBA((uint32_t*)pixels, XGR_ScreenSurface, XGR_ScreenSurface2D);
blitRgba((uint32_t*)pixels, XGR_ScreenSurface, XGR_ScreenSurface2DRgba, XGR_ScreenSurface2D);
SDL_UnlockTexture(sdlTexture);
SDL_RenderClear(sdlRenderer);
@@ -999,17 +1011,13 @@ void XGR_Screen::flush(int x,int y,int sx,int sy)
}*/
}
void XGR_Screen::fill(int col)
void XGR_Screen::fill(int col, void* buffer)
{
//int i;
//unsigned char* ptr = ScreenBuf;
memset(ScreenBuf, col, ScreenX*ScreenY);
/*for(i = 0; i < ScreenY; i ++){
ptr = ScreenBuf + yOffsTable[i];
memset(ptr,col,ScreenX);
}*/
if (buffer == XGR_ScreenSurface2DRgba) {
memset(XGR_ScreenSurface2DRgba, col, ScreenX * ScreenY * 4);
} else {
memset(buffer == NULL ? ScreenBuf : buffer, col, ScreenX * ScreenY);
}
}
void XGR_Screen::fill16(int col)

View File

@@ -136,7 +136,7 @@ struct XGR_Screen
void flush(int x,int y,int sx,int sy);
void flip();
void fill(int col);
void fill(int col, void* buffer = NULL);
void erase(int x,int y,int sx,int sy,int col);
void rectangle(int x,int y,int sx,int sy,int outcol,int incol,int mode);
@@ -173,13 +173,14 @@ struct XGR_Screen
void rectangle16(int x,int y,int sx,int sy,int outcol,int incol,int mode);
void blitRGBA(uint32_t *dst, uint8_t *screenPixels, uint8_t *overlayPixels);
void blitRgba(uint32_t *dstRgba, uint8_t *screenIndexes, uint32_t *screen2DRgba, uint8_t *screen2DIndexes);
void clear_2d_surface();
uint8_t* get_active_render_buffer();
uint8_t* get_default_render_buffer();
uint8_t* get_2d_render_buffer();
uint32_t* get_2d_rgba_render_buffer();
void set_default_render_buffer();
void set_2d_render_buffer();
@@ -196,6 +197,7 @@ private:
uint8_t *XGR_ScreenSurface;
uint8_t *XGR_ScreenSurface2D;
uint32_t *XGR_ScreenSurface2DRgba;
SDL_Surface *XGR32_ScreenSurface;
SDL_Surface *IconSurface;
@@ -223,7 +225,7 @@ private:
friend void Draw3DPlane(int x,int y,int size,int shift,unsigned char* buffer,int image,int y_offset);
friend void smart_putspr(unsigned char* data,int Xcenter,int Ycenter,int XsizeB,int YsizeB,int ScaleXsize,int height,unsigned char* color_table);
friend void CastShadow(int x,int y,int zg,int size,int shift,unsigned char* buffer);
friend void ibsout(int x,int y,void* ptr);
friend void ibsout(int x,int y,void* ptr,uint8_t* renderBuffer);
friend void put_map(int x,int y,int sx,int sy);
friend void i_get_scrfon(int x,int y,int sx,int sy,unsigned char* buf);
friend void i_put_scrfon(int x,int y,int sx,int sy,unsigned char* buf);

View File

@@ -50,18 +50,6 @@ void SoundStreamRelease(void *stream);
#define SoundStreamPlay(lpDSB, channel, priority, cropos, flags) SoundPlay(lpDSB, channel, priority, cropos, flags | DS_STREAM)
int AVIopen(char *filename, int flags, int channel, void **avi);
void AVIplay(void *avi,int x, int y);
void AVIstop(void *avi);
void AVIclose(void *avi);
int AVIwidth(void *avi);
int AVIheight(void *avi);
int AVIredraw(void *avi);
void AVIredraw(void *avi, int state);
void AVIdraw(void *avi);
void AVIGetData(void *avi, void *data);
void *AVIGetPalette(void *avi);
/* --------------------- CD Management --------------------- */
// xsGetStatusCD() return values...

View File

@@ -18,7 +18,6 @@ void FinitAVI(void);
void xtRegisterSysFinitFnc(void (*fPtr)(void),int id);
void xtUnRegisterSysFinitFnc(int id);
/* --------------------------- DEFINITION SECTION --------------------------- */
// compatability with newer libavcodec
@@ -122,13 +121,6 @@ int AVIFile::open(char* aviname, int initFlags, int channel)
if (flags & AVI_INTERPOLATE)
return 0; // XXX: add support for palettes
for (i = 0; i < 256; i++){
//gray
palette[i*3] = i >> 2;
palette[i*3 + 1] = i >> 2;
palette[i*3 + 2] = i >> 2;
}
released = redraw = x = y = 0;
if(flags & AVI_DRAW){
@@ -225,12 +217,6 @@ void AVIFile::draw(void) {
return; // Could not open codec
}
draw();
}else{
for (i = 0; i < 256; i++) {
palette[i*3] = pFrame->data[1][i*4+2] >> 2;
palette[i*3+1] = pFrame->data[1][i*4+1] >> 2;
palette[i*3+2] = pFrame->data[1][i*4] >> 2;
}
}
}
}
@@ -313,32 +299,61 @@ void AVIredraw(void *avi,int state)
((AVIFile *)avi) -> redraw = state;
}
void AVIdraw(void *avi)
void AVIPrepareFrame(void *avi)
{
((AVIFile *)avi) -> draw();
}
void AVIGetData(void *avi,void *data)
void AVIDrawFrame(void *avi, int offsetX, int offsetY, int lineWidth, uint32_t* rgba, float bright)
{
XCriticalSection critical(((AVIFile *)avi) -> avCriticalSection);
int xs = AVIwidth(avi);
int ys = AVIheight(avi);
int i, i2;
int width = AVIwidth(avi);
int height = AVIheight(avi);
bright = std::min(1.0f, bright);
if (((AVIFile *)avi)->pFrame)
for(i=0; i<ys; ++i){
for (i2=0;i2<xs;++i2){
((unsigned char *)data)[i*xs+i2]=
((unsigned char *)((AVIFile *)avi)->pFrame->data[0])[i*((AVIFile *)avi)->pFrame->linesize[0]+i2];
AVFrame* frame = ((AVIFile *) avi)->pFrame;
if (frame->format == AV_PIX_FMT_PAL8) {
for (int y = 0; y < height; ++y) {
for (int x = 0; x < width; ++x) {
int index = frame->data[0][y * frame->linesize[0] + x];
uint32_t* pixel = rgba + (y + offsetY) * lineWidth + x + offsetX;
*pixel = ((uint32_t *)frame->data[1])[index];
((uint8_t*) pixel)[3] = 255;
if (bright < 1) {
((uint8_t*) pixel)[0] *= bright;
((uint8_t*) pixel)[1] *= bright;
((uint8_t*) pixel)[2] *= bright;
}
}
}
}
} else if (frame->format == AV_PIX_FMT_YUV444P) {
for (int y = 0; y < height; ++y) {
for (int x = 0; x < width; ++x) {
uint8_t *pixel = (uint8_t*) (rgba + (y + offsetY) * lineWidth + x + offsetX);
void *AVIGetPalette(void *avi)
{
XCriticalSection critical(((AVIFile *)avi) -> avCriticalSection);
return ((AVIFile *)avi) -> palette;
double Y = frame->data[0][y * frame->linesize[0] + x];
double U = frame->data[1][y * frame->linesize[0] + x];
double V = frame->data[2][y * frame->linesize[0] + x];
double R = Y + + (U - 128) * 1.40200;
double G = Y + (V - 128) * -0.34414 + (U - 128) * -0.71414;
double B = Y + (V - 128) * 1.77200;
pixel[0] = std::max(std::min(R, 255.0), 0.0) * bright;
pixel[1] = std::max(std::min(G, 255.0), 0.0) * bright;
pixel[2] = std::max(std::min(B, 255.0), 0.0) * bright;
pixel[3] = 255;
}
}
} else {
static bool warn = true;
if (warn) {
printf("WARN! Video pixel format '%d' is not supported\n", frame->format);
printf("WARN! Video pixel format should be one of pal8, yuv444p\n");
warn = false;
}
}
}
void FinitAVI(void)

View File

@@ -39,8 +39,6 @@ struct AVIFile : XListElement
int redraw;
int released;
int flags;
unsigned char* color_table;
unsigned char palette[768];
std::string filename;
~AVIFile();
@@ -51,4 +49,16 @@ struct AVIFile : XListElement
void close(void);
};
int AVIopen(char *filename, int flags, int channel, void **avi);
void AVIplay(void *avi,int x, int y);
void AVIstop(void *avi);
void AVIclose(void *avi);
int AVIwidth(void *avi);
int AVIheight(void *avi);
int AVIredraw(void *avi);
void AVIredraw(void *avi, int state);
void AVIPrepareFrame(void *avi);
void AVIDrawFrame(void *avi, int offsetX, int offsetY, int lineWidth, uint32_t* rgba, float bright = 1.0);
#endif //__AVI_H__

View File

@@ -286,7 +286,8 @@ void a_buf_line(int x1,int y1,int x2,int y2,int col,int sx,int sy,unsigned char*
void a_buf_line2(int x1,int y1,int x2,int y2,int col,int sx,int sy,unsigned char* buf);
void a_buf_setpixel(int x,int y,int sx,int sy,int col,unsigned char* buf);
void ibsout(int x,int y,void* ptr);
void ibsout(int x, int y, void* ptr);
void ibsout(int x, int y, void* ptr, uint8_t *renderBuffer);
void change_screen(int scr);
@@ -1226,9 +1227,9 @@ void ibsObject::load(char* fname)
CenterY = PosY + SideY;
}
void ibsObject::show(void)
void ibsObject::show(uint8_t* renderBuffer)
{
ibsout(PosX,PosY,image);
ibsout(PosX, PosY, image, renderBuffer);
}
void ibsObject::show_bground(void)

View File

@@ -4502,12 +4502,12 @@ void aciDetectLeaks(void)
}
#endif
void ibsout(int x,int y,void* ptr)
void ibsout(int x,int y,void* ptr, uint8_t *renderBuffer)
{
int _x,_y,cnt;
int* offs_table = XGR_Obj.yOffsTable;
unsigned char* vbuf = XGR_VIDEOBUF;
unsigned char* vbuf = renderBuffer == NULL ? XGR_VIDEOBUF : renderBuffer;
unsigned char* pbuf = (unsigned char*)ptr;
cnt = *((int*)pbuf);
@@ -4526,6 +4526,11 @@ void ibsout(int x,int y,void* ptr)
}
}
void ibsout(int x,int y,void* ptr)
{
ibsout(x, y, ptr, NULL);
}
void aciPrepareMenus(void)
{

View File

@@ -788,6 +788,10 @@ int iQuantSecond(void)
if((k->type == SDL_KEYDOWN && k->key.keysym.scancode == SDL_SCANCODE_ESCAPE) && actIntLog){
iPause ^= 1;
acsScreenID = 2;
if (iPause) {
XGR_Obj.fill(0, XGR_Obj.get_2d_render_buffer());
XGR_Obj.fill(0, XGR_Obj.get_2d_rgba_render_buffer());
}
}
// if(k->type == SDL_KEYDOWN && k->key.keysym.scancode == SDL_SCANCODE_F11) {
@@ -1504,8 +1508,6 @@ void aciSwapMatrices(void)
put_map(iScreenOffs,0,I_RES_X,I_RES_Y);
aScrDisp -> curMatrix -> redraw();
iScrDisp -> curScr -> show_avi();
#ifdef _ACI_NO_SHOP_ANIMATION_
XGR_Flush(0,0,XGR_MAXX,XGR_MAXY);
#else
@@ -1616,8 +1618,6 @@ void aciCancelMatrix(void)
if(aScrDisp -> curMatrix)
aScrDisp -> curMatrix -> redraw();
iScrDisp -> curScr -> show_avi();
#ifdef _ACI_NO_SHOP_ANIMATION_
XGR_Flush(0,0,XGR_MAXX,XGR_MAXY);
#else
@@ -1710,8 +1710,6 @@ void aciShowScMatrix(void)
aScrDisp -> secondMatrix -> redraw();
iScrDisp -> curScr -> show_avi();
#ifdef _ACI_NO_SHOP_ANIMATION_
XGR_Flush(0,0,XGR_MAXX,XGR_MAXY);
#else

View File

@@ -16,6 +16,7 @@
#include "../actint/aci_scr.h"
#include "../sound/hsound.h"
#include "avi.h"
#ifndef _WIN32
#include <arpa/inet.h> // ntohl() FIXME: remove
@@ -641,7 +642,6 @@ iAVIElement::iAVIElement(void)
memset(avi_name, 0, sizeof(char));
border_shape_file = NULL;
palBuf = NULL;
ibs = NULL;
@@ -683,8 +683,7 @@ void iAVIElement::free_mem(void)
free();
if(border_shape_file)
delete border_shape_file;
//if(palBuf)
// delete palBuf;
free_shape();
}
@@ -723,9 +722,6 @@ void iAVIElement::free(void)
AVIstop(data);
AVIclose(data);
//delete palBuf;
palBuf = NULL;
flags ^= EL_DATA_LOADED;
}
}
@@ -734,7 +730,6 @@ void iAVIElement::load(void)
{
if(!(flags & EL_DATA_LOADED)){
flags &= ~AVI_STOPPED;
//palBuf = new unsigned char[768];
iResBuf -> init();
*iResBuf < iVideoPathDefault < avi_name;
@@ -751,11 +746,6 @@ void iAVIElement::load(void)
}
AVIplay(data,0,0);
//pal_tmp = (char*)AVIGetPalette(data);
palBuf=(unsigned char*)AVIGetPalette(data);
//memcpy(palBuf,pal_tmp,768);
//std::cout<<"iAVIElement::load"<<std::endl;
flags |= EL_DATA_LOADED;
}
}
@@ -1606,48 +1596,27 @@ void iScreenElement::redraw(int x,int y,int sc,int sm,int hide_mode)
put_fon(x,y,bsx,bsy,p1);
_iFREE_A_(unsigned char,p1,bsx * bsy);
break;
case I_AVI_ELEM://Draw video
if(((iAVIElement*)this) -> check_visible()){
_iALLOC_A_(unsigned char,p,SizeX * SizeY);
memset(p,0,SizeX * SizeY);
case I_AVI_ELEM: { // Draw video
fncMenu* menu = aScrDisp -> get_imenu(SHOP_ITEMS_MENU_ID);
uint8_t *screen = XGR_Obj.get_2d_render_buffer();
uint32_t *screenRgba = XGR_Obj.get_2d_rgba_render_buffer();
int offsetX = x + lX - iScreenOffs;
int offsetY = y + lY;
lev = (null_lev * abs(sc)) >> 8;
AVIdraw(((iAVIElement*)this) -> data);
AVIGetData(((iAVIElement*)this) -> data,p);
lev = (null_lev * abs(sc)) >> 8;
if(lev != null_lev){
i_pal_quant(((iAVIElement*)this) -> palBuf,lev,null_lev);
flags |= EL_PAL_CHANGE;
}
else {
if(flags & EL_PAL_CHANGE){
i_pal_quant(((iAVIElement*)this) -> palBuf,lev,null_lev);
flags ^= EL_PAL_CHANGE;
}
}
if (((iAVIElement *)this)->check_visible() && !(menu && menu->flags & FM_ACTIVE)) {
AVIPrepareFrame(((iAVIElement *)this)->data);
AVIDrawFrame(
((iAVIElement *)this)->data, offsetX, offsetY, xgrScreenSizeX, screenRgba, lev / 82.0f);
if(lev){
put_frame2scr(x + lX,y + lY,SizeX,SizeY,p);
if(((iAVIElement*)this) -> ibs)
((iAVIElement*)this) -> ibs -> show();
}
else {
memset(p,0,SizeX * SizeY);
put_buf2col(x + lX,y + lY,SizeX,SizeY,p,iAVI_NULL_LEV,1);
put_map(x + lX,y + lY,SizeX,SizeY);
if(((iAVIElement*)this) -> ibs)
((iAVIElement*)this) -> ibs -> show();
}
_iFREE_A_(unsigned char,p,SizeX * SizeY);
if (((iAVIElement *)this)->ibs)
((iAVIElement *)this)->ibs->show(screen);
} else {
XGR_Obj.fill(0, screen);
XGR_Obj.fill(0, screenRgba);
}
else {
_iALLOC_A_(unsigned char,p,SizeX * SizeY);
memset(p,0,SizeX * SizeY);
put_buf2col(x + lX,y + lY,SizeX,SizeY,p,iAVI_NULL_LEV,1);
_iFREE_A_(unsigned char,p,SizeX * SizeY);
}
break;
} break;
case I_AVI_BORDER_ELEM:
if(((iAVIBorderElement*)this) -> border_type == AVI_FLAT_BORDER){
_iALLOC_A_(unsigned char,p,SizeX * SizeY);
@@ -3624,7 +3593,6 @@ void iScreenDispatcher::aci_move_screen(int val,int time)
aScrDisp -> flags &= ~AS_FULL_FLUSH;
aScrDisp -> i_redraw();
aScrDisp -> i_flush();
curScr -> show_avi();
}
for(i = 0; i < time; i ++){
iScreenOffs += iScreenOffsDelta;
@@ -3732,8 +3700,6 @@ void iScreenDispatcher::move2screen(iScreen* p,int time)
show_screen(p);
flags |= (SD_GETFON | SD_END_GETFON);
redraw_quant();
p -> show_avi();
p -> hide_avi();
if(actIntLog)
aci_move_screen(delta,time);
@@ -3742,7 +3708,6 @@ void iScreenDispatcher::move2screen(iScreen* p,int time)
drwObjHeap -> init_list();
hide_screen(cp);
redraw_quant();
cp -> hide_avi_place();
}
drwObjHeap -> init_list();
if(p != cp)
@@ -3861,55 +3826,6 @@ int iAVIElement::check_visible(void)
return 1;
}
void iScreen::show_avi(void)
{
int sz;
iAVIElement* avi;
iScreenElement* el;
iScreenObject* obj = (iScreenObject*)objList -> last;
unsigned char* p;
while(obj){
if(obj -> flags & OBJ_AVI_PRESENT){
el = (iScreenElement*)obj -> ElementList -> last;
while(el){
if(el -> type == I_AVI_ELEM){
avi = (iAVIElement*)el;
sz = avi -> SizeX * avi -> SizeY;
_iALLOC_A_(unsigned char,p,sz);
memset(p,0,sz);
put_buf2col(obj -> PosX + avi -> lX,obj -> PosY + avi -> lY,avi -> SizeX,avi -> SizeY,p,iAVI_NULL_LEV,1);
_iFREE_A_(unsigned char,p,sz);
}
el = (iScreenElement*)el -> prev;
}
}
obj = (iScreenObject*)obj -> prev;
}
}
void iScreen::hide_avi(void)
{
iScreenObject* obj = (iScreenObject*)objList -> last;
while(obj){
if(obj -> flags & OBJ_AVI_PRESENT){
obj -> curHeightScale = 0;
}
obj = (iScreenObject*)obj -> prev;
}
}
void iScreen::hide_avi_place(void)
{
iScreenObject* obj = (iScreenObject*)objList -> last;
while(obj){
if(obj -> flags & OBJ_AVI_PRESENT){
obj -> curHeightScale = 0;
iregRender(obj -> PosX,obj -> PosY,obj -> PosX + obj -> SizeX,obj -> PosY + obj -> SizeY);
}
obj = (iScreenObject*)obj -> prev;
}
}
void iTriggerObject::init_state(void)
{
if (StateElem==NULL) {

View File

@@ -160,7 +160,7 @@ struct ibsObject : public iListElement
unsigned char* image;
void load(char* fname = NULL);
void show(void);
void show(uint8_t* renderBuffer = NULL);
void show_bground(void);
void free(void);
@@ -412,8 +412,6 @@ struct iAVIElement : public iScreenElement
ibsObject* ibs;
unsigned char* palBuf;
short ShSizeX;
short ShSizeY;
@@ -710,10 +708,6 @@ struct iScreen : public iListElement
void load_palette(void);
void free_palette(void);
void show_avi(void);
void hide_avi(void);
void hide_avi_place(void);
void load_data(void);
void free_data(void);
void getfon(void);