/* called when a new media pipeline is constructed. We can query the * pipeline and configure our appsrc */ void ReStream::media_configure_feature (GstRTSPMediaFactory * factory, GstRTSPMedia * media, gpointer user_data) { try{ GstElement *element, *appsrc; struct MyContext *ctx = (struct MyContext *)user_data; element = gst_rtsp_media_get_element (media); appsrc = gst_bin_get_by_name_recurse_up (GST_BIN (element), "mysrc"); gst_util_set_object_arg (G_OBJECT (appsrc), "format", "time"); g_object_set (G_OBJECT (appsrc), "caps", gst_caps_new_simple ("video/x-raw", "format", G_TYPE_STRING, "BGR", "width", G_TYPE_INT, ctx->width, "height", G_TYPE_INT,ctx->height, "framerate", GST_TYPE_FRACTION, FPS, 1, NULL),NULL ); //ctx->white = FALSE; ctx->timestamp = 0; ctx->buffer = gst_buffer_new_allocate (NULL, ctx->height * ctx->width*3 , NULL); gst_buffer_map (ctx->buffer, &ctx->map, GST_MAP_WRITE); /* make sure ther datais freed when the media is gone */ //g_object_set_data_full (G_OBJECT (media), "my-extra-data", ctx, (GDestroyNotify) g_free); g_signal_connect (appsrc, "need-data", (GCallback)need_data_feature, ctx); g_signal_connect (media, "unprepared", (GCallback)unprepared_feature, ctx); if ( ISDEBUG ) cout<<"media prepared_feature\n"; gst_object_unref (appsrc); gst_object_unref (element); } catch(Exception &e){ CommonClass localcommclass; localcommclass.PrintException("ReStream","CV::media_configure_feature",e); } catch(exception &e){ CommonClass localcommclass; localcommclass.PrintException("ReStream","STD::media_configure_feature",e); } }
void ReStream::unprepared_feature (GstRTSPMedia *gstrtspmedia, MyContext* ctx) { try{ if ( ISDEBUG ) cout<<"media unprepared_feature "<<endl; //cvReleaseCapture(&ctx->cap); gst_buffer_unmap (ctx->buffer, &ctx->map); gst_buffer_unref(ctx->buffer); if ( ISDEBUG ) cout<<"Successfully released buffers"; } catch(Exception &e){ CommonClass localcommclass; localcommclass.PrintException("ReStream","CV::unprepared_feature",e); } catch(exception &e){ CommonClass localcommclass; localcommclass.PrintException("ReStream","STD::unprepared_feature",e); } }
void ReStream::need_data_feature (GstElement * appsrc, guint unused, gpointer user_data) { try{ struct MyContext* ctx = (struct MyContext*)user_data; if(ctx==NULL){ cout<<"ctx is NUll"; return; } else if ( ISDEBUG ) cout<<"buffer size"<<gst_buffer_get_size( ctx->buffer ); guint size,depth,height,width,step,channels; GstFlowReturn ret; IplImage* img = cvCreateImage(cvSize(ctx->width,ctx->height),IPL_DEPTH_8U,3); guchar *data1; CvRect rect; rect.width = ctx->width; rect.height = ctx->height; rect.x = 0; rect.y = 0; pthread_mutex_lock(&ctx->imgLock); while(ctx->image == NULL){ if ( ISDEBUG ) cout<<"inside lock ! ImgBuffer is Empty. Please push images.\n"; } cvSetImageROI( ctx->image, rect ); cvCopy(ctx->image, img ); cvResetImageROI(ctx->image); if ( ISDEBUG ) cout<<"inside lock ! Copying Image to local Buffer.\n"; pthread_mutex_unlock(&ctx->imgLock); if( img == NULL ){ cout<<"Failed to fetch the image:( \n"; return; } else { height = img->height; width = img->width; step = img->widthStep; channels = img->nChannels; depth = img->depth; data1 = (guchar *)img->imageData; size = height*width*channels; memcpy( (guchar *)ctx->map.data, data1, gst_buffer_get_size( ctx->buffer ) ); GST_BUFFER_PTS (ctx->buffer) = ctx->timestamp; GST_BUFFER_DURATION (ctx->buffer) = gst_util_uint64_scale_int (1, GST_SECOND, FPS); ctx->timestamp += GST_BUFFER_DURATION (ctx->buffer); g_signal_emit_by_name (appsrc, "push-buffer", ctx->buffer, &ret); if (ret != GST_FLOW_OK) { if ( ISDEBUG ) cout<<"error pushing image\n"; } else{ if ( ISDEBUG ) cout<<"Successfully pushed\n"; if(img!=NULL) cvReleaseImage(&img); } } } catch(Exception &e){ CommonClass localcommclass; localcommclass.PrintException("ReStream","CV::need_data_feature",e); } catch(exception &e){ CommonClass localcommclass; localcommclass.PrintException("ReStream","STD::need_data_feature",e); } }