root/vic/branches/mpeg4/codec/packetbuffer.cpp @ 3974

Revision 3974, 2.1 KB (checked in by piers, 7 years ago)

RTP Payload format for H.264 (RFC 3984)

Most of this work below has been done by Socrates. Tidy up and bug fixes by Piers.

General comments:

1. Implemented the H.264 RTP framing according to RFC 3984. The implementation covers the "Single NAL Unit" (Single NALU packet type) and "Non-Interleaved" modes (STAP-A, FU-A packet types). The interleaved mode (STAP-B, MTAP16, MTAP24, FU-B) has not been implemented at this stage. [I don't know of another tool, closed source or open, that has implemented this mode to date to be able to test with (the current QuickTime? Player 7.1.3 does not implement it either, as far as I know).]

2. The decoder has been tested with the MPEG4IP's mp4live server 1.5.0.1. An example SDP file is provided to set up VIC to decode mp4live streams. Please edit the file default_mpeg4ip.sdp with your details, or better generate your own SDP files using mp4live, and place the edited SDP file in your home directory. The filename should be "default.sdp"

3. The H264 depayloader implementation is currently based libavformat (part of ffpmeg). The plan to is re-write the H264 depayloader under BSD license in the near future.

4. The H.264 VIC encoder will not aggregate NAL units at the moment (STAP-A). The decoder will properly decode such packets.

5. VIC sends SPS/PPS NAL units in-band at the start of H.264 transmission. One has to check whether this can be done periodically. This way we may avoid SDP and sprep-parameter-set.

6. The SDP may be configured for the decoder which uses either a default embedded SDP or from "$HOME/default.sdp"

7. The SDP file is only used to convey SPS/PPS sprop-parameter-sets. IP addresses, ports, etc. are read from VIC command-line as normal.

Line 
1#include "config.h"
2#include "packetbuffer.h"
3#include "databuffer.h"
4
5#include <stdio.h>
6#include <stdlib.h>
7#include <string.h>
8
9
10PacketBuffer::PacketBuffer(int maxPacket, int maxLength)
11{
12    totalPkts = 0;
13    maxPkts = maxPacket;
14    maxLen = maxLength;
15    stream = new DataBuffer(maxPacket * maxLength);
16
17    for (int i = 0; i < maxPkts; i++) {
18        isDataRecv[i] = false;
19        packets[i] = new DataBuffer(maxLen);
20        //std::cout << "allocate databuffer " << i << "\n";
21    }
22}
23
24PacketBuffer::~PacketBuffer()
25{
26    delete stream;
27    for (int i = 0; i < maxPkts; i++)
28        delete packets[i];
29}
30
31void PacketBuffer::writeAppend(int idx, int size, char *buffer)
32{
33    if (idx > MAX_PACKETS || idx < 0)
34        return;
35    isDataRecv[idx] = packets[idx]->writeAppend(buffer, size);
36}
37
38void PacketBuffer::write(int idx, int size, char *buffer)
39{
40    if (idx > MAX_PACKETS || idx < 0)
41        return;
42    isDataRecv[idx] = packets[idx]->write(buffer, size);
43}
44
45void PacketBuffer::setSize(int idx, int size)
46{
47    if (idx > MAX_PACKETS || idx < 0)
48        return;
49    isDataRecv[idx] = packets[idx]->setSize(size);
50}
51
52bool PacketBuffer::isComplete()
53{
54    if (totalPkts == 0)
55        return false;
56    for (int i = 0; i < totalPkts; i++){       
57        if (!isDataRecv[i]){
58            //debug_msg("lost packet %d\n", i);
59            return false;
60        }
61    }
62    return true;
63}
64
65void PacketBuffer::setTotalPkts(int n)
66{
67    totalPkts = n;
68}
69
70int PacketBuffer::getTotalPkts()
71{
72    return totalPkts;
73}
74
75//return bitstream , corrupted packets will be ignored
76DataBuffer *PacketBuffer::getStream()
77{
78    if (totalPkts == 0)
79        return NULL;
80
81    //int offset = 0;
82    //char* dst = stream->getData();
83    for (int i = 0; i < totalPkts; i++) {
84        if (isDataRecv[i]) {
85            //memcpy(dst+offset, packets[i]->getData(), packets[i]->getDataSize() );
86            //offset+=packets[i]->getDataSize();
87            stream->writeAppend(packets[i]->getData(),
88                                packets[i]->getDataSize());
89        }
90    }
91    //stream->setSize(offset);
92    return stream;
93}
94
95void PacketBuffer::clear()
96{
97    //std::cout << "Total packets " << totalPkts << "\n";
98    for (int i = 0; i < totalPkts; i++) {
99        packets[i]->setSize(0);
100        stream->setSize(0);
101        isDataRecv[i] = false;
102    }
103    totalPkts = 0;
104}
Note: See TracBrowser for help on using the browser.