/****************************************************************************** * gst_tiprepencbuf_convert_gst_to_dmai * This function convert gstreamer buffer into DMAI graphics buffer. *****************************************************************************/ static Buffer_Handle gst_tiprepencbuf_convert_gst_to_dmai(GstTIPrepEncBuf * prepencbuf, GstBuffer * buf, gboolean reference) { BufferGfx_Attrs gfxAttrs = BufferGfx_Attrs_DEFAULT; Buffer_Handle hBuf = NULL; gfxAttrs.bAttrs.reference = reference; gfxAttrs.dim.width = prepencbuf->srcWidth; gfxAttrs.dim.height = prepencbuf->srcHeight; gfxAttrs.colorSpace = prepencbuf->srcColorSpace; gfxAttrs.dim.lineLength = BufferGfx_calcLineLength(gfxAttrs.dim.width, prepencbuf->srcColorSpace); hBuf = Buffer_create(GST_BUFFER_SIZE(buf), BufferGfx_getBufferAttrs(&gfxAttrs)); if (hBuf == NULL) { GST_ERROR("failed to create buffer\n"); return NULL; } Buffer_setUserPtr(hBuf, (Int8 *) GST_BUFFER_DATA(buf)); Buffer_setNumBytesUsed(hBuf, GST_BUFFER_SIZE(buf)); return hBuf; }
struct Array *Array_create( size_t data_size){ struct Array * array = calloc( sizeof( struct Array ), 1); array -> data_size = data_size; array -> used = 0; array -> buffer = Buffer_create(); return array; }
void write_depth_png_netstring(FILE *file) { Buffer *buffer = Buffer_create(); Image *image = Image_create(320, 240); Image_downsample(kinect_depth_image, image); if (Image_get_png(image, buffer)) { fprintf(file, "%lu:", buffer->size); Buffer_write(buffer, file); fputc(',', file); } Image_destroy(image); Buffer_destroy(buffer); }
/****************************************************************************** * Buffer_clone ******************************************************************************/ Buffer_Handle Buffer_clone(Buffer_Handle hBuf) { BufferGfx_Attrs gfxAttrs = BufferGfx_Attrs_DEFAULT; Buffer_Handle hNewBuf; Buffer_getAttrs(hBuf, BufferGfx_getBufferAttrs(&gfxAttrs)); hNewBuf = Buffer_create(hBuf->origState.numBytes, BufferGfx_getBufferAttrs(&gfxAttrs)); if (hNewBuf == NULL) { Dmai_err0("Failed to create new Buffer while cloning\n"); return NULL; } return hNewBuf; }
/****************************************************************************** * gst_ticircbuffer_new * Create a circular buffer to store an encoded input stream. Increasing * the number of windows stored in the buffer can help performance if * adequate memory is available. ******************************************************************************/ GstTICircBuffer* gst_ticircbuffer_new(Int32 windowSize, Int32 numWindows, Bool fixedBlockSize) { GstTICircBuffer *circBuf; Buffer_Attrs bAttrs = Buffer_Attrs_DEFAULT; Int32 bufSize; circBuf = (GstTICircBuffer*)gst_mini_object_new(GST_TYPE_TICIRCBUFFER); g_return_val_if_fail(circBuf != NULL, NULL); GST_INFO("requested windowSize: %ld\n", windowSize); circBuf->windowSize = windowSize; GST_INFO("fixed block size is %s\n", fixedBlockSize ? "ON" : "OFF"); circBuf->fixedBlockSize = fixedBlockSize; /* We need to have at least 2 windows allocated for us to be able * to copy buffer data while the consumer is running. */ if (numWindows < 3 && circBuf->fixedBlockSize != TRUE) { GST_ERROR("numWindows must be at least 3 when fixedBlockSize=FALSE"); return NULL; } /* Set the read ahead size to be 1/4 of a window */ circBuf->readAheadSize = (fixedBlockSize) ? 0 : windowSize >> 2; /* Allocate the circular buffer */ bufSize = (numWindows * windowSize) + (circBuf->readAheadSize << 1); GST_LOG("creating circular input buffer of size %lu\n", bufSize); circBuf->hBuf = Buffer_create(bufSize, &bAttrs); if (circBuf->hBuf == NULL) { GST_ERROR("failed to create buffer"); gst_object_unref(circBuf); return NULL; } circBuf->readPtr = circBuf->writePtr = Buffer_getUserPtr(circBuf->hBuf); return circBuf; }
int main(int argc, char *argv[]){ if (argc != 4){ printf("Incorrect use of the program...\n"); printf("You must input 3 arguments\n"); exit(EXIT_FAILURE); } // [name, clients, printers, buffer] int clientSize = atoi(argv[1]); int printerSize = atoi(argv[2]); int bufferSize = atoi(argv[3]); buffer = Buffer_create(bufferSize); int i; pthread_t clients[clientSize]; pthread_t printers[printerSize]; // create clients for (i=0;i<clientSize;i++){ pthread_create(&clients[i], NULL, clientThread, i); } // create printers for(i=0;i<printerSize;i++){ pthread_create(&printers[i], NULL, printerThread, i); } printf("Main Thread: Threads launched\n"); // for (i=0;i<clientSize;i++){ // pthread_join(clients[i], NULL); // } // for(i=0;i<printerSize;i++){ // pthread_join(printers[i], NULL); // } // printf("\nThreads are done\n"); pthread_exit(NULL); return EXIT_SUCCESS; }
/******************************************************************************* * gst_tidmaivideosink_render *******************************************************************************/ static GstFlowReturn gst_tidmaivideosink_render(GstBaseSink * bsink, GstBuffer * buf) { BufferGfx_Attrs gfxAttrs = BufferGfx_Attrs_DEFAULT; Buffer_Handle hDispBuf = NULL; Buffer_Handle inBuf = NULL; BufferGfx_Dimensions inDimSave; GstTIDmaiVideoSink *sink = GST_TIDMAIVIDEOSINK_CAST(bsink); GST_DEBUG("Begin, buffer %p",buf); /* The base sink send us the first buffer twice, so we avoid processing * it again, since the Display_put may fail on this case when using * pad_allocation */ if (sink->prerolledBuffer == buf){ GST_DEBUG("Not displaying previously pre-rolled buffer"); sink->prerolledBuffer = NULL; return GST_FLOW_OK; } sink->prerolledBuffer = NULL; /* If the input buffer is non dmai buffer, then allocate dmai buffer and * copy input buffer in dmai buffer using memcpy routine. */ if (GST_IS_TIDMAIBUFFERTRANSPORT(buf)) { inBuf = GST_TIDMAIBUFFERTRANSPORT_DMAIBUF(buf); } else { /* allocate DMAI buffer */ if (sink->tempDmaiBuf == NULL) { GST_DEBUG("Input buffer is non-dmai, allocating new buffer"); gfxAttrs.dim.width = sink->width; gfxAttrs.dim.height = sink->height; gfxAttrs.dim.lineLength = BufferGfx_calcLineLength(sink->width, sink->colorSpace); gfxAttrs.colorSpace = sink->colorSpace; sink->tempDmaiBuf = Buffer_create(GST_BUFFER_SIZE(buf), BufferGfx_getBufferAttrs(&gfxAttrs)); if (sink->tempDmaiBuf == NULL) { GST_ELEMENT_ERROR(sink,STREAM,FAILED,(NULL), ("Failed to allocate memory for the input buffer")); return GST_FLOW_UNEXPECTED; } } inBuf = sink->tempDmaiBuf; memcpy(Buffer_getUserPtr(inBuf), buf->data, buf->size); } if (Buffer_getBufTab(inBuf) == Display_getBufTab(sink->hDisplay)) { GST_DEBUG("Flipping pad allocated buffer"); /* We got a buffer that is already on video memory, just flip it */ hDispBuf = inBuf; if (sink->numAllocatedBuffers) sink->numAllocatedBuffers--; sink->allocatedBuffers[Buffer_getId(inBuf)] = NULL; if (buf == sink->lastAllocatedBuffer){ sink->lastAllocatedBuffer = NULL; } } else { /* Check if we can allocate a new buffer, otherwise we may need * to drop the buffer */ BufferGfx_getDimensions(inBuf, &inDimSave); if ((sink->numAllocatedBuffers >= (BufTab_getNumBufs(Display_getBufTab(sink->hDisplay)) - 1)) && (sink->numUnusedBuffers == 0)){ GST_ELEMENT_WARNING(sink,RESOURCE,NO_SPACE_LEFT,(NULL), ("Dropping incoming buffers because no display buffer" " available")); return GST_FLOW_OK; } else { GST_DEBUG("Obtaining display buffer"); hDispBuf = gst_tidmaivideosink_get_display_buffer(sink,inBuf); if (!hDispBuf){ return GST_FLOW_UNEXPECTED; } } if (Framecopy_config(sink->hFc, inBuf, hDispBuf) < 0) { GST_ELEMENT_ERROR(sink,STREAM,FAILED,(NULL), ("Failed to configure the frame copy")); return GST_FLOW_UNEXPECTED; } if (Framecopy_execute(sink->hFc, inBuf, hDispBuf) < 0) { GST_ELEMENT_ERROR(sink,STREAM,FAILED,(NULL), ("Failed to execute the frame copy")); return GST_FLOW_UNEXPECTED; } BufferGfx_resetDimensions(hDispBuf); BufferGfx_setDimensions(inBuf, &inDimSave); } /* Send filled buffer to display device driver to be displayed */ if (Display_put(sink->hDisplay, hDispBuf) < 0) { GST_ELEMENT_ERROR(sink,STREAM,FAILED,(NULL), ("Failed to put the buffer on display")); return GST_FLOW_UNEXPECTED; } GST_DEBUG("Finish"); return GST_FLOW_OK; }
/****************************************************************************** * speechThrFxn ******************************************************************************/ Void *speechThrFxn(Void *arg) { SpeechEnv *envp = (SpeechEnv *) arg; SPHDEC1_Params defaultParams = Sdec1_Params_DEFAULT; SPHDEC1_DynamicParams defaultDynParams = Sdec1_DynamicParams_DEFAULT; Void *status = THREAD_SUCCESS; Sound_Attrs sAttrs = Sound_Attrs_MONO_DEFAULT; Loader_Attrs lAttrs = Loader_Attrs_DEFAULT; Buffer_Attrs bAttrs = Buffer_Attrs_DEFAULT; Sdec1_Handle hSd1 = NULL; Sound_Handle hSound = NULL; Loader_Handle hLoader = NULL; Engine_Handle hEngine = NULL; Buffer_Handle hOutBuf = NULL; SPHDEC1_Params *params; SPHDEC1_DynamicParams *dynParams; Buffer_Handle hInBuf; /* Open the codec engine */ hEngine = Engine_open(envp->engineName, NULL, NULL); if (hEngine == NULL) { ERR("Failed to open codec engine %s\n", envp->engineName); cleanup(THREAD_FAILURE); } /* Create the sound device */ sAttrs.sampleRate = 8000; sAttrs.mode = Sound_Mode_OUTPUT; sAttrs.leftGain = 127; sAttrs.rightGain = 127; sAttrs.bufSize = 128; hSound = Sound_create(&sAttrs); if (hSound == NULL) { ERR("Failed to create audio device\n"); cleanup(THREAD_FAILURE); } /* Set the sample rate for the user interface */ gblSetSamplingFrequency(sAttrs.sampleRate); /* Use supplied params if any, otherwise use defaults */ params = envp->params ? envp->params : &defaultParams; dynParams = envp->dynParams ? envp->dynParams : &defaultDynParams; /* Create the speech decoder */ hSd1 = Sdec1_create(hEngine, envp->speechDecoder, params, dynParams); if (hSd1 == NULL) { ERR("Failed to create speech decoder: %s\n", envp->speechDecoder); cleanup(THREAD_FAILURE); } /* * Make the output buffer size twice the size of what the codec needs * as the codec needs mono and the Sound module converts the decoded * mono samples to stereo before writing to the device driver. */ hOutBuf = Buffer_create(OUTBUFSIZE, &bAttrs); if (hOutBuf == NULL) { ERR("Failed to allocate output buffer\n"); cleanup(THREAD_FAILURE); } /* How much encoded data to feed the codec each process call */ lAttrs.readSize = INBUFSIZE; /* Make the total ring buffer larger */ lAttrs.readBufSize = lAttrs.readSize * 512; /* Create the file loader for reading encoded data */ hLoader = Loader_create(envp->speechFile, &lAttrs); if (hLoader == NULL) { ERR("Failed to create loader\n"); cleanup(THREAD_FAILURE); } /* Signal that initialization is done and wait for other threads */ Rendezvous_meet(envp->hRendezvousInit); /* Prime the file loader */ Loader_prime(hLoader, &hInBuf); while (!gblGetQuit()) { /* Pause processing? */ Pause_test(envp->hPauseProcess); /* Decode the audio buffer */ if (Sdec1_process(hSd1, hInBuf, hOutBuf) < 0) { ERR("Failed to decode audio buffer\n"); cleanup(THREAD_FAILURE); } /* Increment statistics for user interface */ gblIncSoundBytesProcessed(Buffer_getNumBytesUsed(hInBuf)); /* * Force the output buffer size since we are forcing the size of the * output buffer allocated as opposed to asking the codec for a size. */ Buffer_setNumBytesUsed(hOutBuf, OUTBUFSIZE); /* Write the decoded samples to the sound device */ if (Sound_write(hSound, hOutBuf) < 0) { ERR("Failed to write audio buffer\n"); cleanup(THREAD_FAILURE); } /* Load a new frame from the file system */ if (Loader_getFrame(hLoader, hInBuf) < 0) { ERR("Failed to read a frame of encoded data\n"); cleanup(THREAD_FAILURE); } /* Check if the clip has ended */ if (Buffer_getUserPtr(hInBuf) == NULL) { /* Wait for the video clip to finish, if applicable */ Rendezvous_meet(envp->hRendezvousLoop); /* If we are to loop the clip, start over */ if (envp->loop) { /* Recreate the speech codec */ Sdec1_delete(hSd1); hSd1 = Sdec1_create(hEngine, envp->speechDecoder, params, dynParams); if (hSd1 == NULL) { ERR("Failed to create speech decoder: %s\n", envp->speechDecoder); cleanup(THREAD_FAILURE); } /* Re-prime the file loader */ Loader_prime(hLoader, &hInBuf); } else { printf("End of clip reached, exiting..\n"); cleanup(THREAD_SUCCESS); } } } cleanup: /* Make sure the other threads aren't waiting for us */ Rendezvous_force(envp->hRendezvousInit); Rendezvous_force(envp->hRendezvousLoop); Pause_off(envp->hPauseProcess); /* Meet up with other threads before cleaning up */ Rendezvous_meet(envp->hRendezvousCleanup); /* Clean up the thread before exiting */ if (hLoader) { Loader_delete(hLoader); } if (hSd1) { Sdec1_delete(hSd1); } if (hSound) { Sound_delete(hSound); } if (hOutBuf) { Buffer_delete(hOutBuf); } if (hEngine) { Engine_close(hEngine); } return status; }
/* Default implementation for _chain */ static GstFlowReturn gst_tidmai_base_video_dualencoder_default_realize_instance (GstTIDmaiBaseVideoDualEncoder *video_dualencoder, GstTIDmaiDualEncInstance *encoder_instance, GstBuffer *entry_buffer) { GST_DEBUG_OBJECT (video_dualencoder, "Entry gst_tidmai_base_video_dualencoder_default_realize_instance"); /* Only for test */ //GstClockTime time_start, time_start2, time_end, time_end2; //GstClockTimeDiff time_diff; Buffer_Attrs Attrs; Buffer_Handle outBufHandle; //Buffer_Attrs inAttrs; //Buffer_Handle inBufHandle; GstTIDmaiVideoInfo *video_info; UInt32 phys = 10; Bool isContiguous = FALSE; //time_start = gst_util_get_timestamp (); int ret; GstBuffer *buffer_push_out; /* Tests if the buffer */ phys = Memory_getBufferPhysicalAddress( GST_BUFFER_DATA(entry_buffer), GST_BUFFER_SIZE(entry_buffer), &isContiguous); if(phys == 0) { GST_ERROR_OBJECT (video_dualencoder, "Entry buffer isn't CMEM"); return GST_FLOW_NOT_SUPPORTED; } else { GST_DEBUG_OBJECT (video_dualencoder, "Using buffers with contiguos memory"); encoder_instance->input_buffer = entry_buffer; } /* Check for the output_buffer */ if (GST_TI_DMAI_BASE_DUALENCODER (video_dualencoder)->submitted_output_buffers == NULL) { video_info = (GstTIDmaiVideoInfo *) GST_TI_DMAI_BASE_DUALENCODER (video_dualencoder)->high_resolution_encoder->media_info; GST_TI_DMAI_BASE_DUALENCODER (video_dualencoder)->inBufSize = (video_info->width * video_info->height) * 1.8; if (GST_TI_DMAI_BASE_DUALENCODER (video_dualencoder)->outBufSize == 0) { /* Default value for the out buffer size */ GST_TI_DMAI_BASE_DUALENCODER (video_dualencoder)->outBufSize = GST_TI_DMAI_BASE_DUALENCODER (video_dualencoder)->inBufSize * 5; } /* Add the free memory slice to the list */ struct cmemSlice *slice = g_malloc0 (sizeof (struct cmemSlice)); slice->start = 0; slice->end = GST_TI_DMAI_BASE_DUALENCODER (video_dualencoder)->outBufSize; slice->size = GST_TI_DMAI_BASE_DUALENCODER (video_dualencoder)->outBufSize; #ifdef GLIB_2_31_AND_UP g_mutex_init(&(GST_TI_DMAI_BASE_DUALENCODER (video_dualencoder)->freeMutex)); #else GST_TI_DMAI_BASE_DUALENCODER (video_dualencoder)->freeMutex = g_mutex_new(); #endif GST_TI_DMAI_BASE_DUALENCODER (video_dualencoder)->freeSlices = g_list_append (GST_TI_DMAI_BASE_DUALENCODER (video_dualencoder)->freeSlices, slice); /* Allocate the circular buffer */ Attrs = Buffer_Attrs_DEFAULT; Attrs.useMask = gst_tidmaibuffertransport_GST_FREE; outBufHandle = Buffer_create(GST_TI_DMAI_BASE_DUALENCODER (video_dualencoder)->outBufSize, &Attrs); GST_TI_DMAI_BASE_DUALENCODER (video_dualencoder)->submitted_output_buffers = gst_tidmaibuffertransport_new(outBufHandle, NULL, NULL, FALSE); } /* Encode the actual buffer */ buffer_push_out = gst_tidmai_base_dualencoder_encode (GST_TI_DMAI_BASE_DUALENCODER (video_dualencoder), encoder_instance); gst_buffer_copy_metadata(buffer_push_out, entry_buffer, GST_BUFFER_COPY_FLAGS | GST_BUFFER_COPY_TIMESTAMPS); //time_end = gst_util_get_timestamp (); //time_diff = GST_CLOCK_DIFF (time_start, time_end); //g_print ("DualEncoder time: %" G_GUINT64_FORMAT " ns.\n", time_diff); /* push the buffer and check for any error */ //time_start2 = gst_util_get_timestamp (); GST_BUFFER_CAPS (buffer_push_out) = gst_caps_ref(GST_PAD_CAPS(encoder_instance->src_pad)); ret = gst_pad_push (encoder_instance->src_pad, buffer_push_out); //time_end2 = gst_util_get_timestamp (); //time_diff = GST_CLOCK_DIFF (time_start2, time_end2); //g_print ("\nPush time: %" G_GUINT64_FORMAT " ns.\n\n", time_diff); if (GST_FLOW_OK != ret) { GST_ERROR_OBJECT (video_dualencoder, "Push buffer return with error: %d", ret); } GST_DEBUG_OBJECT (video_dualencoder, "Leave gst_tidmai_base_video_dualencoder_default_realize_instance"); return ret; }
/****************************************************************************** * appMain ******************************************************************************/ Int appMain(Args * args) { VIDENC1_Params params = Venc1_Params_DEFAULT; VIDENC1_DynamicParams dynParams = Venc1_DynamicParams_DEFAULT; BufferGfx_Attrs gfxAttrs = BufferGfx_Attrs_DEFAULT; Buffer_Attrs bAttrs = Buffer_Attrs_DEFAULT; Time_Attrs tAttrs = Time_Attrs_DEFAULT; Venc1_Handle hVe1 = NULL; FILE *outFile = NULL; FILE *reconFile = NULL; FILE *inFile = NULL; Engine_Handle hEngine = NULL; Time_Handle hTime = NULL; Bool flushed = FALSE; Bool mustExit = FALSE; BufTab_Handle hBufTab = NULL; Buffer_Handle hOutBuf = NULL; Buffer_Handle hFreeBuf = NULL; Buffer_Handle hInBuf = NULL; Buffer_Handle hReconBuf = NULL; Int numFrame = 0; Int flushCntr = 1; Int bufIdx; Int inBufSize, outBufSize; Cpu_Device device; Int numBufs; ColorSpace_Type colorSpace; UInt32 time; Int ret = Dmai_EOK; printf("Starting application...\n"); /* Initialize the codec engine run time */ CERuntime_init(); /* Initialize DMAI */ Dmai_init(); /* Determine which device the application is running on */ if (Cpu_getDevice(NULL, &device) < 0) { ret = Dmai_EFAIL; fprintf(stderr,"Failed to determine target board\n"); goto cleanup; } if (args->benchmark) { hTime = Time_create(&tAttrs); if (hTime == NULL) { ret = Dmai_EFAIL; fprintf(stderr,"Failed to create Time object\n"); goto cleanup; } } /* Open the input file with raw yuv data */ inFile = fopen(args->inFile, "rb"); if (inFile == NULL) { ret = Dmai_EFAIL; fprintf(stderr,"Failed to open input file %s\n", args->inFile); goto cleanup; } /* Using a larger vbuf to enhance performance of file i/o */ if (setvbuf(inFile, vbufferIn, _IOFBF, sizeof(vbufferIn)) != 0) { ret = Dmai_EFAIL; fprintf(stderr,"Failed to setvbuf on input file descriptor\n"); goto cleanup; } /* Open the output file where to put encoded data */ outFile = fopen(args->outFile, "wb"); if (outFile == NULL) { ret = Dmai_EFAIL; fprintf(stderr,"Failed to open output file %s\n", args->outFile); goto cleanup; } /* Using a larger vbuf to enhance performance of file i/o */ if (setvbuf(outFile, vbufferOut, _IOFBF, sizeof(vbufferOut)) != 0) { ret = Dmai_EFAIL; fprintf(stderr,"Failed to setvbuf on output file descriptor\n"); goto cleanup; } /* Open the output file where to put reconstructed frames */ if (args->writeReconFrames) { reconFile = fopen(args->reconFile, "wb"); if (reconFile == NULL) { ret = Dmai_EFAIL; fprintf(stderr,"Failed to open output file %s\n", args->reconFile); goto cleanup; } /* Using a larger vbuf to enhance performance of file i/o */ if (setvbuf(reconFile, vbufferRecon, _IOFBF, sizeof(vbufferRecon)) != 0) { ret = Dmai_EFAIL; fprintf(stderr,"Failed to setvbuf on output file descriptor\n"); goto cleanup; } } /* Open the codec engine */ hEngine = Engine_open(args->engineName, NULL, NULL); if (hEngine == NULL) { ret = Dmai_EFAIL; fprintf(stderr,"Failed to open codec engine: %s\n", args->engineName); goto cleanup; } /* Set up codec parameters depending on bit rate */ if (args->bitRate < 0) { /* Variable bit rate */ params.rateControlPreset = IVIDEO_NONE; /* * If variable bit rate use a bogus bit rate value (> 0) * since it will be ignored. */ params.maxBitRate = 2000000; } else { /* Constant bit rate */ params.rateControlPreset = IVIDEO_LOW_DELAY; params.maxBitRate = args->bitRate; } /* Set up codec parameters depending on device */ switch (device) { case Cpu_Device_DM6467: params.inputChromaFormat = XDM_YUV_420SP; params.reconChromaFormat = XDM_CHROMA_NA; break; case Cpu_Device_DM355: params.inputChromaFormat = XDM_YUV_422ILE; params.reconChromaFormat = XDM_YUV_420P; break; case Cpu_Device_DM365: case Cpu_Device_DM368: params.inputChromaFormat = XDM_YUV_420SP; params.reconChromaFormat = XDM_YUV_420SP; break; case Cpu_Device_DM3730: params.rateControlPreset = IVIDEO_STORAGE; params.inputChromaFormat = XDM_YUV_422ILE; break; default: params.inputChromaFormat = XDM_YUV_422ILE; break; } params.maxWidth = args->width; params.maxHeight = args->height; /* Workaround for SDOCM00068944: h264fhdvenc fails to create codec when params.dataEndianness is set as XDM_BYTE */ if(device == Cpu_Device_DM6467) { if (!strcmp(args->codecName, "h264fhdvenc")) { params.dataEndianness = XDM_LE_32; } } params.maxInterFrameInterval = 1; dynParams.targetBitRate = params.maxBitRate; dynParams.inputWidth = params.maxWidth; dynParams.inputHeight = params.maxHeight; /* Create the video encoder */ hVe1 = Venc1_create(hEngine, args->codecName, ¶ms, &dynParams); if (hVe1 == NULL) { ret = Dmai_EFAIL; fprintf(stderr,"Failed to create video encoder: %s\n", args->codecName); goto cleanup; } /* Ask the codec how much input data it needs */ inBufSize = Venc1_getInBufSize(hVe1); /* Ask the codec how much space it needs for output data */ outBufSize = Venc1_getOutBufSize(hVe1); /* Which color space to use in the graphics buffers depends on the device */ colorSpace = ((device == Cpu_Device_DM6467)|| (device == Cpu_Device_DM365) || (device == Cpu_Device_DM368)) ? ColorSpace_YUV420PSEMI : ColorSpace_UYVY; /* Align buffers to cache line boundary */ gfxAttrs.bAttrs.memParams.align = bAttrs.memParams.align = BUFSIZEALIGN; /* Use cached buffers if requested */ if (args->cache) { gfxAttrs.bAttrs.memParams.flags = bAttrs.memParams.flags = Memory_CACHED; } gfxAttrs.dim.width = args->width; gfxAttrs.dim.height = args->height; if ((device == Cpu_Device_DM6467) || (device == Cpu_Device_DM365) || (device == Cpu_Device_DM368)) { gfxAttrs.dim.height = Dmai_roundUp(gfxAttrs.dim.height, CODECHEIGHTALIGN); } gfxAttrs.dim.lineLength = BufferGfx_calcLineLength(args->width, colorSpace); gfxAttrs.colorSpace = colorSpace; if (inBufSize < 0) { ret = Dmai_EFAIL; fprintf(stderr,"Failed to calculate buffer attributes\n"); goto cleanup; } /* Number of input buffers required */ if(params.maxInterFrameInterval>1) { /* B frame support */ numBufs = params.maxInterFrameInterval; } else { numBufs = 1; } /* Create a table of input buffers of the size requested by the codec */ hBufTab = BufTab_create(numBufs, Dmai_roundUp(inBufSize, BUFSIZEALIGN), BufferGfx_getBufferAttrs(&gfxAttrs)); if (hBufTab == NULL) { ret = Dmai_EFAIL; fprintf(stderr,"Failed to allocate contiguous buffers\n"); goto cleanup; } /* Set input buffer table */ Venc1_setBufTab(hVe1, hBufTab); /* Create the reconstructed frame buffer for raw yuv data */ if (args->writeReconFrames) { hReconBuf = Buffer_create(Dmai_roundUp(inBufSize, BUFSIZEALIGN), BufferGfx_getBufferAttrs(&gfxAttrs)); if (hReconBuf == NULL) { ret = Dmai_EFAIL; fprintf(stderr,"Failed to allocate contiguous buffer\n"); goto cleanup; } } /* Create the output buffer for encoded video data */ hOutBuf = Buffer_create(Dmai_roundUp(outBufSize, BUFSIZEALIGN), &bAttrs); if (hOutBuf == NULL) { ret = Dmai_EFAIL; fprintf(stderr,"Failed to create contiguous buffer\n"); goto cleanup; } while (1) { /* Get a buffer for input */ hInBuf = BufTab_getFreeBuf(hBufTab); if (hInBuf == NULL) { ret = Dmai_EFAIL; fprintf(stderr,"Failed to get a free contiguous buffer from BufTab\n"); BufTab_print(hBufTab); goto cleanup; } if (args->benchmark) { if (Time_reset(hTime) < 0) { ret = Dmai_EFAIL; fprintf(stderr,"Failed to reset timer\n"); goto cleanup; } } /* Read a yuv input frame */ printf("\n Frame %d: ", numFrame); if ((device == Cpu_Device_DM6467)|| (device == Cpu_Device_DM365) || (device == Cpu_Device_DM368)) { if(args->sp) { if (readFrame420SP(hInBuf, inFile, args->height) < 0) { ret = Dmai_EFAIL; goto cleanup; } } else { if (readFrame420P(hInBuf, inFile, args->height) < 0) { ret = Dmai_EFAIL; goto cleanup; } } } else { if (readFrameUYVY(hInBuf, inFile) < 0) { ret = Dmai_EFAIL; mustExit = TRUE; } } if (++numFrame == args->numFrames||mustExit == TRUE) { if(!(params.maxInterFrameInterval>1)) { /* No B-frame support */ printf("... exiting \n"); goto cleanup; } /* * When encoding a stream with B-frames, ending the processing * requires to free the buffer held by the encoder. This is done by * flushing the encoder and performing a last process() call * with a dummy input buffer. */ printf("\n... exiting with flush (B-frame stream) \n"); flushCntr = params.maxInterFrameInterval-1; flushed = TRUE; Venc1_flush(hVe1); } if (args->benchmark) { if (Time_delta(hTime, &time) < 0) { ret = Dmai_EFAIL; fprintf(stderr,"Failed to get timer delta\n"); goto cleanup; } printf("Read time: %uus\n", (Uns)time); } /* * Following flushing loop will iterate more than one time only * when the encoder completes processing by flushing the frames * held by the encoder. All flushed frames will be encoded as P * or I frames. */ for(bufIdx = 0; bufIdx < flushCntr; bufIdx++) { if (args->cache) { /* * To meet xDAIS DMA Rule 7, when input buffers are cached, we * must writeback the cache into physical memory. Also, per DMA * Rule 7, we must invalidate the output buffer from * cache before providing it to any xDAIS algorithm. */ Memory_cacheWbInv(Buffer_getUserPtr(hInBuf), Buffer_getSize(hInBuf)); /* Per DMA Rule 7, our output buffer cache lines must be cleaned */ Memory_cacheInv(Buffer_getUserPtr(hOutBuf), Buffer_getSize(hOutBuf)); if (args->benchmark) { if (Time_delta(hTime, &time) < 0) { ret = Dmai_EFAIL; fprintf(stderr,"Failed to get timer delta\n"); goto cleanup; } printf("Pre-process cache maintenance: %uus \n", (Uns) time); } } /* Make sure the whole buffer is used for input */ BufferGfx_resetDimensions(hInBuf); /* Encode the video buffer */ if (Venc1_process(hVe1, hInBuf, hOutBuf) < 0) { ret = Dmai_EFAIL; fprintf(stderr,"Failed to encode video buffer\n"); goto cleanup; } /* if encoder generated output content, free released buffer */ if (Buffer_getNumBytesUsed(hOutBuf)>0) { /* Get free buffer */ hFreeBuf = Venc1_getFreeBuf(hVe1); /* Free buffer */ BufTab_freeBuf(hFreeBuf); } /* if encoder did not generate output content */ else { /* if non B frame sequence */ /* encoder skipped frame probably exceeding target bitrate */ if (params.maxInterFrameInterval<=1) { /* free buffer */ printf(" Encoder generated 0 size frame\n"); BufTab_freeBuf(hInBuf); } } if (args->benchmark) { if (Time_delta(hTime, &time) < 0) { ret = Dmai_EFAIL; fprintf(stderr,"Failed to get encode time\n"); goto cleanup; } printf("[%d] Encode: %uus\n", numFrame, (Uns)time); } if (args->cache) { /* Writeback the outBuf. */ Memory_cacheWb(Buffer_getUserPtr(hOutBuf), Buffer_getSize(hOutBuf)); if (args->benchmark) { if (Time_delta(hTime, &time) < 0) { ret = Dmai_EFAIL; fprintf(stderr,"Failed to get timer delta\n"); goto cleanup; } printf("Post-process cache write back: %uus \n", (Uns) time); } } /* Write the encoded frame to the file system */ if (Buffer_getNumBytesUsed(hOutBuf)) { if (fwrite(Buffer_getUserPtr(hOutBuf), Buffer_getNumBytesUsed(hOutBuf), 1, outFile) != 1) { ret = Dmai_EFAIL; fprintf(stderr,"Failed to write encoded video data to file\n"); goto cleanup; } } /* Write the reconstructed frame to the file system */ if (args->writeReconFrames) { processReconData(Venc1_getReconBufs(hVe1), hInBuf, hReconBuf); if (Buffer_getNumBytesUsed(hReconBuf)) { if (fwrite(Buffer_getUserPtr(hReconBuf), Buffer_getNumBytesUsed(hReconBuf), 1, reconFile) != 1) { ret = Dmai_EFAIL; fprintf(stderr,"Failed to write reconstructed frame to file\n"); goto cleanup; } } } if (args->benchmark) { if (Time_delta(hTime, &time) < 0) { ret = Dmai_EFAIL; printf("Failed to get timer delta\n"); goto cleanup; } printf("File write time: %uus\n", (Uns)time); if (Time_total(hTime, &time) < 0) { ret = Dmai_EFAIL; fprintf(stderr,"Failed to get timer total\n"); goto cleanup; } printf("Total: %uus\n", (Uns)time); } } /* If the codec flushing completed, exit main thread */ if (flushed) { /* Free dummy input buffer used for flushing process() calls */ printf("freeing dummy input buffer ... \n"); BufTab_freeBuf(hInBuf); break; } } cleanup: /* Clean up the application */ if (hOutBuf) { Buffer_delete(hOutBuf); } if (hReconBuf) { Buffer_delete(hReconBuf); } if (hVe1) { Venc1_delete(hVe1); } if (hBufTab) { BufTab_delete(hBufTab); } if (hEngine) { Engine_close(hEngine); } if (inFile) { fclose(inFile); } if (outFile) { fclose(outFile); } if (reconFile) { fclose(reconFile); } if (hTime) { Time_delete(hTime); } printf("End of application.\n"); if (ret == Dmai_EFAIL) return 1; else return 0; }
/****************************************************************************** * appMain ******************************************************************************/ Void appMain(Args * args) { Buffer_Attrs bAttrs = Buffer_Attrs_DEFAULT; Time_Attrs tAttrs = Time_Attrs_DEFAULT; SPHENC1_Params params = Senc1_Params_DEFAULT; SPHENC1_DynamicParams dynParams = Senc1_DynamicParams_DEFAULT; Senc1_Handle hSe1 = NULL; Engine_Handle hEngine = NULL; Buffer_Handle hOutBuf = NULL; Buffer_Handle hInBuf = NULL; Time_Handle hTime = NULL; FILE *inFile = NULL; FILE *outFile = NULL; Int numFrame = 0; Int32 bytesRead; UInt32 time; printf("Starting application...\n"); if (args->benchmark) { hTime = Time_create(&tAttrs); if (hTime == NULL) { printf("Failed to create Time object\n"); goto cleanup; } } /* Initialize the codec engine run time */ CERuntime_init(); /* Initialize DMAI */ Dmai_init(); /* Open the output file */ outFile = fopen(args->outFile, "wb"); if (outFile == NULL) { printf("Failed to create output file %s\n", args->outFile); goto cleanup; } /* Open the input file */ inFile = fopen(args->inFile, "rb"); if (inFile == NULL) { printf("Failed to open input file %s\n", args->inFile); goto cleanup; } /* Using a larger vbuf to enhance performance of file i/o */ if (setvbuf(outFile, vbuffer, _IOFBF, sizeof(vbuffer)) != 0) { printf("Failed to setvbuf on file descriptor\n"); goto cleanup; } /* Open the codec engine */ hEngine = Engine_open(args->engineName, NULL, NULL); if (hEngine == NULL) { printf("Failed to open codec engine %s\n", args->engineName); goto cleanup; } params.compandingLaw = args->compandingLaw; /* Create the SPHENC1 based speech encoder */ hSe1 = Senc1_create(hEngine, args->codecName, ¶ms, &dynParams); if (hSe1 == NULL) { printf("Failed to create %s\n", args->codecName); goto cleanup; } /* Align buffers to cache line boundary */ bAttrs.memParams.align = BUFSIZEALIGN; /* Use cached buffers if requested */ if (args->cache) { bAttrs.memParams.flags = Memory_CACHED; } /* Create an output buffer for encoded data */ hOutBuf = Buffer_create( Dmai_roundUp(Senc1_getOutBufSize(hSe1), BUFSIZEALIGN), &bAttrs); if (hOutBuf == NULL) { printf("Failed to create contiguous buffer\n"); goto cleanup; } /* Create an input buffer for input data */ hInBuf = Buffer_create(Dmai_roundUp(Senc1_getInBufSize(hSe1), BUFSIZEALIGN), &bAttrs); if (hInBuf == NULL) { printf("Failed to create contiguous buffer\n"); goto cleanup; } while (numFrame++ < args->numFrames) { printf("Frame %d: ", numFrame); if (args->benchmark) { if (Time_reset(hTime) < 0) { printf("Failed to reset timer\n"); goto cleanup; } } /* Read raw PCM data from input file */ bytesRead = fread(Buffer_getUserPtr(hInBuf), 1, Senc1_getInBufSize(hSe1), inFile); if (bytesRead < Senc1_getInBufSize(hSe1)) { if (ferror(inFile)) { printf("Failed to read data from input file\n"); goto cleanup; } printf("Failed to read full frame %ld bytes, read %ld bytes\n", Senc1_getInBufSize(hSe1),bytesRead); goto cleanup; } Buffer_setNumBytesUsed(hInBuf, bytesRead); if (args->benchmark) { if (Time_delta(hTime, &time) < 0) { printf("Failed to get timer delta\n"); goto cleanup; } printf("Read: %uus ", (Uns) time); } if (args->cache) { /* * To meet xDAIS DMA Rule 7, when input buffers are cached, we * must writeback the cache into physical memory. Also, per DMA * Rule 7, we must invalidate the output buffer from * cache before providing it to any xDAIS algorithm. */ Memory_cacheWbInv(Buffer_getUserPtr(hInBuf), Buffer_getSize(hInBuf)); /* Per DMA Rule 7, our output buffer cache lines must be cleaned */ Memory_cacheInv(Buffer_getUserPtr(hOutBuf), Buffer_getSize(hOutBuf)); if (args->benchmark) { if (Time_delta(hTime, &time) < 0) { printf("Failed to get timer delta\n"); goto cleanup; } printf("Pre-process cache maintenance: %uus ", (Uns) time); } } /* Encode the speech buffer */ if (Senc1_process(hSe1, hInBuf, hOutBuf) < 0) { printf("Failed to encode speech buffer\n"); goto cleanup; } if (args->benchmark) { if (Time_delta(hTime, &time) < 0) { printf("Failed to get timer delta\n"); goto cleanup; } printf("Encode: %uus ", (Uns) time); } if (args->cache) { /* Writeback the outBuf. */ Memory_cacheWb(Buffer_getUserPtr(hOutBuf), Buffer_getSize(hOutBuf)); if (args->benchmark) { if (Time_delta(hTime, &time) < 0) { printf("Failed to get timer delta\n"); goto cleanup; } printf("Post-process cache write back: %uus ", (Uns) time); } } printf("Write encoded speech data to output file \n"); /* Write the encoded frame to the file system */ if (Buffer_getNumBytesUsed(hOutBuf)) { if (fwrite(Buffer_getUserPtr(hOutBuf), Buffer_getNumBytesUsed(hOutBuf), 1, outFile) != 1) { printf("Failed to write encoded speech data to file\n"); goto cleanup; } } if (args->benchmark) { if (Time_delta(hTime, &time) < 0) { printf("Failed to get timer delta\n"); goto cleanup; } printf("Write: %uus ", (Uns) time); if (Time_total(hTime, &time) < 0) { printf("Failed to get timer total\n"); goto cleanup; } printf("Total: %uus\n", (unsigned int)time); } } cleanup: /* Clean up the application */ if (hSe1) { Senc1_delete(hSe1); } if (hInBuf) { Buffer_delete(hInBuf); } if (hOutBuf) { Buffer_delete(hOutBuf); } if (hEngine) { Engine_close(hEngine); } if (hTime) { Time_delete(hTime); } if (inFile) { fclose(inFile); } if (outFile) { fclose(outFile); } printf("End of application.\n"); return; }
/****************************************************************************** * main ******************************************************************************/ Int appMain(Args * args) { Buffer_Attrs bAttrs = Buffer_Attrs_DEFAULT; Loader_Attrs lAttrs = Loader_Attrs_DEFAULT; AUDDEC1_Params params = Adec1_Params_DEFAULT; AUDDEC1_DynamicParams dynParams = Adec1_DynamicParams_DEFAULT; Time_Attrs tAttrs = Time_Attrs_DEFAULT; Adec1_Handle hAd1 = NULL; Loader_Handle hLoader = NULL; Engine_Handle hEngine = NULL; Buffer_Handle hOutBuf = NULL; Time_Handle hTime = NULL; Buffer_Handle hInBuf = NULL; FILE *outFile = NULL; Int numFrame = 0; UInt32 time; Int ret = Dmai_EOK; Cpu_Device device; printf("Starting application...\n"); if (args->benchmark) { hTime = Time_create(&tAttrs); if (hTime == NULL) { ret = Dmai_EFAIL; fprintf(stderr, "Failed to create Time object\n"); goto cleanup; } } /* Initialize the codec engine run time */ CERuntime_init(); /* Initialize DMAI */ Dmai_init(); /* Determine which device the application is running on */ if (Cpu_getDevice(NULL, &device) < 0) { ret = Dmai_EFAIL; fprintf(stderr, "Failed to determine target board\n"); goto cleanup; } /* Open the output file */ outFile = fopen(args->outFile, "wb"); if (outFile == NULL) { ret = Dmai_EFAIL; fprintf(stderr,"Failed to create output file %s\n", args->outFile); goto cleanup; } /* Using a larger vbuf to enhance performance of file i/o */ if (setvbuf(outFile, vbuffer, _IOFBF, sizeof(vbuffer)) != 0) { ret = Dmai_EFAIL; fprintf(stderr, "Failed to setvbuf on file descriptor\n"); goto cleanup; } /* Open the codec engine */ hEngine = Engine_open(args->engineName, NULL, NULL); if (hEngine == NULL) { ret = Dmai_EFAIL; fprintf(stderr, "Failed to open codec engine %s\n", args->engineName); goto cleanup; } if (device == Cpu_Device_DM365 || device == Cpu_Device_OMAP3530 || device == Cpu_Device_DM368 || device == Cpu_Device_DM3730) { params.dataEndianness = XDM_LE_16; } /* Create the AUDDEC1 based audio decoder */ hAd1 = Adec1_create(hEngine, args->codecName, ¶ms, &dynParams); if (hAd1 == NULL) { ret = Dmai_EFAIL; fprintf(stderr, "Failed to create audio decoder\n"); goto cleanup; } /* Align buffers to cache line boundary */ bAttrs.memParams.align = lAttrs.mParams.align = BUFSIZEALIGN; /* Use cached buffers if requested */ if (args->cache) { bAttrs.memParams.flags = lAttrs.mParams.flags = Memory_CACHED; } /* Ask the codec how much input data it needs */ lAttrs.readSize = Adec1_getInBufSize(hAd1); /* Make the total ring buffer larger */ lAttrs.readBufSize = Dmai_roundUp(lAttrs.readSize * 10, BUFSIZEALIGN); /* Increase the stdio buffer size for loader for better RTDX performance */ lAttrs.vBufSize = VBUFSIZE; /* Create the file loader */ hLoader = Loader_create(args->inFile, &lAttrs); if (hLoader == NULL) { ret = Dmai_EFAIL; fprintf(stderr, "Failed to create loader\n"); goto cleanup; } /* Create an output buffer for decoded data */ hOutBuf = Buffer_create( Dmai_roundUp(Adec1_getOutBufSize(hAd1), BUFSIZEALIGN), &bAttrs); if (hOutBuf == NULL) { ret = Dmai_EFAIL; fprintf(stderr, "Failed to create contiguous buffers\n"); goto cleanup; } /* Prime the file loader */ Loader_prime(hLoader, &hInBuf); while (numFrame++ < args->numFrames) { if (args->benchmark) { if (Time_reset(hTime) < 0) { ret = Dmai_EFAIL; fprintf(stderr, "Failed to reset timer\n"); goto cleanup; } } if (args->cache) { /* * To meet xDAIS DMA Rule 7, when input buffers are cached, we * must writeback the cache into physical memory. Also, per DMA * Rule 7, we must invalidate the output buffer from * cache before providing it to any xDAIS algorithm. */ Memory_cacheWbInv(Buffer_getUserPtr(hInBuf),Buffer_getSize(hInBuf)); /* Per DMA Rule 7, our output buffer cache lines must be cleaned */ Memory_cacheInv(Buffer_getUserPtr(hOutBuf),Buffer_getSize(hOutBuf)); if (args->benchmark) { if (Time_delta(hTime, &time) < 0) { ret = Dmai_EFAIL; fprintf(stderr,"Failed to get timer delta\n"); goto cleanup; } printf("Pre-process cache maintenance: %uus ", (Uns) time); } } /* Decode the audio buffer */ ret = Adec1_process(hAd1, hInBuf, hOutBuf); if ((ret == Dmai_EFAIL)|| (ret == Dmai_EBITERROR && Buffer_getNumBytesUsed(hInBuf) == 0)) { ret = Dmai_EFAIL; fprintf(stderr, "Failed to decode audio buffer\n"); goto cleanup; } if (args->benchmark) { if (Time_delta(hTime, &time) < 0) { ret = Dmai_EFAIL; fprintf(stderr, "Failed to get timer delta\n"); goto cleanup; } printf("Decode: %uus ", (Uns) time); } if (args->cache) { /* Writeback the outBuf. */ Memory_cacheWb(Buffer_getUserPtr(hOutBuf), Buffer_getSize(hOutBuf)); if (args->benchmark) { if (Time_delta(hTime, &time) < 0) { ret = Dmai_EFAIL; fprintf(stderr, "Failed to get timer delta\n"); goto cleanup; } printf("Post-process cache write back: %uus ", (Uns) time); } } /* Load a new frame from the file system */ Loader_getFrame(hLoader, hInBuf); if (args->benchmark) { if (Time_delta(hTime, &time) < 0) { ret = Dmai_EFAIL; fprintf(stderr,"Failed to get timer delta\n"); goto cleanup; } printf("Loader: %uus\n", (Uns) time); } if (Buffer_getNumBytesUsed(hOutBuf)) { if (numFrame >= args->startFrame) { printf("Frame %d: ", numFrame); if (writeFrame(hOutBuf, outFile) < 0) { ret = Dmai_EFAIL; goto cleanup; } } } if (Buffer_getUserPtr(hInBuf) == NULL) { printf("Loader returned null, clip finished\n"); break; } if (args->benchmark) { if (Time_total(hTime, &time) < 0) { ret = Dmai_EFAIL; fprintf(stderr,"Failed to get timer total\n"); goto cleanup; } printf("Total: %uus\n", (unsigned int)time); } } cleanup: /* Clean up the application */ if (hLoader) { Loader_delete(hLoader); } if (hAd1) { Adec1_delete(hAd1); } if (hOutBuf) { Buffer_delete(hOutBuf); } if (hEngine) { Engine_close(hEngine); } if (hTime) { Time_delete(hTime); } if (outFile) { fclose(outFile); } printf("End of application.\n"); if (ret == Dmai_EFAIL) return 1; else return 0; }
/****************************************************************************** * appMain ******************************************************************************/ Int appMain(Args * args) { IMGDEC1_Params params = Idec1_Params_DEFAULT; IMGDEC1_DynamicParams dynParams = Idec1_DynamicParams_DEFAULT; Buffer_Attrs bAttrs = Buffer_Attrs_DEFAULT; BufferGfx_Attrs gfxAttrs = BufferGfx_Attrs_DEFAULT; Time_Attrs tAttrs = Time_Attrs_DEFAULT; Idec1_Handle hId = NULL; Engine_Handle hEngine = NULL; Time_Handle hTime = NULL; Buffer_Handle hInBuf = NULL; Buffer_Handle hOutBuf = NULL; FILE *outFile = NULL; FILE *inFile = NULL; Int numBytes = 0; Int ret = Dmai_EOK; Cpu_Device device; UInt32 time; printf("Starting application...\n"); if (args->benchmark) { hTime = Time_create(&tAttrs); if (hTime == NULL) { ret = Dmai_EFAIL; fprintf(stderr,"Failed to create Time object\n"); goto cleanup; } } /* Initialize the codec engine run time */ CERuntime_init(); /* Initialize DMAI */ Dmai_init(); /* Determine which device the application is running on */ if (Cpu_getDevice(NULL, &device) < 0) { ret = Dmai_EFAIL; fprintf(stderr,"Failed to determine target board\n"); goto cleanup; } /* Open input file */ inFile = fopen(args->inFile, "rb"); if (inFile == NULL) { ret = Dmai_EFAIL; fprintf(stderr,"Failed to open file %s\n", args->inFile); goto cleanup; } /* Open output file */ outFile = fopen(args->outFile, "wb"); if (outFile == NULL) { ret = Dmai_EFAIL; fprintf(stderr,"Failed to create output file %s\n", args->outFile); goto cleanup; } /* Using a larger vbuf to enhance performance of file i/o */ if (setvbuf(outFile, vbuffer, _IOFBF, sizeof(vbuffer)) != 0) { ret = Dmai_EFAIL; fprintf(stderr,"Failed to setvbuf on file descriptor\n"); goto cleanup; } /* Open the codec engine */ hEngine = Engine_open(args->engineName, NULL, NULL); if (hEngine == NULL) { ret = Dmai_EFAIL; fprintf(stderr,"Failed to open codec engine %s\n", args->engineName); goto cleanup; } /* * Set output color format to UYVY or Planar output. * Here XDM_DEFUALT sets the output planar format to * the planar fromat of the encoded image. * */ switch (args->oColorSpace) { case ColorSpace_UYVY: params.forceChromaFormat = XDM_YUV_422ILE; break; case ColorSpace_NOTSET: params.forceChromaFormat = XDM_CHROMAFORMAT_DEFAULT; break; case ColorSpace_YUV444P: params.forceChromaFormat = XDM_YUV_444P; break; case ColorSpace_YUV422P: params.forceChromaFormat = XDM_YUV_422P; break; case ColorSpace_YUV420P: params.forceChromaFormat = XDM_YUV_420P; break; case ColorSpace_YUV420PSEMI: params.forceChromaFormat = XDM_YUV_420SP; break; case ColorSpace_GRAY: params.forceChromaFormat = ColorSpace_GRAY; break; default: ret = Dmai_EFAIL; fprintf(stderr,"Unsupported output color space %d.\n", args->oColorSpace); goto cleanup; } if ((device == Cpu_Device_DM365) || (device == Cpu_Device_DM368)) { params.maxHeight = VideoStd_720P_HEIGHT; params.maxWidth = VideoStd_720P_WIDTH; } if (device == Cpu_Device_DM6467) { params.maxHeight = VideoStd_720P_HEIGHT; params.maxWidth = VideoStd_720P_WIDTH; } /* Create the image decoder */ hId = Idec1_create(hEngine, args->codecName, ¶ms, &dynParams); if (hId == NULL) { ret = Dmai_EFAIL; fprintf(stderr,"Failed to create image decoder: %s\n", args->codecName); goto cleanup; } /* Align buffers to cache line boundary */ gfxAttrs.bAttrs.memParams.align = bAttrs.memParams.align = BUFSIZEALIGN; /* Use cached buffers if requested */ if (args->cache) { gfxAttrs.bAttrs.memParams.flags = bAttrs.memParams.flags = Memory_CACHED; } gfxAttrs.colorSpace = args->oColorSpace; gfxAttrs.dim.width = params.maxWidth; gfxAttrs.dim.height = params.maxHeight; gfxAttrs.dim.lineLength = BufferGfx_calcLineLength(params.maxWidth, gfxAttrs.colorSpace); /* Create an output buffer for decoded data */ hOutBuf = Buffer_create( Dmai_roundUp(Idec1_getOutBufSize(hId), BUFSIZEALIGN), BufferGfx_getBufferAttrs(&gfxAttrs)); if (hOutBuf == NULL) { ret = Dmai_EFAIL; fprintf(stderr,"Failed to create contiguous buffers\n"); goto cleanup; } /* Create an input buffer for encoded data */ hInBuf = Buffer_create(Dmai_roundUp(Idec1_getInBufSize(hId), BUFSIZEALIGN), &bAttrs); if (hInBuf == NULL) { ret = Dmai_EFAIL; fprintf(stderr,"Failed to create contiguous buffers\n"); goto cleanup; } /* Read encoded image data */ numBytes = fread(Buffer_getUserPtr(hInBuf), 1, Idec1_getInBufSize(hId), inFile); Buffer_setNumBytesUsed(hInBuf, numBytes); if (args->benchmark) { if (Time_reset(hTime) < 0) { ret = Dmai_EFAIL; fprintf(stderr,"Failed to reset timer\n"); goto cleanup; } } if (args->cache) { /* * To meet xDAIS DMA Rule 7, when input buffers are cached, we * must writeback the cache into physical memory. Also, per DMA * Rule 7, we must invalidate the output buffer from * cache before providing it to any xDAIS algorithm. */ Memory_cacheWbInv(Buffer_getUserPtr(hInBuf), Buffer_getSize(hInBuf)); /* Per DMA Rule 7, our output buffer cache lines must be cleaned */ Memory_cacheInv(Buffer_getUserPtr(hOutBuf), Buffer_getSize(hOutBuf)); if (args->benchmark) { if (Time_delta(hTime, &time) < 0) { ret = Dmai_EFAIL; fprintf(stderr,"Failed to get timer delta\n"); goto cleanup; } printf("Pre-process cache maintenance: %uus \n", (Uns) time); } } printf("Decoding image...\n"); /* Decode the image frame */ ret = Idec1_process(hId, hInBuf, hOutBuf); if (ret < 0) { ret = Dmai_EFAIL; fprintf(stderr,"Failed to decode image buffer\n"); goto cleanup; } if (args->benchmark) { if (Time_delta(hTime, &time) < 0) { ret = Dmai_EFAIL; fprintf(stderr,"Failed to get timer delta\n"); goto cleanup; } printf("Frame - Decode: %uus \n", (unsigned int)time); } if (args->cache) { /* Writeback the outBuf. */ Memory_cacheWb(Buffer_getUserPtr(hOutBuf), Buffer_getSize(hOutBuf)); if (args->benchmark) { if (Time_delta(hTime, &time) < 0) { ret = Dmai_EFAIL; fprintf(stderr,"Failed to get timer delta\n"); goto cleanup; } printf("Post-process cache write back: %uus ", (Uns) time); } } /* Write decoded image to a file */ if (BufferGfx_getColorSpace(hOutBuf) == ColorSpace_UYVY){ if (writeFrameUYVY(hOutBuf, outFile) < 0) { ret = Dmai_EFAIL; fprintf(stderr,"Failed to write image to file\n"); goto cleanup; } } else if (BufferGfx_getColorSpace(hOutBuf) == ColorSpace_YUV420PSEMI) { if (writeFrameSemiPlanar(hOutBuf, outFile) < 0) { ret = Dmai_EFAIL; fprintf(stderr,"Failed to write image to file\n"); goto cleanup; } } else if (BufferGfx_getColorSpace(hOutBuf) == ColorSpace_YUV420P || ColorSpace_YUV422P || ColorSpace_YUV444P || ColorSpace_GRAY){ /* For XDM_GRAY ignoring the color planes */ if (args->oColorSpace == ColorSpace_GRAY){ BufferGfx_setColorSpace (hOutBuf, ColorSpace_GRAY); } if (writeFramePlanar(hOutBuf, outFile) < 0) { ret = Dmai_EFAIL; fprintf(stderr,"Failed to write image to file\n"); goto cleanup; } } else { ret = Dmai_EFAIL; fprintf(stderr,"Invalid output colorspace.\n"); goto cleanup; } if (args->benchmark) { if (Time_total(hTime, &time) < 0) { ret = Dmai_EFAIL; fprintf(stderr,"Failed to get timer total\n"); goto cleanup; } printf("Total: %uus\n", (unsigned int)time); } cleanup: /* Clean up the application */ if (hId) { Idec1_delete(hId); } if (hInBuf) { Buffer_delete(hInBuf); } if (hOutBuf) { Buffer_delete(hOutBuf); } if (hEngine) { Engine_close(hEngine); } if (hTime) { Time_delete(hTime); } if (inFile) { fclose(inFile); } if (outFile) { fclose(outFile); } printf("End of application.\n"); if (ret == Dmai_EFAIL) return 1; else return 0; }
/****************************************************************************** * gst_ticircbuffer_get_data ******************************************************************************/ GstBuffer* gst_ticircbuffer_get_data(GstTICircBuffer *circBuf) { Buffer_Handle hCircBufWindow; Buffer_Attrs bAttrs; GstBuffer *result; Int32 bufSize; if (circBuf == NULL) { return NULL; } /* Reset our mutex condition so calling wait_on_consumer will block */ Rendezvous_reset(circBuf->waitOnProducer); /* Reset the read pointer to the beginning of the buffer when we're * approaching the buffer's end (see function definition for reset * conditions). */ gst_ticircbuffer_reset_read_pointer(circBuf); /* Don't return any data util we have a full window available */ while (!circBuf->drain && !gst_ticircbuffer_window_available(circBuf)) { GST_LOG("blocking output until a full window is available\n"); gst_ticircbuffer_wait_on_producer(circBuf); GST_LOG("unblocking output\n"); gst_ticircbuffer_reset_read_pointer(circBuf); /* Reset our mutex condition so calling wait_on_consumer will block */ Rendezvous_reset(circBuf->waitOnProducer); } /* Set the size of the buffer to be no larger than the window size. Some * audio codecs have an issue when you pass a buffer larger than 64K. * We need to pass it smaller buffer sizes though, as the EOS is detected * when we return a 0 size buffer. */ bufSize = gst_ticircbuffer_data_available(circBuf); if (bufSize > circBuf->windowSize) { bufSize = circBuf->windowSize; } /* Return a reference buffer that points to the area of the circular * buffer we want to decode. */ Buffer_getAttrs(circBuf->hBuf, &bAttrs); bAttrs.reference = TRUE; hCircBufWindow = Buffer_create(bufSize, &bAttrs); Buffer_setUserPtr(hCircBufWindow, circBuf->readPtr); Buffer_setNumBytesUsed(hCircBufWindow, bufSize); GST_LOG("returning data at offset %u\n", circBuf->readPtr - Buffer_getUserPtr(circBuf->hBuf)); result = (GstBuffer*)(gst_tidmaibuffertransport_new(hCircBufWindow, NULL)); GST_BUFFER_TIMESTAMP(result) = circBuf->dataTimeStamp; GST_BUFFER_DURATION(result) = GST_CLOCK_TIME_NONE; return result; }
/***************************************************************************** * gst_tidmaiaccel_prepare_output_buffer * Function is used to allocate output buffer *****************************************************************************/ static GstFlowReturn gst_tidmaiaccel_prepare_output_buffer (GstBaseTransform *trans, GstBuffer *inBuf, gint size, GstCaps *caps, GstBuffer **outBuf) { GstTIDmaiaccel *dmaiaccel = GST_TIDMAIACCEL(trans); Buffer_Handle hOutBuf; Bool isContiguous = FALSE; UInt32 phys = 0; /* Always check if the buffer is contiguous */ phys = Memory_getBufferPhysicalAddress( GST_BUFFER_DATA(inBuf), GST_BUFFER_SIZE(inBuf), &isContiguous); if (isContiguous && dmaiaccel->width){ GST_DEBUG("Is contiguous video buffer"); Memory_registerContigBuf((UInt32)GST_BUFFER_DATA(inBuf), GST_BUFFER_SIZE(inBuf),phys); /* This is a contiguous buffer, create a dmai buffer transport */ BufferGfx_Attrs gfxAttrs = BufferGfx_Attrs_DEFAULT; gfxAttrs.bAttrs.reference = TRUE; gfxAttrs.dim.width = dmaiaccel->width; gfxAttrs.dim.height = dmaiaccel->height; gfxAttrs.colorSpace = dmaiaccel->colorSpace; gfxAttrs.dim.lineLength = dmaiaccel->lineLength; hOutBuf = Buffer_create(GST_BUFFER_SIZE(inBuf), &gfxAttrs.bAttrs); BufferGfx_setDimensions(hOutBuf,&gfxAttrs.dim); BufferGfx_setColorSpace(hOutBuf,gfxAttrs.colorSpace); Buffer_setUserPtr(hOutBuf, (Int8*)GST_BUFFER_DATA(inBuf)); Buffer_setNumBytesUsed(hOutBuf, GST_BUFFER_SIZE(inBuf)); *outBuf = gst_tidmaibuffertransport_new(hOutBuf, NULL, NULL, FALSE); gst_buffer_set_data(*outBuf, (guint8*) Buffer_getUserPtr(hOutBuf), Buffer_getSize(hOutBuf)); gst_buffer_copy_metadata(*outBuf,inBuf,GST_BUFFER_COPY_ALL); gst_buffer_set_caps(*outBuf, GST_PAD_CAPS(trans->srcpad)); /* We need to grab a reference to the input buffer since we have * a pointer to his buffer */ gst_buffer_ref(inBuf); gst_tidmaibuffertransport_set_release_callback( (GstTIDmaiBufferTransport *)*outBuf, dmaiaccel_release_cb,inBuf); return GST_FLOW_OK; } else { GST_DEBUG("Copying into contiguous video buffer"); /* This is a contiguous buffer, create a dmai buffer transport */ if (!dmaiaccel->bufTabAllocated){ /* Initialize our buffer tab */ BufferGfx_Attrs gfxAttrs = BufferGfx_Attrs_DEFAULT; gfxAttrs.dim.width = dmaiaccel->width; gfxAttrs.dim.height = dmaiaccel->height; gfxAttrs.colorSpace = dmaiaccel->colorSpace; gfxAttrs.dim.lineLength = dmaiaccel->lineLength; dmaiaccel->hOutBufTab = BufTab_create(2, GST_BUFFER_SIZE(inBuf), BufferGfx_getBufferAttrs(&gfxAttrs)); pthread_mutex_init(&dmaiaccel->bufTabMutex, NULL); pthread_cond_init(&dmaiaccel->bufTabCond, NULL); if (dmaiaccel->hOutBufTab == NULL) { GST_ELEMENT_ERROR(dmaiaccel,RESOURCE,NO_SPACE_LEFT,(NULL), ("failed to create output buffer tab")); return GST_FLOW_ERROR; } dmaiaccel->bufTabAllocated = TRUE; } pthread_mutex_lock(&dmaiaccel->bufTabMutex); hOutBuf = BufTab_getFreeBuf(dmaiaccel->hOutBufTab); if (hOutBuf == NULL) { GST_INFO("Failed to get free buffer, waiting on bufTab\n"); pthread_cond_wait(&dmaiaccel->bufTabCond, &dmaiaccel->bufTabMutex); hOutBuf = BufTab_getFreeBuf(dmaiaccel->hOutBufTab); if (hOutBuf == NULL) { GST_ELEMENT_ERROR(dmaiaccel,RESOURCE,NO_SPACE_LEFT,(NULL), ("failed to get a free contiguous buffer from BufTab")); pthread_mutex_unlock(&dmaiaccel->bufTabMutex); return GST_FLOW_ERROR; } } pthread_mutex_unlock(&dmaiaccel->bufTabMutex); memcpy(Buffer_getUserPtr(hOutBuf),GST_BUFFER_DATA(inBuf), GST_BUFFER_SIZE(inBuf)); Buffer_setNumBytesUsed(hOutBuf, GST_BUFFER_SIZE(inBuf)); *outBuf = gst_tidmaibuffertransport_new(hOutBuf, &dmaiaccel->bufTabMutex, &dmaiaccel->bufTabCond, FALSE); gst_buffer_set_data(*outBuf, (guint8*) Buffer_getUserPtr(hOutBuf), Buffer_getSize(hOutBuf)); gst_buffer_copy_metadata(*outBuf,inBuf,GST_BUFFER_COPY_ALL); gst_buffer_set_caps(*outBuf, GST_PAD_CAPS(trans->srcpad)); return GST_FLOW_OK; } }
/****************************************************************************** * appMain ******************************************************************************/ Void appMain(Args * args) { VIDENC_Params params = Venc_Params_DEFAULT; VIDENC_DynamicParams dynParams = Venc_DynamicParams_DEFAULT; BufferGfx_Attrs gfxAttrs = BufferGfx_Attrs_DEFAULT; Buffer_Attrs bAttrs = Buffer_Attrs_DEFAULT; Time_Attrs tAttrs = Time_Attrs_DEFAULT; Venc_Handle hVe = NULL; FILE *outFile = NULL; FILE *inFile = NULL; Engine_Handle hEngine = NULL; Time_Handle hTime = NULL; Int numFrame = 0; Buffer_Handle hOutBuf = NULL; Buffer_Handle hInBuf = NULL; ColorSpace_Type colorSpace; UInt32 time; printf("Starting application...\n"); /* Initialize the codec engine run time */ CERuntime_init(); /* Initialize DMAI */ Dmai_init(); if (args->benchmark) { hTime = Time_create(&tAttrs); if (hTime == NULL) { printf("Failed to create Time object\n"); goto cleanup; } } /* Open input file */ inFile = fopen(args->inFile, "rb"); if (inFile == NULL) { printf("Failed to open input file %s\n", args->inFile); goto cleanup; } /* Using a larger vbuf to enhance performance of file i/o */ if (setvbuf(inFile, vbufferIn, _IOFBF, sizeof(vbufferIn)) != 0) { printf("Failed to setvbuf on input file descriptor\n"); goto cleanup; } /* Open output file */ outFile = fopen(args->outFile, "wb"); if (outFile == NULL) { printf("Failed to open output file %s\n", args->outFile); goto cleanup; } /* Using a larger vbuf to enhance performance of file i/o */ if (setvbuf(outFile, vbufferOut, _IOFBF, sizeof(vbufferOut)) != 0) { printf("Failed to setvbuf on output file descriptor\n"); goto cleanup; } /* Open the codec engine */ hEngine = Engine_open(args->engineName, NULL, NULL); if (hEngine == NULL) { printf("Failed to open codec engine: %s\n", args->engineName); goto cleanup; } params.maxWidth = args->width; params.maxHeight = args->height; /* Set up codec parameters depending on bit rate */ if (args->bitRate < 0) { /* Variable bit rate */ params.rateControlPreset = IVIDEO_NONE; /* * If variable bit rate use a bogus bit rate value (> 0) * since it will be ignored. */ params.maxBitRate = 2000000; } else { /* Constant bit rate */ params.rateControlPreset = IVIDEO_LOW_DELAY; params.maxBitRate = args->bitRate; } params.inputChromaFormat = XDM_YUV_422ILE; dynParams.targetBitRate = params.maxBitRate; dynParams.inputWidth = params.maxWidth; dynParams.inputHeight = params.maxHeight; /* Create the video encoder */ hVe = Venc_create(hEngine, args->codecName, ¶ms, &dynParams); if (hVe == NULL) { printf("Failed to create video encoder: %s\n", args->codecName); goto cleanup; } /* Only the UYVY colorspace is supported in this application */ colorSpace = ColorSpace_UYVY; /* Align buffers to cache line boundary */ gfxAttrs.bAttrs.memParams.align = bAttrs.memParams.align = BUFSIZEALIGN; /* Use cached buffers if requested */ if (args->cache) { gfxAttrs.bAttrs.memParams.flags = bAttrs.memParams.flags = Memory_CACHED; } /* Calculate the buffer attributes */ gfxAttrs.dim.width = args->width; gfxAttrs.dim.height = args->height; gfxAttrs.dim.lineLength = BufferGfx_calcLineLength(args->width, colorSpace); gfxAttrs.colorSpace = colorSpace; /* Create input buffer */ hInBuf = Buffer_create(Dmai_roundUp(Venc_getInBufSize(hVe), BUFSIZEALIGN), BufferGfx_getBufferAttrs(&gfxAttrs)); if (hInBuf == NULL) { printf("Failed to allocate contiguous buffer\n"); goto cleanup; } /* Create output buffer */ hOutBuf = Buffer_create(Dmai_roundUp(Venc_getOutBufSize(hVe), BUFSIZEALIGN), &bAttrs); if (hOutBuf == NULL) { printf("Failed to create contiguous buffer\n"); goto cleanup; } while (numFrame++ < args->numFrames) { /* Read a yuv input frame */ printf("Frame %d: ", numFrame); if (readFrameUYVY(hInBuf, inFile) < 0) { goto cleanup; } if (args->benchmark) { if (Time_reset(hTime) < 0) { printf("Failed to reset timer\n"); goto cleanup; } } if (args->cache) { /* * To meet xDAIS DMA Rule 7, when input buffers are cached, we * must writeback the cache into physical memory. Also, per DMA * Rule 7, we must invalidate the output buffer from * cache before providing it to any xDAIS algorithm. */ Memory_cacheWbInv(Buffer_getUserPtr(hInBuf), Buffer_getSize(hInBuf)); /* Per DMA Rule 7, our output buffer cache lines must be cleaned */ Memory_cacheInv(Buffer_getUserPtr(hOutBuf), Buffer_getSize(hOutBuf)); if (args->benchmark) { if (Time_delta(hTime, &time) < 0) { printf("Failed to get timer delta\n"); goto cleanup; } printf("Pre-process cache maintenance: %uus \n", (Uns) time); } } /* Encode the video buffer */ if (Venc_process(hVe, hInBuf, hOutBuf) < 0) { printf("Failed to encode video buffer\n"); goto cleanup; } if (args->benchmark) { if (Time_delta(hTime, &time) < 0) { printf("Failed to get encode time\n"); goto cleanup; } printf("[%d] Encode: %uus\n", numFrame, (Uns)time); } if (args->cache) { /* Writeback the outBuf. */ Memory_cacheWb(Buffer_getUserPtr(hOutBuf), Buffer_getSize(hOutBuf)); if (args->benchmark) { if (Time_delta(hTime, &time) < 0) { printf("Failed to get timer delta\n"); goto cleanup; } printf("Post-process cache write back: %uus \n", (Uns) time); } } /* Write the encoded frame to the file system */ if (Buffer_getNumBytesUsed(hOutBuf)) { if (fwrite(Buffer_getUserPtr(hOutBuf), Buffer_getNumBytesUsed(hOutBuf), 1, outFile) != 1) { printf("Failed to write encoded video data to file\n"); goto cleanup; } } if (args->benchmark) { if (Time_total(hTime, &time) < 0) { printf("Failed to get timer total\n"); goto cleanup; } printf("Total: %uus\n", (unsigned int)time); } } cleanup: /* Clean up the application */ if (hOutBuf) { Buffer_delete(hOutBuf); } if (hInBuf) { Buffer_delete(hInBuf); } if (hVe) { Venc_delete(hVe); } if (hEngine) { Engine_close(hEngine); } if (inFile) { fclose(inFile); } if (outFile) { fclose(outFile); } if (hTime) { Time_delete(hTime); } printf("End of application.\n"); return; }