SceVideodec Hardware Decoder

NGS, codecs, MeP, hardware JPEG, PNG, streaming, etc.
Post Reply
Michael.d
Posts: 5
Joined: Tue Feb 07, 2017 7:56 am

SceVideodec Hardware Decoder

Post by Michael.d » Tue Feb 07, 2017 8:07 am

Hello.
I'm currently working with the videodec lib to try and become familiar with it to use in a few projects.
It seems quite different to other h.264 decompression libraries.

What i'm basically trying to achieve is to simply take an 'in-buffer' containing a h.264 encoded frame, and decode it into an 'out-buffer', which i can later manipulate and use however i'd like.
eg.
- pixel format conversion.
- image transformation.
- apply to a vita2d texture.

The issue i'm having is that sceAvcdecDecode will always fail, with numOfOutput equaling 0.
Most likely due to how i'm writing the procedure.
If anyone could help clear thing up for me that would be more than appreciated.

Code: Select all

int ret;
int DEC_BUFF_SIZE = 2 * 1024 * 1024;

char* outBuffer;
outBuffer = malloc(DEC_BUFF_SIZE);

SceAvcdecCtrl decoder = {0};
SceVideodecQueryInitInfoHwAvcdec init = {0};
init.size = sizeof(init);
init.horizontal = 960;
init.vertical = 544;
init.numOfRefFrames = 1;
init.numOfStreams = 1;

SceAvcdecQueryDecoderInfo decoder_info = {0};
decoder_info.horizontal = init.horizontal;
decoder_info.vertical = init.vertical;
decoder_info.numOfRefFrames = init.numOfRefFrames;

SceAvcdecDecoderInfo decoder_info_out = {0};

ret = sceVideodecInitLibrary(0x1001, &init);
//logcat_add("sceVideodecInitLibrary 0x%x\n", ret);

ret = sceAvcdecQueryDecoderMemSize(0x1001, &decoder_info, &decoder_info_out);
//logcat_add("sceAvcdecQueryDecoderMemSize 0x%x size 0x%x\n", ret, decoder_info_out.frameMemSize);

size_t sz = DEC_BUFF_SIZE;
decoder.frameBuf.size = sz;
//logcat_add("allocating size 0x%x\n", sz);

int decoderblock = sceKernelAllocMemBlock("decoder", SCE_KERNEL_MEMBLOCK_TYPE_USER_MAIN_PHYCONT_NC_RW, sz, NULL);
//logcat_add("decoderblock: 0x%08x\n", decoderblock);

sceKernelGetMemBlockBase(decoderblock, &decoder.frameBuf.pBuf);
//logcat_add("base: 0x%08x\n", decoder.frameBuf.pBuf);

ret = sceAvcdecCreateDecoder(0x1001, &decoder, &decoder_info);
//logcat_add("sceAvcdecCreateDecoder 0x%x\n", ret);



SceAvcdecAu au = {0};
SceAvcdecArrayPicture array_picture = {0};
SceAvcdecPicture picture = {0};

picture.size = sizeof(picture);
picture.frame.pixelType = 0;
picture.frame.framePitch = 960;
picture.frame.frameWidth = 960;
picture.frame.frameHeight = 544;
picture.frame.pPicture[0] = &outBuffer;

array_picture.numOfElm = 1;
array_picture.pPicture = &picture;

au.es.pBuf = inBuffer; // contains h.264 encoded frame
au.es.size = inBufferSize; // size of inBuffer (bytes)
au.dts.lower = 0xFFFFFFFF;
au.dts.upper = 0xFFFFFFFF;
au.pts.lower = 0xFFFFFFFF;
au.pts.upper = 0xFFFFFFFF;
//

ret = sceAvcdecDecode(&decoder, &au, &array_picture);
if (ret < 0) {
	return 0;
	logcat_add("sceAvcdecDecode (len=0x%x): 0x%x numOfOutput %d\n", inBufferSize, ret, array_picture.numOfOutput);
	}
return 1; // returning the size after decoding would be ideal

xyz
Posts: 8
Joined: Sun Jan 01, 2017 12:51 pm

Re: SceVideodec Hardware Decoder

Post by xyz » Wed Feb 08, 2017 10:53 am

why are you setting the size like that:

Code: Select all

size_t sz = DEC_BUFF_SIZE;
decoder.frameBuf.size = sz;
instead of:

Code: Select all

size_t sz = (decoder_info_out.frameMemSize + 0xFFFFF) & ~0xFFFFF;
decoder.frameBuf.size = sz;
what are your video properties? frame size/fps/refframes?

Michael.d
Posts: 5
Joined: Tue Feb 07, 2017 7:56 am

Re: SceVideodec Hardware Decoder

Post by Michael.d » Wed Feb 08, 2017 12:30 pm

Hi xyz, thanks for your reply.

To be honest, i set the size like that in an attempt to test if the issue was that decoder.frambuf.size was to small.
It was originally set to
(decoder_info_out.frameMemSize + 0xFFFFF) & ~0xFFFFF;


The video is a single frame only so it's properties are 1fps, 1rf, 960x544.
An example of an encoded frame can be found here.
https://drive.google.com/file/d/0B4N1_i ... sp=sharing

xyz
Posts: 8
Joined: Sun Jan 01, 2017 12:51 pm

Re: SceVideodec Hardware Decoder

Post by xyz » Thu Feb 09, 2017 12:37 pm

can you paste or better upload to github your full code and data that you are trying to play? are you trying to play that mp4 file? how are you demuxing it?

Michael.d
Posts: 5
Joined: Tue Feb 07, 2017 7:56 am

Re: SceVideodec Hardware Decoder

