1 /*
2 * Permission is hereby granted, free of charge, to any person obtaining a copy
3 * of this software and associated documentation files (the "Software"), to deal
4 * in the Software without restriction, including without limitation the rights
5 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
6 * copies of the Software, and to permit persons to whom the Software is
7 * furnished to do so, subject to the following conditions:
8 *
9 * The above copyright notice and this permission notice shall be included in
10 * all copies or substantial portions of the Software.
11 *
12 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
13 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
14 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
15 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
16 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
17 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
18 * THE SOFTWARE.
19 */
20
21 /**
22 * @file Intel QSV-accelerated video transcoding API usage example
23 * @example qsv_transcode.c
24 *
25 * Perform QSV-accelerated transcoding and show to dynamically change
26 * encoder's options.
27 *
28 * Usage: qsv_transcode input_stream codec output_stream initial option
29 * { frame_number new_option }
30 * e.g: - qsv_transcode input.mp4 h264_qsv output_h264.mp4 "g 60"
31 * - qsv_transcode input.mp4 hevc_qsv output_hevc.mp4 "g 60 async_depth 1"
32 * 100 "g 120"
33 * (initialize codec with gop_size 60 and change it to 120 after 100
34 * frames)
35 */
36
37 #include <stdio.h>
38 #include <errno.h>
39
45
50
58
60 {
62 if (strlen(optstr) == 0)
63 return 0;
64 key = strtok(optstr,
" ");
71 do {
74 return 0;
79 } while(1);
80 }
81
83 {
86 static int frame_number = 0;
87 frame_number++;
93 fprintf(stderr, "The dynamic parameter is wrong\n");
95 }
96 /* Set common option. The dictionary will be freed and replaced
97 * by a new one containing all options not found in common option list.
98 * Then this new dictionary is used to set private option. */
101 /* Set codec specific option */
104 /* There is no "framerate" option in common option list. Use "-r" to set
105 * framerate, which is compatible with ffmpeg commandline. The video is
106 * assumed to be average frame rate, so set time_base to 1/framerate. */
108 if (e) {
111 }
112 }
116 }
117
119 {
123 }
124
126 }
127
128 fprintf(stderr, "The QSV pixel format not offered in get_format()\n");
129
131 }
132
134 {
138
140 fprintf(stderr, "Cannot open input file '%s', Error code: %s\n",
143 }
144
146 fprintf(stderr, "Cannot find input stream information. Error code: %s\n",
149 }
150
153 fprintf(stderr, "Cannot find a video stream in the input file. "
156 }
159
160 switch(
video->codecpar->codec_id) {
163 break;
166 break;
169 break;
172 break;
175 break;
178 break;
181 break;
182 default:
183 fprintf(stderr, "Codec is not supported by qsv\n");
185 }
186
189
191 fprintf(stderr, "avcodec_parameters_to_context error. Error code: %s\n",
194 }
196
199 fprintf(stderr, "A hardware device reference create failed.\n");
201 }
205 fprintf(stderr, "Failed to open codec for decoding. Error code: %s\n",
207
209 }
210
212 {
214
216
218 fprintf(stderr, "Failed to set dynamic parameter. Error code: %s\n",
220 goto end;
221 }
222
224 fprintf(stderr,
"Error during encoding. Error code: %s\n",
av_err2str(
ret));
225 goto end;
226 }
227 while (1) {
229 break;
234 fprintf(stderr, "Error during writing data to output file. "
237 }
238 }
239
240 end:
242 return 0;
245 }
246
248 {
251
254 fprintf(stderr,
"Error during decoding. Error code: %s\n",
av_err2str(
ret));
256 }
257
261
265 return 0;
266 }
else if (
ret < 0) {
267 fprintf(stderr,
"Error while decoding. Error code: %s\n",
av_err2str(
ret));
269 }
274 /* we need to ref hw_frames_ctx of decoder to initialize encoder's codec.
275 Only after we get a decoded frame, can we obtain its hw_frames_ctx */
280 }
281 /* set AVCodecContext Parameters for encoder, here we keep them stay
282 * the same as decoder.
283 */
289 fprintf(stderr, "Failed to set encoding parameter.\n");
291 }
292 /* There is no "framerate" option in common option list. Use "-r" to
293 * set framerate, which is compatible with ffmpeg commandline. The
294 * video is assumed to be average frame rate, so set time_base to
295 * 1/framerate. */
297 if (e) {
300 }
302 fprintf(stderr, "Failed to open encode codec. Error code: %s\n",
306 }
308
310 fprintf(stderr, "Failed to allocate stream for output format.\n");
313 }
314
318 fprintf(stderr, "Failed to copy the stream parameters. "
321 }
322
323 /* write the stream header */
325 fprintf(stderr, "Error while writing stream header. "
328 }
329 }
333 fprintf(stderr, "Error during encoding and writing.\n");
334
337 }
339 }
340
341 int main(
int argc,
char **argv)
342 {
346
347 if (argc < 5 || (argc - 5) % 2) {
349 " <\"encoding option set 0\"> [<frame_number> <\"encoding options set 1\">]...\n", argv[0]);
350 return 1;
351 }
358 }
359
362 fprintf(stderr,
"Failed to create a QSV device. Error code: %s\n",
av_err2str(
ret));
363 goto end;
364 }
365
367 if (!dec_pkt) {
368 fprintf(stderr, "Failed to allocate decode packet\n");
369 goto end;
370 }
371
373 goto end;
374
376 fprintf(stderr, "Could not find encoder '%s'\n", argv[2]);
378 goto end;
379 }
380
382 fprintf(stderr, "Failed to deduce output format from file extension. Error code: "
384 goto end;
385 }
386
389 goto end;
390 }
391
394 fprintf(stderr, "Cannot open output file. "
396 goto end;
397 }
398
399 /* read all packets and only transcoding video */
402 break;
403
406
408 }
409
410 /* flush decoder */
412 if ((
ret =
dec_enc(dec_pkt, enc_codec, argv[4])) < 0) {
413 fprintf(stderr,
"Failed to flush decoder %s\n",
av_err2str(
ret));
414 goto end;
415 }
416
417 /* flush encoder */
419 fprintf(stderr,
"Failed to flush encoder %s\n",
av_err2str(
ret));
420 goto end;
421 }
422
423 /* write the trailer for output stream */
425 fprintf(stderr,
"Failed to write trailer %s\n",
av_err2str(
ret));
426
427 end:
436 }