~siretart/ubuntu/utopic/libav/libav10

« back to all changes in this revision

Viewing changes to libavformat/rtpdec_mpeg4.c

  • Committer: Package Import Robot
  • Author(s): Reinhard Tartler
  • Date: 2014-05-11 12:28:45 UTC
  • mfrom: (1.1.22) (2.1.38 experimental)
  • Revision ID: package-import@ubuntu.com-20140511122845-gxvpts83i958y0i5
Tags: 6:10.1-1
* New upstream release 10:
   - pcm-dvd: Fix 20bit decoding (bug/592)
   - avi: Improve non-interleaved detection (bug/666)
   - arm: hpeldsp: fix put_pixels8_y2_{,no_rnd_}armv6
   - arm: hpeldsp: prevent overreads in armv6 asm (bug/646)
   - avfilter: Add missing emms_c when needed
   - rtmpproto: Check the buffer sizes when copying app/playpath strings
   - swscale: Fix an undefined behaviour
   - vp9: Read the frame size as unsigned
   - dcadec: Use correct channel count in stereo downmix check
   - dcadec: Do not decode the XCh extension when downmixing to stereo
   - matroska: add the Opus mapping
   - matroskadec: read the CodecDelay element
   - rtmpproto: Make sure to pass on the error code if read_connect failed
   - lavr: allocate the resampling buffer with a positive size
   - mp3enc: Properly write bitrate value in XING header (Closes: #736088)
   - golomb: Fix the implementation of get_se_golomb_long
* Drop debian/libav-tools.maintscript. ffserver is no longer found in
  stable, and this seems to cause other problems today (Closes: #742676)

Show diffs side-by-side

added added

removed removed

Lines of Context:
29
29
 
30
30
#include "rtpdec_formats.h"
31
31
#include "internal.h"
 
32
#include "libavutil/attributes.h"
32
33
#include "libavutil/avstring.h"
33
34
#include "libavcodec/get_bits.h"
34
35
 
57
58
    int nb_au_headers;
58
59
    int au_headers_length_bytes;
59
60
    int cur_au_index;
 
61
 
 
62
    uint8_t buf[RTP_MAX_PACKET_LENGTH];
 
63
    int buf_pos, buf_size;
60
64
};
61
65
 
62
66
typedef struct {
109
113
    return 0;
110
114
}
111
115
 
112
 
static int rtp_parse_mp4_au(PayloadContext *data, const uint8_t *buf)
 
116
static int rtp_parse_mp4_au(PayloadContext *data, const uint8_t *buf, int len)
113
117
{
114
118
    int au_headers_length, au_header_size, i;
115
119
    GetBitContext getbitcontext;
116
120
 
 
121
    if (len < 2)
 
122
        return AVERROR_INVALIDDATA;
 
123
 
117
124
    /* decode the first 2 bytes where the AUHeader sections are stored
118
125
       length in bits */
119
126
    au_headers_length = AV_RB16(buf);
125
132
 
126
133
    /* skip AU headers length section (2 bytes) */
127
134
    buf += 2;
 
135
    len -= 2;
 
136
 
 
137
    if (len < data->au_headers_length_bytes)
 
138
        return AVERROR_INVALIDDATA;
128
139
 
129
140
    init_get_bits(&getbitcontext, buf, data->au_headers_length_bytes * 8);
130
141
 
137
148
    if (!data->au_headers || data->au_headers_allocated < data->nb_au_headers) {
138
149
        av_free(data->au_headers);
139
150
        data->au_headers = av_malloc(sizeof(struct AUHeaders) * data->nb_au_headers);
 
151
        if (!data->au_headers)
 
152
            return AVERROR(ENOMEM);
140
153
        data->au_headers_allocated = data->nb_au_headers;
141
154
    }
142
155
 
143
 
    /* XXX: We handle multiple AU Section as only one (need to fix this for interleaving)
144
 
       In my test, the FAAD decoder does not behave correctly when sending each AU one by one
145
 
       but does when sending the whole as one big packet...  */
146
 
    data->au_headers[0].size = 0;
147
 
    data->au_headers[0].index = 0;
148
156
    for (i = 0; i < data->nb_au_headers; ++i) {
149
 
        data->au_headers[0].size += get_bits_long(&getbitcontext, data->sizelength);
150
 
        data->au_headers[0].index = get_bits_long(&getbitcontext, data->indexlength);
 
157
        data->au_headers[i].size  = get_bits_long(&getbitcontext, data->sizelength);
 
158
        data->au_headers[i].index = get_bits_long(&getbitcontext, data->indexlength);
151
159
    }
152
160
 
153
 
    data->nb_au_headers = 1;
154
 
 
155
161
    return 0;
156
162
}
157
163
 
162
168
                            const uint8_t *buf, int len, uint16_t seq,
163
169
                            int flags)
