Rev 6144 | Rev 6438 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 6144 | Rev 6298 | ||
---|---|---|---|
Line 7... | Line 7... | ||
7 | #include |
7 | #include |
8 | #include |
8 | #include |
9 | #include |
9 | #include |
10 | #include |
10 | #include |
11 | #include |
11 | #include |
- | 12 | #include |
|
12 | #include |
13 | #include |
13 | #include "winlib/winlib.h" |
14 | #include "winlib/winlib.h" |
14 | #include "fplay.h" |
15 | #include "fplay.h" |
Line 15... | Line 16... | ||
15 | 16 | ||
Line 54... | Line 55... | ||
54 | PE(MPEG4, MPEG4_ADVANCED_SIMPLE, MPEG4AdvancedSimple), |
55 | PE(MPEG4, MPEG4_ADVANCED_SIMPLE, MPEG4AdvancedSimple), |
55 | PE(MPEG4, MPEG4_MAIN, MPEG4Main), |
56 | PE(MPEG4, MPEG4_MAIN, MPEG4Main), |
56 | PE(MPEG4, MPEG4_SIMPLE, MPEG4Simple), |
57 | PE(MPEG4, MPEG4_SIMPLE, MPEG4Simple), |
57 | PE(H264, H264_HIGH, H264High), |
58 | PE(H264, H264_HIGH, H264High), |
58 | PE(H264, H264_MAIN, H264Main), |
59 | PE(H264, H264_MAIN, H264Main), |
59 | PE(H264, H264_BASELINE, H264Baseline), |
60 | PE(H264, H264_CONSTRAINED_BASELINE, H264ConstrainedBaseline), |
60 | PE(VC1, VC1_ADVANCED, VC1Advanced), |
61 | PE(VC1, VC1_ADVANCED, VC1Advanced), |
61 | PE(VC1, VC1_MAIN, VC1Main), |
62 | PE(VC1, VC1_MAIN, VC1Main), |
62 | PE(VC1, VC1_SIMPLE, VC1Simple), |
63 | PE(VC1, VC1_SIMPLE, VC1Simple), |
63 | PE(WMV3, VC1_ADVANCED, VC1Advanced), |
64 | PE(WMV3, VC1_ADVANCED, VC1Advanced), |
64 | PE(WMV3, VC1_MAIN, VC1Main), |
65 | PE(WMV3, VC1_MAIN, VC1Main), |
Line 219... | Line 220... | ||
219 | 220 | ||
220 | static int has_profile(struct vaapi_context *vaapi, VAProfile profile) |
221 | static int has_profile(struct vaapi_context *vaapi, VAProfile profile) |
221 | { |
222 | { |
222 | VAProfile *profiles; |
223 | VAProfile *profiles; |
- | 224 | int n_profiles; |
|
223 | int n_profiles; |
225 | size_t size; |
224 | VAStatus status; |
226 | VAStatus status; |
Line 225... | Line 227... | ||
225 | int i; |
227 | int i; |
- | 228 | ||
- | 229 | size = vaMaxNumProfiles(vaapi->display) * sizeof(VAProfile); |
|
- | 230 | ||
Line 226... | Line 231... | ||
226 | 231 | profiles = alloca(size); |
|
Line 227... | Line 232... | ||
227 | profiles = calloc(vaMaxNumProfiles(vaapi->display), sizeof(profiles[0])); |
232 | memset(profiles, 0, size); |
228 | 233 | ||
Line 243... | Line 248... | ||
243 | 248 | ||
244 | static int has_entrypoint(struct vaapi_context *vaapi, VAProfile profile, VAEntrypoint entrypoint) |
249 | static int has_entrypoint(struct vaapi_context *vaapi, VAProfile profile, VAEntrypoint entrypoint) |
245 | { |
250 | { |
246 | VAEntrypoint *entrypoints; |
251 | VAEntrypoint *entrypoints; |
- | 252 | int n_entrypoints; |
|
247 | int n_entrypoints; |
253 | size_t size; |
248 | VAStatus status; |
254 | VAStatus status; |
Line 249... | Line 255... | ||
249 | int i; |
255 | int i; |
- | 256 | ||
- | 257 | size = vaMaxNumEntrypoints(vaapi->display) * sizeof(VAEntrypoint); |
|
- | 258 | ||
Line 250... | Line 259... | ||
250 | 259 | entrypoints = alloca(size); |
|
251 | entrypoints = calloc(vaMaxNumEntrypoints(vaapi->display), sizeof(entrypoints[0])); |
260 | memset(entrypoints, 0, size); |
252 | 261 | ||
253 | status = vaQueryConfigEntrypoints(vaapi->display, profile, |
262 | status = vaQueryConfigEntrypoints(vaapi->display, profile, |
Line 276... | Line 285... | ||
276 | VAConfigID config_id = VA_INVALID_ID; |
285 | VAConfigID config_id = VA_INVALID_ID; |
277 | VAContextID context_id = VA_INVALID_ID; |
286 | VAContextID context_id = VA_INVALID_ID; |
278 | VAStatus status; |
287 | VAStatus status; |
Line 279... | Line 288... | ||
279 | 288 | ||
- | 289 | ENTER(); |
|
- | 290 | ||
- | 291 | printf("%s profile %x width:%d height:%d\n", |
|
- | 292 | __FUNCTION__, profile, picture_width, picture_height); |
|
280 | ENTER(); |
293 | |
281 | if (!vaapi) |
294 | if (!vaapi) |
282 | { |
295 | { |
283 | FAIL(); |
296 | FAIL(); |
284 | return -1; |
297 | return -1; |
Line 380... | Line 393... | ||
380 | 393 | ||
381 | static enum PixelFormat get_format(struct AVCodecContext *avctx, |
394 | static enum PixelFormat get_format(struct AVCodecContext *avctx, |
382 | const enum AVPixelFormat *fmt) |
395 | const enum AVPixelFormat *fmt) |
383 | { |
396 | { |
384 | vst_t *vst = (vst_t*)avctx->opaque; |
397 | vst_t *vst = (vst_t*)avctx->opaque; |
385 | VAProfile profile = VAProfileNone; |
- | |
386 | - | ||
387 | ENTER(); |
- | |
388 | for (int i = 0; fmt[i] != PIX_FMT_NONE; i++) |
- | |
389 | { |
398 | VAProfile profile = avctx->profile; |
Line 390... | Line 399... | ||
390 | enum AVCodecID codec = avctx->codec_id; |
399 | enum AVCodecID codec = avctx->codec_id; |
391 | - | ||
Line 392... | Line 400... | ||
392 | if (fmt[i] != AV_PIX_FMT_VAAPI_VLD) |
400 | |
393 | continue; |
401 | printf("%s codec %d profile %x\n", __FUNCTION__,avctx->codec_id, avctx->profile); |
394 | 402 | ||
395 | if (codec == AV_CODEC_ID_H264) |
403 | if (codec == AV_CODEC_ID_H264) |
396 | { |
404 | { |
Line -... | Line 405... | ||
- | 405 | if(profile == FF_PROFILE_H264_BASELINE) |
|
- | 406 | profile = FF_PROFILE_H264_CONSTRAINED_BASELINE; |
|
- | 407 | }; |
|
- | 408 | ||
- | 409 | for (int i = 0; fmt[i] != PIX_FMT_NONE; i++) |
|
397 | if (profile == FF_PROFILE_H264_CONSTRAINED_BASELINE) |
410 | { |
398 | profile = FF_PROFILE_H264_MAIN; |
411 | if (fmt[i] != AV_PIX_FMT_VAAPI_VLD) |
399 | }; |
412 | continue; |
400 | 413 | ||
401 | for (int n = 0; hw_profiles[n].av_codec; n++) |
414 | for (int n = 0; hw_profiles[n].av_codec; n++) |
402 | { |
415 | { |
403 | if (hw_profiles[n].av_codec == codec && |
416 | if (hw_profiles[n].av_codec == codec && |
404 | hw_profiles[n].ff_profile == avctx->profile) |
417 | hw_profiles[n].ff_profile == profile) |
405 | { |
418 | { |
- | 419 | profile = hw_profiles[n].va_profile; |
|
406 | profile = hw_profiles[n].va_profile; |
420 | if (vaapi_init_decoder(vst, profile, VAEntrypointVLD, avctx->width, avctx->height) == 0) |
407 | if (vaapi_init_decoder(vst, profile, VAEntrypointVLD, avctx->width, avctx->height) == 0) |
421 | { |
408 | { |
422 | avctx->hwaccel_context = v_context; |
409 | avctx->hwaccel_context = v_context; |
423 | printf("%s format: %x\n",__FUNCTION__, fmt[i]); |
Line 410... | Line 424... | ||
410 | return fmt[i]; ; |
424 | return fmt[i]; |
- | 425 | } |
|
411 | } |
426 | } |
412 | } |
427 | } |
Line 413... | Line 428... | ||
413 | } |
428 | |
414 | 429 | } |
|
Line 423... | Line 438... | ||
423 | VASurfaceID id; |
438 | VASurfaceID id; |
424 | }; |
439 | }; |
Line 425... | Line 440... | ||
425 | 440 | ||
426 | static void av_release_buffer(void *opaque, uint8_t *data) |
441 | static void av_release_buffer(void *opaque, uint8_t *data) |
427 | { |
- | |
428 | struct av_surface surface = *(struct av_surface*)data; |
- | |
429 | av_freep(&data); |
442 | { |
Line 430... | Line 443... | ||
430 | } |
443 | } |
431 | 444 | ||
- | 445 | static int get_buffer2(AVCodecContext *avctx, AVFrame *pic, int flags) |
|
432 | static int get_buffer2(AVCodecContext *avctx, AVFrame *pic, int flags) |
446 | { |
433 | { |
447 | static struct av_surface avsurface; |
Line 434... | Line 448... | ||
434 | vst_t *vst = (vst_t*)avctx->opaque; |
448 | vst_t *vst = (vst_t*)avctx->opaque; |
Line 435... | Line 449... | ||
435 | void *surface; |
449 | void *surface; |
Line 436... | Line -... | ||
436 | - | ||
437 | surface = (void *)(uintptr_t)v_surface_id[vst->decoder->active_frame->index]; |
- | |
438 | - | ||
439 | pic->data[3] = surface; |
- | |
440 | - | ||
441 | struct av_surface *avsurface; |
450 | |
442 | surface = av_malloc(sizeof(*avsurface)); |
451 | surface = (void *)(uintptr_t)v_surface_id[vst->decoder->active_frame->index]; |
443 | if (!surface) |
452 | |
444 | return AVERROR(ENOMEM); |
453 | pic->data[3] = surface; |
445 | 454 | ||
Line 575... | Line 584... | ||
575 | vaReleaseBufferHandle(vaapi->display, vaimage.buf); |
584 | vaReleaseBufferHandle(vaapi->display, vaimage.buf); |
576 | vaDestroyImage(vaapi->display, vaimage.image_id); |
585 | vaDestroyImage(vaapi->display, vaimage.image_id); |
Line 577... | Line 586... | ||
577 | 586 | ||
Line -... | Line 587... | ||
- | 587 | } |
|
- | 588 | ||
- | 589 | static enum AVCodecID profile_to_codec(VAProfile profile) |
|
- | 590 | { |
|
- | 591 | enum AVCodecID id; |
|
- | 592 | ||
- | 593 | switch(profile) |
|
- | 594 | { |
|
- | 595 | case VAProfileMPEG2Simple: |
|
- | 596 | case VAProfileMPEG2Main: |
|
- | 597 | id = AV_CODEC_ID_MPEG2VIDEO; |
|
- | 598 | break; |
|
- | 599 | ||
- | 600 | case VAProfileMPEG4Simple: |
|
- | 601 | case VAProfileMPEG4AdvancedSimple: |
|
- | 602 | case VAProfileMPEG4Main: |
|
- | 603 | id = AV_CODEC_ID_MPEG4; |
|
- | 604 | break; |
|
- | 605 | ||
- | 606 | case VAProfileH264Baseline: |
|
- | 607 | case VAProfileH264Main: |
|
- | 608 | case VAProfileH264High: |
|
- | 609 | case VAProfileH264ConstrainedBaseline: |
|
- | 610 | case VAProfileH264MultiviewHigh: |
|
- | 611 | case VAProfileH264StereoHigh: |
|
- | 612 | id = AV_CODEC_ID_H264; |
|
- | 613 | break; |
|
- | 614 | ||
- | 615 | case VAProfileVC1Simple: |
|
- | 616 | case VAProfileVC1Main: |
|
- | 617 | case VAProfileVC1Advanced: |
|
- | 618 | id = AV_CODEC_ID_VC1; |
|
- | 619 | break; |
|
- | 620 | ||
- | 621 | case VAProfileHEVCMain: |
|
- | 622 | case VAProfileHEVCMain10: |
|
- | 623 | id = AV_CODEC_ID_HEVC; |
|
- | 624 | break; |
|
- | 625 | ||
- | 626 | default: |
|
- | 627 | id = AV_CODEC_ID_NONE; |
|
- | 628 | }; |
|
- | 629 | return id; |
|
- | 630 | }; |
|
- | 631 | ||
- | 632 | static VAProfile get_profile(VADisplay dpy, enum AVCodecID codec_id) |
|
- | 633 | { |
|
- | 634 | VAProfile profile = VAProfileNone, *profile_list = NULL; |
|
- | 635 | int num_profiles, max_num_profiles; |
|
- | 636 | enum AVCodecID ff_id; |
|
- | 637 | VAStatus va_status; |
|
- | 638 | int i; |
|
- | 639 | ||
- | 640 | max_num_profiles = vaMaxNumProfiles(dpy); |
|
- | 641 | ||
- | 642 | profile_list = alloca(max_num_profiles * sizeof(VAProfile)); |
|
- | 643 | if (!profile_list) |
|
- | 644 | { |
|
- | 645 | printf("Failed to allocate memory for profile list\n"); |
|
- | 646 | goto err_0; |
|
- | 647 | } |
|
- | 648 | ||
- | 649 | va_status = vaQueryConfigProfiles(dpy, profile_list, &num_profiles); |
|
- | 650 | if(!vaapi_check_status(va_status, "vaQueryConfigProfiles()")) |
|
- | 651 | goto err_0; |
|
- | 652 | ||
- | 653 | if(codec_id == AV_CODEC_ID_H263) |
|
- | 654 | ff_id = AV_CODEC_ID_H264; |
|
- | 655 | else if(codec_id == AV_CODEC_ID_WMV3) |
|
- | 656 | ff_id = AV_CODEC_ID_VC1; |
|
- | 657 | else |
|
- | 658 | ff_id = codec_id; |
|
- | 659 | ||
- | 660 | for (i = 0; i < num_profiles; i++) |
|
- | 661 | { |
|
- | 662 | if(ff_id == profile_to_codec(profile_list[i])) |
|
- | 663 | { |
|
- | 664 | profile = profile_list[i]; |
|
- | 665 | break; |
|
- | 666 | } |
|
- | 667 | }; |
|
- | 668 | ||
- | 669 | err_0: |
|
- | 670 | return profile; |
|
578 | } |
671 | } |
579 | 672 | ||
580 | struct decoder* va_init_decoder(vst_t *vst) |
673 | struct decoder* va_init_decoder(vst_t *vst) |
581 | { |
674 | { |
582 | AVCodecContext *vCtx = vst->vCtx; |
675 | AVCodecContext *vCtx = vst->vCtx; |
Line 597... | Line 690... | ||
597 | 690 | ||
598 | decoder->hwctx = vaapi_init(dpy); |
691 | decoder->hwctx = vaapi_init(dpy); |
599 | if(decoder->hwctx == NULL) |
692 | if(decoder->hwctx == NULL) |
Line -... | Line 693... | ||
- | 693 | goto err_1; |
|
- | 694 | ||
- | 695 | if(get_profile(dpy, vCtx->codec_id) == VAProfileNone) |
|
600 | goto err_1; |
696 | goto err_1; |
601 | 697 | ||
602 | decoder->Frame = av_frame_alloc(); |
698 | decoder->Frame = av_frame_alloc(); |
Line 603... | Line 699... | ||
603 | if(decoder->Frame == NULL) |
699 | if(decoder->Frame == NULL) |
Line 643... | Line 739... | ||
643 | return decoder; |
739 | return decoder; |
Line 644... | Line 740... | ||
644 | 740 | ||
645 | err_2: |
741 | err_2: |
646 | av_frame_free(&decoder->Frame); |
742 | av_frame_free(&decoder->Frame); |
647 | err_1: |
- | |
648 | free(decoder); |
743 | err_1: |
- | 744 | vaTerminate(dpy); |
|
649 | vaTerminate(dpy); |
745 | free(decoder); |
650 | err_0: |
746 | err_0: |
651 | drm_fd = 0; |
747 | drm_fd = 0; |
652 | return NULL; |
748 | return NULL; |