void decode_jpeg(struct jpeg_t *jpeg) { if (!ve_open()) err(EXIT_FAILURE, "Can't open VE"); int input_size =(jpeg->data_len + 65535) & ~65535; uint8_t *input_buffer = ve_malloc(input_size); int output_size = ((jpeg->width + 31) & ~31) * ((jpeg->height + 31) & ~31); uint8_t *luma_output = ve_malloc(output_size); uint8_t *chroma_output = ve_malloc(output_size); memcpy(input_buffer, jpeg->data, jpeg->data_len); ve_flush_cache(input_buffer, jpeg->data_len); // activate MPEG engine void *ve_regs = ve_get(VE_ENGINE_MPEG, 0); // set restart interval writel(jpeg->restart_interval, ve_regs + VE_MPEG_JPEG_RES_INT); // set JPEG format set_format(jpeg, ve_regs); // set output buffers (Luma / Croma) writel(ve_virt2phys(luma_output), ve_regs + VE_MPEG_ROT_LUMA); writel(ve_virt2phys(chroma_output), ve_regs + VE_MPEG_ROT_CHROMA); // set size set_size(jpeg, ve_regs); // ?? writel(0x00000000, ve_regs + VE_MPEG_SDROT_CTRL); // input end writel(ve_virt2phys(input_buffer) + input_size - 1, ve_regs + VE_MPEG_VLD_END); // ?? writel(0x0000007c, ve_regs + VE_MPEG_CTRL); // set input offset in bits writel(0 * 8, ve_regs + VE_MPEG_VLD_OFFSET); // set input length in bits writel(jpeg->data_len * 8, ve_regs + VE_MPEG_VLD_LEN); // set input buffer writel(ve_virt2phys(input_buffer) | 0x70000000, ve_regs + VE_MPEG_VLD_ADDR); // set Quantisation Table set_quantization_tables(jpeg, ve_regs); // set Huffman Table writel(0x00000000, ve_regs + VE_MPEG_RAM_WRITE_PTR); set_huffman_tables(jpeg, ve_regs); // start writeb(0x0e, ve_regs + VE_MPEG_TRIGGER); // wait for interrupt ve_wait(1); // clean interrupt flag (??) writel(0x0000c00f, ve_regs + VE_MPEG_STATUS); // stop MPEG engine ve_put(); //output_ppm(stdout, jpeg, output, output + (output_buf_size / 2)); if (!disp_open()) { fprintf(stderr, "Can't open /dev/disp\n"); return; } int color; switch ((jpeg->comp[0].samp_h << 4) | jpeg->comp[0].samp_v) { case 0x11: case 0x21: color = COLOR_YUV422; break; case 0x12: case 0x22: default: color = COLOR_YUV420; break; } disp_set_para(ve_virt2phys(luma_output), ve_virt2phys(chroma_output), color, jpeg->width, jpeg->height, 0, 0, 800, 600); getchar(); disp_close(); ve_free(input_buffer); ve_free(luma_output); ve_free(chroma_output); ve_close(); }
void decode_mpeg(struct frame_buffers_t *frame_buffers, const struct mpeg_t * const mpeg) { int input_size = (mpeg->len + 65535) & ~65535; uint8_t *input_buffer = ve_malloc(input_size); memcpy(input_buffer, mpeg->data, mpeg->len); ve_flush_cache(input_buffer, mpeg->len); void *ve_regs = ve_get_regs(); // set quantisation tables set_quantization_tables(ve_regs, mpeg_default_intra_quant, mpeg_default_non_intra_quant); // set size uint16_t width = (mpeg->width + 15) / 16; uint16_t height = (mpeg->height + 15) / 16; writel(ve_regs + 0x100 + 0x08, (width << 8) | height); writel(ve_regs + 0x100 + 0x0c, ((width * 16) << 16) | (height * 16)); // set picture header uint32_t pic_header = 0x00000000; pic_header |= ((mpeg->picture_coding_type & 0xf) << 28); pic_header |= ((mpeg->f_code[0][0] & 0xf) << 24); pic_header |= ((mpeg->f_code[0][1] & 0xf) << 20); pic_header |= ((mpeg->f_code[1][0] & 0xf) << 16); pic_header |= ((mpeg->f_code[1][1] & 0xf) << 12); pic_header |= ((mpeg->intra_dc_precision & 0x3) << 10); pic_header |= ((mpeg->picture_structure & 0x3) << 8); pic_header |= ((mpeg->top_field_first & 0x1) << 7); pic_header |= ((mpeg->frame_pred_frame_dct & 0x1) << 6); pic_header |= ((mpeg->concealment_motion_vectors & 0x1) << 5); pic_header |= ((mpeg->q_scale_type & 0x1) << 4); pic_header |= ((mpeg->intra_vlc_format & 0x1) << 3); pic_header |= ((mpeg->alternate_scan & 0x1) << 2); pic_header |= ((mpeg->full_pel_forward_vector & 0x1) << 1); pic_header |= ((mpeg->full_pel_backward_vector & 0x1) << 0); writel(ve_regs + 0x100 + 0x00, pic_header); // ?? writel(ve_regs + 0x100 + 0x10, 0x00000000); // ?? writel(ve_regs + 0x100 + 0x14, 0x800001b8); // ?? writel(ve_regs + 0x100 + 0xc4, 0x00000000); // ?? writel(ve_regs + 0x100 + 0xc8, 0x00000000); // set forward/backward predicion buffers if (mpeg->picture_coding_type == PCT_I || mpeg->picture_coding_type == PCT_P) { frame_unref(frame_buffers->forward); frame_buffers->forward = frame_ref(frame_buffers->backward); frame_unref(frame_buffers->backward); frame_buffers->backward = frame_ref(frame_buffers->output); } writel(ve_regs + 0x100 + 0x50, ve_virt2phys(frame_buffers->forward->luma_buffer)); writel(ve_regs + 0x100 + 0x54, ve_virt2phys(frame_buffers->forward->chroma_buffer)); writel(ve_regs + 0x100 + 0x58, ve_virt2phys(frame_buffers->backward->luma_buffer)); writel(ve_regs + 0x100 + 0x5c, ve_virt2phys(frame_buffers->backward->chroma_buffer)); // set output buffers (Luma / Croma) writel(ve_regs + 0x100 + 0x48, ve_virt2phys(frame_buffers->output->luma_buffer)); writel(ve_regs + 0x100 + 0x4c, ve_virt2phys(frame_buffers->output->chroma_buffer)); writel(ve_regs + 0x100 + 0xcc, ve_virt2phys(frame_buffers->output->luma_buffer)); writel(ve_regs + 0x100 + 0xd0, ve_virt2phys(frame_buffers->output->chroma_buffer)); // set input offset in bits writel(ve_regs + 0x100 + 0x2c, (mpeg->pos - 4) * 8); // set input length in bits (+ little bit more, else it fails sometimes ??) writel(ve_regs + 0x100 + 0x30, (mpeg->len - (mpeg->pos - 4) + 16) * 8); // input end writel(ve_regs + 0x100 + 0x34, ve_virt2phys(input_buffer) + input_size - 1); // set input buffer writel(ve_regs + 0x100 + 0x28, ve_virt2phys(input_buffer) | 0x50000000); // trigger writel(ve_regs + 0x100 + 0x18, (mpeg->type ? 0x02000000 : 0x01000000) | 0x8000000f); // wait for interrupt ve_wait(1); // clean interrupt flag (??) writel(ve_regs + 0x100 + 0x1c, 0x0000c00f); ve_free(input_buffer); }