Cleanup IMX.6 decoder code

This commit is contained in:
Iwan Timmer
2016-01-17 13:25:53 +01:00
parent e2ac244053
commit bb8ddb8ebe
+56 -50
View File
@@ -50,6 +50,10 @@
#define MODE422 2 #define MODE422 2
#define MODE224 3 #define MODE224 3
#define THRESHOLD 2
#define MIN_FRAME_BUFFER_COUNT 18;
#define WORST_SLICE_SIZE 3188
struct v4l_buf { struct v4l_buf {
void *start; void *start;
off_t offset; off_t offset;
@@ -62,11 +66,14 @@ static vpu_mem_desc slice_mem_desc = {0};
static DecHandle handle = {0}; static DecHandle handle = {0};
static DecParam decparam = {0}; static DecParam decparam = {0};
static DecBufInfo bufinfo = {0};
static int fd; static int fd;
static int regfbcount, stride;
static bool initialized = false, decoding = false, displaying = false; static bool initialized = false, decoding = false, displaying = false;
static int queued_count, threshold; static int queued_count;
static int disp_clr_index = 0; static int disp_clr_index = 0;
static FrameBuffer *fb; static FrameBuffer *fb;
@@ -141,49 +148,13 @@ static void decoder_renderer_setup(int width, int height, int redrawRate, void*
decparam.skipframeMode = 0; decparam.skipframeMode = 0;
decparam.skipframeNum = 0; decparam.skipframeNum = 0;
decparam.iframeSearchEnable = 0; decparam.iframeSearchEnable = 0;
}
static int decoder_renderer_submit_decode_unit(PDECODE_UNIT decodeUnit) { regfbcount = MIN_FRAME_BUFFER_COUNT + 2;
PLENTRY entry = decodeUnit->bufferList; int picWidth = ((width + 15) & ~15);
while (entry != NULL) { int picHeight = ((height + 15) & ~15);
Uint32 space; stride = picWidth;
PhysicalAddress pa_read_ptr, pa_write_ptr;
if (vpu_DecGetBitstreamBuffer(handle, &pa_read_ptr, &pa_write_ptr, &space) != RETCODE_SUCCESS) {
fprintf(stderr, "Can't get video decoder buffer\n");
exit(EXIT_FAILURE);
}
Uint32 target_addr = mem_desc.virt_uaddr + (pa_write_ptr - mem_desc.phy_addr); int phy_slicebuf_size = WORST_SLICE_SIZE * 1024;
if ( (target_addr + entry->length) > mem_desc.virt_uaddr + STREAM_BUF_SIZE) {
int room = mem_desc.virt_uaddr + STREAM_BUF_SIZE - target_addr;
memcpy((void *)target_addr, entry->data, room);
memcpy((void *)mem_desc.virt_uaddr, entry->data + room, entry->length - room);
} else {
memcpy((void *)target_addr, entry->data, entry->length);
}
vpu_DecUpdateBitstreamBuffer(handle, entry->length);
entry = entry->next;
}
if (!initialized) {
initialized = true;
vpu_DecSetEscSeqInit(handle, 1);
DecInitialInfo initinfo = {0};
if (vpu_DecGetInitialInfo(handle, &initinfo) != RETCODE_SUCCESS) {
fprintf(stderr, "Can't get initial info\n");
exit(EXIT_FAILURE);
}
vpu_DecSetEscSeqInit(handle, 0);
int regfbcount = initinfo.minFrameBufferCount + 2;
threshold = regfbcount - initinfo.minFrameBufferCount;
int picWidth = ((initinfo.picWidth + 15) & ~15);
int picHeight = ((initinfo.picHeight + 15) & ~15);
int stride = picWidth;
int phy_slicebuf_size = initinfo.worstSliceSize * 1024;
slice_mem_desc.size = phy_slicebuf_size; slice_mem_desc.size = phy_slicebuf_size;
if (IOGetPhyMem(&slice_mem_desc)){ if (IOGetPhyMem(&slice_mem_desc)){
@@ -247,7 +218,8 @@ static int decoder_renderer_submit_decode_unit(PDECODE_UNIT decodeUnit) {
buf = calloc(1, sizeof(struct v4l_buf)); buf = calloc(1, sizeof(struct v4l_buf));
if (buf == NULL) { if (buf == NULL) {
return -9; fprintf(stderr, "Not enough memory\n");
exit(EXIT_FAILURE);
} }
buffers[i] = buf; buffers[i] = buf;
@@ -306,7 +278,6 @@ static int decoder_renderer_submit_decode_unit(PDECODE_UNIT decodeUnit) {
fb[i].bufMvCol = mvcol_md[i].phy_addr; fb[i].bufMvCol = mvcol_md[i].phy_addr;
} }
DecBufInfo bufinfo;
bufinfo.avcSliceBufInfo.bufferBase = slice_mem_desc.phy_addr; bufinfo.avcSliceBufInfo.bufferBase = slice_mem_desc.phy_addr;
bufinfo.avcSliceBufInfo.bufferSize = phy_slicebuf_size; bufinfo.avcSliceBufInfo.bufferSize = phy_slicebuf_size;
@@ -316,7 +287,44 @@ static int decoder_renderer_submit_decode_unit(PDECODE_UNIT decodeUnit) {
int delay = -1; int delay = -1;
vpu_DecGiveCommand(handle, DEC_SET_FRAME_DELAY, &delay); vpu_DecGiveCommand(handle, DEC_SET_FRAME_DELAY, &delay);
}
static int decoder_renderer_submit_decode_unit(PDECODE_UNIT decodeUnit) {
Uint32 space;
PhysicalAddress pa_read_ptr, pa_write_ptr;
if (vpu_DecGetBitstreamBuffer(handle, &pa_read_ptr, &pa_write_ptr, &space) != RETCODE_SUCCESS) {
fprintf(stderr, "Can't get video decoder buffer\n");
exit(EXIT_FAILURE);
}
Uint32 target_addr = mem_desc.virt_uaddr + (pa_write_ptr - mem_desc.phy_addr);
if (space < decodeUnit->fullLength) {
fprintf(stderr, "Not enough space in buffer %d/%d\n", decodeUnit->fullLength, space);
}
PLENTRY entry = decodeUnit->bufferList;
int written = 0;
while (entry != NULL) {
if ( (target_addr + entry->length) > mem_desc.virt_uaddr + STREAM_BUF_SIZE) {
int room = mem_desc.virt_uaddr + STREAM_BUF_SIZE - target_addr;
memcpy((void *)target_addr, entry->data, room);
memcpy((void *)mem_desc.virt_uaddr, entry->data + room, entry->length - room);
target_addr = mem_desc.virt_uaddr + entry->length - room;
} else {
memcpy((void *)target_addr, entry->data, entry->length);
target_addr += entry->length;
}
entry = entry->next;
}
vpu_DecUpdateBitstreamBuffer(handle, decodeUnit->fullLength);
if (!initialized) {
initialized = true;
DecInitialInfo info = {0};
vpu_DecSetEscSeqInit(handle, 1);
vpu_DecGetInitialInfo(handle, &info);
vpu_DecSetEscSeqInit(handle, 0);
if (vpu_DecRegisterFrameBuffer(handle, fb, regfbcount, stride, &bufinfo) != RETCODE_SUCCESS) { if (vpu_DecRegisterFrameBuffer(handle, fb, regfbcount, stride, &bufinfo) != RETCODE_SUCCESS) {
fprintf(stderr, "Can't register decoder to framebuffer\n"); fprintf(stderr, "Can't register decoder to framebuffer\n");
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
@@ -341,7 +349,6 @@ static int decoder_renderer_submit_decode_unit(PDECODE_UNIT decodeUnit) {
vpu_WaitForInt(100); vpu_WaitForInt(100);
loop_id++; loop_id++;
} }
loop_id = 0;
if (decoding) { if (decoding) {
decoding = 0; decoding = 0;
@@ -353,7 +360,7 @@ static int decoder_renderer_submit_decode_unit(PDECODE_UNIT decodeUnit) {
} }
if (outinfo.decodingSuccess & 0x10) { if (outinfo.decodingSuccess & 0x10) {
return 0; return DR_OK;
} else if (outinfo.notSufficientPsBuffer) { } else if (outinfo.notSufficientPsBuffer) {
fprintf(stderr, "Not enough space in stream buffer\n"); fprintf(stderr, "Not enough space in stream buffer\n");
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
@@ -394,7 +401,7 @@ static int decoder_renderer_submit_decode_unit(PDECODE_UNIT decodeUnit) {
queued_count++; queued_count++;
if (queued_count > threshold) { if (queued_count > THRESHOLD) {
dbuf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT; dbuf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
dbuf.memory = V4L2_MEMORY_MMAP; dbuf.memory = V4L2_MEMORY_MMAP;
if (ioctl(fd, VIDIOC_DQBUF, &dbuf) < 0) { if (ioctl(fd, VIDIOC_DQBUF, &dbuf) < 0) {
@@ -402,8 +409,7 @@ static int decoder_renderer_submit_decode_unit(PDECODE_UNIT decodeUnit) {
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} else } else
queued_count--; queued_count--;
} else }
dbuf.index = -1;
if (disp_clr_index >= 0) if (disp_clr_index >= 0)
vpu_DecClrDispFlag(handle, disp_clr_index); vpu_DecClrDispFlag(handle, disp_clr_index);
@@ -431,5 +437,5 @@ DECODER_RENDERER_CALLBACKS decoder_callbacks_imx = {
.setup = decoder_renderer_setup, .setup = decoder_renderer_setup,
.cleanup = decoder_renderer_cleanup, .cleanup = decoder_renderer_cleanup,
.submitDecodeUnit = decoder_renderer_submit_decode_unit, .submitDecodeUnit = decoder_renderer_submit_decode_unit,
.capabilities = CAPABILITY_DIRECT_SUBMIT, .capabilities = CAPABILITY_DIRECT_SUBMIT | CAPABILITY_SLICES_PER_FRAME(2),
}; };