demuxing.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2012 Stefano Sabatini
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a copy
5  * of this software and associated documentation files (the "Software"), to deal
6  * in the Software without restriction, including without limitation the rights
7  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8  * copies of the Software, and to permit persons to whom the Software is
9  * furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice shall be included in
12  * all copies or substantial portions of the Software.
13  *
14  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20  * THE SOFTWARE.
21  */
22 
23 /**
24  * @file
25  * libavformat demuxing API use example.
26  *
27  * Show how to use the libavformat and libavcodec API to demux and
28  * decode audio and video data.
29  * @example doc/examples/demuxing.c
30  */
31 
32 #include <libavutil/imgutils.h>
33 #include <libavutil/samplefmt.h>
34 #include <libavutil/timestamp.h>
35 #include <libavformat/avformat.h>
36 
40 static const char *src_filename = NULL;
41 static const char *video_dst_filename = NULL;
42 static const char *audio_dst_filename = NULL;
43 static FILE *video_dst_file = NULL;
44 static FILE *audio_dst_file = NULL;
45 
46 static uint8_t *video_dst_data[4] = {NULL};
47 static int video_dst_linesize[4];
48 static int video_dst_bufsize;
49 
51 static int audio_dst_linesize;
52 static int audio_dst_bufsize;
53 
54 static int video_stream_idx = -1, audio_stream_idx = -1;
55 static AVFrame *frame = NULL;
56 static AVPacket pkt;
57 static int video_frame_count = 0;
58 static int audio_frame_count = 0;
59 
60 static int decode_packet(int *got_frame, int cached)
61 {
62  int ret = 0;
63 
64  if (pkt.stream_index == video_stream_idx) {
65  /* decode video frame */
66  ret = avcodec_decode_video2(video_dec_ctx, frame, got_frame, &pkt);
67  if (ret < 0) {
68  fprintf(stderr, "Error decoding video frame\n");
69  return ret;
70  }
71 
72  if (*got_frame) {
73  printf("video_frame%s n:%d coded_n:%d pts:%s\n",
74  cached ? "(cached)" : "",
76  av_ts2timestr(frame->pts, &video_dec_ctx->time_base));
77 
78  /* copy decoded frame to destination buffer:
79  * this is required since rawvideo expects non aligned data */
81  (const uint8_t **)(frame->data), frame->linesize,
82  video_dec_ctx->pix_fmt, video_dec_ctx->width, video_dec_ctx->height);
83 
84  /* write to rawvideo file */
86  }
87  } else if (pkt.stream_index == audio_stream_idx) {
88  /* decode audio frame */
89  ret = avcodec_decode_audio4(audio_dec_ctx, frame, got_frame, &pkt);
90  if (ret < 0) {
91  fprintf(stderr, "Error decoding audio frame\n");
92  return ret;
93  }
94 
95  if (*got_frame) {
96  printf("audio_frame%s n:%d nb_samples:%d pts:%s\n",
97  cached ? "(cached)" : "",
98  audio_frame_count++, frame->nb_samples,
100 
102  frame->nb_samples, frame->format, 1);
103  if (ret < 0) {
104  fprintf(stderr, "Could not allocate audio buffer\n");
105  return AVERROR(ENOMEM);
106  }
107 
108  /* TODO: extend return code of the av_samples_* functions so that this call is not needed */
111  frame->nb_samples, frame->format, 1);
112 
113  /* copy audio data to destination buffer:
114  * this is required since rawaudio expects non aligned data */
115  av_samples_copy(audio_dst_data, frame->data, 0, 0,
116  frame->nb_samples, av_frame_get_channels(frame), frame->format);
117 
118  /* write to rawaudio file */
121  }
122  }
123 
124  return ret;
125 }
126 
127 static int open_codec_context(int *stream_idx,
128  AVFormatContext *fmt_ctx, enum AVMediaType type)
129 {
130  int ret;
131  AVStream *st;
133  AVCodec *dec = NULL;
134 
135  ret = av_find_best_stream(fmt_ctx, type, -1, -1, NULL, 0);
136  if (ret < 0) {
137  fprintf(stderr, "Could not find %s stream in input file '%s'\n",
139  return ret;
140  } else {
141  *stream_idx = ret;
142  st = fmt_ctx->streams[*stream_idx];
143 
144  /* find decoder for the stream */
145  dec_ctx = st->codec;
146  dec = avcodec_find_decoder(dec_ctx->codec_id);
147  if (!dec) {
148  fprintf(stderr, "Failed to find %s codec\n",
150  return ret;
151  }
152 
153  if ((ret = avcodec_open2(dec_ctx, dec, NULL)) < 0) {
154  fprintf(stderr, "Failed to open %s codec\n",
156  return ret;
157  }
158  }
159 
160  return 0;
161 }
162 
163 static int get_format_from_sample_fmt(const char **fmt,
164  enum AVSampleFormat sample_fmt)
165 {
166  int i;
167  struct sample_fmt_entry {
168  enum AVSampleFormat sample_fmt; const char *fmt_be, *fmt_le;
169  } sample_fmt_entries[] = {
170  { AV_SAMPLE_FMT_U8, "u8", "u8" },
171  { AV_SAMPLE_FMT_S16, "s16be", "s16le" },
172  { AV_SAMPLE_FMT_S32, "s32be", "s32le" },
173  { AV_SAMPLE_FMT_FLT, "f32be", "f32le" },
174  { AV_SAMPLE_FMT_DBL, "f64be", "f64le" },
175  };
176  *fmt = NULL;
177 
178  for (i = 0; i < FF_ARRAY_ELEMS(sample_fmt_entries); i++) {
179  struct sample_fmt_entry *entry = &sample_fmt_entries[i];
180  if (sample_fmt == entry->sample_fmt) {
181  *fmt = AV_NE(entry->fmt_be, entry->fmt_le);
182  return 0;
183  }
184  }
185 
186  fprintf(stderr,
187  "sample format %s is not supported as output format\n",
188  av_get_sample_fmt_name(sample_fmt));
189  return -1;
190 }
191 
192 int main (int argc, char **argv)
193 {
194  int ret = 0, got_frame;
195 
196  if (argc != 4) {
197  fprintf(stderr, "usage: %s input_file video_output_file audio_output_file\n"
198  "API example program to show how to read frames from an input file.\n"
199  "This program reads frames from a file, decodes them, and writes decoded\n"
200  "video frames to a rawvideo file named video_output_file, and decoded\n"
201  "audio frames to a rawaudio file named audio_output_file.\n"
202  "\n", argv[0]);
203  exit(1);
204  }
205  src_filename = argv[1];
206  video_dst_filename = argv[2];
207  audio_dst_filename = argv[3];
208 
209  /* register all formats and codecs */
210  av_register_all();
211 
212  /* open input file, and allocate format context */
213  if (avformat_open_input(&fmt_ctx, src_filename, NULL, NULL) < 0) {
214  fprintf(stderr, "Could not open source file %s\n", src_filename);
215  exit(1);
216  }
217 
218  /* retrieve stream information */
219  if (avformat_find_stream_info(fmt_ctx, NULL) < 0) {
220  fprintf(stderr, "Could not find stream information\n");
221  exit(1);
222  }
223 
225  video_stream = fmt_ctx->streams[video_stream_idx];
226  video_dec_ctx = video_stream->codec;
227 
228  video_dst_file = fopen(video_dst_filename, "wb");
229  if (!video_dst_file) {
230  fprintf(stderr, "Could not open destination file %s\n", video_dst_filename);
231  ret = 1;
232  goto end;
233  }
234 
235  /* allocate image where the decoded image will be put */
237  video_dec_ctx->width, video_dec_ctx->height,
238  video_dec_ctx->pix_fmt, 1);
239  if (ret < 0) {
240  fprintf(stderr, "Could not allocate raw video buffer\n");
241  goto end;
242  }
244  }
245 
247  int nb_planes;
248 
251  audio_dst_file = fopen(audio_dst_filename, "wb");
252  if (!audio_dst_file) {
253  fprintf(stderr, "Could not open destination file %s\n", video_dst_filename);
254  ret = 1;
255  goto end;
256  }
257 
259  audio_dec_ctx->channels : 1;
260  audio_dst_data = av_mallocz(sizeof(uint8_t *) * nb_planes);
261  if (!audio_dst_data) {
262  fprintf(stderr, "Could not allocate audio data buffers\n");
263  ret = AVERROR(ENOMEM);
264  goto end;
265  }
266  }
267 
268  /* dump input information to stderr */
269  av_dump_format(fmt_ctx, 0, src_filename, 0);
270 
271  if (!audio_stream && !video_stream) {
272  fprintf(stderr, "Could not find audio or video stream in the input, aborting\n");
273  ret = 1;
274  goto end;
275  }
276 
277  frame = avcodec_alloc_frame();
278  if (!frame) {
279  fprintf(stderr, "Could not allocate frame\n");
280  ret = AVERROR(ENOMEM);
281  goto end;
282  }
283 
284  /* initialize packet, set data to NULL, let the demuxer fill it */
285  av_init_packet(&pkt);
286  pkt.data = NULL;
287  pkt.size = 0;
288 
289  if (video_stream)
290  printf("Demuxing video from file '%s' into '%s'\n", src_filename, video_dst_filename);
291  if (audio_stream)
292  printf("Demuxing audio from file '%s' into '%s'\n", src_filename, audio_dst_filename);
293 
294  /* read frames from the file */
295  while (av_read_frame(fmt_ctx, &pkt) >= 0) {
296  decode_packet(&got_frame, 0);
297  av_free_packet(&pkt);
298  }
299 
300  /* flush cached frames */
301  pkt.data = NULL;
302  pkt.size = 0;
303  do {
304  decode_packet(&got_frame, 1);
305  } while (got_frame);
306 
307  printf("Demuxing succeeded.\n");
308 
309  if (video_stream) {
310  printf("Play the output video file with the command:\n"
311  "ffplay -f rawvideo -pix_fmt %s -video_size %dx%d %s\n",
312  av_get_pix_fmt_name(video_dec_ctx->pix_fmt), video_dec_ctx->width, video_dec_ctx->height,
314  }
315 
316  if (audio_stream) {
317  const char *fmt;
318 
319  if ((ret = get_format_from_sample_fmt(&fmt, audio_dec_ctx->sample_fmt)) < 0)
320  goto end;
321  printf("Play the output audio file with the command:\n"
322  "ffplay -f %s -ac %d -ar %d %s\n",
325  }
326 
327 end:
328  if (video_dec_ctx)
329  avcodec_close(video_dec_ctx);
330  if (audio_dec_ctx)
332  avformat_close_input(&fmt_ctx);
333  if (video_dst_file)
335  if (audio_dst_file)
337  av_free(frame);
340 
341  return ret < 0;
342 }
void * av_mallocz(size_t size)
Allocate a block of size bytes with alignment suitable for all memory accesses (including vectors if ...
Definition: mem.c:205
void av_free_packet(AVPacket *pkt)
Free a packet.
Definition: avpacket.c:242
This structure describes decoded (raw) audio or video data.
Definition: frame.h:76
static FILE * audio_dst_file
Definition: demuxing.c:44
int av_samples_get_buffer_size(int *linesize, int nb_channels, int nb_samples, enum AVSampleFormat sample_fmt, int align)
Get the required buffer size for the given audio parameters.
Definition: samplefmt.c:125
static int video_frame_count
Definition: demuxing.c:57
const char * fmt
Definition: avisynth_c.h:669
misc image utilities
static int open_codec_context(int *stream_idx, AVFormatContext *fmt_ctx, enum AVMediaType type)
Definition: demuxing.c:127
int avformat_open_input(AVFormatContext **ps, const char *filename, AVInputFormat *fmt, AVDictionary **options)
Open an input stream and read the header.
int av_image_alloc(uint8_t *pointers[4], int linesizes[4], int w, int h, enum AVPixelFormat pix_fmt, int align)
Allocate an image with size w and h and pixel format pix_fmt, and fill pointers and linesizes accordi...
Definition: imgutils.c:190
static int audio_stream_idx
Definition: demuxing.c:54
static AVFrame * frame
Definition: demuxing.c:55
int main(int argc, char **argv)
Definition: demuxing.c:192
enum AVPixelFormat pix_fmt
Pixel format, see AV_PIX_FMT_xxx.
static const char * audio_dst_filename
Definition: demuxing.c:42
#define FF_ARRAY_ELEMS(a)
signed 16 bits
Definition: samplefmt.h:52
static AVStream * video_stream
Definition: demuxing.c:39
AVRational time_base
This is the fundamental unit of time (in seconds) in terms of which frame timestamps are represented...
void av_freep(void *arg)
Free a memory block which has been allocated with av_malloc(z)() or av_realloc() and set the pointer ...
Definition: mem.c:198
Format I/O context.
Definition: avformat.h:944
enum AVSampleFormat sample_fmt
audio sample format
uint8_t
AV_SAMPLE_FMT_U8
timestamp utils, mostly useful for debugging/logging purposes
static AVFormatContext * fmt_ctx
Definition: demuxing.c:37
static AVPacket pkt
Definition: demuxing.c:56
end end
#define AV_NE(be, le)
Definition: common.h:44
int64_t pts
Presentation timestamp in time_base units (time when frame should be shown to user).
Definition: frame.h:159
AVStream ** streams
Definition: avformat.h:992
uint8_t * data
static int video_dst_bufsize
Definition: demuxing.c:48
static const char * video_dst_filename
Definition: demuxing.c:41
void av_dump_format(AVFormatContext *ic, int index, const char *url, int is_output)
int av_find_best_stream(AVFormatContext *ic, enum AVMediaType type, int wanted_stream_nb, int related_stream, AVCodec **decoder_ret, int flags)
Find the "best" stream in the file.
int avcodec_close(AVCodecContext *avctx)
Close a given AVCodecContext and free all the data associated with it (but not the AVCodecContext its...
void av_free(void *ptr)
Free a memory block which has been allocated with av_malloc(z)() or av_realloc(). ...
Definition: mem.c:183
int avcodec_decode_video2(AVCodecContext *avctx, AVFrame *picture, int *got_picture_ptr, const AVPacket *avpkt)
Decode the video frame of size avpkt->size from avpkt->data into picture.
static int audio_dst_bufsize
Definition: demuxing.c:52
#define av_ts2timestr(ts, tb)
Convenience macro, the return value should be used only directly in function arguments but never stan...
Definition: timestamp.h:72
void av_image_copy(uint8_t *dst_data[4], int dst_linesizes[4], const uint8_t *src_data[4], const int src_linesizes[4], enum AVPixelFormat pix_fmt, int width, int height)
Copy image in src_data to dst_data.
Definition: imgutils.c:257
AVCodecContext * codec
Codec context associated with this stream.
Definition: avformat.h:662
signed 32 bits
Definition: samplefmt.h:53
AVFrame * avcodec_alloc_frame(void)
Allocate an AVFrame and set its fields to default values.
int av_frame_get_channels(const AVFrame *frame)
ret
Definition: avfilter.c:821
int width
picture width / height.
static AVCodecContext * video_dec_ctx
Definition: demuxing.c:38
int avcodec_decode_audio4(AVCodecContext *avctx, AVFrame *frame, int *got_frame_ptr, const AVPacket *avpkt)
Decode the audio frame of size avpkt->size from avpkt->data into frame.
static AVStream * audio_stream
Definition: demuxing.c:39
static int decode_packet(int *got_frame, int cached)
Definition: demuxing.c:60
const char * av_get_sample_fmt_name(enum AVSampleFormat sample_fmt)
Return the name of sample_fmt, or NULL if sample_fmt is not recognized.
Definition: samplefmt.c:47
Stream structure.
Definition: avformat.h:643
int format
format of the frame, -1 if unknown or unset Values correspond to enum AVPixelFormat for video frames...
Definition: frame.h:134
NULL
Definition: eval.c:55
int coded_picture_number
picture number in bitstream order
Definition: frame.h:176
static uint8_t ** audio_dst_data
Definition: demuxing.c:50
int av_samples_alloc(uint8_t **audio_data, int *linesize, int nb_channels, int nb_samples, enum AVSampleFormat sample_fmt, int align)
Allocate a samples buffer for nb_samples samples, and fill data pointers and linesize accordingly...
Definition: samplefmt.c:181
enum AVCodecID codec_id
int sample_rate
samples per second
int linesize[AV_NUM_DATA_POINTERS]
For video, size in bytes of each picture line.
Definition: frame.h:101
Close file fclose(fid)
main external API structure.
AVCodec * avcodec_find_decoder(enum AVCodecID id)
Find a registered decoder with a matching codec ID.
int av_samples_copy(uint8_t **dst, uint8_t *const *src, int dst_offset, int src_offset, int nb_samples, int nb_channels, enum AVSampleFormat sample_fmt)
Copy samples from src to dst.
Definition: samplefmt.c:225
static int audio_dst_linesize
Definition: demuxing.c:51
static FILE * video_dst_file
Definition: demuxing.c:43
static int audio_frame_count
Definition: demuxing.c:58
int av_sample_fmt_is_planar(enum AVSampleFormat sample_fmt)
Check if the sample format is planar.
Definition: samplefmt.c:118
synthesis window for stochastic i
AVMediaType
Definition: avutil.h:141
int avcodec_open2(AVCodecContext *avctx, const AVCodec *codec, AVDictionary **options)
Initialize the AVCodecContext to use the given AVCodec.
static int get_format_from_sample_fmt(const char **fmt, enum AVSampleFormat sample_fmt)
Definition: demuxing.c:163
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFilterBuffer 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.Buffer references ownership and permissions
#define type
int av_read_frame(AVFormatContext *s, AVPacket *pkt)
Return the next frame of a stream.
const char * av_get_media_type_string(enum AVMediaType media_type)
Return a string describing the media_type enum, NULL if media_type is unknown.
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
Definition: frame.h:87
Main libavformat public API header.
static uint8_t * video_dst_data[4]
Definition: demuxing.c:46
int avformat_find_stream_info(AVFormatContext *ic, AVDictionary **options)
Read packets of a media file to get stream information.
static int video_stream_idx
Definition: demuxing.c:54
static AVCodecContext * dec_ctx
AVSampleFormat
Audio Sample Formats.
Definition: samplefmt.h:49
void av_init_packet(AVPacket *pkt)
Initialize optional fields of a packet with default values.
Definition: avpacket.c:56
void avformat_close_input(AVFormatContext **s)
Close an opened input AVFormatContext.
int channels
number of audio channels
printf("static const uint8_t my_array[100] = {\n")
static AVCodecContext * audio_dec_ctx
Definition: demuxing.c:38
const char * av_get_pix_fmt_name(enum AVPixelFormat pix_fmt)
Return the short name for a pixel format, NULL in case pix_fmt is unknown.
Definition: pixdesc.c:1700
static int video_dst_linesize[4]
Definition: demuxing.c:47
static const char * src_filename
Definition: demuxing.c:40
This structure stores compressed data.
void av_register_all(void)
Initialize libavformat and register all the muxers, demuxers and protocols.
Definition: allformats.c:52
int nb_samples
number of audio samples (per channel) described by this frame
Definition: frame.h:127