164
170
{
165
 
    if (rtp_parse_mp4_au(data, buf))
 
171
    int ret;
 
172
 
 
173
    if (!buf) {
 
174
        if (data->cur_au_index > data->nb_au_headers)
 
175
            return AVERROR_INVALIDDATA;
 
176
        if (data->buf_size - data->buf_pos < data->au_headers[data->cur_au_index].size)
 
177
            return AVERROR_INVALIDDATA;
 
178
        if ((ret = av_new_packet(pkt, data->au_headers[data->cur_au_index].size)) < 0)
 
179
            return ret;
 
180
        memcpy(pkt->data, &data->buf[data->buf_pos], data->au_headers[data->cur_au_index].size);
 
181
        data->buf_pos += data->au_headers[data->cur_au_index].size;
 
182
        pkt->stream_index = st->index;
 
183
        data->cur_au_index++;
 
184
        return data->cur_au_index < data->nb_au_headers;
 
185
    }
 
186
 
 
187
    if (rtp_parse_mp4_au(data, buf, len))
166
188
        return -1;
167
189
 
168
190
    buf += data->au_headers_length_bytes + 2;
169
191
    len -= data->au_headers_length_bytes + 2;
170
192
 
171
 
    /* XXX: Fixme we only handle the case where rtp_parse_mp4_au define
172
 
                    one au_header */
173
 
    av_new_packet(pkt, data->au_headers[0].size);
 
193
    if (len < data->au_headers[0].size)
 
194
        return AVERROR_INVALIDDATA;
 
195
    if ((ret = av_new_packet(pkt, data->au_headers[0].size)) < 0)
 
196
        return ret;
174
197
    memcpy(pkt->data, buf, data->au_headers[0].size);
175
 
 
 
198
    len -= data->au_headers[0].size;
 
199
    buf += data->au_headers[0].size;
176
200
    pkt->stream_index = st->index;
 
201
 
 
202
    if (len > 0 && data->nb_au_headers > 1) {
 
203
        data->buf_size = FFMIN(len, sizeof(data->buf));
 
204
        memcpy(data->buf, buf, data->buf_size);
 
205
        data->cur_au_index = 1;
 
206
        data->buf_pos = 0;
 
207
        return 1;
 
208
    }
 
209
 
177
210
    return 0;
178
211
}
179
212
 
220
253
    return 0;
221
254
}
222
255
 
 
256
static av_cold int init_video(AVFormatContext *s, int st_index,
 
257
                              PayloadContext *data)
 
258
{
 
259
    if (st_index < 0)
 
260
        return 0;
 
261
    s->streams[st_index]->need_parsing = AVSTREAM_PARSE_FULL;
 
262
    return 0;
 
263
}
 
264
 
223
265
RTPDynamicProtocolHandler ff_mp4v_es_dynamic_handler = {
224
266
    .enc_name           = "MP4V-ES",
225
267
    .codec_type         = AVMEDIA_TYPE_VIDEO,
226
268
    .codec_id           = AV_CODEC_ID_MPEG4,
 
269
    .init               = init_video,
227
270
    .parse_sdp_a_line   = parse_sdp_line,
228
271
};
229
272