FFmpeg
amvenc.c
Go to the documentation of this file.
1 /*
2  * AMV muxer
3  *
4  * Copyright (C) 2020 Zane van Iperen (zane@zanevaniperen.com)
5  *
6  * This file is part of FFmpeg.
7  *
8  * FFmpeg is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Lesser General Public
10  * License as published by the Free Software Foundation; either
11  * version 2.1 of the License, or (at your option) any later version.
12  *
13  * FFmpeg is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16  * Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with FFmpeg; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21  */
22 #include "avformat.h"
23 #include "mux.h"
24 #include "riff.h"
25 #include "internal.h"
26 #include "avio_internal.h"
27 #include "libavutil/intreadwrite.h"
28 #include "libavutil/avassert.h"
29 
30 /*
31  * Things to note:
32  * - AMV is a hard-coded (and broken) subset of AVI. It's not worth sullying the
33  * existing AVI muxer with its filth.
34  * - No separate demuxer as the existing AVI demuxer can handle these.
35  * - The sizes of certain tags are deliberately set to 0 as some players break
36  * when they're set correctly. Ditto with some header fields.
37  * - There is no index.
38  * - Players are **very** sensitive to the frame order and sizes.
39  * - Frames must be strictly interleaved as V-A, any V-V or A-A will
40  * cause crashes.
41  * - Variable video frame sizes seem to be handled fine.
42  * - Variable audio frame sizes cause crashes.
43  * - If audio is shorter than video, it's padded with silence.
44  * - If video is shorter than audio, the most recent frame is repeated.
45  */
46 
47 #define AMV_STREAM_COUNT 2
48 #define AMV_STREAM_VIDEO 0
49 #define AMV_STREAM_AUDIO 1
50 #define AMV_VIDEO_STRH_SIZE 56
51 #define AMV_VIDEO_STRF_SIZE 36
52 #define AMV_AUDIO_STRH_SIZE 48
53 #define AMV_AUDIO_STRF_SIZE 20 /* sizeof(WAVEFORMATEX) + 2 */
54 
55 typedef struct AMVContext
56 {
57  int64_t riff_start;
58  int64_t movi_list;
59  int64_t offset_duration;
61 
62  int32_t us_per_frame; /* Microseconds per frame. */
63 
64  int32_t aframe_size; /* Expected audio frame size. */
65  int32_t ablock_align; /* Expected audio block align. */
66  AVPacket *apad; /* Dummy audio packet for padding; not owned by us. */
67  AVPacket *vpad; /* Most recent video frame, for padding. */
68 
69  /*
70  * Cumulative PTS values for each stream, used for the final
71  * duration calculcation.
72  */
74 } AMVContext;
75 
76 /* ff_{start,end}_tag(), but sets the size to 0. */
77 static int64_t amv_start_tag(AVIOContext *pb, const char *tag)
78 {
79  ffio_wfourcc(pb, tag);
80  avio_wl32(pb, 0);
81  return avio_tell(pb);
82 }
83 
84 static void amv_end_tag(AVIOContext *pb, int64_t start)
85 {
86  int64_t pos;
87  av_assert0((start&1) == 0);
88 
89  pos = avio_tell(pb);
90  if (pos & 1)
91  avio_w8(pb, 0);
92 }
93 
95 {
96  AMVContext *amv = s->priv_data;
97  AVStream *vst, *ast;
98  int ret;
99 
100  amv->last_stream = -1;
101 
102  if (s->nb_streams != AMV_STREAM_COUNT) {
103  av_log(s, AV_LOG_ERROR, "AMV files only support 2 streams\n");
104  return AVERROR(EINVAL);
105  }
106 
107  vst = s->streams[AMV_STREAM_VIDEO];
108  ast = s->streams[AMV_STREAM_AUDIO];
109 
110  if (vst->codecpar->codec_id != AV_CODEC_ID_AMV) {
111  av_log(s, AV_LOG_ERROR, "First AMV stream must be %s\n",
113  return AVERROR(EINVAL);
114  }
115 
117 
118  /* These files are broken-enough as they are. They shouldn't be streamed. */
119  if (!(s->pb->seekable & AVIO_SEEKABLE_NORMAL)) {
120  av_log(s, AV_LOG_ERROR, "Stream not seekable, unable to write output file\n");
121  return AVERROR(EINVAL);
122  }
123 
126  amv->ablock_align = 8 + (FFALIGN(amv->aframe_size, 2) / 2);
127 
128  av_log(s, AV_LOG_TRACE, "us_per_frame = %d\n", amv->us_per_frame);
129  av_log(s, AV_LOG_TRACE, "aframe_size = %d\n", amv->aframe_size);
130  av_log(s, AV_LOG_TRACE, "ablock_align = %d\n", amv->ablock_align);
131 
132  /*
133  * Bail if the framerate's too high. Prevents the audio frame size from
134  * getting too small. 63fps is the closest value to 60fps that divides
135  * cleanly, so cap it there.
136  */
137  if (amv->us_per_frame < 15873) {
138  av_log(s, AV_LOG_ERROR, "Refusing to mux >63fps video\n");
139  return AVERROR(EINVAL);
140  }
141 
142  /*
143  * frame_size will be set if coming from the encoder.
144  * Make sure the its been configured correctly. The audio frame duration
145  * needs to match that of the video.
146  */
147  if (ast->codecpar->frame_size) {
148  AVCodecParameters *par = ast->codecpar;
149  int bad = 0;
150 
151  if (par->frame_size != amv->aframe_size) {
152  av_log(s, AV_LOG_ERROR, "Invalid audio frame size. Got %d, wanted %d\n",
153  par->frame_size, amv->aframe_size);
154  bad = 1;
155  }
156 
157  if (par->block_align != amv->ablock_align) {
158  av_log(s, AV_LOG_ERROR, "Invalid audio block align. Got %d, wanted %d\n",
159  par->block_align, amv->ablock_align);
160  bad = 1;
161  }
162 
163  if (bad) {
164  av_log(s, AV_LOG_ERROR, "Try -block_size %d\n", amv->aframe_size);
165  return AVERROR(EINVAL);
166  }
167 
168  if (ast->codecpar->sample_rate % amv->aframe_size) {
169  av_log(s, AV_LOG_ERROR, "Audio sample rate not a multiple of the frame size.\n"
170  "Please change video frame rate. Suggested rates: 10,14,15,18,21,25,30\n");
171  return AVERROR(EINVAL);
172  }
173  } else {
174  /* If remuxing from the same source, then this will match the video. */
176  if (aus != amv->us_per_frame) {
177  av_log(s, AV_LOG_ERROR, "Cannot remux streams with a different time base\n");
178  return AVERROR(EINVAL);
179  }
180  }
181 
182  /* Allocate and fill dummy packet so we can pad the audio. */
183  amv->apad = ffformatcontext(s)->pkt;
184  if ((ret = av_new_packet(amv->apad, amv->ablock_align)) < 0) {
185  return ret;
186  }
187 
189  memset(amv->apad->data, 0, amv->ablock_align);
190  AV_WL32(amv->apad->data + 4, amv->aframe_size);
191 
192  amv->vpad = av_packet_alloc();
193  if (!amv->vpad) {
194  return AVERROR(ENOMEM);
195  }
197  amv->vpad->duration = 1;
198  return 0;
199 }
200 
202 {
203  AMVContext *amv = s->priv_data;
204 
205  av_packet_free(&amv->vpad);
206 }
207 
209 {
210  int64_t tag_list, tag_str;
211 
213 
214  tag_list = amv_start_tag(s->pb, "LIST");
215  ffio_wfourcc(s->pb, "strl");
216  tag_str = ff_start_tag(s->pb, "strh");
218  ff_end_tag(s->pb, tag_str);
219 
220  tag_str = ff_start_tag(s->pb, "strf");
222  ff_end_tag(s->pb, tag_str);
223 
224  amv_end_tag(s->pb, tag_list);
225 }
226 
228 {
229  uint8_t buf[AMV_AUDIO_STRF_SIZE];
230  AVIOContext *pb = s->pb;
231  int64_t tag_list, tag_str;
232 
234 
235  tag_list = amv_start_tag(pb, "LIST");
236  ffio_wfourcc(pb, "strl");
237  tag_str = ff_start_tag(pb, "strh");
239  ff_end_tag(pb, tag_str);
240 
241  /* Bodge an (incorrect) WAVEFORMATEX (+2 pad bytes) */
242  tag_str = ff_start_tag(pb, "strf");
243  AV_WL16(buf + 0, 1);
244  AV_WL16(buf + 2, par->ch_layout.nb_channels);
245  AV_WL32(buf + 4, par->sample_rate);
246  AV_WL32(buf + 8, par->sample_rate * par->ch_layout.nb_channels * 2);
247  AV_WL16(buf + 12, 2);
248  AV_WL16(buf + 14, 16);
249  AV_WL16(buf + 16, 0);
250  AV_WL16(buf + 18, 0);
252  ff_end_tag(pb, tag_str);
253 
254  amv_end_tag(pb, tag_list);
255 }
256 
258 {
259  AMVContext *amv = s->priv_data;
260  AVIOContext *pb = s->pb;
261  AVStream *vst = s->streams[AMV_STREAM_VIDEO];
262  AVStream *ast = s->streams[AMV_STREAM_AUDIO];
263  uint8_t amvh[56] = {0};
264  int64_t list1;
265 
266  amv->riff_start = amv_start_tag(pb, "RIFF");
267  ffio_wfourcc(pb, "AMV ");
268  list1 = amv_start_tag(pb, "LIST");
269  ffio_wfourcc(pb, "hdrl");
270 
271  ffio_wfourcc(pb, "amvh");
272  avio_wl32(pb, 56);
273 
274  AV_WL32(amvh + 0, amv->us_per_frame);
275  AV_WL32(amvh + 32, vst->codecpar->width);
276  AV_WL32(amvh + 36, vst->codecpar->height);
277  AV_WL32(amvh + 40, vst->time_base.den);
278  AV_WL32(amvh + 44, vst->time_base.num);
279  AV_WL32(amvh + 48, 0);
280  AV_WL32(amvh + 52, 0); /* duration, filled in later. */
281 
282  avio_write(pb, amvh, sizeof(amvh));
283  amv->offset_duration = avio_tell(pb) - 4;
284 
285  amv_write_vlist(s, vst->codecpar);
286  amv_write_alist(s, ast->codecpar);
287  amv_end_tag(pb, list1);
288 
289  amv->movi_list = amv_start_tag(pb, "LIST");
290  ffio_wfourcc(pb, "movi");
291  return 0;
292 }
293 
295 {
296  AMVContext *amv = s->priv_data;
297 
299  ffio_wfourcc(s->pb, "00dc");
300  else if (pkt->stream_index == AMV_STREAM_AUDIO)
301  ffio_wfourcc(s->pb, "01wb");
302  else
303  av_assert0(0);
304 
305  if (pkt->stream_index == AMV_STREAM_AUDIO && pkt->size != amv->ablock_align) {
306  /* Can happen when remuxing files produced by another encoder. */
307  av_log(s, AV_LOG_WARNING, "Invalid audio packet size (%d != %d)\n",
308  pkt->size, amv->ablock_align);
309  }
310 
311  avio_wl32(s->pb, pkt->size);
312  avio_write(s->pb, pkt->data, pkt->size);
313 
314  amv->lastpts[pkt->stream_index] += pkt->duration;
315  amv->last_stream = pkt->stream_index;
316  return 0;
317 }
318 
320 {
321  AMVContext *amv = s->priv_data;
322  int stream_index = pkt->stream_index;
323 
324  if (stream_index != amv->last_stream)
325  return 0;
326 
327  stream_index = (stream_index + 1) % s->nb_streams;
328  if (stream_index == AMV_STREAM_VIDEO)
329  return amv_write_packet_internal(s, amv->vpad);
330  else if (stream_index == AMV_STREAM_AUDIO)
331  return amv_write_packet_internal(s, amv->apad);
332  else
333  av_assert0(0);
334 
335  return AVERROR(EINVAL);
336 }
337 
339 {
340  AMVContext *amv = s->priv_data;
341  int ret;
342 
343  /* Add a dummy frame if we've received two of the same index. */
344  if ((ret = amv_pad(s, pkt)) < 0)
345  return ret;
346 
347  if ((ret = amv_write_packet_internal(s, pkt)) < 0)
348  return ret;
349 
351  /* Save the last packet for padding. */
352  av_packet_unref(amv->vpad);
353  if ((ret = av_packet_ref(amv->vpad, pkt)) < 0)
354  return ret;
355  }
356 
357  return 0;
358 }
359 
361 {
362  AMVContext *amv = s->priv_data;
363  AVStream *vst = s->streams[AMV_STREAM_VIDEO];
364  AVStream *ast = s->streams[AMV_STREAM_AUDIO];
365  int64_t maxpts, ret;
366  int hh, mm, ss;
367 
368  /* Pad-out one last audio frame if needed. */
369  if (amv->last_stream == AMV_STREAM_VIDEO) {
370  if ((ret = amv_write_packet_internal(s, amv->apad)) < 0)
371  return ret;
372  }
373 
374  amv_end_tag(s->pb, amv->movi_list);
375  amv_end_tag(s->pb, amv->riff_start);
376 
377  ffio_wfourcc(s->pb, "AMV_");
378  ffio_wfourcc(s->pb, "END_");
379 
380  if ((ret = avio_seek(s->pb, amv->offset_duration, SEEK_SET)) < 0)
381  return ret;
382 
383  /* Go back and write the duration. */
384  maxpts = FFMAX(
387  );
388 
389  ss = maxpts / AV_TIME_BASE;
390  mm = ss / 60;
391  hh = mm / 60;
392  ss %= 60;
393  mm %= 60;
394 
395  avio_w8(s->pb, ss);
396  avio_w8(s->pb, mm);
397  avio_wl16(s->pb, hh);
398  return 0;
399 }
400 
402  .p.name = "amv",
403  .p.long_name = NULL_IF_CONFIG_SMALL("AMV"),
404  .p.mime_type = "video/amv",
405  .p.extensions = "amv",
406  .priv_data_size = sizeof(AMVContext),
407  .p.audio_codec = AV_CODEC_ID_ADPCM_IMA_AMV,
408  .p.video_codec = AV_CODEC_ID_AMV,
409  .p.subtitle_codec = AV_CODEC_ID_NONE,
410  .flags_internal = FF_OFMT_FLAG_MAX_ONE_OF_EACH |
412  .init = amv_init,
413  .deinit = amv_deinit,
414  .write_header = amv_write_header,
415  .write_packet = amv_write_packet,
416  .write_trailer = amv_write_trailer,
417 };
av_packet_unref
void av_packet_unref(AVPacket *pkt)
Wipe the packet.
Definition: avpacket.c:427
AMVContext::lastpts
int64_t lastpts[AMV_STREAM_COUNT]
Definition: amvenc.c:73
AV_LOG_WARNING
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition: log.h:186
AVOutputFormat::name
const char * name
Definition: avformat.h:510
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
AV_WL32
#define AV_WL32(p, v)
Definition: intreadwrite.h:424
ffio_wfourcc
static av_always_inline void ffio_wfourcc(AVIOContext *pb, const uint8_t *s)
Definition: avio_internal.h:124
AMV_STREAM_VIDEO
#define AMV_STREAM_VIDEO
Definition: amvenc.c:48
AVCodecParameters
This struct describes the properties of an encoded stream.
Definition: codec_par.h:47
ffformatcontext
static av_always_inline FFFormatContext * ffformatcontext(AVFormatContext *s)
Definition: internal.h:188
AMV_STREAM_COUNT
#define AMV_STREAM_COUNT
Definition: amvenc.c:47
AV_TIME_BASE_Q
#define AV_TIME_BASE_Q
Internal time base represented as fractional value.
Definition: avutil.h:264
amv_start_tag
static int64_t amv_start_tag(AVIOContext *pb, const char *tag)
Definition: amvenc.c:77
amv_deinit
static void amv_deinit(AVFormatContext *s)
Definition: amvenc.c:201
AVPacket::data
uint8_t * data
Definition: packet.h:522
AVPacket::duration
int64_t duration
Duration of this packet in AVStream->time_base units, 0 if unknown.
Definition: packet.h:540
FF_OFMT_FLAG_ONLY_DEFAULT_CODECS
#define FF_OFMT_FLAG_ONLY_DEFAULT_CODECS
If this flag is set, then the only permitted audio/video/subtitle codec ids are AVOutputFormat....
Definition: mux.h:59
FFMAX
#define FFMAX(a, b)
Definition: macros.h:47
AMV_STREAM_AUDIO
#define AMV_STREAM_AUDIO
Definition: amvenc.c:49
ff_amv_muxer
const FFOutputFormat ff_amv_muxer
Definition: amvenc.c:401
AVChannelLayout::nb_channels
int nb_channels
Number of channels in this layout.
Definition: channel_layout.h:313
av_packet_free
void av_packet_free(AVPacket **pkt)
Free the packet, if the packet is reference counted, it will be unreferenced first.
Definition: avpacket.c:74
amv_pad
static int amv_pad(AVFormatContext *s, AVPacket *pkt)
Definition: amvenc.c:319
AMV_VIDEO_STRF_SIZE
#define AMV_VIDEO_STRF_SIZE
Definition: amvenc.c:51
FFOutputFormat::p
AVOutputFormat p
The public AVOutputFormat.
Definition: mux.h:65
avio_wl16
void avio_wl16(AVIOContext *s, unsigned int val)
Definition: aviobuf.c:436
avio_tell
static av_always_inline int64_t avio_tell(AVIOContext *s)
ftell() equivalent for AVIOContext.
Definition: avio.h:494
ss
#define ss(width, name, subs,...)
Definition: cbs_vp9.c:202
AVRational::num
int num
Numerator.
Definition: rational.h:59
amv_write_vlist
static void amv_write_vlist(AVFormatContext *s, AVCodecParameters *par)
Definition: amvenc.c:208
ff_start_tag
int64_t ff_start_tag(AVIOContext *pb, const char *tag)
Definition: riffenc.c:31
avassert.h
AV_LOG_TRACE
#define AV_LOG_TRACE
Extremely verbose debugging, useful for libav* development.
Definition: log.h:206
pkt
AVPacket * pkt
Definition: movenc.c:59
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:180
av_cold
#define av_cold
Definition: attributes.h:90
AVCodecParameters::frame_size
int frame_size
Audio only.
Definition: codec_par.h:195
intreadwrite.h
s
#define s(width, name)
Definition: cbs_vp9.c:198
av_new_packet
int av_new_packet(AVPacket *pkt, int size)
Allocate the payload of a packet and initialize its fields with default values.
Definition: avpacket.c:98
AMVContext::vpad
AVPacket * vpad
Definition: amvenc.c:67
amv_init
static av_cold int amv_init(AVFormatContext *s)
Definition: amvenc.c:94
AVCodecParameters::width
int width
Video only.
Definition: codec_par.h:134
av_assert0
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition: avassert.h:40
av_rescale_q
int64_t av_rescale_q(int64_t a, AVRational bq, AVRational cq)
Rescale a 64-bit integer by 2 rational numbers.
Definition: mathematics.c:142
amv_write_packet
static int amv_write_packet(AVFormatContext *s, AVPacket *pkt)
Definition: amvenc.c:338
if
if(ret)
Definition: filter_design.txt:179
AVFormatContext
Format I/O context.
Definition: avformat.h:1255
internal.h
AVStream::codecpar
AVCodecParameters * codecpar
Codec parameters associated with this stream.
Definition: avformat.h:766
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
AMV_AUDIO_STRF_SIZE
#define AMV_AUDIO_STRF_SIZE
Definition: amvenc.c:53
FFOutputFormat
Definition: mux.h:61
AV_CODEC_ID_ADPCM_IMA_AMV
@ AV_CODEC_ID_ADPCM_IMA_AMV
Definition: codec_id.h:386
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
AMV_AUDIO_STRH_SIZE
#define AMV_AUDIO_STRH_SIZE
Definition: amvenc.c:52
av_packet_ref
int av_packet_ref(AVPacket *dst, const AVPacket *src)
Setup a new reference to the data described by a given packet.
Definition: avpacket.c:435
AVCodecParameters::ch_layout
AVChannelLayout ch_layout
Audio only.
Definition: codec_par.h:180
AVCodecParameters::sample_rate
int sample_rate
Audio only.
Definition: codec_par.h:184
AMVContext::us_per_frame
int32_t us_per_frame
Definition: amvenc.c:62
amv_write_packet_internal
static int amv_write_packet_internal(AVFormatContext *s, AVPacket *pkt)
Definition: amvenc.c:294
AVIOContext
Bytestream IO Context.
Definition: avio.h:160
AVPacket::size
int size
Definition: packet.h:523
NULL_IF_CONFIG_SMALL
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification.
Definition: internal.h:106
avio_write
void avio_write(AVIOContext *s, const unsigned char *buf, int size)
Definition: aviobuf.c:200
AV_WL16
#define AV_WL16(p, v)
Definition: intreadwrite.h:410
avio_wl32
void avio_wl32(AVIOContext *s, unsigned int val)
Definition: aviobuf.c:356
av_packet_alloc
AVPacket * av_packet_alloc(void)
Allocate an AVPacket and set its fields to default values.
Definition: avpacket.c:63
ff_end_tag
void ff_end_tag(AVIOContext *pb, int64_t start)
Definition: riffenc.c:38
avcodec_get_name
const char * avcodec_get_name(enum AVCodecID id)
Get the name of a codec.
Definition: utils.c:406
AV_CODEC_ID_NONE
@ AV_CODEC_ID_NONE
Definition: codec_id.h:50
avio_internal.h
AMVContext::offset_duration
int64_t offset_duration
Definition: amvenc.c:59
AVCodecParameters::height
int height
Definition: codec_par.h:135
AV_TIME_BASE
#define AV_TIME_BASE
Internal time base represented as integer.
Definition: avutil.h:254
AVCodecParameters::block_align
int block_align
Audio only.
Definition: codec_par.h:191
AMVContext::riff_start
int64_t riff_start
Definition: amvenc.c:57
AMVContext::last_stream
int last_stream
Definition: amvenc.c:60
FF_OFMT_FLAG_MAX_ONE_OF_EACH
#define FF_OFMT_FLAG_MAX_ONE_OF_EACH
If this flag is set, it indicates that for each codec type whose corresponding default codec (i....
Definition: mux.h:50
av_assert1
#define av_assert1(cond)
assert() equivalent, that does not lie in speed critical code.
Definition: avassert.h:56
AMVContext::movi_list
int64_t movi_list
Definition: amvenc.c:58
av_rescale
int64_t av_rescale(int64_t a, int64_t b, int64_t c)
Rescale a 64-bit integer with rounding to nearest.
Definition: mathematics.c:129
tag
uint32_t tag
Definition: movenc.c:1786
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
avformat.h
amv_write_trailer
static int amv_write_trailer(AVFormatContext *s)
Definition: amvenc.c:360
AV_CODEC_ID_AMV
@ AV_CODEC_ID_AMV
Definition: codec_id.h:159
AVIO_SEEKABLE_NORMAL
#define AVIO_SEEKABLE_NORMAL
Seeking works like for a local file.
Definition: avio.h:41
AVRational::den
int den
Denominator.
Definition: rational.h:60
amv_write_header
static int amv_write_header(AVFormatContext *s)
Definition: amvenc.c:257
tag_list
static const struct exif_tag tag_list[]
Definition: exif.c:38
AVPacket::stream_index
int stream_index
Definition: packet.h:524
AMVContext::ablock_align
int32_t ablock_align
Definition: amvenc.c:65
bad
static int bad(InterplayACMContext *s, unsigned ind, unsigned col)
Definition: interplayacm.c:129
AMVContext::aframe_size
int32_t aframe_size
Definition: amvenc.c:64
FFFormatContext::pkt
AVPacket * pkt
Used to hold temporary packets for the generic demuxing code.
Definition: internal.h:134
AMV_VIDEO_STRH_SIZE
#define AMV_VIDEO_STRH_SIZE
Definition: amvenc.c:50
FFALIGN
#define FFALIGN(x, a)
Definition: macros.h:78
AVCodecParameters::codec_id
enum AVCodecID codec_id
Specific type of the encoded data (the codec used).
Definition: codec_par.h:55
AVPacket
This structure stores compressed data.
Definition: packet.h:499
riff.h
int32_t
int32_t
Definition: audioconvert.c:56
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:27
AMVContext::apad
AVPacket * apad
Definition: amvenc.c:66
amv_write_alist
static void amv_write_alist(AVFormatContext *s, AVCodecParameters *par)
Definition: amvenc.c:227
amv_end_tag
static void amv_end_tag(AVIOContext *pb, int64_t start)
Definition: amvenc.c:84
AMVContext
Definition: amvenc.c:55
mux.h