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 libavformat and libavcodec demuxing and decoding API usage example
25 * @example demux_decode.c
26 *
27 * Show how to use the libavformat and libavcodec API to demux and decode audio
28 * and video data. Write the output as raw audio and input files to be played by
29 * ffplay.
30 */
31
37
48
52
58
60 {
63 /* To handle this change, one could call av_image_alloc again and
64 * decode the following frames into another rawvideo file. */
65 fprintf(stderr, "Error: Width, height and pixel format have to be "
66 "constant in a rawvideo file, but the width, height or "
67 "pixel format of the input video changed:\n"
68 "old: width = %d, height = %d, format = %s\n"
69 "new: width = %d, height = %d, format = %s\n",
73 return -1;
74 }
75
76 printf(
"video_frame n:%d\n",
78
79 /* copy decoded frame to destination buffer:
80 * this is required since rawvideo expects non aligned data */
84
85 /* write to rawvideo file */
87 return 0;
88 }
89
91 {
93 printf(
"audio_frame n:%d nb_samples:%d pts:%s\n",
96
97 /* Write the raw audio data samples of the first plane. This works
98 * fine for packed formats (e.g. AV_SAMPLE_FMT_S16). However,
99 * most audio decoders output planar audio, which uses a separate
100 * plane of audio samples for each channel (e.g. AV_SAMPLE_FMT_S16P).
101 * In other words, this code will write only the first audio channel
102 * in these cases.
103 * You should use libswresample or libavfilter to convert the frame
104 * to packed data. */
106
107 return 0;
108 }
109
111 {
113
114 // submit the packet to the decoder
117 fprintf(stderr,
"Error submitting a packet for decoding (%s)\n",
av_err2str(
ret));
119 }
120
121 // get all the available frames from the decoder
125 // those two return values are special and mean there is no output
126 // frame available, but there were no errors during decoding
128 return 0;
129
130 fprintf(stderr,
"Error during decoding (%s)\n",
av_err2str(
ret));
132 }
133
134 // write the frame data to output file
137 else
139
141 }
142
144 }
145
148 {
149 int ret, stream_index;
152
155 fprintf(stderr, "Could not find %s stream in input file '%s'\n",
158 } else {
161
162 /* find decoder for the stream */
164 if (!dec) {
165 fprintf(stderr, "Failed to find %s codec\n",
168 }
169
170 /* Allocate a codec context for the decoder */
173 fprintf(stderr, "Failed to allocate the %s codec context\n",
176 }
177
178 /* Copy codec parameters from input stream to output codec context */
180 fprintf(stderr, "Failed to copy %s codec parameters to decoder context\n",
183 }
184
185 /* Init the decoders */
187 fprintf(stderr, "Failed to open %s codec\n",
190 }
191 *stream_idx = stream_index;
192 }
193
194 return 0;
195 }
196
199 {
201 struct sample_fmt_entry {
203 } sample_fmt_entries[] = {
209 };
211
213 struct sample_fmt_entry *
entry = &sample_fmt_entries[
i];
214 if (sample_fmt ==
entry->sample_fmt) {
216 return 0;
217 }
218 }
219
220 fprintf(stderr,
221 "sample format %s is not supported as output format\n",
223 return -1;
224 }
225
226 int main (
int argc,
char **argv)
227 {
229
230 if (argc != 4) {
231 fprintf(stderr, "usage: %s input_file video_output_file audio_output_file\n"
232 "API example program to show how to read frames from an input file.\n"
233 "This program reads frames from a file, decodes them, and writes decoded\n"
234 "video frames to a rawvideo file named video_output_file, and decoded\n"
235 "audio frames to a rawaudio file named audio_output_file.\n",
236 argv[0]);
237 exit(1);
238 }
242
243 /* open input file, and allocate format context */
245 fprintf(stderr,
"Could not open source file %s\n",
src_filename);
246 exit(1);
247 }
248
249 /* retrieve stream information */
251 fprintf(stderr, "Could not find stream information\n");
252 exit(1);
253 }
254
257
262 goto end;
263 }
264
265 /* allocate image where the decoded image will be put */
272 fprintf(stderr, "Could not allocate raw video buffer\n");
273 goto end;
274 }
276 }
277
284 goto end;
285 }
286 }
287
288 /* dump input information to stderr */
290
292 fprintf(stderr, "Could not find audio or video stream in the input, aborting\n");
294 goto end;
295 }
296
299 fprintf(stderr, "Could not allocate frame\n");
301 goto end;
302 }
303
306 fprintf(stderr, "Could not allocate packet\n");
308 goto end;
309 }
310
315
316 /* read frames from the file */
318 // check if the packet belongs to a stream we are interested in, otherwise
319 // skip it
326 break;
327 }
328
329 /* flush the decoders */
334
335 printf(
"Demuxing succeeded.\n");
336
338 printf(
"Play the output video file with the command:\n"
339 "ffplay -f rawvideo -pix_fmt %s -video_size %dx%d %s\n",
342 }
343
347 const char *fmt;
348
351 printf(
"Warning: the sample format the decoder produced is planar "
352 "(%s). This example will output the first channel only.\n",
353 packed ? packed : "?");
355 n_channels = 1;
356 }
357
359 goto end;
360
361 printf(
"Play the output audio file with the command:\n"
362 "ffplay -f %s -ac %d -ar %d %s\n",
365 }
366
367 end:
378
380 }