FFmpeg
movenchint.c
Go to the documentation of this file.
1 /*
2  * MOV, 3GP, MP4 muxer RTP hinting
3  * Copyright (c) 2010 Martin Storsjo
4  *
5  * This file is part of FFmpeg.
6  *
7  * FFmpeg is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * FFmpeg is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with FFmpeg; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20  */
21 
22 #include "movenc.h"
23 #include "libavutil/intreadwrite.h"
24 #include "mux.h"
25 #include "rtpenc_chain.h"
26 #include "avio_internal.h"
27 #include "rtp.h"
28 
29 int ff_mov_init_hinting(AVFormatContext *s, int index, int src_index)
30 {
31  MOVMuxContext *mov = s->priv_data;
32  MOVTrack *track = &mov->tracks[index];
33  MOVTrack *src_track = &mov->tracks[src_index];
34  AVStream *src_st = s->streams[src_index];
35  int ret = AVERROR(ENOMEM);
36 
37  track->tag = MKTAG('r','t','p',' ');
38  track->src_track = src_index;
39 
40  track->par = avcodec_parameters_alloc();
41  if (!track->par)
42  goto fail;
44  track->par->codec_tag = track->tag;
45 
46  ret = ff_rtp_chain_mux_open(&track->rtp_ctx, s, src_st, NULL,
47  RTP_MAX_PACKET_SIZE, src_index);
48  if (ret < 0)
49  goto fail;
50 
51  /* Copy the RTP AVStream timebase back to the hint AVStream */
52  track->timescale = track->rtp_ctx->streams[0]->time_base.den;
53 
54  /* Mark the hinted track that packets written to it should be
55  * sent to this track for hinting. */
56  src_track->hint_track = index;
57  return 0;
58 fail:
60  "Unable to initialize hinting of stream %d\n", src_index);
62  /* Set a default timescale, to avoid crashes in av_dump_format */
63  track->timescale = 90000;
64  return ret;
65 }
66 
67 /**
68  * Remove the first sample from the sample queue.
69  */
70 static void sample_queue_pop(HintSampleQueue *queue)
71 {
72  if (queue->len <= 0)
73  return;
74  if (queue->samples[0].own_data)
75  av_freep(&queue->samples[0].data);
76  queue->len--;
77  memmove(queue->samples, queue->samples + 1, sizeof(HintSample)*queue->len);
78 }
79 
80 /**
81  * Empty the sample queue, releasing all memory.
82  */
84 {
85  int i;
86  for (i = 0; i < queue->len; i++)
87  if (queue->samples[i].own_data)
88  av_freep(&queue->samples[i].data);
89  av_freep(&queue->samples);
90  queue->len = 0;
91  queue->size = 0;
92 }
93 
94 /**
95  * Add a reference to the sample data to the sample queue. The data is
96  * not copied. sample_queue_retain should be called before pkt->data
97  * is reused/freed.
98  */
99 static void sample_queue_push(HintSampleQueue *queue, const uint8_t *data, int size,
100  int sample)
101 {
102  /* No need to keep track of smaller samples, since describing them
103  * with immediates is more efficient. */
104  if (size <= 14)
105  return;
106  if (!queue->samples || queue->len >= queue->size) {
108  samples = av_realloc_array(queue->samples, queue->size + 10, sizeof(HintSample));
109  if (!samples)
110  return;
111  queue->size += 10;
112  queue->samples = samples;
113  }
114  queue->samples[queue->len].data = data;
115  queue->samples[queue->len].size = size;
116  queue->samples[queue->len].sample_number = sample;
117  queue->samples[queue->len].offset = 0;
118  queue->samples[queue->len].own_data = 0;
119  queue->len++;
120 }
121 
122 /**
123  * Make local copies of all referenced sample data in the queue.
124  */
126 {
127  int i;
128  for (i = 0; i < queue->len; ) {
129  HintSample *sample = &queue->samples[i];
130  if (!sample->own_data) {
131  uint8_t *ptr = av_malloc(sample->size);
132  if (!ptr) {
133  /* Unable to allocate memory for this one, remove it */
134  memmove(queue->samples + i, queue->samples + i + 1,
135  sizeof(HintSample)*(queue->len - i - 1));
136  queue->len--;
137  continue;
138  }
139  memcpy(ptr, sample->data, sample->size);
140  sample->data = ptr;
141  sample->own_data = 1;
142  }
143  i++;
144  }
145 }
146 
147 /**
148  * Find matches of needle[n_pos ->] within haystack. If a sufficiently
149  * large match is found, matching bytes before n_pos are included
150  * in the match, too (within the limits of the arrays).
151  *
152  * @param haystack buffer that may contain parts of needle
153  * @param h_len length of the haystack buffer
154  * @param needle buffer containing source data that have been used to
155  * construct haystack
156  * @param n_pos start position in needle used for looking for matches
157  * @param n_len length of the needle buffer
158  * @param match_h_offset_ptr offset of the first matching byte within haystack
159  * @param match_n_offset_ptr offset of the first matching byte within needle
160  * @param match_len_ptr length of the matched segment
161  * @return 0 if a match was found, < 0 if no match was found
162  */
163 static int match_segments(const uint8_t *haystack, int h_len,
164  const uint8_t *needle, int n_pos, int n_len,
165  int *match_h_offset_ptr, int *match_n_offset_ptr,
166  int *match_len_ptr)
167 {
168  int h_pos;
169  for (h_pos = 0; h_pos < h_len; h_pos++) {
170  int match_len = 0;
171  int match_h_pos, match_n_pos;
172 
173  /* Check how many bytes match at needle[n_pos] and haystack[h_pos] */
174  while (h_pos + match_len < h_len && n_pos + match_len < n_len &&
175  needle[n_pos + match_len] == haystack[h_pos + match_len])
176  match_len++;
177  if (match_len <= 8)
178  continue;
179 
180  /* If a sufficiently large match was found, try to expand
181  * the matched segment backwards. */
182  match_h_pos = h_pos;
183  match_n_pos = n_pos;
184  while (match_n_pos > 0 && match_h_pos > 0 &&
185  needle[match_n_pos - 1] == haystack[match_h_pos - 1]) {
186  match_n_pos--;
187  match_h_pos--;
188  match_len++;
189  }
190  if (match_len <= 14)
191  continue;
192  *match_h_offset_ptr = match_h_pos;
193  *match_n_offset_ptr = match_n_pos;
194  *match_len_ptr = match_len;
195  return 0;
196  }
197  return -1;
198 }
199 
200 /**
201  * Look for segments in samples in the sample queue matching the data
202  * in ptr. Samples not matching are removed from the queue. If a match
203  * is found, the next time it will look for matches starting from the
204  * end of the previous matched segment.
205  *
206  * @param data data to find matches for in the sample queue
207  * @param len length of the data buffer
208  * @param queue samples used for looking for matching segments
209  * @param pos the offset in data of the matched segment
210  * @param match_sample the number of the sample that contained the match
211  * @param match_offset the offset of the matched segment within the sample
212  * @param match_len the length of the matched segment
213  * @return 0 if a match was found, < 0 if no match was found
214  */
215 static int find_sample_match(const uint8_t *data, int len,
216  HintSampleQueue *queue, int *pos,
217  int *match_sample, int *match_offset,
218  int *match_len)
219 {
220  while (queue->len > 0) {
221  HintSample *sample = &queue->samples[0];
222  /* If looking for matches in a new sample, skip the first 5 bytes,
223  * since they often may be modified/removed in the output packet. */
224  if (sample->offset == 0 && sample->size > 5)
225  sample->offset = 5;
226 
227  if (match_segments(data, len, sample->data, sample->offset,
228  sample->size, pos, match_offset, match_len) == 0) {
229  *match_sample = sample->sample_number;
230  /* Next time, look for matches at this offset, with a little
231  * margin to this match. */
232  sample->offset = *match_offset + *match_len + 5;
233  if (sample->offset + 10 >= sample->size)
234  sample_queue_pop(queue); /* Not enough useful data left */
235  return 0;
236  }
237 
238  if (sample->offset < 10 && sample->size > 20) {
239  /* No match found from the start of the sample,
240  * try from the middle of the sample instead. */
241  sample->offset = sample->size/2;
242  } else {
243  /* No match for this sample, remove it */
244  sample_queue_pop(queue);
245  }
246  }
247  return -1;
248 }
249 
250 static void output_immediate(const uint8_t *data, int size,
251  AVIOContext *out, int *entries)
252 {
253  while (size > 0) {
254  int len = size;
255  if (len > 14)
256  len = 14;
257  avio_w8(out, 1); /* immediate constructor */
258  avio_w8(out, len); /* amount of valid data */
259  avio_write(out, data, len);
260  data += len;
261  size -= len;
262 
263  ffio_fill(out, 0, 14 - len);
264 
265  (*entries)++;
266  }
267 }
268 
269 static void output_match(AVIOContext *out, int match_sample,
270  int match_offset, int match_len, int *entries)
271 {
272  avio_w8(out, 2); /* sample constructor */
273  avio_w8(out, 0); /* track reference */
274  avio_wb16(out, match_len);
275  avio_wb32(out, match_sample);
276  avio_wb32(out, match_offset);
277  avio_wb16(out, 1); /* bytes per block */
278  avio_wb16(out, 1); /* samples per block */
279  (*entries)++;
280 }
281 
282 static void describe_payload(const uint8_t *data, int size,
283  AVIOContext *out, int *entries,
284  HintSampleQueue *queue)
285 {
286  /* Describe the payload using different constructors */
287  while (size > 0) {
288  int match_sample, match_offset, match_len, pos;
289  if (find_sample_match(data, size, queue, &pos, &match_sample,
290  &match_offset, &match_len) < 0)
291  break;
292  output_immediate(data, pos, out, entries);
293  data += pos;
294  size -= pos;
295  output_match(out, match_sample, match_offset, match_len, entries);
296  data += match_len;
297  size -= match_len;
298  }
299  output_immediate(data, size, out, entries);
300 }
301 
302 /**
303  * Write an RTP hint (that may contain one or more RTP packets)
304  * for the packets in data. data contains one or more packets with a
305  * BE32 size header.
306  *
307  * @param out buffer where the hints are written
308  * @param data buffer containing RTP packets
309  * @param size the size of the data buffer
310  * @param trk the MOVTrack for the hint track
311  * @param dts pointer where the timestamp for the written RTP hint is stored
312  * @return the number of RTP packets in the written hint
313  */
314 static int write_hint_packets(AVIOContext *out, const uint8_t *data,
315  int size, MOVTrack *trk, int64_t *dts)
316 {
317  int64_t curpos;
318  int64_t count_pos, entries_pos;
319  int count = 0, entries;
320 
321  count_pos = avio_tell(out);
322  /* RTPsample header */
323  avio_wb16(out, 0); /* packet count */
324  avio_wb16(out, 0); /* reserved */
325 
326  while (size > 4) {
327  uint32_t packet_len = AV_RB32(data);
328  uint16_t seq;
329  uint32_t ts;
330  int32_t ts_diff;
331 
332  data += 4;
333  size -= 4;
334  if (packet_len > size || packet_len <= 12)
335  break;
336  if (RTP_PT_IS_RTCP(data[1])) {
337  /* RTCP packet, just skip */
338  data += packet_len;
339  size -= packet_len;
340  continue;
341  }
342 
343  if (packet_len > trk->max_packet_size)
344  trk->max_packet_size = packet_len;
345 
346  seq = AV_RB16(&data[2]);
347  ts = AV_RB32(&data[4]);
348 
349  if (trk->prev_rtp_ts == 0)
350  trk->prev_rtp_ts = ts;
351  /* Unwrap the 32-bit RTP timestamp that wraps around often
352  * into a not (as often) wrapping 64-bit timestamp. */
353  ts_diff = ts - trk->prev_rtp_ts;
354  if (ts_diff > 0) {
355  trk->cur_rtp_ts_unwrapped += ts_diff;
356  trk->prev_rtp_ts = ts;
357  ts_diff = 0;
358  }
359  if (*dts == AV_NOPTS_VALUE)
360  *dts = trk->cur_rtp_ts_unwrapped;
361 
362  count++;
363  /* RTPpacket header */
364  avio_wb32(out, 0); /* relative_time */
365  avio_write(out, data, 2); /* RTP header */
366  avio_wb16(out, seq); /* RTPsequenceseed */
367  avio_wb16(out, ts_diff ? 4 : 0); /* reserved + flags (extra_flag) */
368  entries_pos = avio_tell(out);
369  avio_wb16(out, 0); /* entry count */
370  if (ts_diff) { /* if extra_flag is set */
371  avio_wb32(out, 16); /* extra_information_length */
372  avio_wb32(out, 12); /* rtpoffsetTLV box */
373  avio_write(out, "rtpo", 4);
374  avio_wb32(out, ts_diff);
375  }
376 
377  data += 12;
378  size -= 12;
379  packet_len -= 12;
380 
381  entries = 0;
382  /* Write one or more constructors describing the payload data */
383  describe_payload(data, packet_len, out, &entries, &trk->sample_queue);
384  data += packet_len;
385  size -= packet_len;
386 
387  curpos = avio_tell(out);
388  avio_seek(out, entries_pos, SEEK_SET);
389  avio_wb16(out, entries);
390  avio_seek(out, curpos, SEEK_SET);
391  }
392 
393  curpos = avio_tell(out);
394  avio_seek(out, count_pos, SEEK_SET);
395  avio_wb16(out, count);
396  avio_seek(out, curpos, SEEK_SET);
397  return count;
398 }
399 
401  int track_index, int sample,
402  uint8_t *sample_data, int sample_size)
403 {
404  MOVMuxContext *mov = s->priv_data;
405  MOVTrack *trk = &mov->tracks[track_index];
406  AVFormatContext *rtp_ctx = trk->rtp_ctx;
407  uint8_t *buf = NULL;
408  int size;
409  AVIOContext *hintbuf = NULL;
410  AVPacket *hint_pkt = mov->pkt;
411  int ret = 0, count;
412 
413  if (!rtp_ctx)
414  return AVERROR(ENOENT);
415  if (!rtp_ctx->pb)
416  return AVERROR(ENOMEM);
417 
418  if (sample_data)
419  sample_queue_push(&trk->sample_queue, sample_data, sample_size, sample);
420  else
422 
423  /* Feed the packet to the RTP muxer */
424  ff_write_chained(rtp_ctx, 0, pkt, s, 0);
425 
426  /* Fetch the output from the RTP muxer, open a new output buffer
427  * for next time. */
428  size = avio_close_dyn_buf(rtp_ctx->pb, &buf);
429  if ((ret = ffio_open_dyn_packet_buf(&rtp_ctx->pb,
430  RTP_MAX_PACKET_SIZE)) < 0)
431  goto done;
432 
433  if (size <= 0)
434  goto done;
435 
436  /* Open a buffer for writing the hint */
437  if ((ret = avio_open_dyn_buf(&hintbuf)) < 0)
438  goto done;
439  av_packet_unref(hint_pkt);
440  count = write_hint_packets(hintbuf, buf, size, trk, &hint_pkt->dts);
441  av_freep(&buf);
442 
443  /* Write the hint data into the hint track */
444  hint_pkt->size = size = avio_close_dyn_buf(hintbuf, &buf);
445  hint_pkt->data = buf;
446  hint_pkt->pts = hint_pkt->dts;
447  hint_pkt->stream_index = track_index;
448  if (pkt->flags & AV_PKT_FLAG_KEY)
449  hint_pkt->flags |= AV_PKT_FLAG_KEY;
450  if (count > 0)
451  ff_mov_write_packet(s, hint_pkt);
452 done:
453  av_free(buf);
454  av_packet_unref(hint_pkt);
456  return ret;
457 }
458 
460 {
461  AVFormatContext *rtp_ctx = track->rtp_ctx;
462 
463  avcodec_parameters_free(&track->par);
465  if (!rtp_ctx)
466  return;
467  if (rtp_ctx->pb) {
468  av_write_trailer(rtp_ctx);
469  ffio_free_dyn_buf(&rtp_ctx->pb);
470  }
471  avformat_free_context(rtp_ctx);
472 }
av_packet_unref
void av_packet_unref(AVPacket *pkt)
Wipe the packet.
Definition: avpacket.c:427
sample_queue_free
static void sample_queue_free(HintSampleQueue *queue)
Empty the sample queue, releasing all memory.
Definition: movenchint.c:83
sample_queue_pop
static void sample_queue_pop(HintSampleQueue *queue)
Remove the first sample from the sample queue.
Definition: movenchint.c:70
AV_LOG_WARNING
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition: log.h:186
AVERROR
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample they are references to shared objects When the negotiation mechanism computes the intersection of the formats supported at each end of a all references to both lists are replaced with a reference to the intersection And when a single format is eventually chosen for a link amongst the remaining all references to the list are updated That means that if a filter requires that its input and output have the same format amongst a supported all it has to do is use a reference to the same list of formats query_formats can leave some formats unset and return AVERROR(EAGAIN) to cause the negotiation mechanism toagain later. That can be used by filters with complex requirements to use the format negotiated on one link to set the formats supported on another. Frame references ownership and permissions
AVCodecParameters::codec_type
enum AVMediaType codec_type
General type of the encoded data.
Definition: codec_par.h:51
out
FILE * out
Definition: movenc.c:54
int64_t
long long int64_t
Definition: coverity.c:34
ff_mov_close_hinting
void ff_mov_close_hinting(MOVTrack *track)
Definition: movenchint.c:459
AVFormatContext::streams
AVStream ** streams
A list of all streams in the file.
Definition: avformat.h:1323
AVPacket::data
uint8_t * data
Definition: packet.h:522
HintSample::data
const uint8_t * data
Definition: movenc.h:65
data
const char data[16]
Definition: mxf.c:148
MOVTrack::tag
int tag
stsd fourcc
Definition: movenc.h:108
AVCodecParameters::codec_tag
uint32_t codec_tag
Additional information about the codec (corresponds to the AVI FOURCC).
Definition: codec_par.h:59
HintSampleQueue::size
int size
Definition: movenc.h:73
track_index
static int track_index(VividasDemuxContext *viv, AVFormatContext *s, const uint8_t *buf, unsigned size)
Definition: vividas.c:437
AV_PKT_FLAG_KEY
#define AV_PKT_FLAG_KEY
The packet contains a keyframe.
Definition: packet.h:577
av_malloc
#define av_malloc(s)
Definition: tableprint_vlc.h:30
MOVTrack
Definition: movenc.h:86
describe_payload
static void describe_payload(const uint8_t *data, int size, AVIOContext *out, int *entries, HintSampleQueue *queue)
Definition: movenchint.c:282
fail
#define fail()
Definition: checkasm.h:179
HintSample::own_data
int own_data
Definition: movenc.h:69
rtpenc_chain.h
ff_mov_add_hinted_packet
int ff_mov_add_hinted_packet(AVFormatContext *s, AVPacket *pkt, int track_index, int sample, uint8_t *sample_data, int sample_size)
Definition: movenchint.c:400
avio_tell
static av_always_inline int64_t avio_tell(AVIOContext *s)
ftell() equivalent for AVIOContext.
Definition: avio.h:494
MOVTrack::cur_rtp_ts_unwrapped
int64_t cur_rtp_ts_unwrapped
Definition: movenc.h:132
HintSample::offset
int offset
Definition: movenc.h:68
avio_close_dyn_buf
int avio_close_dyn_buf(AVIOContext *s, uint8_t **pbuffer)
Return the written size and a pointer to the buffer.
Definition: aviobuf.c:1406
pkt
AVPacket * pkt
Definition: movenc.c:59
MOVMuxContext::pkt
AVPacket * pkt
Definition: movenc.h:230
avio_open_dyn_buf
int avio_open_dyn_buf(AVIOContext **s)
Open a write only memory stream.
Definition: aviobuf.c:1361
intreadwrite.h
s
#define s(width, name)
Definition: cbs_vp9.c:198
MOVTrack::sample_queue
HintSampleQueue sample_queue
Definition: movenc.h:139
av_realloc_array
void * av_realloc_array(void *ptr, size_t nmemb, size_t size)
Definition: mem.c:215
HintSampleQueue
Definition: movenc.h:72
MOVTrack::max_packet_size
uint32_t max_packet_size
Definition: movenc.h:133
HintSample::size
int size
Definition: movenc.h:66
AVMEDIA_TYPE_DATA
@ AVMEDIA_TYPE_DATA
Opaque data information usually continuous.
Definition: avutil.h:203
AVFormatContext
Format I/O context.
Definition: avformat.h:1255
AVStream::time_base
AVRational time_base
This is the fundamental unit of time (in seconds) in terms of which frame timestamps are represented.
Definition: avformat.h:782
NULL
#define NULL
Definition: coverity.c:32
MOVTrack::src_track
int src_track
the track that this hint (or tmcd) track describes
Definition: movenc.h:129
avcodec_parameters_free
void avcodec_parameters_free(AVCodecParameters **ppar)
Free an AVCodecParameters instance and everything associated with it and write NULL to the supplied p...
Definition: codec_par.c:66
AVFormatContext::pb
AVIOContext * pb
I/O context.
Definition: avformat.h:1297
write_hint_packets
static int write_hint_packets(AVIOContext *out, const uint8_t *data, int size, MOVTrack *trk, int64_t *dts)
Write an RTP hint (that may contain one or more RTP packets) for the packets in data.
Definition: movenchint.c:314
MOVTrack::prev_rtp_ts
uint32_t prev_rtp_ts
Definition: movenc.h:131
MOVMuxContext
Definition: movenc.h:192
avio_w8
void avio_w8(AVIOContext *s, int b)
Definition: aviobuf.c:178
ffio_fill
void ffio_fill(AVIOContext *s, int b, int64_t count)
Definition: aviobuf.c:186
HintSample::sample_number
int sample_number
Definition: movenc.h:67
index
int index
Definition: gxfenc.c:89
movenc.h
RTP_PT_IS_RTCP
#define RTP_PT_IS_RTCP(x)
Definition: rtp.h:112
AVIOContext
Bytestream IO Context.
Definition: avio.h:160
AVPacket::size
int size
Definition: packet.h:523
sample
#define sample
Definition: flacdsp_template.c:44
size
int size
Definition: twinvq_data.h:10344
AV_NOPTS_VALUE
#define AV_NOPTS_VALUE
Undefined timestamp value.
Definition: avutil.h:248
AV_RB32
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_WL32 unsigned int_TMPL AV_WL24 unsigned int_TMPL AV_WL16 uint64_t_TMPL AV_WB64 unsigned int_TMPL AV_RB32
Definition: bytestream.h:96
AVPacket::dts
int64_t dts
Decompression timestamp in AVStream->time_base units; the time at which the packet is decompressed.
Definition: packet.h:521
avio_write
void avio_write(AVIOContext *s, const unsigned char *buf, int size)
Definition: aviobuf.c:200
avio_wb32
void avio_wb32(AVIOContext *s, unsigned int val)
Definition: aviobuf.c:364
ffio_open_dyn_packet_buf
int ffio_open_dyn_packet_buf(AVIOContext **s, int max_packet_size)
Open a write only packetized memory stream with a maximum packet size of 'max_packet_size'.
Definition: aviobuf.c:1366
HintSampleQueue::len
int len
Definition: movenc.h:74
AVPacket::flags
int flags
A combination of AV_PKT_FLAG values.
Definition: packet.h:528
sample_queue_retain
static void sample_queue_retain(HintSampleQueue *queue)
Make local copies of all referenced sample data in the queue.
Definition: movenchint.c:125
match_segments
static int match_segments(const uint8_t *haystack, int h_len, const uint8_t *needle, int n_pos, int n_len, int *match_h_offset_ptr, int *match_n_offset_ptr, int *match_len_ptr)
Find matches of needle[n_pos ->] within haystack.
Definition: movenchint.c:163
rtp.h
avcodec_parameters_alloc
AVCodecParameters * avcodec_parameters_alloc(void)
Allocate a new AVCodecParameters and set its fields to default values (unknown/invalid/0).
Definition: codec_par.c:56
MOVTrack::hint_track
int hint_track
the track that hints this track, -1 if no hint track is set
Definition: movenc.h:128
av_write_trailer
int av_write_trailer(AVFormatContext *s)
Write the stream trailer to an output media file and free the file private data.
Definition: mux.c:1294
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:255
AVPacket::pts
int64_t pts
Presentation timestamp in AVStream->time_base units; the time at which the decompressed packet will b...
Definition: packet.h:515
avio_internal.h
ff_mov_write_packet
int ff_mov_write_packet(AVFormatContext *s, AVPacket *pkt)
Definition: movenc.c:6182
MOVTrack::rtp_ctx
AVFormatContext * rtp_ctx
the format context for the hinting rtp muxer
Definition: movenc.h:130
len
int len
Definition: vorbis_enc_data.h:426
ff_mov_init_hinting
int ff_mov_init_hinting(AVFormatContext *s, int index, int src_index)
Definition: movenchint.c:29
ffio_free_dyn_buf
void ffio_free_dyn_buf(AVIOContext **s)
Free a dynamic buffer.
Definition: aviobuf.c:1434
ret
ret
Definition: filter_design.txt:187
AVStream
Stream structure.
Definition: avformat.h:743
avio_seek
int64_t avio_seek(AVIOContext *s, int64_t offset, int whence)
fseek() equivalent for AVIOContext.
Definition: aviobuf.c:230
pos
unsigned int pos
Definition: spdifenc.c:413
ff_rtp_chain_mux_open
int ff_rtp_chain_mux_open(AVFormatContext **out, AVFormatContext *s, AVStream *st, URLContext *handle, int packet_size, int idx)
Definition: rtpenc_chain.c:29
MOVTrack::par
AVCodecParameters * par
Definition: movenc.h:110
AVRational::den
int den
Denominator.
Definition: rational.h:60
HintSampleQueue::samples
HintSample * samples
Definition: movenc.h:75
avformat_free_context
void avformat_free_context(AVFormatContext *s)
Free an AVFormatContext and all its streams.
Definition: avformat.c:141
MOVMuxContext::tracks
MOVTrack * tracks
Definition: movenc.h:202
samples
Filter the word “frame” indicates either a video frame or a group of audio samples
Definition: filter_design.txt:8
AVPacket::stream_index
int stream_index
Definition: packet.h:524
output_match
static void output_match(AVIOContext *out, int match_sample, int match_offset, int match_len, int *entries)
Definition: movenchint.c:269
MOVTrack::timescale
unsigned timescale
Definition: movenc.h:89
output_immediate
static void output_immediate(const uint8_t *data, int size, AVIOContext *out, int *entries)
Definition: movenchint.c:250
find_sample_match
static int find_sample_match(const uint8_t *data, int len, HintSampleQueue *queue, int *pos, int *match_sample, int *match_offset, int *match_len)
Look for segments in samples in the sample queue matching the data in ptr.
Definition: movenchint.c:215
HintSample
Definition: movenc.h:64
av_free
#define av_free(p)
Definition: tableprint_vlc.h:33
AVPacket
This structure stores compressed data.
Definition: packet.h:499
av_freep
#define av_freep(p)
Definition: tableprint_vlc.h:34
sample_queue_push
static void sample_queue_push(HintSampleQueue *queue, const uint8_t *data, int size, int sample)
Add a reference to the sample data to the sample queue.
Definition: movenchint.c:99
int32_t
int32_t
Definition: audioconvert.c:56
avio_wb16
void avio_wb16(AVIOContext *s, unsigned int val)
Definition: aviobuf.c:442
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:27
MKTAG
#define MKTAG(a, b, c, d)
Definition: macros.h:55
RTP_MAX_PACKET_SIZE
#define RTP_MAX_PACKET_SIZE
Definition: movenc.h:35
AV_RB16
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_WL32 unsigned int_TMPL AV_WL24 unsigned int_TMPL AV_WL16 uint64_t_TMPL AV_WB64 unsigned int_TMPL AV_WB32 unsigned int_TMPL AV_WB24 unsigned int_TMPL AV_RB16
Definition: bytestream.h:98
mux.h
ff_write_chained
int ff_write_chained(AVFormatContext *dst, int dst_stream, AVPacket *pkt, AVFormatContext *src, int interleave)
Write a packet to another muxer than the one the user originally intended.
Definition: mux.c:1393