Вообщем есть задача получения на пк, в реальном времени, видео с телефона, для теста выбрал плеер VLC(он же умеет проигрывать RTP потоки?!). Вообщем всё было написано, пакеты уходят, плеер принимает, но не воспроизводит, в чем проблема? Нужно использовать дополнительные протоколы RTCP, RTSP? Или косяк заполнения заголовков? Уже бьюсь немало времени над этим.
Видео получается в формате 3gp(h.263), звука нет.
Показания wireshark'а:
Код | No. Time Source Destination Protocol Info 215 14.180627 192.168.1.9 192.168.1.5 H.263 PT=ITU-T H.263, SSRC=0xBC614E, Seq=195, Time=133156 MODE B H263 payload
Frame 215: 1462 bytes on wire (11696 bits), 1462 bytes captured (11696 bits) Arrival Time: Apr 29, 2011 19:54:52.599963000 Московское время (лето) Epoch Time: 1304092492.599963000 seconds [Time delta from previous captured frame: 0.055939000 seconds] [Time delta from previous displayed frame: 0.055939000 seconds] [Time since reference or first frame: 14.180627000 seconds] Frame Number: 215 Frame Length: 1462 bytes (11696 bits) Capture Length: 1462 bytes (11696 bits) [Frame is marked: False] [Frame is ignored: False] [Protocols in frame: eth:ip:udp:rtp:rfc2190:h263] [Coloring Rule Name: UDP] [Coloring Rule String: udp] Ethernet II, Src: MurataMa_a1:35:73 (00:26:e8:a1:35:73), Dst: Giga-Byt_86:07:fd (1c:6f:65:86:07:fd) Destination: Giga-Byt_86:07:fd (1c:6f:65:86:07:fd) Address: Giga-Byt_86:07:fd (1c:6f:65:86:07:fd) .... ...0 .... .... .... .... = IG bit: Individual address (unicast) .... ..0. .... .... .... .... = LG bit: Globally unique address (factory default) Source: MurataMa_a1:35:73 (00:26:e8:a1:35:73) Address: MurataMa_a1:35:73 (00:26:e8:a1:35:73) .... ...0 .... .... .... .... = IG bit: Individual address (unicast) .... ..0. .... .... .... .... = LG bit: Globally unique address (factory default) Type: IP (0x0800) Internet Protocol, Src: 192.168.1.9 (192.168.1.9), Dst: 192.168.1.5 (192.168.1.5) Version: 4 Header length: 20 bytes Differentiated Services Field: 0x00 (DSCP 0x00: Default; ECN: 0x00) 0000 00.. = Differentiated Services Codepoint: Default (0x00) .... ..0. = ECN-Capable Transport (ECT): 0 .... ...0 = ECN-CE: 0 Total Length: 1448 Identification: 0x9541 (38209) Flags: 0x02 (Don't Fragment) 0... .... = Reserved bit: Not set .1.. .... = Don't fragment: Set ..0. .... = More fragments: Not set Fragment offset: 0 Time to live: 64 Protocol: UDP (17) Header checksum: 0x1ca5 [correct] [Good: True] [Bad: False] Source: 192.168.1.9 (192.168.1.9) Destination: 192.168.1.5 (192.168.1.5) User Datagram Protocol, Src Port: 59423 (59423), Dst Port: krb524 (4444) Source port: 59423 (59423) Destination port: krb524 (4444) Length: 1428 Checksum: 0xcb58 [validation disabled] [Good Checksum: False] [Bad Checksum: False] Real-Time Transport Protocol 10.. .... = Version: RFC 1889 Version (2) ..0. .... = Padding: False ...0 .... = Extension: False .... 0000 = Contributing source identifiers count: 0 0... .... = Marker: False Payload type: ITU-T H.263 (34) Sequence number: 195 Timestamp: 133156 Synchronization Source identifier: 0x00bc614e (12345678) H.263 RTP Payload header (RFC2190) F: True p/b frame: False Start bit position: 4 End bit position: 1 SRC format: CIF 352x288 (3) Quantizer: 7 GOB Number: 0 Macroblock address: 6 Reserved field: 0 Inter-coded frame: True Motion vector: False Syntax-based arithmetic coding: False Advanced prediction option: False Horizontal motion vector 1: 120 Vertical motion vector 1: 2 Horizontal motion vector 2: 0 Vertical motion vector 2: 0 ITU-T Recommendation H.263 H.263 stream: fbefbefbefbeeeeafb19e17bdcefbee1da48254dfdae0656...
|
класс rtp пакета
Код | package nd.test.video.net;
import java.net.DatagramPacket; import java.util.BitSet;
import android.os.SystemClock;
public class RTPpacket { //размерности private int HEADER_SIZE = 12; private int PAYLOAD_SIZE = 0; private int CODEC_HEADER_SIZE = 2; //поля заголовка private byte version; private byte padding; private byte extension; private byte CC; private byte marker; private byte payload_type; private short sequence_number; private int time_stamp; private int SSRC; //заголовок и данные private byte[] header; private byte[] payload; private byte[] codec_header; //RTP пакет private DatagramPacket rtp_packet; //конструктор public RTPpacket(byte[] data, int size, short cseq, int ts, int ssrc) { //поля заголовка version = 2; padding = 0; extension = 0; CC = 0; marker = 0; PAYLOAD_SIZE = size; sequence_number = cseq; time_stamp = ts; SSRC = ssrc; /* * F=0, P=1, SBIT=0, EBIT=5, * SRC= 3(CIF), I=0, U=0, S=0, * A=0, R=0, DBQ=0, TRB=0, * TR=0 * */ header = new byte[HEADER_SIZE]; payload = new byte[PAYLOAD_SIZE]; codec_header = new byte[]{ (byte)0x05, (byte)0x60, (byte)0x00, (byte)0x00}; codec_header[0] ^= 1<<30; payload = data; BitSet bitset = new BitSet(16); //version = 2 bitset.flip(15); //padding = 1 bitset.flip(13); //payload type = 34 bitset.flip(1); bitset.flip(5); //marker = 1 bitset.flip(7); byte[] temp = toByteArray(bitset); header[0] = temp[1]; header[1] = temp[2]; byte[] temp2 = short_to_byte_array(sequence_number); header[2] = temp2[0]; header[3] = temp2[1]; byte[] temp3 = int_to_byte_array(time_stamp); header[4] = temp3[0]; header[5] = temp3[1]; header[6] = temp3[2]; header[7] = temp3[3]; byte[] temp4 = int_to_byte_array(SSRC); header[8] = temp4[0]; header[9] = temp4[1]; header[10] = temp4[2]; header[11] = temp4[3]; } public byte[] toByteArray(BitSet bits) { byte[] bytes = new byte[bits.length()/8+1]; for (int i=0; i<bits.length(); i++) if (bits.get(i)) bytes[bytes.length-i/8-1] |= 1<<(i%8); return bytes; } public static byte[] short_to_byte_array(short number) { return new byte[]{(byte)(number >>> 8),(byte)(number)}; } public static byte[] int_to_byte_array(int number) { return new byte[]{(byte)(number >>> 24), (byte)(number >>> 16), (byte)(number >>> 8), (byte)(number)}; } private void make_packet() { byte[] packet = new byte[HEADER_SIZE + PAYLOAD_SIZE]; for(int i = 0; i < HEADER_SIZE; i++) packet[i] = header[i]; for(int i = 0; i < PAYLOAD_SIZE; i++) packet[i+HEADER_SIZE] = payload[i]; rtp_packet = new DatagramPacket(payload, HEADER_SIZE + CODEC_HEADER_SIZE + PAYLOAD_SIZE); } public byte[] get_packet() { return rtp_packet; }
public byte[] get_packet_data() { byte[] packet = new byte[HEADER_SIZE + CODEC_HEADER_SIZE + PAYLOAD_SIZE]; for(int i = 0; i < HEADER_SIZE; i++) packet[i] = header[i]; for(int i = 0; i < CODEC_HEADER_SIZE; i++) packet[i + HEADER_SIZE] = codec_header[i]; for(int i = 0; i < PAYLOAD_SIZE; i++) packet[i + HEADER_SIZE + CODEC_HEADER_SIZE] = payload[i]; return packet; } public int get_size() { return HEADER_SIZE + CODEC_HEADER_SIZE + PAYLOAD_SIZE; } }
|
|