summaryrefslogtreecommitdiff
path: root/video.c
diff options
context:
space:
mode:
Diffstat (limited to 'video.c')
-rw-r--r--video.c143
1 files changed, 130 insertions, 13 deletions
diff --git a/video.c b/video.c
index 992dd95..0743c89 100644
--- a/video.c
+++ b/video.c
@@ -1465,14 +1465,14 @@ static void VaapiDestroySurfaces(VaapiDecoder * decoder)
if (vaDestroySurfaces(decoder->VaDisplay, decoder->SurfacesFree,
decoder->SurfaceFreeN)
!= VA_STATUS_SUCCESS) {
- Error("video/vaapi: can't destroy %d surfaces\n",
+ Error(_("video/vaapi: can't destroy %d surfaces\n"),
decoder->SurfaceFreeN);
}
decoder->SurfaceFreeN = 0;
if (vaDestroySurfaces(decoder->VaDisplay, decoder->SurfacesUsed,
decoder->SurfaceUsedN)
!= VA_STATUS_SUCCESS) {
- Error("video/vaapi: can't destroy %d surfaces\n",
+ Error(_("video/vaapi: can't destroy %d surfaces\n"),
decoder->SurfaceUsedN);
}
decoder->SurfaceUsedN = 0;
@@ -1506,7 +1506,7 @@ static VASurfaceID VaapiGetSurface(VaapiDecoder * decoder)
}
// surface still in use, try next
if (status != VASurfaceReady) {
- Debug("video/vaapi: surface %#010x not ready: %d\n", surface,
+ Debug(3, "video/vaapi: surface %#010x not ready: %d\n", surface,
status);
if (!VaapiBuggyVdpau || i < 1) {
continue;
@@ -1839,6 +1839,111 @@ static void VaapiDelDecoder(VaapiDecoder * decoder)
free(decoder);
}
+static VAProfile VaapiFindProfile(const VAProfile * profiles, unsigned n,
+ VAProfile profile);
+static VAEntrypoint VaapiFindEntrypoint(const VAEntrypoint * entrypoints,
+ unsigned n, VAEntrypoint entrypoint);
+
+///
+/// 1080i
+///
+static void Vaapi1080i(void)
+{
+ VAProfile profiles[vaMaxNumProfiles(VaDisplay)];
+ int profile_n;
+ VAEntrypoint entrypoints[vaMaxNumEntrypoints(VaDisplay)];
+ int entrypoint_n;
+ int p;
+ int e;
+ VAConfigAttrib attrib;
+ VAConfigID config_id;
+ VAContextID context_id;
+ VASurfaceID surfaces[32];
+ int n;
+ uint32_t start_tick;
+ uint32_t tick;
+
+ p = -1;
+ e = -1;
+
+ // prepare va-api profiles
+ if (vaQueryConfigProfiles(VaDisplay, profiles, &profile_n)) {
+ Error(_("codec: vaQueryConfigProfiles failed"));
+ return;
+ }
+ // check profile
+ p = VaapiFindProfile(profiles, profile_n, VAProfileH264High);
+ if (p == -1) {
+ Debug(3, "\tno profile found\n");
+ return;
+ }
+ // prepare va-api entry points
+ if (vaQueryConfigEntrypoints(VaDisplay, p, entrypoints, &entrypoint_n)) {
+ Error(_("codec: vaQueryConfigEntrypoints failed"));
+ return;
+ }
+ e = VaapiFindEntrypoint(entrypoints, entrypoint_n, VAEntrypointVLD);
+ if (e == -1) {
+ Warning(_("codec: unsupported: slow path\n"));
+ return;
+ }
+ memset(&attrib, 0, sizeof(attrib));
+ attrib.type = VAConfigAttribRTFormat;
+ attrib.value = VA_RT_FORMAT_YUV420;
+ // create a configuration for the decode pipeline
+ if (vaCreateConfig(VaDisplay, p, e, &attrib, 1, &config_id)) {
+ Error(_("codec: can't create config"));
+ return;
+ }
+ if (vaCreateSurfaces(VaDisplay, 1920, 1080, VA_RT_FORMAT_YUV420, 32,
+ surfaces) != VA_STATUS_SUCCESS) {
+ Error(_("video/vaapi: can't create surfaces\n"));
+ return;
+ }
+ // bind surfaces to context
+ if (vaCreateContext(VaDisplay, config_id, 1920, 1080, VA_PROGRESSIVE,
+ surfaces, 32, &context_id)) {
+ Error(_("codec: can't create context"));
+ return;
+ }
+
+ start_tick = GetMsTicks();
+ for (n = 1; n < 10000; ++n) {
+ if (vaPutSurface(VaDisplay, surfaces[0], VideoWindow,
+ // decoder src
+ 0, 0, 1920, 1080,
+ // video dst
+ 0, 0, 1920, 1080, NULL, 0, VA_TOP_FIELD | VA_CLEAR_DRAWABLE)
+ != VA_STATUS_SUCCESS) {
+ Error(_("video/vaapi: vaPutSurface failed\n"));
+ }
+ if (vaPutSurface(VaDisplay, surfaces[0], VideoWindow,
+ // decoder src
+ 0, 0, 1920, 1080,
+ // video dst
+ 0, 0, 1920, 1080, NULL, 0, VA_BOTTOM_FIELD | VA_CLEAR_DRAWABLE)
+ != VA_STATUS_SUCCESS) {
+ Error(_("video/vaapi: vaPutSurface failed\n"));
+ }
+ tick = GetMsTicks();
+ if (!(n % 100)) {
+ fprintf(stderr, "%d ms / frame\n", (tick - start_tick) / n);
+ }
+ }
+
+ // destory the stuff.
+ if (vaDestroyContext(VaDisplay, context_id) != VA_STATUS_SUCCESS) {
+ Error(_("video/vaapi: can't destroy context!\n"));
+ }
+ if (vaDestroySurfaces(VaDisplay, surfaces, 32) != VA_STATUS_SUCCESS) {
+ Error(_("video/vaapi: can't destroy surfaces\n"));
+ }
+ if (vaDestroyConfig(VaDisplay, config_id) != VA_STATUS_SUCCESS) {
+ Error(_("video/vaapi: can't destroy config!\n"));
+ }
+ printf("done\n");
+}
+
///
/// VA-API setup.
///
@@ -1909,7 +2014,9 @@ static int VaapiInit(const char *display_name)
// check the chroma format
//
attr.type = VAConfigAttribRTFormat attr.flags = VA_DISPLAY_ATTRIB_GETTABLE;
+ Vaapi1080i();
#endif
+
return 1;
}
@@ -3719,13 +3826,18 @@ static void VaapiAdvanceFrame(void)
}
// debug duplicate frames
} else if (filled == 1) {
+ static int last_warned_frame;
+
++decoder->FramesDuped;
decoder->DropNextFrame = 0;
- // FIXME: don't warn after stream start
- Warning(_
- ("video: display buffer empty, duping frame (%d/%d) %d\n"),
- decoder->FramesDuped, decoder->FrameCounter,
- atomic_read(&VideoPacketsFilled));
+ // FIXME: don't warn after stream start, don't warn during pause
+ if (last_warned_frame != decoder->FrameCounter) {
+ Warning(_
+ ("video: display buffer empty, duping frame (%d/%d) %d\n"),
+ decoder->FramesDuped, decoder->FrameCounter,
+ atomic_read(&VideoPacketsFilled));
+ }
+ last_warned_frame = decoder->FrameCounter;
if (!(decoder->FramesDisplayed % 300)) {
VaapiPrintFrames(decoder);
}
@@ -6652,14 +6764,19 @@ static void VdpauAdvanceFrame(void)
// need 4 frames for interlaced
filled = atomic_read(&decoder->SurfacesFilled);
if (filled <= 1 + 2 * decoder->Interlaced) {
+ static int last_warned_frame;
+
// keep use of last surface
++decoder->FramesDuped;
decoder->DropNextFrame = 0;
- // FIXME: don't warn after stream start
- Warning(_
- ("video: display buffer empty, duping frame (%d/%d) %d\n"),
- decoder->FramesDuped, decoder->FrameCounter,
- atomic_read(&VideoPacketsFilled));
+ // FIXME: don't warn after stream start, don't warn during pause
+ if (last_warned_frame != decoder->FrameCounter) {
+ Warning(_
+ ("video: display buffer empty, duping frame (%d/%d) %d\n"),
+ decoder->FramesDuped, decoder->FrameCounter,
+ atomic_read(&VideoPacketsFilled));
+ }
+ last_warned_frame = decoder->FrameCounter;
if (!(decoder->FramesDisplayed % 300)) {
VdpauPrintFrames(decoder);
}