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  av_log(s, AV_LOG_ERROR, "Second AMV stream must be %s\n",
119  return AVERROR(EINVAL);
120  }
121 
122  /* These files are broken-enough as they are. They shouldn't be streamed. */
123  if (!(s->pb->seekable & AVIO_SEEKABLE_NORMAL)) {
124  av_log(s, AV_LOG_ERROR, "Stream not seekable, unable to write output file\n");
125  return AVERROR(EINVAL);
126  }
127 
130  amv->ablock_align = 8 + (FFALIGN(amv->aframe_size, 2) / 2);
131 
132  av_log(s, AV_LOG_TRACE, "us_per_frame = %d\n", amv->us_per_frame);
133  av_log(s, AV_LOG_TRACE, "aframe_size = %d\n", amv->aframe_size);
134  av_log(s, AV_LOG_TRACE, "ablock_align = %d\n", amv->ablock_align);
135 
136  /*
137  * Bail if the framerate's too high. Prevents the audio frame size from
138  * getting too small. 63fps is the closest value to 60fps that divides
139  * cleanly, so cap it there.
140  */
141  if (amv->us_per_frame < 15873) {
142  av_log(s, AV_LOG_ERROR, "Refusing to mux >63fps video\n");
143  return AVERROR(EINVAL);
144  }
145 
146  /*
147  * frame_size will be set if coming from the encoder.
148  * Make sure the its been configured correctly. The audio frame duration
149  * needs to match that of the video.
150  */
151  if (ast->codecpar->frame_size) {
152  AVCodecParameters *par = ast->codecpar;
153  int bad = 0;
154 
155  if (par->frame_size != amv->aframe_size) {
156  av_log(s, AV_LOG_ERROR, "Invalid audio frame size. Got %d, wanted %d\n",
157  par->frame_size, amv->aframe_size);
158  bad = 1;
159  }
160 
161  if (par->block_align != amv->ablock_align) {
162  av_log(s, AV_LOG_ERROR, "Invalid audio block align. Got %d, wanted %d\n",
163  par->block_align, amv->ablock_align);
164  bad = 1;
165  }
166 
167  if (bad) {
168  av_log(s, AV_LOG_ERROR, "Try -block_size %d\n", amv->aframe_size);
169  return AVERROR(EINVAL);
170  }
171 
172  if (ast->codecpar->sample_rate % amv->aframe_size) {
173  av_log(s, AV_LOG_ERROR, "Audio sample rate not a multiple of the frame size.\n"
174  "Please change video frame rate. Suggested rates: 10,14,15,18,21,25,30\n");
175  return AVERROR(EINVAL);
176  }
177  } else {
178  /* If remuxing from the same source, then this will match the video. */
180  if (aus != amv->us_per_frame) {
181  av_log(s, AV_LOG_ERROR, "Cannot remux streams with a different time base\n");
182  return AVERROR(EINVAL);
183  }
184  }
185 
186  /* Allocate and fill dummy packet so we can pad the audio. */
187  amv->apad = ffformatcontext(s)->pkt;
188  if ((ret = av_new_packet(amv->apad, amv->ablock_align)) < 0) {
189  return ret;
190  }
191 
193  memset(amv->apad->data, 0, amv->ablock_align);
194  AV_WL32(amv->apad->data + 4, amv->aframe_size);
195 
196  amv->vpad = av_packet_alloc();
197  if (!amv->vpad) {
198  return AVERROR(ENOMEM);
199  }
201  amv->vpad->duration = 1;
202  return 0;
203 }
204 
206 {
207  AMVContext *amv = s->priv_data;
208 
209  av_packet_free(&amv->vpad);
210 }
211 
213 {
214  int64_t tag_list, tag_str;
215 
217 
218  tag_list = amv_start_tag(s->pb, "LIST");
219  ffio_wfourcc(s->pb, "strl");
220  tag_str = ff_start_tag(s->pb, "strh");
222  ff_end_tag(s->pb, tag_str);
223 
224  tag_str = ff_start_tag(s->pb, "strf");
226  ff_end_tag(s->pb, tag_str);
227 
228  amv_end_tag(s->pb, tag_list);
229 }
230 
232 {
233  uint8_t buf[AMV_AUDIO_STRF_SIZE];
234  AVIOContext *pb = s->pb;
235  int64_t tag_list, tag_str;
236 
238 
239  tag_list = amv_start_tag(pb, "LIST");
240  ffio_wfourcc(pb, "strl");
241  tag_str = ff_start_tag(pb, "strh");
243  ff_end_tag(pb, tag_str);
244 
245  /* Bodge an (incorrect) WAVEFORMATEX (+2 pad bytes) */
246  tag_str = ff_start_tag(pb, "strf");
247  AV_WL16(buf + 0, 1);
248  AV_WL16(buf + 2, par->ch_layout.nb_channels);
249  AV_WL32(buf + 4, par->sample_rate);
250  AV_WL32(buf + 8, par->sample_rate * par->ch_layout.nb_channels * 2);
251  AV_WL16(buf + 12, 2);
252  AV_WL16(buf + 14, 16);
253  AV_WL16(buf + 16, 0);
254  AV_WL16(buf + 18, 0);
256  ff_end_tag(pb, tag_str);
257 
258  amv_end_tag(pb, tag_list);
259 }
260 
262 {
263  AMVContext *amv = s->priv_data;
264  AVIOContext *pb = s->pb;
265  AVStream *vst = s->streams[AMV_STREAM_VIDEO];
266  AVStream *ast = s->streams[AMV_STREAM_AUDIO];
267  uint8_t amvh[56] = {0};
268  int64_t list1;
269 
270  amv->riff_start = amv_start_tag(pb, "RIFF");
271  ffio_wfourcc(pb, "AMV ");
272  list1 = amv_start_tag(pb, "LIST");
273  ffio_wfourcc(pb, "hdrl");
274 
275  ffio_wfourcc(pb, "amvh");
276  avio_wl32(pb, 56);
277 
278  AV_WL32(amvh + 0, amv->us_per_frame);
279  AV_WL32(amvh + 32, vst->codecpar->width);
280  AV_WL32(amvh + 36, vst->codecpar->height);
281  AV_WL32(amvh + 40, vst->time_base.den);
282  AV_WL32(amvh + 44, vst->time_base.num);
283  AV_WL32(amvh + 48, 0);
284  AV_WL32(amvh + 52, 0); /* duration, filled in later. */
285 
286  avio_write(pb, amvh, sizeof(amvh));
287  amv->offset_duration = avio_tell(pb) - 4;
288 
289  amv_write_vlist(s, vst->codecpar);
290  amv_write_alist(s, ast->codecpar);
291  amv_end_tag(pb, list1);
292 
293  amv->movi_list = amv_start_tag(pb, "LIST");
294  ffio_wfourcc(pb, "movi");
295  return 0;
296 }
297 
299 {
300  AMVContext *amv = s->priv_data;
301 
303  ffio_wfourcc(s->pb, "00dc");
304  else if (pkt->stream_index == AMV_STREAM_AUDIO)
305  ffio_wfourcc(s->pb, "01wb");
306  else
307  av_assert0(0);
308 
309  if (pkt->stream_index == AMV_STREAM_AUDIO && pkt->size != amv->ablock_align) {
310  /* Can happen when remuxing files produced by another encoder. */
311  av_log(s, AV_LOG_WARNING, "Invalid audio packet size (%d != %d)\n",
312  pkt->size, amv->ablock_align);
313  }
314 
315  avio_wl32(s->pb, pkt->size);
316  avio_write(s->pb, pkt->data, pkt->size);
317 
318  amv->lastpts[pkt->stream_index] += pkt->duration;
319  amv->last_stream = pkt->stream_index;
320  return 0;
321 }
322 
324 {
325  AMVContext *amv = s->priv_data;
326  int stream_index = pkt->stream_index;
327 
328  if (stream_index != amv->last_stream)
329  return 0;
330 
331  stream_index = (stream_index + 1) % s->nb_streams;
332  if (stream_index == AMV_STREAM_VIDEO)
333  return amv_write_packet_internal(s, amv->vpad);
334  else if (stream_index == AMV_STREAM_AUDIO)
335  return amv_write_packet_internal(s, amv->apad);
336  else
337  av_assert0(0);
338 
339  return AVERROR(EINVAL);
340 }
341 
343 {
344  AMVContext *amv = s->priv_data;
345  int ret;
346 
347  /* Add a dummy frame if we've received two of the same index. */
348  if ((ret = amv_pad(s, pkt)) < 0)
349  return ret;
350 
351  if ((ret = amv_write_packet_internal(s, pkt)) < 0)
352  return ret;
353 
355  /* Save the last packet for padding. */
356  av_packet_unref(amv->vpad);
357  if ((ret = av_packet_ref(amv->vpad, pkt)) < 0)
358  return ret;
359  }
360 
361  return 0;
362 }
363 
365 {
366  AMVContext *amv = s->priv_data;
367  AVStream *vst = s->streams[AMV_STREAM_VIDEO];
368  AVStream *ast = s->streams[AMV_STREAM_AUDIO];
369  int64_t maxpts, ret;
370  int hh, mm, ss;
371 
372  /* Pad-out one last audio frame if needed. */
373  if (amv->last_stream == AMV_STREAM_VIDEO) {
374  if ((ret = amv_write_packet_internal(s, amv->apad)) < 0)
375  return ret;
376  }
377 
378  amv_end_tag(s->pb, amv->movi_list);
379  amv_end_tag(s->pb, amv->riff_start);
380 
381  ffio_wfourcc(s->pb, "AMV_");
382  ffio_wfourcc(s->pb, "END_");
383 
384  if ((ret = avio_seek(s->pb, amv->offset_duration, SEEK_SET)) < 0)
385  return ret;
386 
387  /* Go back and write the duration. */
388  maxpts = FFMAX(
391  );
392 
393  ss = maxpts / AV_TIME_BASE;
394  mm = ss / 60;
395  hh = mm / 60;
396  ss %= 60;
397  mm %= 60;
398 
399  avio_w8(s->pb, ss);
400  avio_w8(s->pb, mm);
401  avio_wl16(s->pb, hh);
402  return 0;
403 }
404 
406  .p.name = "amv",
407  .p.long_name = NULL_IF_CONFIG_SMALL("AMV"),
408  .p.mime_type = "video/amv",
409  .p.extensions = "amv",
410  .priv_data_size = sizeof(AMVContext),
411  .p.audio_codec = AV_CODEC_ID_ADPCM_IMA_AMV,
412  .p.video_codec = AV_CODEC_ID_AMV,
413  .init = amv_init,
414  .deinit = amv_deinit,
415  .write_header = amv_write_header,
416  .write_packet = amv_write_packet,
417  .write_trailer = amv_write_trailer,
418 };
av_packet_unref
void av_packet_unref(AVPacket *pkt)
Wipe the packet.
Definition: avpacket.c:423
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:511
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:128
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:194
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:205
AVPacket::data
uint8_t * data
Definition: packet.h:491
AVPacket::duration
int64_t duration
Duration of this packet in AVStream->time_base units, 0 if unknown.
Definition: packet.h:509
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:405
AVChannelLayout::nb_channels
int nb_channels
Number of channels in this layout.
Definition: channel_layout.h:317
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:323
AMV_VIDEO_STRF_SIZE
#define AMV_VIDEO_STRF_SIZE
Definition: amvenc.c:51
FFOutputFormat::p
AVOutputFormat p
The public AVOutputFormat.
Definition: mux.h:36
avio_wl16
void avio_wl16(AVIOContext *s, unsigned int val)
Definition: aviobuf.c:484
avio_tell
static av_always_inline int64_t avio_tell(AVIOContext *s)
ftell() equivalent for AVIOContext.
Definition: avio.h:513
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:212
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:182
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:121
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:342
if
if(ret)
Definition: filter_design.txt:179
AVFormatContext
Format I/O context.
Definition: avformat.h:1115
internal.h
AVStream::codecpar
AVCodecParameters * codecpar
Codec parameters associated with this stream.
Definition: avformat.h:864
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:880
AMV_AUDIO_STRF_SIZE
#define AMV_AUDIO_STRF_SIZE
Definition: amvenc.c:53
FFOutputFormat
Definition: mux.h:32
AV_CODEC_ID_ADPCM_IMA_AMV
@ AV_CODEC_ID_ADPCM_IMA_AMV
Definition: codec_id.h:388
avio_w8
void avio_w8(AVIOContext *s, int b)
Definition: aviobuf.c:226
ffio_fill
void ffio_fill(AVIOContext *s, int b, int64_t count)
Definition: aviobuf.c:234
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:431
AVCodecParameters::ch_layout
AVChannelLayout ch_layout
Audio only.
Definition: codec_par.h:206
AVCodecParameters::sample_rate
int sample_rate
Audio only.
Definition: codec_par.h:171
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:298
AVIOContext
Bytestream IO Context.
Definition: avio.h:166
AVPacket::size
int size
Definition: packet.h:492
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:248
AV_WL16
#define AV_WL16(p, v)
Definition: intreadwrite.h:410
avio_wl32
void avio_wl32(AVIOContext *s, unsigned int val)
Definition: aviobuf.c:404
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:417
avio_internal.h
AMVContext::offset_duration
int64_t offset_duration
Definition: amvenc.c:59
AVCodecParameters::height
int height
Definition: codec_par.h:122
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:178
AMVContext::riff_start
int64_t riff_start
Definition: amvenc.c:57
AMVContext::last_stream
int last_stream
Definition: amvenc.c:60
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:1737
ret
ret
Definition: filter_design.txt:187
AVStream
Stream structure.
Definition: avformat.h:841
avio_seek
int64_t avio_seek(AVIOContext *s, int64_t offset, int whence)
fseek() equivalent for AVIOContext.
Definition: aviobuf.c:278
pos
unsigned int pos
Definition: spdifenc.c:413
avformat.h
amv_write_trailer
static int amv_write_trailer(AVFormatContext *s)
Definition: amvenc.c:364
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:261
tag_list
static const struct exif_tag tag_list[]
Definition: exif.c:38
AVPacket::stream_index
int stream_index
Definition: packet.h:493
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:140
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:468
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:231
amv_end_tag
static void amv_end_tag(AVIOContext *pb, int64_t start)
Definition: amvenc.c:84
AMVContext
Definition: amvenc.c:55
mux.h