Rev 6438 | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 6438 | Rev 6658 | ||
---|---|---|---|
Line 35... | Line 35... | ||
35 | #endif |
35 | #endif |
Line 36... | Line 36... | ||
36 | 36 | ||
37 | #undef ARRAY_ELEMS |
37 | #undef ARRAY_ELEMS |
Line -... | Line 38... | ||
- | 38 | #define ARRAY_ELEMS(a) (sizeof(a) / sizeof((a)[0])) |
|
- | 39 | ||
- | 40 | struct va_decoder |
|
- | 41 | { |
|
- | 42 | struct decoder decoder; |
|
- | 43 | VADisplay dpy; |
|
- | 44 | void *hwctx; |
|
- | 45 | VASurfaceID v_surface_id[16]; |
|
- | 46 | }; |
|
- | 47 | ||
38 | #define ARRAY_ELEMS(a) (sizeof(a) / sizeof((a)[0])) |
48 | static struct va_decoder va_decoder; |
39 | 49 | ||
Line 40... | Line -... | ||
40 | static int drm_fd = 0; |
- | |
41 | static struct vaapi_context *v_context; |
- | |
42 | 50 | static int drm_fd = 0; |
|
43 | static VASurfaceID v_surface_id[16]; |
51 | static struct vaapi_context *v_context; |
Line 44... | Line 52... | ||
44 | 52 | ||
45 | #define HAS_HEVC VA_CHECK_VERSION(0, 38, 0) |
53 | #define HAS_HEVC VA_CHECK_VERSION(0, 38, 0) |
Line 279... | Line 287... | ||
279 | VAEntrypoint entrypoint, |
287 | VAEntrypoint entrypoint, |
280 | unsigned int picture_width, |
288 | unsigned int picture_width, |
281 | unsigned int picture_height) |
289 | unsigned int picture_height) |
282 | { |
290 | { |
283 | struct vaapi_context* const vaapi = v_context; |
291 | struct vaapi_context* const vaapi = v_context; |
- | 292 | struct va_decoder *hw_decoder = (struct va_decoder*)vst->decoder; |
|
284 | VAConfigAttrib attrib; |
293 | VAConfigAttrib attrib; |
285 | VAConfigID config_id = VA_INVALID_ID; |
294 | VAConfigID config_id = VA_INVALID_ID; |
286 | VAContextID context_id = VA_INVALID_ID; |
295 | VAContextID context_id = VA_INVALID_ID; |
287 | VAStatus status; |
296 | VAStatus status; |
Line 307... | Line 316... | ||
307 | { |
316 | { |
308 | FAIL(); |
317 | FAIL(); |
309 | return -1; |
318 | return -1; |
310 | }; |
319 | }; |
Line -... | Line 320... | ||
- | 320 | ||
- | 321 | if (vaapi->context_id != VA_INVALID_ID) |
|
- | 322 | vaDestroyContext(vaapi->display, vaapi->context_id); |
|
- | 323 | ||
- | 324 | if (hw_decoder->decoder.has_surfaces) |
|
- | 325 | { |
|
- | 326 | vaDestroySurfaces(vaapi->display,hw_decoder->v_surface_id,hw_decoder->decoder.nframes); |
|
- | 327 | hw_decoder->decoder.has_surfaces = 0; |
|
- | 328 | } |
|
311 | 329 | ||
312 | if (vaapi->config_id != VA_INVALID_ID) |
330 | if (vaapi->config_id != VA_INVALID_ID) |
Line -... | Line 331... | ||
- | 331 | vaDestroyConfig(vaapi->display, vaapi->config_id); |
|
313 | vaDestroyConfig(vaapi->display, vaapi->config_id); |
332 | |
Line 314... | Line 333... | ||
314 | 333 | ||
315 | attrib.type = VAConfigAttribRTFormat; |
334 | attrib.type = VAConfigAttribRTFormat; |
316 | 335 | ||
Line 339... | Line 358... | ||
339 | return -1; |
358 | return -1; |
340 | } |
359 | } |
Line 341... | Line 360... | ||
341 | 360 | ||
342 | printf("vaCreateSurfaces %dx%d\n",picture_width,picture_height); |
361 | printf("vaCreateSurfaces %dx%d\n",picture_width,picture_height); |
343 | status = vaCreateSurfaces(vaapi->display, VA_RT_FORMAT_YUV420, picture_width, picture_height, |
362 | status = vaCreateSurfaces(vaapi->display, VA_RT_FORMAT_YUV420, picture_width, picture_height, |
344 | v_surface_id,vst->decoder->nframes,NULL,0); |
363 | hw_decoder->v_surface_id,hw_decoder->decoder.nframes,NULL,0); |
345 | if (!vaapi_check_status(status, "vaCreateSurfaces()")) |
364 | if (!vaapi_check_status(status, "vaCreateSurfaces()")) |
346 | { |
365 | { |
347 | FAIL(); |
366 | FAIL(); |
348 | return -1; |
367 | return -1; |
- | 368 | }; |
|
- | 369 | ||
- | 370 | hw_decoder->decoder.has_surfaces = 1; |
|
349 | }; |
371 | |
350 | { |
372 | { |
351 | VAImage vaimage; |
373 | VAImage vaimage; |
Line 352... | Line 374... | ||
352 | VABufferInfo info = {0}; |
374 | VABufferInfo info = {0}; |
353 | 375 | ||
354 | vaDeriveImage(vaapi->display,v_surface_id[0],&vaimage); |
376 | vaDeriveImage(vaapi->display,hw_decoder->v_surface_id[0],&vaimage); |
355 | printf("vaDeriveImage: %x fourcc: %x\n" |
377 | printf("vaDeriveImage: %x fourcc: %x\n" |
356 | "offset0: %d pitch0: %d\n" |
378 | "offset0: %d pitch0: %d\n" |
357 | "offset1: %d pitch1: %d\n" |
379 | "offset1: %d pitch1: %d\n" |
Line 374... | Line 396... | ||
374 | 396 | ||
375 | printf("vaCreateContext %dx%d\n",picture_width,picture_height); |
397 | printf("vaCreateContext %dx%d\n",picture_width,picture_height); |
376 | status = vaCreateContext(vaapi->display, config_id, |
398 | status = vaCreateContext(vaapi->display, config_id, |
377 | picture_width, picture_height, |
399 | picture_width, picture_height, |
378 | VA_PROGRESSIVE, |
400 | VA_PROGRESSIVE, |
379 | v_surface_id, vst->decoder->nframes, |
401 | hw_decoder->v_surface_id, vst->decoder->nframes, |
380 | &context_id); |
402 | &context_id); |
381 | if (!vaapi_check_status(status, "vaCreateContext()")) |
403 | if (!vaapi_check_status(status, "vaCreateContext()")) |
382 | { |
404 | { |
383 | FAIL(); |
405 | FAIL(); |
Line 393... | Line 415... | ||
393 | 415 | ||
394 | static enum PixelFormat get_format(struct AVCodecContext *avctx, |
416 | static enum PixelFormat get_format(struct AVCodecContext *avctx, |
395 | const enum AVPixelFormat *fmt) |
417 | const enum AVPixelFormat *fmt) |
396 | { |
418 | { |
- | 419 | vst_t *vst = (vst_t*)avctx->opaque; |
|
- | 420 | struct va_decoder* hw_decoder = (struct va_decoder*)vst->decoder; |
|
397 | vst_t *vst = (vst_t*)avctx->opaque; |
421 | struct decoder* decoder = &hw_decoder->decoder; |
398 | VAProfile profile = avctx->profile; |
422 | VAProfile profile = avctx->profile; |
Line 399... | Line 423... | ||
399 | enum AVCodecID codec = avctx->codec_id; |
423 | enum AVCodecID codec = avctx->codec_id; |
400 | 424 | ||
401 | if (codec == AV_CODEC_ID_H264) |
- | |
402 | { |
- | |
403 | if(profile == FF_PROFILE_H264_BASELINE) |
- | |
404 | profile = FF_PROFILE_H264_CONSTRAINED_BASELINE; |
- | |
405 | }; |
- | |
406 | 425 | if(avctx->hwaccel_context != NULL) |
|
407 | if(avctx->hwaccel_context != NULL && |
426 | { |
408 | (vst->codec_id != codec || |
427 | if(decoder->codec_id != avctx->codec_id || |
409 | vst->codec_profile != profile)) |
- | |
410 | { |
- | |
411 | struct decoder* decoder = vst->decoder; |
428 | decoder->profile != avctx->profile) |
412 | 429 | { |
|
413 | printf("\n%s codec changed!!!\n" |
430 | printf("\n%s codec changed!!!\n" |
414 | "old id %d profile %x new id %d profile %x\n", |
431 | "old id %d profile %x new id %d profile %x\n", |
Line 415... | Line 432... | ||
415 | __FUNCTION__, vst->codec_id, vst->codec_profile, |
432 | __FUNCTION__, decoder->codec_id, decoder->profile, |
416 | codec, profile); |
433 | codec, profile); |
417 | 434 | ||
418 | for(int i = 0; i < decoder->nframes; i++) |
435 | for(int i = 0; i < decoder->nframes; i++) |
419 | { |
436 | { |
420 | vframe_t *vframe = &decoder->vframes[i]; |
437 | vframe_t *vframe = &decoder->vframes[i]; |
- | 438 | vframe->format = AV_PIX_FMT_NONE; |
|
- | 439 | }; |
|
- | 440 | } |
|
- | 441 | else |
|
- | 442 | return AV_PIX_FMT_VAAPI_VLD; |
|
- | 443 | } |
|
- | 444 | ||
- | 445 | if (codec == AV_CODEC_ID_H264) |
|
- | 446 | { |
|
Line 421... | Line 447... | ||
421 | vframe->format = AV_PIX_FMT_NONE; |
447 | if(profile == FF_PROFILE_H264_BASELINE) |
Line 422... | Line 448... | ||
422 | }; |
448 | profile = FF_PROFILE_H264_CONSTRAINED_BASELINE; |
423 | } |
449 | }; |
Line 436... | Line 462... | ||
436 | { |
462 | { |
437 | profile = hw_profiles[n].va_profile; |
463 | profile = hw_profiles[n].va_profile; |
438 | if (vaapi_init_decoder(vst, profile, VAEntrypointVLD, avctx->width, avctx->height) == 0) |
464 | if (vaapi_init_decoder(vst, profile, VAEntrypointVLD, avctx->width, avctx->height) == 0) |
439 | { |
465 | { |
440 | avctx->hwaccel_context = v_context; |
466 | avctx->hwaccel_context = v_context; |
441 | vst->codec_id = codec; |
- | |
442 | vst->codec_profile = profile; |
- | |
443 | printf("%s format: %x\n",__FUNCTION__, fmt[i]); |
467 | printf("%s format: %x\n",__FUNCTION__, fmt[i]); |
444 | return fmt[i]; |
468 | return fmt[i]; |
445 | } |
469 | } |
446 | } |
470 | } |
447 | } |
471 | } |
Line 464... | Line 488... | ||
464 | 488 | ||
465 | static int get_buffer2(AVCodecContext *avctx, AVFrame *pic, int flags) |
489 | static int get_buffer2(AVCodecContext *avctx, AVFrame *pic, int flags) |
466 | { |
490 | { |
467 | static struct av_surface avsurface; |
491 | static struct av_surface avsurface; |
- | 492 | vst_t *vst = (vst_t*)avctx->opaque; |
|
468 | vst_t *vst = (vst_t*)avctx->opaque; |
493 | struct va_decoder* hw_decoder = (struct va_decoder*)vst->decoder; |
Line 469... | Line 494... | ||
469 | void *surface; |
494 | void *surface; |
Line 470... | Line 495... | ||
470 | 495 | ||
Line 471... | Line 496... | ||
471 | surface = (void *)(uintptr_t)v_surface_id[vst->decoder->active_frame->index]; |
496 | surface = (void *)(uintptr_t)hw_decoder->v_surface_id[vst->decoder->active_frame->index]; |
472 | 497 | ||
Line 545... | Line 570... | ||
545 | }; |
570 | }; |
Line 546... | Line 571... | ||
546 | 571 | ||
547 | void va_create_planar(vst_t *vst, vframe_t *vframe) |
572 | void va_create_planar(vst_t *vst, vframe_t *vframe) |
548 | { |
573 | { |
- | 574 | struct vaapi_context* const vaapi = v_context; |
|
549 | struct vaapi_context* const vaapi = v_context; |
575 | struct va_decoder* hw_decoder = (struct va_decoder*)vst->decoder; |
Line 550... | Line 576... | ||
550 | VABufferInfo info = {0}; |
576 | VABufferInfo info = {0}; |
551 | 577 | ||
552 | VAImage vaimage; |
578 | VAImage vaimage; |
Line 553... | Line 579... | ||
553 | VAStatus status; |
579 | VAStatus status; |
Line 554... | Line 580... | ||
554 | planar_t *planar; |
580 | planar_t *planar; |
555 | 581 | ||
Line -... | Line 582... | ||
- | 582 | vaSyncSurface(vaapi->display,hw_decoder->v_surface_id[vframe->index]); |
|
- | 583 | ||
- | 584 | if(vframe->format != AV_PIX_FMT_NONE) |
|
- | 585 | return; |
|
- | 586 | ||
- | 587 | if(vframe->planar != NULL) |
|
556 | vaSyncSurface(vaapi->display,v_surface_id[vframe->index]); |
588 | { |
557 | 589 | pxDestroyPlanar(vframe->planar); |
|
558 | if(vframe->format != AV_PIX_FMT_NONE) |
590 | vframe->planar = NULL; |
559 | return; |
591 | }; |
560 | 592 | ||
561 | status = vaDeriveImage(vaapi->display,v_surface_id[vframe->index],&vaimage); |
593 | status = vaDeriveImage(vaapi->display,hw_decoder->v_surface_id[vframe->index],&vaimage); |
Line 685... | Line 717... | ||
685 | 717 | ||
686 | err_0: |
718 | err_0: |
687 | return profile; |
719 | return profile; |
Line -... | Line 720... | ||
- | 720 | } |
|
- | 721 | ||
- | 722 | static void fini_va_decoder(vst_t *vst) |
|
- | 723 | { |
|
- | 724 | struct vaapi_context* const vaapi = v_context; |
|
- | 725 | struct va_decoder *hw_decoder = (struct va_decoder*)vst->decoder; |
|
- | 726 | ENTER(); |
|
- | 727 | for(int i = 0; i < hw_decoder->decoder.nframes; i++) |
|
- | 728 | { |
|
- | 729 | vframe_t *vframe = &hw_decoder->decoder.vframes[i]; |
|
- | 730 | if(vframe->planar != NULL) |
|
- | 731 | { |
|
- | 732 | printf("destroy planar %d\n", i); |
|
- | 733 | pxDestroyPlanar(vframe->planar); |
|
- | 734 | vframe->planar = NULL; |
|
- | 735 | }; |
|
- | 736 | }; |
|
- | 737 | ||
- | 738 | av_frame_free(&hw_decoder->decoder.Frame); |
|
- | 739 | ||
- | 740 | if (vaapi->context_id != VA_INVALID_ID) |
|
- | 741 | vaDestroyContext(vaapi->display, vaapi->context_id); |
|
- | 742 | ||
- | 743 | if (hw_decoder->decoder.has_surfaces) |
|
- | 744 | vaDestroySurfaces(vaapi->display,hw_decoder->v_surface_id,hw_decoder->decoder.nframes); |
|
- | 745 | ||
- | 746 | if (vaapi->config_id != VA_INVALID_ID) |
|
- | 747 | vaDestroyConfig(vaapi->display, vaapi->config_id); |
|
- | 748 | ||
- | 749 | vaTerminate(hw_decoder->dpy); |
|
- | 750 | LEAVE(); |
|
- | 751 | }; |
|
688 | } |
752 | |
689 | 753 | ||
690 | struct decoder* va_init_decoder(vst_t *vst) |
754 | struct decoder* init_va_decoder(vst_t *vst) |
691 | { |
755 | { |
692 | AVCodecContext *vCtx = vst->vCtx; |
756 | AVCodecContext *vCtx = vst->vCtx; |
Line 693... | Line 757... | ||
693 | struct decoder *decoder; |
757 | struct va_decoder *hw_decoder = &va_decoder; |
694 | VADisplay dpy; |
758 | struct decoder *decoder = &hw_decoder->decoder; |
695 | 759 | ||
Line 696... | Line 760... | ||
696 | drm_fd = get_service("DISPLAY"); |
760 | drm_fd = get_service("DISPLAY"); |
697 | if (drm_fd == 0) |
- | |
698 | return NULL; |
- | |
699 | - | ||
700 | dpy = vaGetDisplayDRM(drm_fd); |
- | |
701 | if (dpy == NULL) |
761 | if (drm_fd == 0) |
702 | goto err_0; |
762 | return NULL; |
Line 703... | Line 763... | ||
703 | 763 | ||
704 | decoder = calloc(1, sizeof(struct decoder)); |
764 | hw_decoder->dpy = vaGetDisplayDRM(drm_fd); |
705 | if(decoder == NULL) |
765 | if (hw_decoder->dpy == NULL) |
Line 706... | Line 766... | ||
706 | goto err_0; |
766 | goto err_0; |
707 | 767 | ||
Line 708... | Line 768... | ||
708 | decoder->hwctx = vaapi_init(dpy); |
768 | hw_decoder->hwctx = vaapi_init(hw_decoder->dpy); |
709 | if(decoder->hwctx == NULL) |
769 | if(hw_decoder->hwctx == NULL) |
710 | goto err_1; |
770 | goto err_1; |
Line 726... | Line 786... | ||
726 | vframe_t *vframe = &decoder->vframes[i]; |
786 | vframe_t *vframe = &decoder->vframes[i]; |
Line 727... | Line 787... | ||
727 | 787 | ||
728 | vframe->format = AV_PIX_FMT_NONE; |
788 | vframe->format = AV_PIX_FMT_NONE; |
729 | vframe->is_hw_pic = 1; |
789 | vframe->is_hw_pic = 1; |
730 | vframe->index = i; |
- | |
731 | vframe->pts = 0; |
- | |
732 | vframe->ready = 0; |
790 | vframe->index = i; |
733 | list_add_tail(&vframe->list, &vst->input_list); |
791 | list_add_tail(&vframe->list, &vst->input_list); |
Line 734... | Line 792... | ||
734 | }; |
792 | }; |
735 | 793 | ||
Line 745... | Line 803... | ||
745 | goto err_2; |
803 | goto err_2; |
746 | }; |
804 | }; |
Line 747... | Line 805... | ||
747 | 805 | ||
748 | decoder->name = vst->vCodec->name; |
806 | decoder->name = vst->vCodec->name; |
- | 807 | decoder->codec_id = vCtx->codec_id; |
|
749 | decoder->codec_id = vCtx->codec_id; |
808 | decoder->profile = vCtx->profile; |
750 | decoder->pix_fmt = vCtx->pix_fmt; |
809 | decoder->pix_fmt = vCtx->pix_fmt; |
751 | decoder->width = vCtx->width; |
810 | decoder->width = vCtx->width; |
752 | decoder->height = vCtx->height; |
811 | decoder->height = vCtx->height; |
753 | decoder->is_hw = 1; |
812 | decoder->is_hw = 1; |
- | 813 | decoder->frame_reorder = 1; |
|
Line 754... | Line 814... | ||
754 | decoder->frame_reorder = 1; |
814 | decoder->fini = fini_va_decoder; |
Line 755... | Line 815... | ||
755 | 815 | ||
756 | return decoder; |
816 | return (struct decoder*)decoder; |
757 | 817 | ||
758 | err_2: |
818 | err_2: |
759 | av_frame_free(&decoder->Frame); |
- | |
760 | err_1: |
819 | av_frame_free(&decoder->Frame); |
761 | vaTerminate(dpy); |
820 | err_1: |
762 | free(decoder); |
821 | vaTerminate(hw_decoder->dpy); |
763 | err_0: |
822 | err_0: |