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
44
49
57
59 {
61 if (strlen(optstr) == 0)
62 return 0;
63 key = strtok(optstr,
" ");
70 do {
73 return 0;
78 } while(1);
79 }
80
82 {
85 static int frame_number = 0;
86 frame_number++;
92 fprintf(stderr, "The dynamic parameter is wrong\n");
94 }
95 /* Set common option. The dictionary will be freed and replaced
96 * by a new one containing all options not found in common option list.
97 * Then this new dictionary is used to set private option. */
100 /* Set codec specific option */
103 /* There is no "framerate" option in commom option list. Use "-r" to set
104 * framerate, which is compatible with ffmpeg commandline. The video is
105 * assumed to be average frame rate, so set time_base to 1/framerate. */
107 if (e) {
110 }
111 }
115 }
116
118 {
122 }
123
125 }
126
127 fprintf(stderr, "The QSV pixel format not offered in get_format()\n");
128
130 }
131
133 {
137
139 fprintf(stderr, "Cannot open input file '%s', Error code: %s\n",
142 }
143
145 fprintf(stderr, "Cannot find input stream information. Error code: %s\n",
148 }
149
152 fprintf(stderr, "Cannot find a video stream in the input file. "
155 }
158
159 switch(
video->codecpar->codec_id) {
162 break;
165 break;
168 break;
171 break;
174 break;
177 break;
180 break;
181 default:
182 fprintf(stderr, "Codec is not supportted by qsv\n");
184 }
185
188
190 fprintf(stderr, "avcodec_parameters_to_context error. Error code: %s\n",
193 }
195
198 fprintf(stderr, "A hardware device reference create failed.\n");
200 }
204 fprintf(stderr, "Failed to open codec for decoding. Error code: %s\n",
206
208 }
209
211 {
213
215
217 fprintf(stderr, "Failed to set dynamic parameter. Error code: %s\n",
219 goto end;
220 }
221
223 fprintf(stderr,
"Error during encoding. Error code: %s\n",
av_err2str(
ret));
224 goto end;
225 }
226 while (1) {
228 break;
233 fprintf(stderr, "Error during writing data to output file. "
236 }
237 }
238
239 end:
241 return 0;
244 }
245
247 {
250
253 fprintf(stderr,
"Error during decoding. Error code: %s\n",
av_err2str(
ret));
255 }
256
260
264 return 0;
265 }
else if (
ret < 0) {
266 fprintf(stderr,
"Error while decoding. Error code: %s\n",
av_err2str(
ret));
268 }
273 /* we need to ref hw_frames_ctx of decoder to initialize encoder's codec.
274 Only after we get a decoded frame, can we obtain its hw_frames_ctx */
279 }
280 /* set AVCodecContext Parameters for encoder, here we keep them stay
281 * the same as decoder.
282 */
288 fprintf(stderr, "Failed to set encoding parameter.\n");
290 }
291 /* There is no "framerate" option in commom option list. Use "-r" to
292 * set framerate, which is compatible with ffmpeg commandline. The
293 * video is assumed to be average frame rate, so set time_base to
294 * 1/framerate. */
296 if (e) {
299 }
301 fprintf(stderr, "Failed to open encode codec. Error code: %s\n",
305 }
307
309 fprintf(stderr, "Failed to allocate stream for output format.\n");
312 }
313
317 fprintf(stderr, "Failed to copy the stream parameters. "
320 }
321
322 /* write the stream header */
324 fprintf(stderr, "Error while writing stream header. "
327 }
328 }
332 fprintf(stderr, "Error during encoding and writing.\n");
333
336 }
338 }
339
340 int main(
int argc,
char **argv)
341 {
345
346 if (argc < 5 || (argc - 5) % 2) {
348 " <\"encoding option set 0\"> [<frame_number> <\"encoding options set 1\">]...\n", argv[0]);
349 return 1;
350 }
357 }
358
361 fprintf(stderr,
"Failed to create a QSV device. Error code: %s\n",
av_err2str(
ret));
362 goto end;
363 }
364
366 if (!dec_pkt) {
367 fprintf(stderr, "Failed to allocate decode packet\n");
368 goto end;
369 }
370
372 goto end;
373
375 fprintf(stderr, "Could not find encoder '%s'\n", argv[2]);
377 goto end;
378 }
379
381 fprintf(stderr, "Failed to deduce output format from file extension. Error code: "
383 goto end;
384 }
385
388 goto end;
389 }
390
393 fprintf(stderr, "Cannot open output file. "
395 goto end;
396 }
397
398 /* read all packets and only transcoding video */
401 break;
402
405
407 }
408
409 /* flush decoder */
411 if ((
ret =
dec_enc(dec_pkt, enc_codec, argv[4])) < 0) {
412 fprintf(stderr,
"Failed to flush decoder %s\n",
av_err2str(
ret));
413 goto end;
414 }
415
416 /* flush encoder */
418 fprintf(stderr,
"Failed to flush encoder %s\n",
av_err2str(
ret));
419 goto end;
420 }
421
422 /* write the trailer for output stream */
424 fprintf(stderr,
"Failed to write trailer %s\n",
av_err2str(
ret));
425
426 end:
435 }