#include #include #include #include #include #include #include #include #include #include #include "memalloc.h" #include "mfcapi.h" #include "ppapi.h" #define MEMALLOC_MODULE_PATH "/dev/memalloc" #define MAX_STREAM_BUFFER_SIZE (1024*1024) int fd_memalloc = -1; int lg_nCurWriteFrame = 0; OutFrameBuffer out_buffer; DWLLinearMem_t in_buffer; int alloc_input_buffer(void) { u32 pgsize = getpagesize(); MemallocParams params; DWLLinearMem_t *info = &in_buffer; int fd_mem; int size = MAX_STREAM_BUFFER_SIZE; fd_memalloc = open(MEMALLOC_MODULE_PATH, O_RDWR | O_SYNC); if (fd_memalloc == -1) { printf("Failed to open: %s\n", MEMALLOC_MODULE_PATH); return -1; } info->size = size; info->virtualAddress = MAP_FAILED; info->busAddress = 0; params.size = size; fd_mem = open("/dev/mem", O_RDWR | O_SYNC); if (fd_mem == -1) { printf("Failed to open: %s\n", "/dev/mem"); return -1; } /* get memory linear memory buffers */ ioctl(fd_memalloc, MEMALLOC_IOCXGETBUFFER, ¶ms); if (params.busAddress == 0) { printf("Memalloc: get buffer failure\n"); close(fd_mem); return -1; } info->busAddress = params.busAddress; //printf("busAddress=0x%x\n", params.busAddress); /* Map the bus address to virtual address */ info->virtualAddress = (u32 *) mmap(0, info->size, PROT_READ | PROT_WRITE, MAP_SHARED, fd_mem, params.busAddress); if (info->virtualAddress == MAP_FAILED) { close(fd_mem); return -1; } close(fd_mem); return 0; } int free_input_buffer(void) { ioctl(fd_memalloc, MEMALLOC_IOCSFREEBUFFER, &in_buffer.busAddress); close(fd_memalloc); munmap(in_buffer.virtualAddress, MAX_STREAM_BUFFER_SIZE); return 0; } unsigned long get_file_size(const char *path) { unsigned long filesize = -1; struct stat statbuff; if(stat(path, &statbuff) < 0){ return filesize; }else{ filesize = statbuff.st_size; } return filesize; } int hd_save_decoded_picture(char *output_file_name, char *pData, int nLen) { int nWriteLen; int fdOutput; if (lg_nCurWriteFrame == 0) fdOutput = open(output_file_name, O_WRONLY | O_CREAT | O_TRUNC | O_SYNC, S_IRUSR | S_IWUSR); else fdOutput = open(output_file_name, O_WRONLY | O_CREAT | O_APPEND | O_SYNC, S_IRUSR | S_IWUSR); if (fdOutput == -1) { printf("Open saved file failed\r\n"); return 0; } nWriteLen = write(fdOutput, pData, nLen); if (nWriteLen != nLen) { printf("Write data len less than requested\r\n"); } close(fdOutput); lg_nCurWriteFrame++; return nWriteLen; } static int get_stream_type(char *type_name) { if (!strcasecmp(type_name, "h264")) return RAW_STRM_TYPE_H264; else if (!strcasecmp(type_name, "mpeg2")) return RAW_STRM_TYPE_MP2; else if (!strcasecmp(type_name, "mp4")) return RAW_STRM_TYPE_MP4; else if (!strcasecmp(type_name, "rv30") || !strcasecmp(type_name, "rv40")) return RAW_STRM_TYPE_REAL; else if (!strcasecmp(type_name, "vc1")) return RAW_STRM_TYPE_VC1; else if (!strcasecmp(type_name, "jpeg")) return RAW_STRM_TYPE_JPEG; else if (!strcasecmp(type_name, "sor")) return RAW_STRM_TYPE_SOR; else if (!strcasecmp(type_name, "vp8")) return RAW_STRM_TYPE_VP8; else if (!strcasecmp(type_name, "vp6")) return RAW_STRM_TYPE_VP6; else if (!strcasecmp(type_name, "wmv3")) return RAW_STRM_TYPE_WMV3; else { printf("unsupported stream type.\n"); return -1; } } int main(int argc, char *argv[]) { int i, j; char filename[32]; MFCHandle *handle; int stream_type; int fd_stream = -1, fd_len = -1; int len; int ppenable = 0; int ppoutw, ppouth, ppformat; int framelen; int ret; if (argc != 5 && argc != 8) {/*/media/testfile/VC1/5.wmv.vbs /media/testfile/VC1/5.wmv.len vc1 /media/tmfcout/vc1.yuv*/ printf("Usage: %s stream_file len_file stream_type outputfile [ppoutw ppouth ppformat(0:RGB565 1:RGB32)].\n", argv[0]); return -1; } if ((stream_type = get_stream_type(argv[3])) < 0) return -1; again: alloc_input_buffer(); handle = mfc_init(stream_type); if (!handle) { printf("streamType %d mfc_init fail.\n", stream_type); } printf("handle=0x%x, instance=0x%x.\n", handle, handle->decInst); if (argc > 5) { ppenable = 1; char *endptr; ppoutw = strtoul(argv[5], &endptr, 10); ppouth = strtoul(argv[6], &endptr, 10); ppformat = strtoul(argv[7], &endptr, 10); mfc_pp_init(handle, ppoutw, ppouth, ppformat); } fd_stream = open(argv[1], O_RDWR); if (fd_stream == -1) { printf("open stream file %s fail.\n", argv[1]); goto end; } fd_len = open(argv[2], O_RDWR); if (fd_len == -1) { printf("open len file %s fail.\n", argv[2]); goto end; } while(read(fd_len, &len, 4) > 0) { printf("len %d.\n", len); read(fd_stream, in_buffer.virtualAddress, len); in_buffer.size = len; out_buffer.num = 0; struct timeval tm1, tm2; gettimeofday(&tm1, NULL); ret = mfc_decode(handle, &in_buffer, &out_buffer); gettimeofday(&tm2, NULL); /*printf("decode %d frame time %d us.\n", out_buffer.num, (tm2.tv_sec - tm1.tv_sec) * 1000000 + tm2.tv_usec - tm1.tv_usec); printf("%d,%d - %d,%d.ret=%d.\n", out_buffer.codedWidth, out_buffer.codedHeight, out_buffer.frameWidth, out_buffer.frameHeight, ret);*/ if (ppenable) { if (ppformat) framelen = out_buffer.frameWidth * out_buffer.frameHeight * 4; else framelen = out_buffer.frameWidth * out_buffer.frameHeight * 2; } else { framelen = out_buffer.frameWidth * out_buffer.frameHeight * 3 / 2; } for (j = 0; j < out_buffer.num; j++) { printf("frame %d saved.\n", lg_nCurWriteFrame); printf("outbuf 0x%x.%d.%d\n", out_buffer.buffer[j].pyVirAddress, out_buffer.frameWidth, out_buffer.frameHeight); hd_save_decoded_picture(argv[4], (char*) out_buffer.buffer[j].pyVirAddress, framelen); } } /* while(mfc_decode_eof(handle, &out_buffer)) { printf("frame %d saved.\n", lg_nCurWriteFrame); printf("outbuf 0x%x.\n", out_buffer.buffer[0].pyVirAddress); hd_save_decoded_picture(argv[4], (char*) out_buffer.buffer[0].pyVirAddress, framelen); } */ end: if (fd_stream > 0) close(fd_stream); if (fd_len > 0) close(fd_len); mfc_uninit(handle); free_input_buffer(); //goto again; return 0; }