1 /*
2  * This file is part of mpv.
3  *
4  * mpv is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * mpv is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with mpv.  If not, see <http://www.gnu.org/licenses/>.
16  */
17 
18 #include <stdlib.h>
19 #include <stdio.h>
20 #include <string.h>
21 #include <assert.h>
22 
23 #include <libavcodec/avcodec.h>
24 #include <libavutil/intreadwrite.h>
25 
26 #include "config.h"
27 
28 #include "common/av_common.h"
29 #include "common/common.h"
30 #include "demux.h"
31 
32 #include "packet.h"
33 
34 // Free any refcounted data dp holds (but don't free dp itself). This does not
35 // care about pointers that are _not_ refcounted (like demux_packet.codec).
36 // Normally, a user should use talloc_free(dp). This function is only for
37 // annoyingly specific obscure use cases.
demux_packet_unref_contents(struct demux_packet * dp)38 void demux_packet_unref_contents(struct demux_packet *dp)
39 {
40     if (dp->avpacket) {
41         assert(!dp->is_cached);
42         av_packet_unref(dp->avpacket);
43         talloc_free(dp->avpacket);
44         dp->avpacket = NULL;
45         dp->buffer = NULL;
46         dp->len = 0;
47     }
48 }
49 
packet_destroy(void * ptr)50 static void packet_destroy(void *ptr)
51 {
52     struct demux_packet *dp = ptr;
53     demux_packet_unref_contents(dp);
54 }
55 
56 // This actually preserves only data and side data, not PTS/DTS/pos/etc.
57 // It also allows avpkt->data==NULL with avpkt->size!=0 - the libavcodec API
58 // does not allow it, but we do it to simplify new_demux_packet().
new_demux_packet_from_avpacket(struct AVPacket * avpkt)59 struct demux_packet *new_demux_packet_from_avpacket(struct AVPacket *avpkt)
60 {
61     if (avpkt->size > 1000000000)
62         return NULL;
63     struct demux_packet *dp = talloc(NULL, struct demux_packet);
64     talloc_set_destructor(dp, packet_destroy);
65     *dp = (struct demux_packet) {
66         .pts = MP_NOPTS_VALUE,
67         .dts = MP_NOPTS_VALUE,
68         .duration = -1,
69         .pos = -1,
70         .start = MP_NOPTS_VALUE,
71         .end = MP_NOPTS_VALUE,
72         .stream = -1,
73         .avpacket = talloc_zero(dp, AVPacket),
74     };
75     av_init_packet(dp->avpacket);
76     int r = -1;
77     if (avpkt->data) {
78         // We hope that this function won't need/access AVPacket input padding,
79         // because otherwise new_demux_packet_from() wouldn't work.
80         r = av_packet_ref(dp->avpacket, avpkt);
81     } else {
82         r = av_new_packet(dp->avpacket, avpkt->size);
83     }
84     if (r < 0) {
85         *dp->avpacket = (AVPacket){0};
86         talloc_free(dp);
87         return NULL;
88     }
89     dp->buffer = dp->avpacket->data;
90     dp->len = dp->avpacket->size;
91     return dp;
92 }
93 
94 // (buf must include proper padding)
new_demux_packet_from_buf(struct AVBufferRef * buf)95 struct demux_packet *new_demux_packet_from_buf(struct AVBufferRef *buf)
96 {
97     if (!buf)
98         return NULL;
99     AVPacket pkt = {
100         .size = buf->size,
101         .data = buf->data,
102         .buf = buf,
103     };
104     return new_demux_packet_from_avpacket(&pkt);
105 }
106 
107 // Input data doesn't need to be padded.
new_demux_packet_from(void * data,size_t len)108 struct demux_packet *new_demux_packet_from(void *data, size_t len)
109 {
110     if (len > INT_MAX)
111         return NULL;
112     AVPacket pkt = { .data = data, .size = len };
113     return new_demux_packet_from_avpacket(&pkt);
114 }
115 
new_demux_packet(size_t len)116 struct demux_packet *new_demux_packet(size_t len)
117 {
118     if (len > INT_MAX)
119         return NULL;
120     AVPacket pkt = { .data = NULL, .size = len };
121     return new_demux_packet_from_avpacket(&pkt);
122 }
123 
demux_packet_shorten(struct demux_packet * dp,size_t len)124 void demux_packet_shorten(struct demux_packet *dp, size_t len)
125 {
126     assert(len <= dp->len);
127     if (dp->len) {
128         dp->len = len;
129         memset(dp->buffer + dp->len, 0, AV_INPUT_BUFFER_PADDING_SIZE);
130     }
131 }
132 
free_demux_packet(struct demux_packet * dp)133 void free_demux_packet(struct demux_packet *dp)
134 {
135     talloc_free(dp);
136 }
137 
demux_packet_copy_attribs(struct demux_packet * dst,struct demux_packet * src)138 void demux_packet_copy_attribs(struct demux_packet *dst, struct demux_packet *src)
139 {
140     dst->pts = src->pts;
141     dst->dts = src->dts;
142     dst->duration = src->duration;
143     dst->pos = src->pos;
144     dst->segmented = src->segmented;
145     dst->start = src->start;
146     dst->end = src->end;
147     dst->codec = src->codec;
148     dst->back_restart = src->back_restart;
149     dst->back_preroll = src->back_preroll;
150     dst->keyframe = src->keyframe;
151     dst->stream = src->stream;
152 }
153 
demux_copy_packet(struct demux_packet * dp)154 struct demux_packet *demux_copy_packet(struct demux_packet *dp)
155 {
156     struct demux_packet *new = NULL;
157     if (dp->avpacket) {
158         new = new_demux_packet_from_avpacket(dp->avpacket);
159     } else {
160         // Some packets might be not created by new_demux_packet*().
161         new = new_demux_packet_from(dp->buffer, dp->len);
162     }
163     if (!new)
164         return NULL;
165     demux_packet_copy_attribs(new, dp);
166     return new;
167 }
168 
169 #define ROUND_ALLOC(s) MP_ALIGN_UP((s), 16)
170 
171 // Attempt to estimate the total memory consumption of the given packet.
172 // This is important if we store thousands of packets and not to exceed
173 // user-provided limits. Of course we can't know how much memory internal
174 // fragmentation of the libc memory allocator will waste.
175 // Note that this should return a "stable" value - e.g. if a new packet ref
176 // is created, this should return the same value with the new ref. (This
177 // implies the value is not exact and does not return the actual size of
178 // memory wasted due to internal fragmentation.)
demux_packet_estimate_total_size(struct demux_packet * dp)179 size_t demux_packet_estimate_total_size(struct demux_packet *dp)
180 {
181     size_t size = ROUND_ALLOC(sizeof(struct demux_packet));
182     size += 8 * sizeof(void *); // ta  overhead
183     size += 10 * sizeof(void *); // additional estimate for ta_ext_header
184     if (dp->avpacket) {
185         assert(!dp->is_cached);
186         size += ROUND_ALLOC(dp->len);
187         size += ROUND_ALLOC(sizeof(AVPacket));
188         size += 8 * sizeof(void *); // ta  overhead
189         size += ROUND_ALLOC(sizeof(AVBufferRef));
190         size += ROUND_ALLOC(64); // upper bound estimate on sizeof(AVBuffer)
191         size += ROUND_ALLOC(dp->avpacket->side_data_elems *
192                             sizeof(dp->avpacket->side_data[0]));
193         for (int n = 0; n < dp->avpacket->side_data_elems; n++)
194             size += ROUND_ALLOC(dp->avpacket->side_data[n].size);
195     }
196     return size;
197 }
198 
demux_packet_set_padding(struct demux_packet * dp,int start,int end)199 int demux_packet_set_padding(struct demux_packet *dp, int start, int end)
200 {
201     if (!start && !end)
202         return 0;
203     if (!dp->avpacket)
204         return -1;
205     uint8_t *p = av_packet_new_side_data(dp->avpacket, AV_PKT_DATA_SKIP_SAMPLES, 10);
206     if (!p)
207         return -1;
208 
209     AV_WL32(p + 0, start);
210     AV_WL32(p + 4, end);
211     return 0;
212 }
213 
demux_packet_add_blockadditional(struct demux_packet * dp,uint64_t id,void * data,size_t size)214 int demux_packet_add_blockadditional(struct demux_packet *dp, uint64_t id,
215                                      void *data, size_t size)
216 {
217     if (!dp->avpacket)
218         return -1;
219     uint8_t *sd =  av_packet_new_side_data(dp->avpacket,
220                                            AV_PKT_DATA_MATROSKA_BLOCKADDITIONAL,
221                                            8 + size);
222     if (!sd)
223         return -1;
224     AV_WB64(sd, id);
225     if (size > 0)
226         memcpy(sd + 8, data, size);
227     return 0;
228 }
229