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 "libavutil/mem.h"
25 #include "mux.h"
26 #include "rtpenc_chain.h"
27 #include "avio_internal.h"
28 #include "rtp.h"
29 
30 int ff_mov_init_hinting(AVFormatContext *s, int index, int src_index)
31 {
32  MOVMuxContext *mov = s->priv_data;
33  MOVTrack *track = &mov->tracks[index];
34  MOVTrack *src_track = &mov->tracks[src_index];
35  AVStream *src_st = s->streams[src_index];
36  int ret = AVERROR(ENOMEM);
37 
38  track->tag = MKTAG('r','t','p',' ');
39  track->src_track = src_index;
40 
41  track->par = avcodec_parameters_alloc();
42  if (!track->par)
43  goto fail;
45  track->par->codec_tag = track->tag;
46 
47  ret = ff_rtp_chain_mux_open(&track->rtp_ctx, s, src_st, NULL,
48  RTP_MAX_PACKET_SIZE, src_index);
49  if (ret < 0)
50  goto fail;
51 
52  /* Copy the RTP AVStream timebase back to the hint AVStream */
53  track->timescale = track->rtp_ctx->streams[0]->time_base.den;
54 
55  /* Mark the hinted track that packets written to it should be
56  * sent to this track for hinting. */
57  src_track->hint_track = index;
58  return 0;
59 fail:
61  "Unable to initialize hinting of stream %d\n", src_index);
63  /* Set a default timescale, to avoid crashes in av_dump_format */
64  track->timescale = 90000;
65  return ret;
66 }
67 
68 /**
69  * Remove the first sample from the sample queue.
70  */
71 static void sample_queue_pop(HintSampleQueue *queue)
72 {
73  if (queue->len <= 0)
74  return;
75  if (queue->samples[0].own_data)
76  av_freep(&queue->samples[0].data);
77  queue->len--;
78  memmove(queue->samples, queue->samples + 1, sizeof(HintSample)*queue->len);
79 }
80 
81 /**
82  * Empty the sample queue, releasing all memory.
83  */
85 {
86  int i;
87  for (i = 0; i < queue->len; i++)
88  if (queue->samples[i].own_data)
89  av_freep(&queue->samples[i].data);
90  av_freep(&queue->samples);
91  queue->len = 0;
92  queue->size = 0;
93 }
94 
95 /**
96  * Add a reference to the sample data to the sample queue. The data is
97  * not copied. sample_queue_retain should be called before pkt->data
98  * is reused/freed.
99  */
100 static void sample_queue_push(HintSampleQueue *queue, const uint8_t *data, int size,
101  int sample)
102 {
103  /* No need to keep track of smaller samples, since describing them
104  * with immediates is more efficient. */
105  if (size <= 14)
106  return;
107  if (!queue->samples || queue->len >= queue->size) {
109  samples = av_realloc_array(queue->samples, queue->size + 10, sizeof(HintSample));
110  if (!samples)
111  return;
112  queue->size += 10;
113  queue->samples = samples;
114  }
115  queue->samples[queue->len].data = data;
116  queue->samples[queue->len].size = size;
117  queue->samples[queue->len].sample_number = sample;
118  queue->samples[queue->len].offset = 0;
119  queue->samples[queue->len].own_data = 0;
120  queue->len++;
121 }
122 
123 /**
124  * Make local copies of all referenced sample data in the queue.
125  */
127 {
128  int i;
129  for (i = 0; i < queue->len; ) {
130  HintSample *sample = &queue->samples[i];
131  if (!sample->own_data) {
132  uint8_t *ptr = av_malloc(sample->size);
133  if (!ptr) {
134  /* Unable to allocate memory for this one, remove it */
135  memmove(queue->samples + i, queue->samples + i + 1,
136  sizeof(HintSample)*(queue->len - i - 1));
137  queue->len--;
138  continue;
139  }
140  memcpy(ptr, sample->data, sample->size);
141  sample->data = ptr;
142  sample->own_data = 1;
143  }
144  i++;
145  }
146 }
147 
148 /**
149  * Find matches of needle[n_pos ->] within haystack. If a sufficiently
150  * large match is found, matching bytes before n_pos are included
151  * in the match, too (within the limits of the arrays).
152  *
153  * @param haystack buffer that may contain parts of needle
154  * @param h_len length of the haystack buffer
155  * @param needle buffer containing source data that have been used to
156  * construct haystack
157  * @param n_pos start position in needle used for looking for matches
158  * @param n_len length of the needle buffer
159  * @param match_h_offset_ptr offset of the first matching byte within haystack
160  * @param match_n_offset_ptr offset of the first matching byte within needle
161  * @param match_len_ptr length of the matched segment
162  * @return 0 if a match was found, < 0 if no match was found
163  */
164 static int match_segments(const uint8_t *haystack, int h_len,
165  const uint8_t *needle, int n_pos, int n_len,
166  int *match_h_offset_ptr, int *match_n_offset_ptr,
167  int *match_len_ptr)
168 {
169  int h_pos;
170  for (h_pos = 0; h_pos < h_len; h_pos++) {
171  int match_len = 0;
172  int match_h_pos, match_n_pos;
173 
174  /* Check how many bytes match at needle[n_pos] and haystack[h_pos] */
175  while (h_pos + match_len < h_len && n_pos + match_len < n_len &&
176  needle[n_pos + match_len] == haystack[h_pos + match_len])
177  match_len++;
178  if (match_len <= 8)
179  continue;
180 
181  /* If a sufficiently large match was found, try to expand
182  * the matched segment backwards. */
183  match_h_pos = h_pos;
184  match_n_pos = n_pos;
185  while (match_n_pos > 0 && match_h_pos > 0 &&
186  needle[match_n_pos - 1] == haystack[match_h_pos - 1]) {
187  match_n_pos--;
188  match_h_pos--;
189  match_len++;
190  }
191  if (match_len <= 14)
192  continue;
193  *match_h_offset_ptr = match_h_pos;
194  *match_n_offset_ptr = match_n_pos;
195  *match_len_ptr = match_len;
196  return 0;
197  }
198  return -1;
199 }
200 
201 /**
202  * Look for segments in samples in the sample queue matching the data
203  * in ptr. Samples not matching are removed from the queue. If a match
204  * is found, the next time it will look for matches starting from the
205  * end of the previous matched segment.
206  *
207  * @param data data to find matches for in the sample queue
208  * @param len length of the data buffer
209  * @param queue samples used for looking for matching segments
210  * @param pos the offset in data of the matched segment
211  * @param match_sample the number of the sample that contained the match
212  * @param match_offset the offset of the matched segment within the sample
213  * @param match_len the length of the matched segment
214  * @return 0 if a match was found, < 0 if no match was found
215  */
216 static int find_sample_match(const uint8_t *data, int len,
217  HintSampleQueue *queue, int *pos,
218  int *match_sample, int *match_offset,
219  int *match_len)
220 {
221  while (queue->len > 0) {
222  HintSample *sample = &queue->samples[0];
223  /* If looking for matches in a new sample, skip the first 5 bytes,
224  * since they often may be modified/removed in the output packet. */
225  if (sample->offset == 0 && sample->size > 5)
226  sample->offset = 5;
227 
228  if (match_segments(data, len, sample->data, sample->offset,
229  sample->size, pos, match_offset, match_len) == 0) {
230  *match_sample = sample->sample_number;
231  /* Next time, look for matches at this offset, with a little
232  * margin to this match. */
233  sample->offset = *match_offset + *match_len + 5;
234  if (sample->offset + 10 >= sample->size)
235  sample_queue_pop(queue); /* Not enough useful data left */
236  return 0;
237  }
238 
239  if (sample->offset < 10 && sample->size > 20) {
240  /* No match found from the start of the sample,
241  * try from the middle of the sample instead. */
242  sample->offset = sample->size/2;
243  } else {
244  /* No match for this sample, remove it */
245  sample_queue_pop(queue);
246  }
247  }
248  return -1;
249 }
250 
251 static void output_immediate(const uint8_t *data, int size,
252  AVIOContext *out, int *entries)
253 {
254  while (size > 0) {
255  int len = size;
256  if (len > 14)
257  len = 14;
258  avio_w8(out, 1); /* immediate constructor */
259  avio_w8(out, len); /* amount of valid data */
260  avio_write(out, data, len);
261  data += len;
262  size -= len;
263 
264  ffio_fill(out, 0, 14 - len);
265 
266  (*entries)++;
267  }
268 }
269 
270 static void output_match(AVIOContext *out, int match_sample,
271  int match_offset, int match_len, int *entries)
272 {
273  avio_w8(out, 2); /* sample constructor */
274  avio_w8(out, 0); /* track reference */
275  avio_wb16(out, match_len);
276  avio_wb32(out, match_sample);
277  avio_wb32(out, match_offset);
278  avio_wb16(out, 1); /* bytes per block */
279  avio_wb16(out, 1); /* samples per block */
280  (*entries)++;
281 }
282 
283 static void describe_payload(const uint8_t *data, int size,
284  AVIOContext *out, int *entries,
285  HintSampleQueue *queue)
286 {
287  /* Describe the payload using different constructors */
288  while (size > 0) {
289  int match_sample, match_offset, match_len, pos;
290  if (find_sample_match(data, size, queue, &pos, &match_sample,
291  &match_offset, &match_len) < 0)
292  break;
293  output_immediate(data, pos, out, entries);
294  data += pos;
295  size -= pos;
296  output_match(out, match_sample, match_offset, match_len, entries);
297  data += match_len;
298  size -= match_len;
299  }
300  output_immediate(data, size, out, entries);
301 }
302 
303 /**
304  * Write an RTP hint (that may contain one or more RTP packets)
305  * for the packets in data. data contains one or more packets with a
306  * BE32 size header.
307  *
308  * @param out buffer where the hints are written
309  * @param data buffer containing RTP packets
310  * @param size the size of the data buffer
311  * @param trk the MOVTrack for the hint track
312  * @param dts pointer where the timestamp for the written RTP hint is stored
313  * @return the number of RTP packets in the written hint
314  */
315 static int write_hint_packets(AVIOContext *out, const uint8_t *data,
316  int size, MOVTrack *trk, int64_t *dts)
317 {
318  int64_t curpos;
319  int64_t count_pos, entries_pos;
320  int count = 0, entries;
321 
322  count_pos = avio_tell(out);
323  /* RTPsample header */
324  avio_wb16(out, 0); /* packet count */
325  avio_wb16(out, 0); /* reserved */
326 
327  while (size > 4) {
328  uint32_t packet_len = AV_RB32(data);
329  uint16_t seq;
330  uint32_t ts;
331  int32_t ts_diff;
332 
333  data += 4;
334  size -= 4;
335  if (packet_len > size || packet_len <= 12)
336  break;
337  if (RTP_PT_IS_RTCP(data[1])) {
338  /* RTCP packet, just skip */
339  data += packet_len;
340  size -= packet_len;
341  continue;
342  }
343 
344  if (packet_len > trk->max_packet_size)
345  trk->max_packet_size = packet_len;
346 
347  seq = AV_RB16(&data[2]);
348  ts = AV_RB32(&data[4]);
349 
350  if (trk->prev_rtp_ts == 0)
351  trk->prev_rtp_ts = ts;
352  /* Unwrap the 32-bit RTP timestamp that wraps around often
353  * into a not (as often) wrapping 64-bit timestamp. */
354  ts_diff = ts - trk->prev_rtp_ts;
355  if (ts_diff > 0) {
356  trk->cur_rtp_ts_unwrapped += ts_diff;
357  trk->prev_rtp_ts = ts;
358  ts_diff = 0;
359  }
360  if (*dts == AV_NOPTS_VALUE)
361  *dts = trk->cur_rtp_ts_unwrapped;
362 
363  count++;
364  /* RTPpacket header */
365  avio_wb32(out, 0); /* relative_time */
366  avio_write(out, data, 2); /* RTP header */
367  avio_wb16(out, seq); /* RTPsequenceseed */
368  avio_wb16(out, ts_diff ? 4 : 0); /* reserved + flags (extra_flag) */
369  entries_pos = avio_tell(out);
370  avio_wb16(out, 0); /* entry count */
371  if (ts_diff) { /* if extra_flag is set */
372  avio_wb32(out, 16); /* extra_information_length */
373  avio_wb32(out, 12); /* rtpoffsetTLV box */
374  avio_write(out, "rtpo", 4);
375  avio_wb32(out, ts_diff);
376  }
377 
378  data += 12;
379  size -= 12;
380  packet_len -= 12;
381 
382  entries = 0;
383  /* Write one or more constructors describing the payload data */
384  describe_payload(data, packet_len, out, &entries, &trk->sample_queue);
385  data += packet_len;
386  size -= packet_len;
387 
388  curpos = avio_tell(out);
389  avio_seek(out, entries_pos, SEEK_SET);
390  avio_wb16(out, entries);
391  avio_seek(out, curpos, SEEK_SET);
392  }
393 
394  curpos = avio_tell(out);
395  avio_seek(out, count_pos, SEEK_SET);
396  avio_wb16(out, count);
397  avio_seek(out, curpos, SEEK_SET);
398  return count;
399 }
400 
402  int track_index, int sample,
403  uint8_t *sample_data, int sample_size)
404 {
405  MOVMuxContext *mov = s->priv_data;
406  MOVTrack *trk = &mov->tracks[track_index];
407  AVFormatContext *rtp_ctx = trk->rtp_ctx;
408  uint8_t *buf = NULL;
409  int size;
410  AVIOContext *hintbuf = NULL;
411  AVPacket *hint_pkt = mov->pkt;
412  int ret = 0, count;
413 
414  if (!rtp_ctx)
415  return AVERROR(ENOENT);
416  if (!rtp_ctx->pb)
417  return AVERROR(ENOMEM);
418 
419  if (sample_data)
420  sample_queue_push(&trk->sample_queue, sample_data, sample_size, sample);
421  else
423 
424  /* Feed the packet to the RTP muxer */
425  ff_write_chained(rtp_ctx, 0, pkt, s, 0);
426 
427  /* Fetch the output from the RTP muxer, open a new output buffer
428  * for next time. */
429  size = avio_close_dyn_buf(rtp_ctx->pb, &buf);
430  if ((ret = ffio_open_dyn_packet_buf(&rtp_ctx->pb,
431  RTP_MAX_PACKET_SIZE)) < 0)
432  goto done;
433 
434  if (size <= 0)
435  goto done;
436 
437  /* Open a buffer for writing the hint */
438  if ((ret = avio_open_dyn_buf(&hintbuf)) < 0)
439  goto done;
440  av_packet_unref(hint_pkt);
441  count = write_hint_packets(hintbuf, buf, size, trk, &hint_pkt->dts);
442  av_freep(&buf);
443 
444  /* Write the hint data into the hint track */
445  hint_pkt->size = size = avio_close_dyn_buf(hintbuf, &buf);
446  hint_pkt->data = buf;
447  hint_pkt->pts = hint_pkt->dts;
448  hint_pkt->stream_index = track_index;
449  if (pkt->flags & AV_PKT_FLAG_KEY)
450  hint_pkt->flags |= AV_PKT_FLAG_KEY;
451  if (count > 0)
452  ff_mov_write_packet(s, hint_pkt);
453 done:
454  av_free(buf);
455  av_packet_unref(hint_pkt);
457  return ret;
458 }
459 
461 {
462  AVFormatContext *rtp_ctx = track->rtp_ctx;
463 
464  avcodec_parameters_free(&track->par);
466  if (!rtp_ctx)
467  return;
468  if (rtp_ctx->pb) {
469  av_write_trailer(rtp_ctx);
470  ffio_free_dyn_buf(&rtp_ctx->pb);
471  }
472  avformat_free_context(rtp_ctx);
473 }
av_packet_unref
void av_packet_unref(AVPacket *pkt)
Wipe the packet.
Definition: packet.c:427
sample_queue_free
static void sample_queue_free(HintSampleQueue *queue)
Empty the sample queue, releasing all memory.
Definition: movenchint.c:84
sample_queue_pop
static void sample_queue_pop(HintSampleQueue *queue)
Remove the first sample from the sample queue.
Definition: movenchint.c:71
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:55
ff_mov_close_hinting
void ff_mov_close_hinting(MOVTrack *track)
Definition: movenchint.c:460
AVFormatContext::streams
AVStream ** streams
A list of all streams in the file.
Definition: avformat.h:1323
AVPacket::data
uint8_t * data
Definition: packet.h:524
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:438
AV_PKT_FLAG_KEY
#define AV_PKT_FLAG_KEY
The packet contains a keyframe.
Definition: packet.h:579
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:283
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:401
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:1407
pkt
AVPacket * pkt
Definition: movenc.c:60
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:1362
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:217
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:315
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:179
ffio_fill
void ffio_fill(AVIOContext *s, int b, int64_t count)
Definition: aviobuf.c:187
HintSample::sample_number
int sample_number
Definition: movenc.h:67
index
int index
Definition: gxfenc.c:90
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:525
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:523
avio_write
void avio_write(AVIOContext *s, const unsigned char *buf, int size)
Definition: aviobuf.c:201
avio_wb32
void avio_wb32(AVIOContext *s, unsigned int val)
Definition: aviobuf.c:365
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:1367
HintSampleQueue::len
int len
Definition: movenc.h:74
AVPacket::flags
int flags
A combination of AV_PKT_FLAG values.
Definition: packet.h:530
sample_queue_retain
static void sample_queue_retain(HintSampleQueue *queue)
Make local copies of all referenced sample data in the queue.
Definition: movenchint.c:126
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:164
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:1295
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:256
AVPacket::pts
int64_t pts
Presentation timestamp in AVStream->time_base units; the time at which the decompressed packet will b...
Definition: packet.h:517
avio_internal.h
ff_mov_write_packet
int ff_mov_write_packet(AVFormatContext *s, AVPacket *pkt)
Definition: movenc.c:6184
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:30
ffio_free_dyn_buf
void ffio_free_dyn_buf(AVIOContext **s)
Free a dynamic buffer.
Definition: aviobuf.c:1435
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:231
pos
unsigned int pos
Definition: spdifenc.c:414
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:526
output_match
static void output_match(AVIOContext *out, int match_sample, int match_offset, int match_len, int *entries)
Definition: movenchint.c:270
mem.h
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:251
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:216
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:501
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:100
int32_t
int32_t
Definition: audioconvert.c:56
avio_wb16
void avio_wb16(AVIOContext *s, unsigned int val)
Definition: aviobuf.c:443
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:1394