/** Decoder. The supplied buffer should contain an H264 video frame, then DecodeFrame will pass the buffer to the avcode_decode_video2 method. Once decoded we then use the get_picture command to convert the frame to RGB24. The RGB24 buffer is then used to create a FrameInfo object which is placed on our video queue. \param pBuffer Memory buffer holding an H264 frame \param size Size of the buffer */ FrameInfo* CVideoDecoder::DecodeFrame(unsigned char *pBuffer, int size) { FrameInfo *p_block=NULL; uint8_t startCode4[] = {0x00, 0x00, 0x00, 0x01}; int got_frame = 0; AVPacket packet; //Initialize optional fields of a packet with default values. av_init_packet(&packet); //set the buffer and the size packet.data = pBuffer; packet.size = size; while (packet.size > sizeof(startCode4)) { //Decode the video frame of size avpkt->size from avpkt->data into picture. int len = avcodec_decode_video2(m_codecContext, m_frame, &got_frame, &packet); if(len<0) { TRACE_ERROR("Failed to decode video len=%d",len); break; } //sometime we dont get the whole frame, so move //forward and try again if ( !got_frame ) { packet.size -= len; packet.data += len; continue; } //allocate a working frame to store our rgb image AVFrame * rgb = avcodec_alloc_frame(); if(rgb==NULL) { TRACE_ERROR("Failed to allocate new av frame"); return NULL; } //Allocate and return an SwsContext. struct SwsContext * scale_ctx = sws_getContext(m_codecContext->width, m_codecContext->height, m_codecContext->pix_fmt, m_codecContext->width, m_codecContext->height, PIX_FMT_BGR24, SWS_BICUBIC, NULL, NULL, NULL); if (scale_ctx == NULL) { TRACE_ERROR("Failed to get context"); continue; } //Calculate the size in bytes that a picture of the given width and height would occupy if stored in the given picture format. int numBytes = avpicture_get_size(PIX_FMT_RGB24, m_codecContext->width, m_codecContext->height); try{ //create one of our FrameInfo objects p_block = FrameNew(numBytes); if(p_block==NULL){ //cleanup the working buffer av_free(rgb); sws_freeContext(scale_ctx); scale_ctx=NULL; return NULL; } //Fill our frame buffer with the rgb image avpicture_fill((AVPicture*)rgb, (uint8_t*)p_block->pdata, PIX_FMT_RGB24, m_codecContext->width, m_codecContext->height); //Scale the image slice in srcSlice and put the resulting scaled slice in the image in dst. sws_scale(scale_ctx, m_frame->data, m_frame->linesize, 0, m_codecContext->height, rgb->data, rgb->linesize); //set the frame header to indicate rgb24 p_block->frameHead.FrameType = (long)(PIX_FMT_RGB24); p_block->frameHead.TimeStamp = 0; } catch(...) { TRACE_ERROR("EXCEPTION: in afterGettingFrame1 "); } //cleanup the working buffer av_free(rgb); sws_freeContext(scale_ctx); //we got our frame no its time to move on break; } return p_block; }
static PyObject *frputvect(PyObject *self, PyObject *args, PyObject *keywds) { FrFile *oFile; FrameH *frame; FrProcData *proc; FrAdcData *adc; FrSimData *sim; FrVect *vect; int verbose=0, nData, nBits, type, subType, arrayType; double dx, sampleRate, start; char blank[] = ""; char *filename=NULL, *history=NULL; char channel[MAX_STR_LEN], x_unit[MAX_STR_LEN], y_unit[MAX_STR_LEN], kind[MAX_STR_LEN]; PyObject *temp; char msg[MAX_STR_LEN]; PyObject *channellist, *channellist_iter, *framedict, *array; PyArrayIterObject *arrayIter; PyArray_Descr *temp_descr; static char *kwlist[] = {"filename", "channellist", "history", "verbose", NULL}; /*--------------- unpack arguments --------------------*/ verbose = 0; /* The | in the format string indicates the next arguments are optional. They are simply not assigned anything. */ if (!PyArg_ParseTupleAndKeywords(args, keywds, "sO|si", kwlist, &filename, &channellist, &history, &verbose)) { Py_RETURN_NONE; } FrLibSetLvl(verbose); if (history == NULL) { history = blank; } /*-------- create frames, create vectors, and fill them. ------*/ // Channel-list must be any type of sequence if (!PySequence_Check(channellist)) { PyErr_SetNone(PyExc_TypeError); return NULL; } // Get channel name from first dictionary framedict = PySequence_GetItem(channellist, (Py_ssize_t)0); if (framedict == NULL) { PyErr_SetString(PyExc_ValueError, "channellist is empty!"); return NULL; } PyDict_ExtractString(channel, framedict, "name"); Py_XDECREF(framedict); if (PyErr_Occurred()) {return NULL;} if (verbose > 0) { printf("Creating frame %s...\n", channel); } frame = FrameNew(channel); if (frame == NULL) { snprintf(msg, MAX_STR_LEN, "FrameNew failed (%s)", FrErrorGetHistory()); PyErr_SetString(PyExc_FrError, msg); return NULL; } if (verbose > 0) { printf("Now iterating...\n"); } // Iterators allow one to deal with non-contiguous arrays channellist_iter = PyObject_GetIter(channellist); arrayIter = NULL; while ((framedict = PyIter_Next(channellist_iter))) { if (verbose > 0) { printf("In loop...\n"); } // Extract quantities from dict -- all borrowed references PyDict_ExtractString(channel, framedict, "name"); CHECK_ERROR; start = PyDict_ExtractDouble(framedict, "start"); CHECK_ERROR; dx = PyDict_ExtractDouble(framedict, "dx"); CHECK_ERROR; array = PyDict_GetItemString(framedict, "data"); if (!PyArray_Check(array)) { snprintf(msg, MAX_STR_LEN, "data is not an array"); PyErr_SetString(PyExc_TypeError, msg); } CHECK_ERROR; nData = PyArray_SIZE(array); nBits = PyArray_ITEMSIZE(array)*8; arrayType = PyArray_TYPE(array); // kind, x_unit, y_unit, type, and subType have default values temp = PyDict_GetItemString(framedict, "kind"); if (temp != NULL) {strncpy(kind, PyString_AsString(temp), MAX_STR_LEN);} else {snprintf(kind, MAX_STR_LEN, "PROC");} temp = PyDict_GetItemString(framedict, "x_unit"); if (temp != NULL) {strncpy(x_unit, PyString_AsString(temp), MAX_STR_LEN);} else {strncpy(x_unit, blank, MAX_STR_LEN);} temp = PyDict_GetItemString(framedict, "y_unit"); if (temp != NULL) {strncpy(y_unit, PyString_AsString(temp), MAX_STR_LEN);} else {strncpy(y_unit, blank, MAX_STR_LEN);} temp = PyDict_GetItemString(framedict, "type"); if (temp != NULL) {type = (int)PyInt_AsLong(temp);} else {type = 1;} temp = PyDict_GetItemString(framedict, "subType"); if (temp != NULL) {subType = (int)PyInt_AsLong(temp);} else {subType = 0;} // check for errors CHECK_ERROR; if (dx <= 0 || array == NULL || nData==0) { temp = PyObject_Str(framedict); snprintf(msg, MAX_STR_LEN, "Input dictionary contents: %s", PyString_AsString(temp)); Py_XDECREF(temp); FrameFree(frame); Py_XDECREF(framedict); Py_XDECREF(channellist_iter); PyErr_SetString(PyExc_ValueError, msg); return NULL; } if (verbose > 0) { printf("type = %d, subType = %d, start = %f, dx = %f\n", type, subType, start, dx); } sampleRate = 1./dx; if (verbose > 0) { printf("Now copying data to vector...\n"); } // Create empty vector (-typecode ==> empty) with metadata, // then copy data to vector vect = NULL; arrayIter = (PyArrayIterObject *)PyArray_IterNew(array); if(arrayType == NPY_INT16) { vect = FrVectNew1D(channel,-FR_VECT_2S,nData,dx,x_unit,y_unit); while (arrayIter->index < arrayIter->size) { vect->dataS[arrayIter->index] = *((npy_int16 *)arrayIter->dataptr); PyArray_ITER_NEXT(arrayIter);}} else if(arrayType == NPY_INT32) { vect = FrVectNew1D(channel,-FR_VECT_4S,nData,dx,x_unit,y_unit); while (arrayIter->index < arrayIter->size) { vect->dataI[arrayIter->index] = *((npy_int32 *)arrayIter->dataptr); PyArray_ITER_NEXT(arrayIter);}} else if(arrayType == NPY_INT64) { vect = FrVectNew1D(channel,-FR_VECT_8S,nData,dx,x_unit,y_unit); while (arrayIter->index < arrayIter->size) { vect->dataL[arrayIter->index] = *((npy_int64 *)arrayIter->dataptr); PyArray_ITER_NEXT(arrayIter);}} else if(arrayType == NPY_UINT8) { vect = FrVectNew1D(channel,-FR_VECT_1U,nData,dx,x_unit,y_unit); while (arrayIter->index < arrayIter->size) { vect->dataU[arrayIter->index] = *((npy_uint8 *)arrayIter->dataptr); PyArray_ITER_NEXT(arrayIter);}} else if(arrayType == NPY_UINT16) { vect = FrVectNew1D(channel,-FR_VECT_2U,nData,dx,x_unit,y_unit); while (arrayIter->index < arrayIter->size) { vect->dataUS[arrayIter->index] = *((npy_uint16 *)arrayIter->dataptr); PyArray_ITER_NEXT(arrayIter);}} else if(arrayType == NPY_UINT32) { vect = FrVectNew1D(channel,-FR_VECT_4U,nData,dx,x_unit,y_unit); while (arrayIter->index < arrayIter->size) { vect->dataUI[arrayIter->index] = *((npy_uint32 *)arrayIter->dataptr); PyArray_ITER_NEXT(arrayIter);}} else if(arrayType == NPY_UINT64) { vect = FrVectNew1D(channel,-FR_VECT_8U,nData,dx,x_unit,y_unit); while (arrayIter->index < arrayIter->size) { vect->dataUL[arrayIter->index] = *((npy_uint64 *)arrayIter->dataptr); PyArray_ITER_NEXT(arrayIter);}} else if(arrayType == NPY_FLOAT32) { vect = FrVectNew1D(channel,-FR_VECT_4R,nData,dx,x_unit,y_unit); while (arrayIter->index < arrayIter->size) { vect->dataF[arrayIter->index] = *((npy_float32 *)arrayIter->dataptr); PyArray_ITER_NEXT(arrayIter);}} else if(arrayType == NPY_FLOAT64) { vect = FrVectNew1D(channel,-FR_VECT_8R,nData,dx,x_unit,y_unit); while (arrayIter->index < arrayIter->size) { vect->dataD[arrayIter->index] = *((npy_float64 *)arrayIter->dataptr); PyArray_ITER_NEXT(arrayIter);}} /* FrVects don't have complex pointers. Numpy stores complex numbers in the same way, but we have to trick it into giving us a (real) float pointer. */ else if(arrayType == NPY_COMPLEX64) { vect = FrVectNew1D(channel,-FR_VECT_8C,nData,dx,x_unit,y_unit); temp_descr = PyArray_DescrFromType(NPY_FLOAT32); temp = PyArray_View((PyArrayObject *)array, temp_descr, NULL); Py_XDECREF(temp_descr); Py_XDECREF(arrayIter); arrayIter = (PyArrayIterObject *)PyArray_IterNew(temp); while (arrayIter->index < arrayIter->size) { vect->dataF[arrayIter->index] = *((npy_float32 *)arrayIter->dataptr); PyArray_ITER_NEXT(arrayIter);} Py_XDECREF(temp);} else if(arrayType == NPY_COMPLEX128) { vect = FrVectNew1D(channel,-FR_VECT_16C,nData,dx,x_unit,y_unit); temp_descr = PyArray_DescrFromType(NPY_FLOAT64); temp = PyArray_View((PyArrayObject *)array, temp_descr, NULL); Py_XDECREF(temp_descr); Py_XDECREF(arrayIter); arrayIter = (PyArrayIterObject *)PyArray_IterNew(temp); while (arrayIter->index < arrayIter->size) { vect->dataD[arrayIter->index] = *((npy_float64 *)arrayIter->dataptr); PyArray_ITER_NEXT(arrayIter);} Py_XDECREF(temp);} else PyErr_SetString(PyExc_TypeError, msg); if (PyErr_Occurred()) { if (vect != NULL) FrVectFree(vect); FrameFree(frame); Py_XDECREF(framedict); Py_XDECREF(channellist_iter); Py_XDECREF(arrayIter); return NULL; } if (verbose > 0) { printf("Done copying...\n"); FrameDump(frame, stdout, 6); } // Add Fr*Data to frame and attach vector to Fr*Data if (strncmp(kind, "PROC", MAX_STR_LEN)==0) { proc = FrProcDataNew(frame, channel, sampleRate, 1, nBits); FrVectFree(proc->data); proc->data = vect; proc->type = type; proc->subType = subType; frame->GTimeS = (npy_uint32)start; frame->GTimeN = (npy_uint32)((start-(frame->GTimeS))*1e9); if (type==1) { // time series proc->tRange = nData*dx; frame->dt = nData*dx; } else if (type==2) { // frequency series proc->fRange = nData*dx; } } else if (strncmp(kind, "ADC", MAX_STR_LEN)==0) { adc = FrAdcDataNew(frame, channel, sampleRate, 1, nBits); FrVectFree(adc->data); adc->data = vect; frame->dt = nData*dx; frame->GTimeS = (npy_uint32)start; frame->GTimeN = (npy_uint32)((start-(frame->GTimeS))*1e9); } else {// Already tested that kind is one of these strings above sim = FrSimDataNew(frame, channel, sampleRate, 1, nBits); FrVectFree(sim->data); sim->data = vect; frame->dt = nData*dx; frame->GTimeS = (npy_uint32)start; frame->GTimeN = (npy_uint32)((start-(frame->GTimeS))*1e9); } if (verbose > 0) { printf("Attached vect to frame.\n"); } // Clean up (all python objects in loop should be borrowed references) Py_XDECREF(framedict); Py_XDECREF(arrayIter); } // end iteration over channellist Py_XDECREF(channellist_iter); // At this point, there should be no Python references left! /*------------- Write file -----------------------------*/ oFile = FrFileONewH(filename, 1, history); // 1 ==> gzip contents if (oFile == NULL) { snprintf(msg, MAX_STR_LEN, "%s\n", FrErrorGetHistory()); PyErr_SetString(PyExc_FrError, msg); FrFileOEnd(oFile); return NULL; } if (FrameWrite(frame, oFile) != FR_OK) { snprintf(msg, MAX_STR_LEN, "%s\n", FrErrorGetHistory()); PyErr_SetString(PyExc_FrError, msg); FrFileOEnd(oFile); return NULL; } /* The FrFile owns data and vector memory. Do not free them separately. */ FrFileOEnd(oFile); FrameFree(frame); Py_RETURN_NONE; };