FFmpeg
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
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  }
243  video_dst_bufsize = ret;
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)
334  fclose(video_dst_file);
335  if (audio_dst_file)
336  fclose(audio_dst_file);
337  av_free(frame);
340 
341  return ret < 0;
342 }