]> granicus.if.org Git - handbrake/commitdiff
decomb filter modification. BOB mode is restored.
authorhandbrake <no-reply@handbrake.fr>
Tue, 16 Jul 2013 08:09:45 +0000 (08:09 +0000)
committerhandbrake <no-reply@handbrake.fr>
Tue, 16 Jul 2013 08:09:45 +0000 (08:09 +0000)
git-svn-id: svn://svn.handbrake.fr/HandBrake/branches/opencl@5652 b64f7644-9d1e-0410-96f1-a4d463321fa5

libhb/decomb.c
libhb/ocldecomb.c

index 5682311639f6033bb2251ea75a98cadd99a83462..4c58858bab4923551cd4f7f0748f9c1474290e50 100644 (file)
@@ -221,6 +221,10 @@ static int hb_decomb_work( hb_filter_object_t * filter,
                            hb_buffer_t ** buf_in,
                            hb_buffer_t ** buf_out );
 
+static int hb_decomb_work_opencl( hb_filter_object_t * filter,
+                                  hb_buffer_t ** buf_in,
+                                  hb_buffer_t ** buf_out );
+
 static void hb_decomb_close( hb_filter_object_t * filter );
 
 hb_filter_object_t hb_filter_decomb =
@@ -2069,7 +2073,6 @@ static int hb_decomb_init( hb_filter_object_t * filter,
 
 #ifdef USE_OPENCL
     if(pv->use_opencl){
-        hb_log("decomb with OpenCL");
         if( !hb_create_buffer( &(pv->cl_mem_dst), CL_MEM_READ_WRITE, 3133440 ) )
         {
             hb_log("hb_create_buffer cl_outbuf Error\n");
@@ -2532,12 +2535,12 @@ static void hb_decomb_close( hb_filter_object_t * filter )
     hb_buffer_close(&pv->mask);
     hb_buffer_close(&pv->mask_filtered);
     hb_buffer_close(&pv->mask_temp);
-
+#ifdef USE_OPENCL
     clReleaseMemObject( pv->cl_mem_dst );
     clReleaseMemObject( pv->cl_mem_prev );
     clReleaseMemObject( pv->cl_mem_cur );
     clReleaseMemObject( pv->cl_mem_next );
-
+#endif
     if( pv->mode & MODE_EEDI2 )
     {
         /* Cleanup eedi-half  buffers */
@@ -2583,6 +2586,161 @@ static int hb_decomb_work( hb_filter_object_t * filter,
     hb_filter_private_t * pv = filter->private_data;
     hb_buffer_t * in = *buf_in;
     hb_buffer_t * last = NULL, * out = NULL;
+#ifdef USE_OPENCL
+    if (pv->use_opencl && !(pv->mode & (MODE_MCDEINT | MODE_BOB)))
+        return hb_decomb_work_opencl(filter, buf_in, buf_out);
+#endif
+    if ( in->size <= 0 )
+    {
+        *buf_out = in;
+        *buf_in = NULL;
+        return HB_FILTER_DONE;
+    }
+
+    /* Store current frame in yadif cache */
+    *buf_in = NULL;
+    store_ref(pv, in);
+
+    // yadif requires 3 buffers, prev, cur, and next.  For the first
+    // frame, there can be no prev, so we duplicate the first frame.
+    if (!pv->yadif_ready)
+    {
+        // If yadif is not ready, store another ref and return HB_FILTER_DELAY
+        store_ref(pv, hb_buffer_dup(in));
+        pv->yadif_ready = 1;
+        // Wait for next
+        return HB_FILTER_DELAY;
+    }
+
+    /* Determine if top-field first layout */
+    int tff;
+    if( pv->parity < 0 )
+    {
+        tff = !!(in->s.flags & PIC_FLAG_TOP_FIELD_FIRST);
+    }
+    else
+    {
+        tff = (pv->parity & 1) ^ 1;
+    }
+
+    /* deinterlace both fields if mcdeint is enabled without bob */
+    int frame, num_frames = 1;
+    if (pv->mode & (MODE_MCDEINT | MODE_BOB))
+    {
+        num_frames = 2;
+    }
+    
+    // Will need up to 2 buffers simultaneously
+    int idx = 0;
+    hb_buffer_t * o_buf[2] = {NULL,};
+
+    /* Perform yadif filtering */        
+    for( frame = 0; frame < num_frames; frame++ )
+    {
+        int parity = frame ^ tff ^ 1;
+
+        /* Skip the second run if the frame is uncombed */
+        if (frame && pv->is_combed == 0)
+        {
+            break;
+        }
+
+        // tff for eedi2
+        pv->tff = !parity;
+
+        if (o_buf[idx] == NULL)
+        {
+            o_buf[idx] = hb_video_buffer_init(in->f.width, in->f.height);
+        }
+
+        if (frame)
+            pv->skip_comb_check = 1;
+        else
+            pv->skip_comb_check = 0;
+
+        yadif_filter(pv, o_buf[idx], parity, tff);
+
+        // Unfortunately, all frames must be fed to mcdeint combed or
+        // not since it maintains state that is updated by each frame.
+        if (pv->mcdeint_mode >= 0)
+        {
+            if (o_buf[idx^1] == NULL)
+            {
+                o_buf[idx^1] = hb_video_buffer_init(in->f.width, in->f.height);
+            }
+            /* Perform mcdeint filtering */
+            mcdeint_filter(o_buf[idx^1], o_buf[idx], parity, &pv->mcdeint);
+
+            // If frame was combed, we will use results from mcdeint
+            // else we will use yadif result
+            if (pv->is_combed)
+                idx ^= 1;
+        }
+
+        // Add to list of output buffers (should be at most 2)
+        if ((pv->mode & MODE_BOB) ||
+            pv->is_combed == 0 ||
+            frame == num_frames - 1)
+        {
+            if ( out == NULL )
+            {
+                last = out = o_buf[idx];
+            }
+            else
+            {
+                last->next = o_buf[idx];
+                last = last->next;
+            }
+            last->next = NULL;
+
+            // Indicate that buffer was consumed
+            o_buf[idx] = NULL;
+
+            /* Copy buffered settings to output buffer settings */
+            last->s = pv->ref[1]->s;
+            idx ^= 1;
+
+            if ((pv->mode & MODE_MASK) && pv->spatial_metric >= 0 )
+            {
+                if (pv->mode == MODE_MASK ||
+                    ((pv->mode & MODE_MASK) && (pv->mode & MODE_FILTER)) ||
+                    ((pv->mode & MODE_MASK) && (pv->mode & MODE_GAMMA)) ||
+                    pv->is_combed)
+                {
+                    apply_mask(pv, last);
+                }
+            }
+        }
+    }
+    // Copy subs only to first output buffer
+    hb_buffer_move_subs( out, pv->ref[1] );
+
+    hb_buffer_close(&o_buf[0]);
+    hb_buffer_close(&o_buf[1]);
+
+    /* if this frame was deinterlaced and bob mode is engaged, halve
+       the duration of the saved timestamps. */
+    if ((pv->mode & MODE_BOB) && pv->is_combed)
+    {
+        out->s.stop -= (out->s.stop - out->s.start) / 2LL;
+        last->s.start = out->s.stop;
+        last->s.new_chap = 0;
+    }
+
+    *buf_out = out;
+
+    return HB_FILTER_OK;
+}
+
+static int hb_decomb_work_opencl( hb_filter_object_t * filter,
+                                  hb_buffer_t ** buf_in,
+                                  hb_buffer_t ** buf_out )
+{
+    hb_filter_private_t * pv = filter->private_data;
+    hb_buffer_t * in = *buf_in;
+    hb_buffer_t * last = NULL, * out = NULL;
+
+    //hb_log("decomb with OpenCL");
 
     if ( in->size <= 0 )
     {
@@ -2642,7 +2800,6 @@ static int hb_decomb_work( hb_filter_object_t * filter,
         else
             pv->skip_comb_check = 0;
 
-#ifdef USE_OPENCL
         if(pv->use_opencl){
             int is_combed;
             if (!pv->skip_comb_check)
@@ -2700,12 +2857,7 @@ static int hb_decomb_work( hb_filter_object_t * filter,
             {
                 hb_buffer_copy(out, pv->ref[1]); 
             }
-        }else{
-            yadif_filter(pv, out, parity, tff);
         }
-#else
-        yadif_filter(pv, out, parity, tff);
-#endif
 
         hb_buffer_t* mcdeint_out = NULL;
         if (pv->mcdeint_mode >= 0)
index 1e860123cb452e96e2d7190c680ea9071e905db9..f60fbbb4f0855b579ad9d7f78bfc9e905aa79b47 100644 (file)
@@ -1,3 +1,4 @@
+#ifdef USE_OPENCL
 #include "openclwrapper.h"
 
 static int hb_yadif_filter( void **userdata, KernelEnv *kenv )
@@ -90,3 +91,4 @@ int cl_yadif_filter(
     return 0;
 }
 
+#endif