Hi,
I have been trying to implement seek over the network, by connecting two gstreamer pipelines using tcpclientsink (sender) and tcpserversrc (receiver) at either ends. I am using Ubuntu Linux at receiver and Windows at the sender. At the sender side, I just have a filesrc and tcpclientsink (so no time seek is possible at the sender) and at the receiver I have tcpserversrc followed by decodebin connected to audio and video sinks. sender pipeline: filesrc blocksize=4194304 location=C:/Users/Downloads/bbc-japan_1080p.mov ! tcpclientsink blocksize=4194304 async=false host=192.168.100.58 port=3000 receiver pipeline: tcpserversrc host=192.168.100.58 port=3000 blocksize=4194304 ! decodebin name=demux ! autoaudiosink demux. ! imxeglvivsink After some suggestions I got on this forum, I got to know that the way to implement a seek over the network would be to first extract the BYTE offset from the demuxer at the receiver based on a TIME value and then send across the BYTE offset to the sender to do a BYTES seek on the sender pipeline. However, I am not able to ascertain the steps I need to do at the receiver to synchronize the sender and the receiver. After getting a byte location from the receiver (qtdemux in this case), when I do a BYTES seek at the sender I see that either video decoder or the audio decoder exits with decode error at the receiver. I figured that might be due to the demuxer (qtdemux) state machine not being synchronized for start of a segment (KEY frame). I tried to do a pipeline flush start and stop at the receiver before doing a BYTES seek at the sender, but that does not work. It looks like that at the receiver doing a flush stop issues a newsegment event and I also see a end of stream being signaled after that. After the doing the flush_stop the tcpserversrc seems to get stuck and doesn't accept any data from the network. I also tried doing a newsegment myself after the flush_stop, but that does not help. I am pasting below the code for the seek procedure that I perform at the receiver. g_print ("\n Init SEEK \n"); PlayerConnectionWrite(data->playerconn, (gint64) value); // This pauses the sender pipeline if (ifTCPClientReadytoGo(data->playerconn)) // check if sender is ready to start again - do not play sender yet { g_print ("\n Setting receiver pipeline to PAUSE\n"); gst_element_set_state (data->gstpipeline->pipeline, GST_STATE_PAUSED); bus = gst_element_get_bus (data->gstpipeline->pipeline); while (flag == 0) { msg = gst_bus_timed_pop_filtered(bus, GST_CLOCK_TIME_NONE, GST_MESSAGE_STATE_CHANGED); if (GST_MESSAGE_SRC (msg) == GST_OBJECT(data->gstpipeline->pipeline)) { gst_message_parse_state_changed(msg, &old_state, &new_state, &pending_state); if ((old_state == GST_STATE_PLAYING) && (new_state == GST_STATE_PAUSED)) { g_print ("\n Pipeline paused\n"); flag = 1; } else g_print ("\n Pipeline state is %s \n", gst_element_state_get_name(new_state)); } } GstEvent * flush_start = gst_event_new_flush_start(); gboolean ret = FALSE; ret = gst_element_send_event(GST_ELEMENT(data->gstpipeline->pipeline), flush_start); if (!ret) { g_print ("\n failed flush_start\n"); exit(1); } GstEvent* flush_stop = gst_event_new_flush_stop(FALSE); ret = gst_element_send_event(GST_ELEMENT(data->gstpipeline->pipeline), flush_stop); if (!ret) { g_print ("\n failed flush_stop\n"); exit(1); } /** GstSegment *gstsegment = gst_segment_new(); gst_segment_init (gstsegment, GST_FORMAT_TIME); gstsegment->rate = 1.0; gstsegment->start = GST_SECOND * 40; //43667446; gstsegment->stop = -1; GstEvent *eventseg = gst_event_new_segment(gstsegment); g_print ("\n Sending segment event\n"); if (!gst_element_send_event(GST_ELEMENT(data->gstpipeline->pipeline), eventseg)) { g_print ("\n Segment Event Error \n"); //exit(1); } else g_print ("\n Segment event success \n"); **/ g_print ("\n Setting pipeline to Playing\n"); gst_element_set_state (data->gstpipeline->pipeline, GST_STATE_PLAYING); flag = 0; bus = gst_element_get_bus (data->gstpipeline->pipeline); while (flag == 0) { msg = gst_bus_timed_pop_filtered(bus, GST_CLOCK_TIME_NONE, GST_MESSAGE_STATE_CHANGED); if (GST_MESSAGE_SRC (msg) == GST_OBJECT(data->gstpipeline->pipeline)) { gst_message_parse_state_changed(msg, &old_state, &new_state, &pending_state); if ((old_state == GST_STATE_PAUSED) && (new_state == GST_STATE_PLAYING)) { g_print ("\n Pipeline playing\n"); flag = 1; } else g_print ("\n Pipeline state is %s \n", gst_element_state_get_name(new_state)); } } tcp_server_goahead(data->playerconn); // restart sender pipeline after BYTES seek - set to PLAYING } I would be really thankful if anyone could point to the mistake I am doing, or provide some guidance to implementing seek over the network using TCP. Regards Amit |
Hi,
Could anyone please provide some guidance on this issue. Regards Amit |
Hi,
Still waiting.. Regards Amit |
Free forum by Nabble | Edit this page |