Post by Michael.d » Thu Feb 09, 2017 2:31 pm

xyz wrote:
Thu Feb 09, 2017 12:37 pm
can you paste or better upload to github your full code and data that you are trying to play? are you trying to play that mp4 file? how are you demuxing it?

The file i linked was encoded with a h.264 Image encoder i wrote (Windows) using libx264.
It's simply a dump of the encode buffer (nuls->p_payload if your familiar with libx264), no audio data.
If you open it in a supported media player you'll see the single frame/image.

This file is loaded into the 'inBuffer' shown in my original code posted above, and set via:

Code: Select all

au.es.pBuf = inBuffer; 

At the moment i'm just looking to decode a single frame then apply it to a vita2d texture, for such techniques as real-time scaling, movement/animation, rotation, etc.

I have only just started this SceVideodec lib test project, but have put it on hold until i can figure out why sceAvcdecDecode is unable to decode this single frame.

The encode setting should be fine for PS Vita, i'll past bellow the encoder log for the file i posted.

Code: Select all

Format                         : AVC
Format/Info                    : Advanced Video Codec
Format profile                 : Baseline@L3.1
Format settings, CABAC         : No
File size                      : 16.3 KiB
Duration                       : 500ms
Width                          : 960 pixels
Height                         : 544 pixels
Display aspect ratio           : 16:9
Frame rate                     : 1.000 fps
Overall bit rate               : 266 Kbps
Writing library                : x264 core 148 r2728

Encoding settings:
cabac 				= 0 
ref 				= 1 
deblock 			= 1:0:0 
analyse 			= 0x1:0x111 
me 				= hex 
subme 				= 6 
psy 				= 1 
psy_rd 				= 1.00:0.00 
mixed_ref 			= 0 
me_range 			= 16 
chroma_me 			= 1 
trellis 			= 1 
8x8dct 				= 0 
cqm 				= 0 
deadzone 			= 21,11 
fast_pskip 			= 1 
chroma_qp_offset 		= -2 
threads 			= 1 
lookahead_threads 		= 1 
sliced_threads			= 0 
nr 				= 0 
decimate 			= 1 
interlaced 			= 0 
constrained_intra 		= 0 
bframes 			= 0 
weightp 			= 0 
keyint 				= 1 
keyint_min 			= 1 
scenecut 			= 40 
intra_refresh 			= 0 
rc 				= crf 
mbtree 				= 0 
crf 				= 25.0 
qcomp 				= 0.60 
qpmin 				= 0 
qpmax 				= 69 
qpstep 				= 4 
ip_ratio 			= 1.40 
aq 				= 1:1.00

xyz
Posts: 8
Joined: Sun Jan 01, 2017 12:51 pm

Re: SceVideodec Hardware Decoder

Post by xyz » Thu Feb 09, 2017 6:17 pm

the other error i see is that you removed this part

Code: Select all

  SceAvcdecArrayPicture array_picture = {0};
  struct SceAvcdecPicture picture = {0};
  struct SceAvcdecPicture *pictures = { &picture };
  array_picture.numOfElm = 1;
  array_picture.pPicture = &pictures;
and instead do

Code: Select all

SceAvcdecArrayPicture array_picture = {0};
SceAvcdecPicture picture = {0};
// ...
array_picture.pPicture = &picture;
which is completely different... why?

Michael.d
Posts: 5
Joined: Tue Feb 07, 2017 7:56 am

Re: SceVideodec Hardware Decoder

Post by Michael.d » Fri Feb 10, 2017 4:22 am

xyz wrote:
Thu Feb 09, 2017 6:17 pm
the other error i see is that you removed this part

Code: Select all

  SceAvcdecArrayPicture array_picture = {0};
  struct SceAvcdecPicture picture = {0};
  struct SceAvcdecPicture *pictures = { &picture };
  array_picture.numOfElm = 1;
  array_picture.pPicture = &pictures;
and instead do

Code: Select all

SceAvcdecArrayPicture array_picture = {0};
SceAvcdecPicture picture = {0};
// ...
array_picture.pPicture = &picture;
which is completely different... why?


I've used:

Code: Select all

SceAvcdecPicture picture = {0};
as it is defined in the videodec header:

Code: Select all

typedef struct SceAvcdecPicture {
	uint32_t size;
	SceAvcdecFrame frame;
	SceAvcdecInfo info;
    } SceAvcdecPicture;
vita-moonlight defines this in /video/vita.c as:

Code: Select all

struct SceAvcdecPicture {
  uint32_t size;
  struct SceAvcdecFrame frame;
  struct SceAvcdecInfo info;
};
I did initially user the exact code from vita-moonlight, but i really don't like just copying and pasting code.
You never learn anything doing that.
I would rather come to understand how the library works.

I stripped down to:

Code: Select all

SceAvcdecArrayPicture array_picture = {0};
SceAvcdecPicture picture = {0};
array_picture.numOfElm = 1;
array_picture.pPicture = &picture;
as i am only decoding a single frame, not multiple.
Is this incorrect?


EDIT:
Thank you, by the way.
I really do appreciate your help.

xyz
Posts: 8
Joined: Sun Jan 01, 2017 12:51 pm

Re: SceVideodec Hardware Decoder

Post by xyz » Fri Feb 10, 2017 1:25 pm

yes that's incorrect

Michael.d
Posts: 5
Joined: Tue Feb 07, 2017 7:56 am

Re: SceVideodec Hardware Decoder

Post by Michael.d » Fri Feb 10, 2017 3:50 pm

xyz wrote:
Fri Feb 10, 2017 1:25 pm
yes that's incorrect
ok thank you.

Post Reply

Who is online

Users browsing this forum: No registered users and 1 guest