]> git.sesse.net Git - vlc/blobdiff - src/video_output/video_output.c
Add adjust filter features to libvlc_media_player/libvlc_video
[vlc] / src / video_output / video_output.c
index d827b41db8816593d6fbed133a6c463cdfc116fd..01b8ee247457342aee1dfd95d6233795124f9060 100644 (file)
@@ -112,6 +112,7 @@ static vout_thread_t *VoutCreate(vlc_object_t *object,
     vout->p = (vout_thread_sys_t*)&vout[1];
 
     vout->p->original = original;
+    vout->p->dpb_size = cfg->dpb_size;
 
     vout_control_Init(&vout->p->control);
     vout_control_PushVoid(&vout->p->control, VOUT_CONTROL_INIT);
@@ -125,6 +126,7 @@ static vout_thread_t *VoutCreate(vlc_object_t *object,
     /* Initialize locks */
     vlc_mutex_init(&vout->p->picture_lock);
     vlc_mutex_init(&vout->p->vfilter_lock);
+    vlc_mutex_init(&vout->p->spu_lock);
 
     /* Attach the new object now so we can use var inheritance below */
     vlc_object_attach(vout, object);
@@ -154,6 +156,7 @@ static vout_thread_t *VoutCreate(vlc_object_t *object,
     /* */
     if (vlc_clone(&vout->p->thread, Thread, vout,
                   VLC_THREAD_PRIORITY_OUTPUT)) {
+        spu_Destroy(vout->p->p_spu);
         vlc_object_release(vout);
         return NULL;
     }
@@ -177,7 +180,7 @@ vout_thread_t *(vout_Request)(vlc_object_t *object,
                               const vout_configuration_t *cfg)
 {
     vout_thread_t *vout = cfg->vout;
-    if (!cfg->fmt) {
+    if (cfg->change_fmt && !cfg->fmt) {
         if (vout)
             vout_CloseAndRelease(vout);
         return NULL;
@@ -185,9 +188,6 @@ vout_thread_t *(vout_Request)(vlc_object_t *object,
 
     /* If a vout is provided, try reusing it */
     if (vout) {
-        vlc_object_detach(vout);
-        vlc_object_attach(vout, object);
-
         if (vout->p->input != cfg->input) {
             if (vout->p->input)
                 spu_Attach(vout->p->p_spu, vout->p->input, false);
@@ -196,12 +196,15 @@ vout_thread_t *(vout_Request)(vlc_object_t *object,
                 spu_Attach(vout->p->p_spu, vout->p->input, true);
         }
 
-        vout_control_cmd_t cmd;
-        vout_control_cmd_Init(&cmd, VOUT_CONTROL_REINIT);
-        cmd.u.cfg = cfg;
+        if (cfg->change_fmt) {
+            vout_control_cmd_t cmd;
+            vout_control_cmd_Init(&cmd, VOUT_CONTROL_REINIT);
+            cmd.u.cfg = cfg;
+
+            vout_control_Push(&vout->p->control, &cmd);
+            vout_control_WaitEmpty(&vout->p->control);
+        }
 
-        vout_control_Push(&vout->p->control, &cmd);
-        vout_control_WaitEmpty(&vout->p->control);
         if (!vout->p->dead) {
             msg_Dbg(object, "reusing provided vout");
             return vout;
@@ -213,26 +216,22 @@ vout_thread_t *(vout_Request)(vlc_object_t *object,
     return VoutCreate(object, cfg);
 }
 
-/*****************************************************************************
- * vout_Close: Close a vout created by VoutCreate.
- *****************************************************************************
- * You HAVE to call it on vout created by VoutCreate before vlc_object_release.
- * You should NEVER call it on vout not obtained through VoutCreate
- * (like with vout_Request or vlc_object_find.)
- * You can use vout_CloseAndRelease() as a convenience method.
- *****************************************************************************/
 void vout_Close(vout_thread_t *vout)
 {
     assert(vout);
 
     if (vout->p->input)
         spu_Attach(vout->p->p_spu, vout->p->input, false);
-    vlc_object_detach(vout->p->p_spu);
 
     vout_snapshot_End(&vout->p->snapshot);
 
     vout_control_PushVoid(&vout->p->control, VOUT_CONTROL_CLEAN);
     vlc_join(vout->p->thread, NULL);
+
+    vlc_mutex_lock(&vout->p->spu_lock);
+    spu_Destroy(vout->p->p_spu);
+    vout->p->p_spu = NULL;
+    vlc_mutex_unlock(&vout->p->spu_lock);
 }
 
 /* */
@@ -245,10 +244,8 @@ static void VoutDestructor(vlc_object_t *object)
 
     free(vout->p->splitter_name);
 
-    /* */
-    spu_Destroy(vout->p->p_spu);
-
     /* Destroy the locks */
+    vlc_mutex_destroy(&vout->p->spu_lock);
     vlc_mutex_destroy(&vout->p->picture_lock);
     vlc_mutex_destroy(&vout->p->vfilter_lock);
     vout_control_Clean(&vout->p->control);
@@ -348,15 +345,27 @@ void vout_DisplayTitle(vout_thread_t *vout, const char *title)
 
 void vout_PutSubpicture( vout_thread_t *vout, subpicture_t *subpic )
 {
-    spu_DisplaySubpicture(vout->p->p_spu, subpic);
+    vout_control_cmd_t cmd;
+    vout_control_cmd_Init(&cmd, VOUT_CONTROL_SUBPICTURE);
+    cmd.u.subpicture = subpic;
+
+    vout_control_Push(&vout->p->control, &cmd);
 }
 int vout_RegisterSubpictureChannel( vout_thread_t *vout )
 {
-    return spu_RegisterChannel(vout->p->p_spu);
+    int channel = SPU_DEFAULT_CHANNEL;
+
+    vlc_mutex_lock(&vout->p->spu_lock);
+    if (vout->p->p_spu)
+        channel = spu_RegisterChannel(vout->p->p_spu);
+    vlc_mutex_unlock(&vout->p->spu_lock);
+
+    return channel;
 }
 void vout_FlushSubpictureChannel( vout_thread_t *vout, int channel )
 {
-    spu_ClearChannel(vout->p->p_spu, channel);
+    vout_control_PushInteger(&vout->p->control, VOUT_CONTROL_FLUSH_SUBPICTURE,
+                             channel);
 }
 
 /* vout_Control* are usable by anyone at anytime */
@@ -426,6 +435,11 @@ void vout_ControlChangeSubFilters(vout_thread_t *vout, const char *filters)
     vout_control_PushString(&vout->p->control, VOUT_CONTROL_CHANGE_SUB_FILTERS,
                             filters);
 }
+void vout_ControlChangeSubMargin(vout_thread_t *vout, int margin)
+{
+    vout_control_PushInteger(&vout->p->control, VOUT_CONTROL_CHANGE_SUB_MARGIN,
+                             margin);
+}
 
 /* */
 static void VoutGetDisplayCfg(vout_thread_t *vout, vout_display_cfg_t *cfg, const char *title)
@@ -453,9 +467,9 @@ static void VoutGetDisplayCfg(vout_thread_t *vout, vout_display_cfg_t *cfg, cons
     else if (align_mask & 0x2)
         cfg->align.horizontal = VOUT_DISPLAY_ALIGN_RIGHT;
     if (align_mask & 0x4)
-        cfg->align.horizontal = VOUT_DISPLAY_ALIGN_TOP;
+        cfg->align.vertical = VOUT_DISPLAY_ALIGN_TOP;
     else if (align_mask & 0x8)
-        cfg->align.horizontal = VOUT_DISPLAY_ALIGN_BOTTOM;
+        cfg->align.vertical = VOUT_DISPLAY_ALIGN_BOTTOM;
 }
 
 vout_window_t * vout_NewDisplayWindow(vout_thread_t *vout, vout_display_t *vd,
@@ -748,6 +762,17 @@ static void ThreadManage(vout_thread_t *vout,
     vout_ManageWrapper(vout);
 }
 
+static void ThreadDisplaySubpicture(vout_thread_t *vout,
+                                    subpicture_t *subpicture)
+{
+    spu_DisplaySubpicture(vout->p->p_spu, subpicture);
+}
+
+static void ThreadFlushSubpicture(vout_thread_t *vout, int channel)
+{
+    spu_ClearChannel(vout->p->p_spu, channel);
+}
+
 static void ThreadDisplayOsdTitle(vout_thread_t *vout, const char *string)
 {
     if (!vout->p->title.show)
@@ -778,6 +803,10 @@ static void ThreadChangeSubFilters(vout_thread_t *vout, const char *filters)
 {
     spu_ChangeFilters(vout->p->p_spu, filters);
 }
+static void ThreadChangeSubMargin(vout_thread_t *vout, int margin)
+{
+    spu_ChangeMargin(vout->p->p_spu, margin);
+}
 
 static void ThreadChangePause(vout_thread_t *vout, bool is_paused, mtime_t date)
 {
@@ -1027,8 +1056,11 @@ static int ThreadReinit(vout_thread_t *vout,
         ThreadClean(vout);
         return VLC_EGENERIC;
     }
-    if (video_format_IsSimilar(&original, &vout->p->original))
-        return VLC_SUCCESS;
+    if (video_format_IsSimilar(&original, &vout->p->original)) {
+        if (cfg->dpb_size <= vout->p->dpb_size)
+            return VLC_SUCCESS;
+        msg_Warn(vout, "DPB need to be increased");
+    }
 
     vout_display_state_t state;
     memset(&state, 0, sizeof(state));
@@ -1045,6 +1077,7 @@ static int ThreadReinit(vout_thread_t *vout,
      * and I am not sure what to do */
 
     vout->p->original = original;
+    vout->p->dpb_size = cfg->dpb_size;
     if (ThreadStart(vout, &state)) {
         ThreadClean(vout);
         return VLC_EGENERIC;
@@ -1095,6 +1128,13 @@ static void *Thread(void *object)
                 if (ThreadReinit(vout, cmd.u.cfg))
                     return NULL;
                 break;
+            case VOUT_CONTROL_SUBPICTURE:
+                ThreadDisplaySubpicture(vout, cmd.u.subpicture);
+                cmd.u.subpicture = NULL;
+                break;
+            case VOUT_CONTROL_FLUSH_SUBPICTURE:
+                ThreadFlushSubpicture(vout, cmd.u.integer);
+                break;
             case VOUT_CONTROL_OSD_TITLE:
                 ThreadDisplayOsdTitle(vout, cmd.u.string);
                 break;
@@ -1104,6 +1144,9 @@ static void *Thread(void *object)
             case VOUT_CONTROL_CHANGE_SUB_FILTERS:
                 ThreadChangeSubFilters(vout, cmd.u.string);
                 break;
+            case VOUT_CONTROL_CHANGE_SUB_MARGIN:
+                ThreadChangeSubMargin(vout, cmd.u.integer);
+                break;
             case VOUT_CONTROL_PAUSE:
                 ThreadChangePause(vout, cmd.u.pause.is_on, cmd.u.pause.date);
                 break;