Speichern von JPEG-Datei aus Netzwerk-Kamera RTP-Stream

Hatte ich einen RTP-Stream-socket zu empfangen, einen JPEG-Stream von der samsung-Netzwerk-Kamera.

Ich weiß nicht viel darüber aus, wie das JPEG-format funktioniert, aber ich weiß, dass diese eingehende JFIF oder JPEG-stream ist mir das JPEG-header

+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   | Type-specific |              Fragment Offset                  |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |      Type     |       Q       |     Width     |     Height    |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

and then 

 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |       Restart Interval        |F|L|       Restart Count       |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

and then in the first packet, there is this header

   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |      MBZ      |   Precision   |             Length            |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |                    Quantization Table Data                    |
   |                              ...                              |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

Ich glaube, ich Analysierte Sie richtig, und dies ist ein code-snippet, wie ich das SPEICHERN einer JPEG-Stream-Paket.

    int extraOff=0;
    public bool Decode(byte* data, int offset)
    {
        if (_initialized == false)
        {
            type_specific = data[offset + 0];
            _frag[0] = data[offset + 3];
            _frag[1] = data[offset + 2];
            _frag[2] = data[offset + 1];
            _frag[3] = 0x0;
            fragment_offset = System.BitConverter.ToInt32(_frag, 0);
            jpeg_type = data[offset + 4];
            q = data[offset + 5];
            width = data[offset + 6];
            height = data[offset + 7];
            _frag[0] = data[offset + 8];
            _frag[1] = data[offset + 9];
            restart_interval = (ushort)(System.BitConverter.ToUInt16(_frag, 0) & 0x3FF);
            if (width == 0) /** elphel 333 full image size more than just one byte less that < 256 **/
                width = 256;

            byte jpegMBZ = (byte)(data[offset + 12]);
            byte jpegPrecision = (byte)(data[offset + 13]);
            int jpegLength = (int)((data[offset + 14]) * 256 + data[offset + 15]);

            byte[] tableData1 = new byte[64];
            byte[] tableData2 = new byte[64];
            for (int i = 0; i < 64; ++i)
            {
                tableData1[i] = data[offset + 16 + i];
                tableData2[i] = data[offset + 16+64 + i];
            }
            byte[] tmp = new byte[1024];
            _offset = Utils.MakeHeaders(tmp,jpeg_type, width, height, tableData1, tableData2, 0);
            qtable = new byte[_offset];

            Array.Copy(tmp, 0, _buffer, 0, _offset);


            _initialized = true;
            tmp = null;
            GC.Collect();
            extraOff = jpegLength + 4 ;
        }
        else
        {
            _frag[0] = data[15]; //12 + 3
            _frag[1] = data[14]; //12 + 2
            _frag[2] = data[13]; //12 + 1]
            _frag[3] = 0x0;
            fragment_offset = System.BitConverter.ToInt32(_frag, 0);
            _frag[0] = data[offset + 8];
            _frag[1] = data[offset + 9];
            restart_interval = (ushort)(System.BitConverter.ToUInt16(_frag, 0) & 0x3FF);
            extraOff = 0;
        }

        return (next_fragment_offset == fragment_offset);
    }
    public unsafe bool Write(byte* data, int size, out bool sync) //Write(ref byte[] data, int size,out bool sync)
    {
        if (Decode(data, 12))
        {
            for (int i = 24 + extraOff; i < size; )
                buffer_ptr[_offset++] = data[i++];
            size -= 24+extraOff;
            next_fragment_offset += size;
            sync = true;
            return ((data[1] >> 7) == 1);
        }
        else
        {
            _initialized = false;
            _offset = qtable.Length;
            next_fragment_offset = 0;
            sync = false;
            return false;
        }
    }

Das problem, das ich bekomme, ist die JPEG-Datei, die ich erfolgreich gespeichert auf meiner Festplatte, die als Folge der Verkettung der JPEG-streams zeigt nicht den gesamten Strom richtig, alle Bild-previewers zeigen die ERSTEN BEIDEN eingehenden Paketdaten, aber der rest ist GRAU, ich glaube, das bedeutet, die Daten von der Dritten bis zur letzten RTP-Paket werden nicht ausgewertet oder gespeichert werden, richtig.

dies ist der Rahmen, den ich habe
http://rectsoft.net/ideerge/zzz.jpg

bearbeitet werden : Dies ist, wie ich rief die Write-Funktion

            size = rawBuffer.Length;
            if (sync == true)
            {
                unsafe
                {
                    fixed (byte* p = rawBuffer)
                    {
                          if (_frame.Write(p, size, out sync)) //if (_frame.Write(ref _buffer, size, out sync))
                        {
                                //i save my buffer to file here
                        }
                    }
                }
            }
            else if ((rawBuffer[1] >> 7) == 1)
            {
                sync = true;
            }

den rawBuffer gefüllt ist mein UDP-Receive-Funktion, verhält es sich genau wie ich mit meinen h264-stream und sieht 100% wie das, was ich erfasst von WIRESHARK auf VLC.

  • wie Sie controlling-stream??? mit der Bibliothek oder was? kannst du den gesamten code ab, wie Sie eine Verbindung von der cam und etc?
  • Ich bin neugierig auf die _buffer bereits im ersten Array.Copy() call -- und warum gibt es zwei von denen? Sie nur null aus tmp, aber nicht qtable, ist das gewollt?
  • können Sie code wie Sie der Aufruf der Methoden??
  • er ist nicht Eigentümer des Codes, damit er kenne keine Idee, was dieser code tun!
  • ya mekici, ich besitze die Hälfte von diesem code, aber ich weiß, dass alles, was passiert in dem code. dieses Array.Kopieren qtable wurde von jemand den code, du hast Recht, der code, den ich von jemandem bekommen hat, war so Durcheinander, und ich habe nicht gereinigt, weil ich will einfach nur, um zu überprüfen, ob ich sparen könnte, den stream einer JPEG-Datei.
  • Ich glaube nicht, dass es etwas falsch mit meinem stream reader code, den ich schrieb alles selbst, und es hat eine RSTP -, RTP-und RTCP-Controller für die Netzwerk-Kamera, und ich kann erfolgreich decodiert eine H264-stream.
  • Gut, das JPEG-Bild ist definitiv gebrochen. Ich Wette, es ist ein Ergebnis der unsachgemäße Verkettung. Ich würde sogar sagen das Bild ist gut, bis die ersten Verkettung Punkt.
  • na.. das ist der Grund, warum ich Frage, aber kann jemand sehen, was falsch ist? ich folgte der fragment_offset zu verketten, was ich nicht sicher bin, ist, dass das Paket QTable, das Paket hat alle Header, packet hat nur die JPEG-header..
  • Ich sehe nicht ein, etwas besonderes, ohne es hier zu Debuggen, mit Dokumentation. Ich sehe nur jede restart_interval = (ushort)(System.BitConverter.ToUInt16(_frag, 0) & 0x3FF);Linie, die bedeutet, es ist Unsignet Integer und gibt es vielleicht ein Fehler mit " INT " und "UINT" irgendwo? Wenn Sie wollen, kann ich Schritt, dachte der debugger, wenn du wirfst die Sachen auf meine dropbox.
  • sicher, bitte, aber haben Sie eine Netzwerk-Kamera?
  • ideerge, hast du jemals das gelöst? Ich bin haveing exectly das gleiche problem - das Bild, das ich bekommen scheint sehr ähnlich zu dem Bild, das Sie entschlüsseln.

InformationsquelleAutor ideerge | 2011-11-14
Schreibe einen Kommentar