Gstreamer Android - Take Snapshot from Video
Alex Moreno
alexmorenocano at yahoo.com
Mon Apr 13 04:56:14 PDT 2015
Hi Liuting Du,
I am not answering your question, but it may help :)I do a similar thing for taking snapshot images, but I use an appsink instead of a filesink. Basically I convert the GstSample into an Android Bitmap and call a Java method to handle it:
the pipeline part:
videosrc ! queue ! decodebin ! tee name=t ! videoconvert ! queue ! autovideosink t. ! videoconvert ! video/x-raw,format=(string)RGB16 ! appsink name=snap
GstElement *appsink = gst_bin_get_by_name (GST_BIN (data->pipeline), "snap");if (!appsink) { GST_ERROR ("Could not retrieve appsink"); gst_element_set_state (data->pipeline, GST_STATE_NULL); return NULL;}gst_app_sink_set_drop (GST_APP_SINK (appsink), TRUE);gst_app_sink_set_max_buffers (GST_APP_SINK (appsink), 1);
The reason I fixed the pixel color to RGB16 is for the Bitmap.Config (see below). Then when you need the snapshot image:
GstSample *sample;sample = gst_app_sink_pull_sample (GST_APP_SINK(data->appsink));
And then create the bitmap (you do error checking/exception handling):
GstBuffer *buffer = gst_sample_get_buffer (sample);GstCaps *caps = gst_sample_get_caps (sample);
GST_DEBUG ("snapshot caps %" GST_PTR_FORMAT, caps);
GstMapInfo map;gst_buffer_map (buffer, &map, GST_MAP_READ);
GstVideoInfo info;gst_video_info_from_caps (&info, caps);GST_DEBUG ("format name is %s", GST_VIDEO_INFO_NAME(&info));
// get static method id of createBitmap(int width, int height, Bitmap.Config config)jclass java_bitmap_class = (*env)->FindClass (env, "android/graphics/Bitmap");
jmethodID mid = (*env)->GetStaticMethodID (env, java_bitmap_class, "createBitmap", "(IILandroid/graphics/Bitmap$Config;)Landroid/graphics/Bitmap;");
// enum for Bitmap.Config jclass bcfg_class = (*env)->FindClass (env, "android/graphics/Bitmap$Config");
jobject java_bitmap_config = (*env)->CallStaticObjectMethod (env, bcfg_class, (*env)->GetStaticMethodID (env, bcfg_class, "valueOf", "(Ljava/lang/String;)Landroid/graphics/Bitmap$Config;"), (*env)->NewStringUTF (env, "RGB_565"));
// creat the Bitmap objectbitmap = (*env)->CallStaticObjectMethod (env, java_bitmap_class, mid, GST_VIDEO_INFO_WIDTH(&info), GST_VIDEO_INFO_HEIGHT(&info), java_bitmap_config);
void *pixels = NULL;int ret = AndroidBitmap_lockPixels (env, bitmap, &pixels);memcpy (pixels, map.data, map.size);AndroidBitmap_unlockPixels(env, bitmap);
Good luck! Regards,Alexandre Moreno
El Viernes 10 de abril de 2015 21:25, Liuting Du <liuting at evercam.io> escribió:
Hi,
I am developing an Android RTSP player using Gstreamer 1.0. The basic requirement is to make the player load RTSP stream fast and and also allow the user to take snapshots from the video and save it as an image file, without influencing the video stream.
I forked the demo app and made some small changes on the demo code to meet the basic requirements. This is the forked repo: https://github.com/liutingdu/gst-launch-remote
The pileline I am using is:
rtspsrc protocols=4 location=rtsp://172.16.0.21:9021/h264/ch1/main/av_stream user-id=admin user-pw=12345 latency=0 drop-on-latency=1 ! decodebin ! videoconvert ! autovideosink
While the video is playing, I tried to launch a new pipeline for taking snapshot using filesink:
rtspsrc protocols=4 location=rtsp://172.16.0.21:9021/h264/ch1/main/av_stream user-id=admin user-pw=12345 latency=0 drop-on-latency=1 ! jpegenc ! filesink location=/sdcard/snapshot.jpeg
It saves the snapshot image but always interrupt the video that is currently playing, tried to launch the pileline in a new Java thread but got no luck.
After searching around, there seems are some possible approaches:
1. Use the 'tee' plugin to attach and detach the filesink
rtspsrc ...... ! decodebin ! tee name=t ! queue ! videoconvert ! autovideosink t. ! queue ! jpegenc ! filesink location=/snapshot.jpeg
But by simply launching this pipeline, it doesn't seem to be working.
Maybe it requires making lots of changes on the C code to dynamically attach new pipeline?
2. I've got a suggestion from someone who knows about Gstreamer, to use 'tee' with 'intervideosink' and 'intervideosrc'.
But the 'intervideosink' element is not installed on the Android distribution at all?
Then I am stuck with all approaches.. so the questions are:
1. Is any of the approaches listed above will definitely work and is leading me to the right direction?2. If any of them will work, what are the necessary changes that need to be made, and is there any detailed document or sample available somewhere?3. If none of them is correct, any suggestions?
I am completely new to C and Gstreamer, any help would be highly appreciated.
Thanks in advance,
Liuting
_______________________________________________
gstreamer-android mailing list
gstreamer-android at lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/gstreamer-android
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.freedesktop.org/archives/gstreamer-android/attachments/20150413/a162a257/attachment.html>
More information about the gstreamer-android
mailing list