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 "riff.h"
24 #include "internal.h"
25 #include "avio_internal.h"
26 #include "libavutil/intreadwrite.h"
27 #include "libavutil/avassert.h"
28 
29 /*
30  * Things to note:
31  * - AMV is a hard-coded (and broken) subset of AVI. It's not worth sullying the
32  * existing AVI muxer with its filth.
33  * - No separate demuxer as the existing AVI demuxer can handle these.
34  * - The sizes of certain tags are deliberately set to 0 as some players break
35  * when they're set correctly. Ditto with some header fields.
36  * - There is no index.
37  * - Players are **very** sensitive to the frame order and sizes.
38  * - Frames must be strictly interleaved as V-A, any V-V or A-A will
39  * cause crashes.
40  * - Variable video frame sizes seem to be handled fine.
41  * - Variable audio frame sizes cause crashes.
42  * - If audio is shorter than video, it's padded with silence.
43  * - If video is shorter than audio, the most recent frame is repeated.
44  */
45 
46 #define AMV_STREAM_COUNT 2
47 #define AMV_STREAM_VIDEO 0
48 #define AMV_STREAM_AUDIO 1
49 #define AMV_VIDEO_STRH_SIZE 56
50 #define AMV_VIDEO_STRF_SIZE 36
51 #define AMV_AUDIO_STRH_SIZE 48
52 #define AMV_AUDIO_STRF_SIZE 20 /* sizeof(WAVEFORMATEX) + 2 */
53 
54 typedef struct AMVContext
55 {
56  int64_t riff_start;
57  int64_t movi_list;
58  int64_t offset_duration;
60 
61  int32_t us_per_frame; /* Microseconds per frame. */
62 
63  int32_t aframe_size; /* Expected audio frame size. */
64  int32_t ablock_align; /* Expected audio block align. */
65  AVPacket *apad; /* Dummy audio packet for padding. */
66  AVPacket *vpad; /* Most recent video frame, for padding. */
67 
68  /*
69  * Cumulative PTS values for each stream, used for the final
70  * duration calculcation.
71  */
73 } AMVContext;
74 
75 /* ff_{start,end}_tag(), but sets the size to 0. */
76 static int64_t amv_start_tag(AVIOContext *pb, const char *tag)
77 {
78  ffio_wfourcc(pb, tag);
79  avio_wl32(pb, 0);
80  return avio_tell(pb);
81 }
82 
83 static void amv_end_tag(AVIOContext *pb, int64_t start)
84 {
85  int64_t pos;
86  av_assert0((start&1) == 0);
87 
88  pos = avio_tell(pb);
89  if (pos & 1)
90  avio_w8(pb, 0);
91 }
92 
94 {
95  AMVContext *amv = s->priv_data;
96  AVStream *vst, *ast;
97  int ret;
98 
99  amv->last_stream = -1;
100 
101  if (s->nb_streams != AMV_STREAM_COUNT) {
102  av_log(s, AV_LOG_ERROR, "AMV files only support 2 streams\n");
103  return AVERROR(EINVAL);
104  }
105 
106  vst = s->streams[AMV_STREAM_VIDEO];
107  ast = s->streams[AMV_STREAM_AUDIO];
108 
109  if (vst->codecpar->codec_id != AV_CODEC_ID_AMV) {
110  av_log(s, AV_LOG_ERROR, "First AMV stream must be %s\n",
112  return AVERROR(EINVAL);
113  }
114 
116  av_log(s, AV_LOG_ERROR, "Second AMV stream must be %s\n",
118  return AVERROR(EINVAL);
119  }
120 
121  /* These files are broken-enough as they are. They shouldn't be streamed. */
122  if (!(s->pb->seekable & AVIO_SEEKABLE_NORMAL)) {
123  av_log(s, AV_LOG_ERROR, "Stream not seekable, unable to write output file\n");
124  return AVERROR(EINVAL);
125  }
126 
129  amv->ablock_align = 8 + (FFALIGN(amv->aframe_size, 2) / 2);
130 
131  av_log(s, AV_LOG_TRACE, "us_per_frame = %d\n", amv->us_per_frame);
132  av_log(s, AV_LOG_TRACE, "aframe_size = %d\n", amv->aframe_size);
133  av_log(s, AV_LOG_TRACE, "ablock_align = %d\n", amv->ablock_align);
134 
135  /*
136  * Bail if the framerate's too high. Prevents the audio frame size from
137  * getting too small. 63fps is the closest value to 60fps that divides
138  * cleanly, so cap it there.
139  */
140  if (amv->us_per_frame < 15873) {
141  av_log(s, AV_LOG_ERROR, "Refusing to mux >63fps video\n");
142  return AVERROR(EINVAL);
143  }
144 
145  /*
146  * frame_size will be set if coming from the encoder.
147  * Make sure the its been configured correctly. The audio frame duration
148  * needs to match that of the video.
149  */
150  if (ast->codecpar->frame_size) {
151  AVCodecParameters *par = ast->codecpar;
152  int bad = 0;
153 
154  if (par->frame_size != amv->aframe_size) {
155  av_log(s, AV_LOG_ERROR, "Invalid audio frame size. Got %d, wanted %d\n",
156  par->frame_size, amv->aframe_size);
157  bad = 1;
158  }
159 
160  if (par->block_align != amv->ablock_align) {
161  av_log(s, AV_LOG_ERROR, "Invalid audio block align. Got %d, wanted %d\n",
162  par->block_align, amv->ablock_align);
163  bad = 1;
164  }
165 
166  if (bad) {
167  av_log(s, AV_LOG_ERROR, "Try -block_size %d\n", amv->aframe_size);
168  return AVERROR(EINVAL);
169  }
170 
171  if (ast->codecpar->sample_rate % amv->aframe_size) {
172  av_log(s, AV_LOG_ERROR, "Audio sample rate not a multiple of the frame size.\n"
173  "Please change video frame rate. Suggested rates: 10,14,15,18,21,25,30\n");
174  return AVERROR(EINVAL);
175  }
176  } else {
177  /* If remuxing from the same source, then this will match the video. */
179  if (aus != amv->us_per_frame) {
180  av_log(s, AV_LOG_ERROR, "Cannot remux streams with a different time base\n");
181  return AVERROR(EINVAL);
182  }
183  }
184 
185  /* Allocate and fill dummy packet so we can pad the audio. */
186  amv->apad = av_packet_alloc();
187  if (!amv->apad)
188  return AVERROR(ENOMEM);
189  if ((ret = av_new_packet(amv->apad, amv->ablock_align)) < 0) {
190  av_packet_free(&amv->apad);
191  return ret;
192  }
193 
195  memset(amv->apad->data, 0, amv->ablock_align);
196  AV_WL32(amv->apad->data + 4, amv->aframe_size);
197 
198  amv->vpad = av_packet_alloc();
199  if (!amv->vpad) {
200  av_packet_free(&amv->apad);
201  return AVERROR(ENOMEM);
202  }
204  amv->vpad->duration = 1;
205  return 0;
206 }
207 
209 {
210  AMVContext *amv = s->priv_data;
211 
212  av_packet_free(&amv->apad);
213  av_packet_free(&amv->vpad);
214 }
215 
217 {
218  int64_t tag_list, tag_str;
219 
221 
222  tag_list = amv_start_tag(s->pb, "LIST");
223  ffio_wfourcc(s->pb, "strl");
224  tag_str = ff_start_tag(s->pb, "strh");
226  ff_end_tag(s->pb, tag_str);
227 
228  tag_str = ff_start_tag(s->pb, "strf");
230  ff_end_tag(s->pb, tag_str);
231 
232  amv_end_tag(s->pb, tag_list);
233 }
234 
236 {
238  AVIOContext *pb = s->pb;
239  int64_t tag_list, tag_str;
240 
242 
243  tag_list = amv_start_tag(pb, "LIST");
244  ffio_wfourcc(pb, "strl");
245  tag_str = ff_start_tag(pb, "strh");
247  ff_end_tag(pb, tag_str);
248 
249  /* Bodge an (incorrect) WAVEFORMATEX (+2 pad bytes) */
250  tag_str = ff_start_tag(pb, "strf");
251  AV_WL16(buf + 0, 1);
252  AV_WL16(buf + 2, par->channels);
253  AV_WL32(buf + 4, par->sample_rate);
254  AV_WL32(buf + 8, par->sample_rate * par->channels * 2);
255  AV_WL16(buf + 12, 2);
256  AV_WL16(buf + 14, 16);
257  AV_WL16(buf + 16, 0);
258  AV_WL16(buf + 18, 0);
260  ff_end_tag(pb, tag_str);
261 
262  amv_end_tag(pb, tag_list);
263 }
264 
266 {
267  AMVContext *amv = s->priv_data;
268  AVIOContext *pb = s->pb;
269  AVStream *vst = s->streams[AMV_STREAM_VIDEO];
270  AVStream *ast = s->streams[AMV_STREAM_AUDIO];
271  uint8_t amvh[56] = {0};
272  int64_t list1;
273 
274  amv->riff_start = amv_start_tag(pb, "RIFF");
275  ffio_wfourcc(pb, "AMV ");
276  list1 = amv_start_tag(pb, "LIST");
277  ffio_wfourcc(pb, "hdrl");
278 
279  ffio_wfourcc(pb, "amvh");
280  avio_wl32(pb, 56);
281 
282  AV_WL32(amvh + 0, amv->us_per_frame);
283  AV_WL32(amvh + 32, vst->codecpar->width);
284  AV_WL32(amvh + 36, vst->codecpar->height);
285  AV_WL32(amvh + 40, vst->time_base.den);
286  AV_WL32(amvh + 44, vst->time_base.num);
287  AV_WL32(amvh + 48, 0);
288  AV_WL32(amvh + 52, 0); /* duration, filled in later. */
289 
290  avio_write(pb, amvh, sizeof(amvh));
291  amv->offset_duration = avio_tell(pb) - 4;
292 
293  amv_write_vlist(s, vst->codecpar);
294  amv_write_alist(s, ast->codecpar);
295  amv_end_tag(pb, list1);
296 
297  amv->movi_list = amv_start_tag(pb, "LIST");
298  ffio_wfourcc(pb, "movi");
299  return 0;
300 }
301 
303 {
304  AMVContext *amv = s->priv_data;
305 
307  ffio_wfourcc(s->pb, "00dc");
308  else if (pkt->stream_index == AMV_STREAM_AUDIO)
309  ffio_wfourcc(s->pb, "01wb");
310  else
311  av_assert0(0);
312 
313  if (pkt->stream_index == AMV_STREAM_AUDIO && pkt->size != amv->ablock_align) {
314  /* Can happen when remuxing files produced by another encoder. */
315  av_log(s, AV_LOG_WARNING, "Invalid audio packet size (%d != %d)\n",
316  pkt->size, amv->ablock_align);
317  }
318 
319  avio_wl32(s->pb, pkt->size);
320  avio_write(s->pb, pkt->data, pkt->size);
321 
322  amv->lastpts[pkt->stream_index] += pkt->duration;
323  amv->last_stream = pkt->stream_index;
324  return 0;
325 }
326 
328 {
329  AMVContext *amv = s->priv_data;
330  int stream_index = pkt->stream_index;
331 
332  if (stream_index != amv->last_stream)
333  return 0;
334 
335  stream_index = (stream_index + 1) % s->nb_streams;
336  if (stream_index == AMV_STREAM_VIDEO)
337  return amv_write_packet_internal(s, amv->vpad);
338  else if (stream_index == AMV_STREAM_AUDIO)
339  return amv_write_packet_internal(s, amv->apad);
340  else
341  av_assert0(0);
342 
343  return AVERROR(EINVAL);
344 }
345 
347 {
348  AMVContext *amv = s->priv_data;
349  int ret;
350 
351  /* Add a dummy frame if we've received two of the same index. */
352  if ((ret = amv_pad(s, pkt)) < 0)
353  return ret;
354 
355  if ((ret = amv_write_packet_internal(s, pkt)) < 0)
356  return ret;
357 
359  /* Save the last packet for padding. */
360  av_packet_unref(amv->vpad);
361  if ((ret = av_packet_ref(amv->vpad, pkt)) < 0)
362  return ret;
363  }
364 
365  return 0;
366 }
367 
369 {
370  AMVContext *amv = s->priv_data;
371  AVStream *vst = s->streams[AMV_STREAM_VIDEO];
372  AVStream *ast = s->streams[AMV_STREAM_AUDIO];
373  int64_t maxpts, ret;
374  int hh, mm, ss;
375 
376  /* Pad-out one last audio frame if needed. */
377  if (amv->last_stream == AMV_STREAM_VIDEO) {
378  if ((ret = amv_write_packet_internal(s, amv->apad)) < 0)
379  return ret;
380  }
381 
382  amv_end_tag(s->pb, amv->movi_list);
383  amv_end_tag(s->pb, amv->riff_start);
384 
385  ffio_wfourcc(s->pb, "AMV_");
386  ffio_wfourcc(s->pb, "END_");
387 
388  if ((ret = avio_seek(s->pb, amv->offset_duration, SEEK_SET)) < 0)
389  return ret;
390 
391  /* Go back and write the duration. */
392  maxpts = FFMAX(
395  );
396 
397  ss = maxpts / AV_TIME_BASE;
398  mm = ss / 60;
399  hh = mm / 60;
400  ss %= 60;
401  mm %= 60;
402 
403  avio_w8(s->pb, ss);
404  avio_w8(s->pb, mm);
405  avio_wl16(s->pb, hh);
406  return 0;
407 }
408 
410  .name = "amv",
411  .long_name = NULL_IF_CONFIG_SMALL("AMV"),
412  .mime_type = "video/amv",
413  .extensions = "amv",
414  .priv_data_size = sizeof(AMVContext),
415  .audio_codec = AV_CODEC_ID_ADPCM_IMA_AMV,
416  .video_codec = AV_CODEC_ID_AMV,
417  .init = amv_init,
418  .deinit = amv_deinit,
422 };
av_packet_unref
void av_packet_unref(AVPacket *pkt)
Wipe the packet.
Definition: avpacket.c:634
AMVContext::lastpts
int64_t lastpts[AMV_STREAM_COUNT]
Definition: amvenc.c:72
AV_LOG_WARNING
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition: log.h:200
init
static av_cold int init(AVCodecContext *avctx)
Definition: avrndec.c:31
AVOutputFormat::name
const char * name
Definition: avformat.h:491
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:426
ffio_wfourcc
static av_always_inline void ffio_wfourcc(AVIOContext *pb, const uint8_t *s)
Definition: avio_internal.h:58
AMV_STREAM_VIDEO
#define AMV_STREAM_VIDEO
Definition: amvenc.c:47
AVCodecParameters
This struct describes the properties of an encoded stream.
Definition: codec_par.h:52
ff_amv_muxer
AVOutputFormat ff_amv_muxer
Definition: amvenc.c:409
AMV_STREAM_COUNT
#define AMV_STREAM_COUNT
Definition: amvenc.c:46
AV_TIME_BASE_Q
#define AV_TIME_BASE_Q
Internal time base represented as fractional value.
Definition: avutil.h:260
amv_start_tag
static int64_t amv_start_tag(AVIOContext *pb, const char *tag)
Definition: amvenc.c:76
amv_deinit
static void amv_deinit(AVFormatContext *s)
Definition: amvenc.c:208
AVPacket::data
uint8_t * data
Definition: packet.h:369
AVPacket::duration
int64_t duration
Duration of this packet in AVStream->time_base units, 0 if unknown.
Definition: packet.h:387
AMV_STREAM_AUDIO
#define AMV_STREAM_AUDIO
Definition: amvenc.c:48
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:75
amv_pad
static int amv_pad(AVFormatContext *s, AVPacket *pkt)
Definition: amvenc.c:327
AMV_VIDEO_STRF_SIZE
#define AMV_VIDEO_STRF_SIZE
Definition: amvenc.c:50
avio_wl16
void avio_wl16(AVIOContext *s, unsigned int val)
Definition: aviobuf.c:455
AVCodecParameters::channels
int channels
Audio only.
Definition: codec_par.h:166
avio_tell
static av_always_inline int64_t avio_tell(AVIOContext *s)
ftell() equivalent for AVIOContext.
Definition: avio.h:557
ss
#define ss(width, name, subs,...)
Definition: cbs_vp9.c:261
AVRational::num
int num
Numerator.
Definition: rational.h:59
amv_write_vlist
static void amv_write_vlist(AVFormatContext *s, AVCodecParameters *par)
Definition: amvenc.c:216
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:220
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:194
av_cold
#define av_cold
Definition: attributes.h:90
AVCodecParameters::frame_size
int frame_size
Audio only.
Definition: codec_par.h:181
intreadwrite.h
s
#define s(width, name)
Definition: cbs_vp9.c:257
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:99
AMVContext::vpad
AVPacket * vpad
Definition: amvenc.c:66
amv_init
static av_cold int amv_init(AVFormatContext *s)
Definition: amvenc.c:93
AVCodecParameters::width
int width
Video only.
Definition: codec_par.h:126
av_assert0
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition: avassert.h:37
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:346
int32_t
int32_t
Definition: audio_convert.c:194
if
if(ret)
Definition: filter_design.txt:179
AVFormatContext
Format I/O context.
Definition: avformat.h:1232
internal.h
AVStream::codecpar
AVCodecParameters * codecpar
Codec parameters associated with this stream.
Definition: avformat.h:1038
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:902
write_trailer
static int write_trailer(AVFormatContext *s1)
Definition: v4l2enc.c:98
AMV_AUDIO_STRF_SIZE
#define AMV_AUDIO_STRF_SIZE
Definition: amvenc.c:52
AV_CODEC_ID_ADPCM_IMA_AMV
@ AV_CODEC_ID_ADPCM_IMA_AMV
Definition: codec_id.h:372
avio_w8
void avio_w8(AVIOContext *s, int b)
Definition: aviobuf.c:203
AMV_AUDIO_STRH_SIZE
#define AMV_AUDIO_STRH_SIZE
Definition: amvenc.c:51
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:641
AVCodecParameters::sample_rate
int sample_rate
Audio only.
Definition: codec_par.h:170
AMVContext::us_per_frame
int32_t us_per_frame
Definition: amvenc.c:61
amv_write_packet_internal
static int amv_write_packet_internal(AVFormatContext *s, AVPacket *pkt)
Definition: amvenc.c:302
AVIOContext
Bytestream IO Context.
Definition: avio.h:161
AVPacket::size
int size
Definition: packet.h:370
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:117
FFMAX
#define FFMAX(a, b)
Definition: common.h:103
avio_write
void avio_write(AVIOContext *s, const unsigned char *buf, int size)
Definition: aviobuf.c:225
AV_WL16
#define AV_WL16(p, v)
Definition: intreadwrite.h:412
avio_wl32
void avio_wl32(AVIOContext *s, unsigned int val)
Definition: aviobuf.c:375
av_packet_alloc
AVPacket * av_packet_alloc(void)
Allocate an AVPacket and set its fields to default values.
Definition: avpacket.c:64
ff_end_tag
void ff_end_tag(AVIOContext *pb, int64_t start)
Definition: riffenc.c:38
write_packet
static void write_packet(OutputFile *of, AVPacket *pkt, OutputStream *ost, int unqueue)
Definition: ffmpeg.c:729
avcodec_get_name
const char * avcodec_get_name(enum AVCodecID id)
Get the name of a codec.
Definition: utils.c:471
AVOutputFormat
Definition: avformat.h:490
avio_internal.h
AMVContext::offset_duration
int64_t offset_duration
Definition: amvenc.c:58
AVCodecParameters::height
int height
Definition: codec_par.h:127
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:177
AMVContext::riff_start
int64_t riff_start
Definition: amvenc.c:56
AMVContext::last_stream
int last_stream
Definition: amvenc.c:59
uint8_t
uint8_t
Definition: audio_convert.c:194
AMVContext::movi_list
int64_t movi_list
Definition: amvenc.c:57
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:1611
ret
ret
Definition: filter_design.txt:187
AVStream
Stream structure.
Definition: avformat.h:873
avio_seek
int64_t avio_seek(AVIOContext *s, int64_t offset, int whence)
fseek() equivalent for AVIOContext.
Definition: aviobuf.c:253
pos
unsigned int pos
Definition: spdifenc.c:412
avformat.h
amv_write_trailer
static int amv_write_trailer(AVFormatContext *s)
Definition: amvenc.c:368
AV_CODEC_ID_AMV
@ AV_CODEC_ID_AMV
Definition: codec_id.h:156
AVIO_SEEKABLE_NORMAL
#define AVIO_SEEKABLE_NORMAL
Seeking works like for a local file.
Definition: avio.h:40
AVRational::den
int den
Denominator.
Definition: rational.h:60
amv_write_header
static int amv_write_header(AVFormatContext *s)
Definition: amvenc.c:265
AVPacket::stream_index
int stream_index
Definition: packet.h:371
AMVContext::ablock_align
int32_t ablock_align
Definition: amvenc.c:64
bad
static int bad(InterplayACMContext *s, unsigned ind, unsigned col)
Definition: interplayacm.c:116
AMVContext::aframe_size
int32_t aframe_size
Definition: amvenc.c:63
tag_list
static const struct exif_tag tag_list[]
Definition: exif.h:43
AMV_VIDEO_STRH_SIZE
#define AMV_VIDEO_STRH_SIZE
Definition: amvenc.c:49
FFALIGN
#define FFALIGN(x, a)
Definition: macros.h:48
AVCodecParameters::codec_id
enum AVCodecID codec_id
Specific type of the encoded data (the codec used).
Definition: codec_par.h:60
AVPacket
This structure stores compressed data.
Definition: packet.h:346
riff.h
ffio_fill
void ffio_fill(AVIOContext *s, int b, int count)
Definition: aviobuf.c:211
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:28
AMVContext::apad
AVPacket * apad
Definition: amvenc.c:65
amv_write_alist
static void amv_write_alist(AVFormatContext *s, AVCodecParameters *par)
Definition: amvenc.c:235
write_header
static void write_header(FFV1Context *f)
Definition: ffv1enc.c:346
amv_end_tag
static void amv_end_tag(AVIOContext *pb, int64_t start)
Definition: amvenc.c:83
AMVContext
Definition: amvenc.c:54