> Question: Does Motion Adaption implementation (unlike Bob) require two > distinct source surfaces plus an ADDITIONAL surface for the result? Yes. A new surface is required for the result surface.
> -----Original Message----- > From: Libva [mailto:libva-boun...@lists.freedesktop.org] On Behalf Of > Steven Toth > Sent: Wednesday, May 14, 2014 11:57 PM > To: libva@lists.freedesktop.org > Subject: [Libva] VPP Deinterlacing problem > > Hi, > > I'm looking for some help/guidance on implementing Motion Adaptive > deinterlacing. > > Background: I'm working on a libva project that receives raw video > frames (720x480i) from a video4linux SD video capture device, largely > based around the test example projects. Intel IvyBridge platform, i965 > driver. Testing / developing with 1.3.0 va and va-intel-driver on > Ubuntu 12.04. The solution works very well, no major issues, I can > encode for long periods of time, very stable code. > > However, I was asked to add vpp deinterlacing support. Bob deinterlace > works fine, 30fps encoding is reliable. Motion Adaption isn't working > properly, or - my solution isn't working properly, the encoded output > looks like 15fps with duplicate frames. > > Running various h264 analysis tools on the Motion Adaption clip, > stepping through the frames, the 30 fps is actually correct, but every > other frame is a repeat of the previous frame with some very minor > (very very minor) pixel variation. As a result, visually its playing at > 30fps but looks like 15 with odd pixel shimmering effects. > > It feels like I've miss-understood the Motion Adaption VPP > configuration, so I'm hoping someone can point me in the right > direction. > > My workflow is: > 1. I upload the incoming raw video frame into the current source > surface. > 2. I perform vpp de-interlacing on the current source surface and pass > the prior source surface as single and only forward reference via the > pipeline_param struct. I call vaRenderPicture on the pipeline. > 3. I then compress the current surface. > 4. Handle the codec buffer of compressed data. > 5. Repeat for each incoming raw video frame. > > Question: Am I correct in think I should pass the previous source > surface as the single and only forward reference? > (num_forward_references is returned as 1, num_backwards_refs is 0). > > Corrective fixes I've tried and failed with: > > A. If I pass the current surface as the forward reference, no > deinterlacing takes place and the resulting video has 30fps smooth > playback, I assume the motion adaptive algorithm is trying to adapt > exactly the same frame (or rejects the same surface silently) and the > output video is smooth but interlaced. > > B. If I pass the prior source surface -1 (IE current source surface - > 2), or use any other value for the forward reference, I start to get > very odd temporal video effects. I assume the Motion Adaption algorithm > is trying to blend two very different non-adjacent temporal frames and > the output is clearly bad. > > I'm only using an output_region in the pileline_params, not an input > region, as shown below. > > Question: Does Motion Adaption implementation (unlike Bob) require two > distinct source surfaces plus an ADDITIONAL surface for the result? > Perhaps I have my pipeline tuned for Bob (based on GST samples) but its > not reliable for MA? > > For completeness, the pipeline func is here: > > static int func_deinterlace(VASurfaceID surface, unsigned int w, > unsigned int h, VASurfaceID forward_reference) { > VAStatus va_status; > > vaBeginPicture(va_dpy, vpp_context, surface); > > va_status = vaMapBuffer(va_dpy, vpp_pipeline_buf, (void > *)&vpp_pipeline_param); > > CHECK_VASTATUS(va_status, "vaMapBuffer"); > vpp_pipeline_param->surface = surface; > vpp_pipeline_param->surface_region = NULL; > vpp_pipeline_param->output_region = &vpp_output_region; > vpp_pipeline_param->output_background_color = 0; > vpp_pipeline_param->filter_flags = VA_FILTER_SCALING_HQ; > vpp_pipeline_param->filters = vpp_filter_bufs; > vpp_pipeline_param->num_filters = vpp_num_filter_bufs; > va_status = vaUnmapBuffer(va_dpy, vpp_pipeline_buf); > CHECK_VASTATUS(va_status, "vaUnmapBuffer"); > > // Update reference frames for deinterlacing, if necessary > vpp_forward_references[0] = forward_reference; > vpp_pipeline_param->forward_references = > vpp_forward_references; > vpp_pipeline_param->num_forward_references = > vpp_num_forward_references; > vpp_pipeline_param->backward_references = > vpp_backward_references; > vpp_pipeline_param->num_backward_references = > vpp_num_backward_references; > > // Apply filters > va_status = vaRenderPicture(va_dpy, vpp_context, > &vpp_pipeline_buf, 1); > CHECK_VASTATUS(va_status, "vaRenderPicture"); > > vaEndPicture(va_dpy, vpp_context); > return 0; > > } > > Perhaps my overall work simply isn't compatible with MA, IE I should be > loading the 'current incoming pixels' into the 'next source surface' > then passing this next source surface as a forward reference to the > current source? > > Feedback welcome. > > - Steve > > -- > Steven Toth - Kernel Labs > http://www.kernellabs.com > _______________________________________________ > Libva mailing list > Libva@lists.freedesktop.org > http://lists.freedesktop.org/mailman/listinfo/libva _______________________________________________ Libva mailing list Libva@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/libva