]> git.sesse.net Git - vlc/blobdiff - src/video_output/video_output.c
Fixed vertical video alignment (close #3688).
[vlc] / src / video_output / video_output.c
index ebf4c4d91a75d69bb1b362777d60422f9037947a..01b8ee247457342aee1dfd95d6233795124f9060 100644 (file)
@@ -126,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);
@@ -155,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;
     }
@@ -186,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);
@@ -217,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);
 }
 
 /* */
@@ -249,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);
@@ -352,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 */
@@ -430,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)
@@ -457,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,
@@ -752,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)
@@ -782,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)
 {
@@ -1103,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;
@@ -1112,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;