Revision 4de339e2 libavcodec/avpacket.c

View differences:

libavcodec/avpacket.c
26 26
void av_destruct_packet_nofree(AVPacket *pkt)
27 27
{
28 28
    pkt->data = NULL; pkt->size = 0;
29
    pkt->side_data       = NULL;
30
    pkt->side_data_elems = 0;
29 31
}
30 32

  
31 33
void av_destruct_packet(AVPacket *pkt)
32 34
{
35
    int i;
36

  
33 37
    av_free(pkt->data);
34 38
    pkt->data = NULL; pkt->size = 0;
39

  
40
    for (i = 0; i < pkt->side_data_elems; i++)
41
        av_free(pkt->side_data[i].data);
42
    av_freep(&pkt->side_data);
43
    pkt->side_data_elems = 0;
35 44
}
36 45

  
37 46
void av_init_packet(AVPacket *pkt)
......
44 53
    pkt->flags = 0;
45 54
    pkt->stream_index = 0;
46 55
    pkt->destruct= NULL;
56
    pkt->side_data       = NULL;
57
    pkt->side_data_elems = 0;
47 58
}
48 59

  
49 60
int av_new_packet(AVPacket *pkt, int size)
......
89 100
    return 0;
90 101
}
91 102

  
103
#define DUP_DATA(dst, size, padding) \
104
    do { \
105
        void *data; \
106
        if (padding) { \
107
            if ((unsigned)(size) > (unsigned)(size) + FF_INPUT_BUFFER_PADDING_SIZE) \
108
                return AVERROR(ENOMEM); \
109
            data = av_malloc(size + FF_INPUT_BUFFER_PADDING_SIZE); \
110
        } else { \
111
            data = av_malloc(size); \
112
        } \
113
        if (!data) \
114
            return AVERROR(ENOMEM); \
115
        memcpy(data, dst, size); \
116
        if (padding) \
117
            memset((uint8_t*)data + size, 0, FF_INPUT_BUFFER_PADDING_SIZE); \
118
        dst = data; \
119
    } while(0)
120

  
92 121
int av_dup_packet(AVPacket *pkt)
93 122
{
94 123
    if (((pkt->destruct == av_destruct_packet_nofree) || (pkt->destruct == NULL)) && pkt->data) {
95
        uint8_t *data;
96
        /* We duplicate the packet and don't forget to add the padding again. */
97
        if((unsigned)pkt->size > (unsigned)pkt->size + FF_INPUT_BUFFER_PADDING_SIZE)
98
            return AVERROR(ENOMEM);
99
        data = av_malloc(pkt->size + FF_INPUT_BUFFER_PADDING_SIZE);
100
        if (!data) {
101
            return AVERROR(ENOMEM);
102
        }
103
        memcpy(data, pkt->data, pkt->size);
104
        memset(data + pkt->size, 0, FF_INPUT_BUFFER_PADDING_SIZE);
105
        pkt->data = data;
124
        DUP_DATA(pkt->data, pkt->size, 1);
106 125
        pkt->destruct = av_destruct_packet;
126

  
127
        if (pkt->side_data_elems) {
128
            int i;
129

  
130
            DUP_DATA(pkt->side_data, pkt->side_data_elems * sizeof(*pkt->side_data), 0);
131
            for (i = 0; i < pkt->side_data_elems; i++) {
132
                DUP_DATA(pkt->side_data[i].data, pkt->side_data[i].size, 1);
133
            }
134
        }
107 135
    }
108 136
    return 0;
109 137
}
......
113 141
    if (pkt) {
114 142
        if (pkt->destruct) pkt->destruct(pkt);
115 143
        pkt->data = NULL; pkt->size = 0;
144
        pkt->side_data       = NULL;
145
        pkt->side_data_elems = 0;
146
    }
147
}
148

  
149
uint8_t* av_packet_new_side_data(AVPacket *pkt, enum AVPacketSideDataType type,
150
                                 int size)
151
{
152
    int elems = pkt->side_data_elems;
153

  
154
    if ((unsigned)elems + 1 > INT_MAX / sizeof(*pkt->side_data))
155
        return NULL;
156
    if ((unsigned)size > INT_MAX - FF_INPUT_BUFFER_PADDING_SIZE)
157
        return NULL;
158

  
159
    pkt->side_data = av_realloc(pkt->side_data, (elems + 1) * sizeof(*pkt->side_data));
160
    if (!pkt->side_data)
161
        return NULL;
162

  
163
    pkt->side_data[elems].data = av_malloc(size + FF_INPUT_BUFFER_PADDING_SIZE);
164
    if (!pkt->side_data[elems].data)
165
        return NULL;
166
    pkt->side_data[elems].size = size;
167
    pkt->side_data[elems].type = type;
168
    pkt->side_data_elems++;
169

  
170
    return pkt->side_data[elems].data;
171
}
172

  
173
uint8_t* av_packet_get_side_data(AVPacket *pkt, enum AVPacketSideDataType type,
174
                                 int *size)
175
{
176
    int i;
177

  
178
    for (i = 0; i < pkt->side_data_elems; i++) {
179
        if (pkt->side_data[i].type == type) {
180
            if (size)
181
                *size = pkt->side_data[i].size;
182
            return pkt->side_data[i].data;
183
        }
116 184
    }
185
    return NULL;
117 186
}

Also available in: Unified diff