MHEG5  18.9.0
MHEG5 Documentation
mg_video.c
Go to the documentation of this file.
1 /*******************************************************************************
2  * Copyright © 2014 The DTVKit Open Software Foundation Ltd (www.dtvkit.org)
3  * Copyright © 2008 Ocean Blue Software Ltd
4  *
5  * This file is part of a DTVKit Software Component
6  * You are permitted to copy, modify or distribute this file subject to the terms
7  * of the DTVKit 1.0 Licence which can be found in licence.txt or at www.dtvkit.org
8  *
9  * THIS CODE AND INFORMATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND,
10  * EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES
11  * OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE.
12  *
13  * If you or your organisation is not a member of DTVKit then you have access
14  * to this source code outside of the terms of the licence agreement
15  * and you are expected to delete this and any associated files immediately.
16  * Further information on DTVKit, membership and terms can be found at www.dtvkit.org
17  *******************************************************************************/
25 /*---includes for this file--------------------------------------------------*/
26 #include <string.h>
27 #include "dvb_video.h"
28 #include "mg_video.h"
29 #include "mg_api.h"
30 #include "mg_osd.h"
31 
32 #include "mh5profile.h"
33 #include "mh5debug.h"
34 
35 #include "glue_main.h"
36 
37 #ifdef INCLUDE_ICS
38 #include "dvb_ics.h"
39 #endif
40 
41 
42 typedef struct _S_Region
43 {
48 } S_Region;
49 
50 
51 /*---local (static) variable declarations for this file----------------------*/
52 
53 /* Initial values are unlikely to be used in a real application */
54 static MHEG5Bool mg_subtitle_on = MHEG5TRUE;
55 static MHEG5Bool mg_full_screen = MHEG5TRUE;
56 static S_RECTANGLE mg_video_scaling = { -1000, -1000, 1000, 1000 };
57 #ifdef INCLUDE_FREESAT
58 static S_RECTANGLE mg_image_scaling = { -1000, -1000, 1000, 1000 };
59 #endif
60 
61 static void Mheg5ToScalingCoordinates( S_RECTANGLE *rect )
62 {
63  S32BIT tmp;
64  /* Translate according to MHEG5 HD rules */
65  DBGTRACE(TGRAPHICS, " RatioX (%d/%d)", mg_ctxt.vid_x.mlt, mg_ctxt.vid_x.div);
66  tmp = rect->left + rect->width;
67  rect->left = (rect->left * mg_ctxt.vid_x.mlt) / mg_ctxt.vid_x.div;
68  tmp = (tmp * mg_ctxt.vid_x.mlt) / mg_ctxt.vid_x.div;
69  rect->width = tmp - rect->left;
70  DBGTRACE(TGRAPHICS, " RatioY (%d/%d)", mg_ctxt.vid_y.mlt, mg_ctxt.vid_y.div);
71  tmp = rect->top + rect->height;
72  rect->top = (rect->top * mg_ctxt.vid_y.mlt) / mg_ctxt.vid_y.div;
73  tmp = (tmp * mg_ctxt.vid_y.mlt) / mg_ctxt.vid_y.div;
74  rect->height = tmp - rect->top;
75  DBGTRACE(TGRAPHICS,"%ux%u", rect->width, rect->height);
76 }
77 
78 
79 /*---global function definitions---------------------------------------------*/
80 
89 void MG_SetSubtitleMode(MHEG5Bool subtitleOn)
90 {
91  if (mg_subtitle_on != subtitleOn)
92  {
93  mg_subtitle_on = subtitleOn;
94  if (subtitleOn && mg_full_screen)
95  {
97  }
98  else
99  {
101  }
102  }
103 }
104 
105 void MG_SetVideoPosition( MHEG5Video *video, MHEG5Int contentHook )
106 {
107  S_Region rgn;
108  S32BIT xOffset, yOffset;
109  S_RECTANGLE new_video_scaling;
110  MHEG5Bool fullscreen = MHEG5FALSE;
111 
112  if (video && video->visible.ingredient.root.runningStatus)
113  {
114  rgn.left = video->visible.position[0];
115  rgn.top = video->visible.position[1];
116  rgn.right = video->visible.position[0] + video->visible.boxSize[0];
117  rgn.bottom = video->visible.position[1] + video->visible.boxSize[1];
118 
119  xOffset = video->visible.position[0] + video->xOffset;
120  yOffset = video->visible.position[1] + video->yOffset;
121  new_video_scaling.left = xOffset;
122  new_video_scaling.top = yOffset;
123  TRACE(TGRAPHICS | TSTRM | TSTATE, ("rgn=(%d,%d,%d,%d) offset=(%d,%d)", rgn.left, rgn.top, rgn.right, rgn.bottom, xOffset, yOffset))
124 
125  /*clip to SD coordinate screen*/
126  if (rgn.left < 0)
127  rgn.left = 0;
128  else if (rgn.left > mg_ctxt.input_width)
129  rgn.left = mg_ctxt.input_width;
130 
131  if (rgn.top < 0)
132  rgn.top = 0;
133  else if (rgn.top > mg_ctxt.input_height)
134  rgn.top = mg_ctxt.input_height;
135 
136  if (rgn.right > mg_ctxt.input_width)
137  rgn.right = mg_ctxt.input_width;
138  else if (rgn.right < 0)
139  rgn.right = 0;
140 
141  if (rgn.bottom > mg_ctxt.input_height)
143  else if (rgn.bottom < 0)
144  rgn.bottom = 0;
145  TRACE(TGRAPHICS | TSTRM | TSTATE, ("rgn=(%d,%d,%d,%d) offset=(%d,%d)", rgn.left, rgn.top, rgn.right, rgn.bottom, xOffset, yOffset))
146 
147  /* Check for sensible width/height */
148  if (rgn.right < rgn.left) rgn.right = rgn.left;
149  if (rgn.bottom < rgn.top) rgn.bottom = rgn.top;
150 
151  /* Check whether offset clips output */
152  if (video->scaleSet)
153  {
154  if (xOffset + video->xScale < rgn.right)
155  {
156  rgn.right = video->xScale + xOffset;
157  }
158  if (yOffset + video->yScale < rgn.bottom)
159  {
160  rgn.bottom = video->yScale + yOffset;
161  }
162  }
163  else
164  {
165  if (xOffset + mg_ctxt.input_width < rgn.right)
166  {
167  rgn.right = mg_ctxt.input_width + xOffset;
168  }
169  if (yOffset + mg_ctxt.input_height < rgn.bottom)
170  {
171  rgn.bottom = mg_ctxt.input_height + yOffset;
172  }
173  }
174  if (rgn.left < xOffset)
175  {
176  rgn.left = xOffset;
177  xOffset = 0;
178  }
179  else
180  {
181  xOffset = rgn.left - xOffset;
182  }
183  if (rgn.top < yOffset)
184  {
185  rgn.top = yOffset;
186  yOffset = 0;
187  }
188  else
189  {
190  yOffset = rgn.top - yOffset;
191  }
192  TRACE(TGRAPHICS | TSTRM | TSTATE, ("rgn=(%d,%d,%d,%d) offset=(%d,%d)", rgn.left, rgn.top, rgn.right, rgn.bottom, xOffset, yOffset));
193 
194  if (!video->scaleSet)
195  {
196  TRACE(TGRAPHICS | TSTRM | TSTATE, ("No SCALE rgn=(%d,%d,%d,%d) offset=(%d,%d)", rgn.left, rgn.top, rgn.right, rgn.bottom, xOffset, yOffset))
197  new_video_scaling.width = (U16BIT)SD_WIDTH;
198  new_video_scaling.height = (U16BIT)SD_HEIGHT;
199  if (new_video_scaling.left == 0 && new_video_scaling.top == 0)
200  {
201  fullscreen = MHEG5TRUE;
202  }
203  }
204  else
205  {
206  TRACE(TGRAPHICS | TSTRM | TSTATE, ("SCALE(%d,%d) rgn=(%d,%d,%d,%d) offset=(%d,%d)", (int)video->xScale, (int)video->yScale,
207  rgn.left, rgn.top, rgn.right, rgn.bottom, xOffset, yOffset))
208  new_video_scaling.width = (U16BIT)video->xScale;
209  new_video_scaling.height = (U16BIT)video->yScale;
210  if (new_video_scaling.left == 0 && new_video_scaling.top == 0 &&
211  new_video_scaling.width == SD_WIDTH && new_video_scaling.height == SD_HEIGHT)
212  {
213  fullscreen = MHEG5TRUE;
214  }
215  }
216  }
217  else
218  {
219  TRACE(TGRAPHICS | TSTRM | TSTATE, ("default video position"))
220  new_video_scaling.top = 0;
221  new_video_scaling.left = 0;
222  new_video_scaling.width = SD_WIDTH;
223  new_video_scaling.height = SD_HEIGHT;
224  fullscreen = MHEG5TRUE;
225  }
226  #ifdef INCLUDE_FREESAT
227  if (contentHook == CHOOK_BITMAP_IMAGE_PLANE_IFRAME)
228  {
229  if (new_video_scaling.height != mg_image_scaling.height ||
230  new_video_scaling.width != mg_image_scaling.width ||
231  new_video_scaling.left != mg_image_scaling.left ||
232  new_video_scaling.top != mg_image_scaling.top
233  )
234  {
235  mg_image_scaling = new_video_scaling;
236  if (fullscreen)
237  {
238  DVB_MhegSetImageScaling( NULL );
239  }
240  else
241  {
242  /* only after assigning values to global can we translate to final
243  * coordinates. Otherwise VideoToGraphics will be wrong */
244  Mheg5ToScalingCoordinates( &new_video_scaling );
245  DVB_MhegSetImageScaling( &new_video_scaling );
246  }
247  }
248  }
249  else
250  #endif
251  if (new_video_scaling.height != mg_video_scaling.height ||
252  new_video_scaling.width != mg_video_scaling.width ||
253  new_video_scaling.left != mg_video_scaling.left ||
254  new_video_scaling.top != mg_video_scaling.top
255  )
256  {
257  mg_video_scaling = new_video_scaling;
258  if (fullscreen)
259  {
260  DVB_MhegSetVideoScaling( NULL );
261  }
262  else
263  {
264  /* only after assigning values to global can we translate to final
265  * coordinates. Otherwise VideoToGraphics will be wrong */
266  Mheg5ToScalingCoordinates( &new_video_scaling );
267  DVB_MhegSetVideoScaling( &new_video_scaling );
268  }
269  }
270  if (mg_full_screen != fullscreen)
271  {
272  mg_full_screen = fullscreen;
273  if (fullscreen && mg_subtitle_on)
274  {
276  }
277  else
278  {
280  }
281  }
282 }
283 
294 void MG_DisplayVideoToGraphics( MHEG5Int videoXval, MHEG5Int videoYval,
295  MHEG5Int *graphicsXVal, MHEG5Int *graphicsYVal )
296 {
297  E_FORMAT_CONVERSION formatConversion;
298  BOOLEAN scaled;
299  S32BIT width = (S32BIT)mg_video_scaling.width;
300  S32BIT height = (S32BIT)mg_video_scaling.height;
301 #ifdef INCLUDE_USER_DEFINED_VTG
302  S32BIT xVal, yVal;
303 #endif /* INCLUDE_USER_DEFINED_VTG */
304 
305  scaled = TRUE;
306  formatConversion = DVB_MhegGetDecoderFormatConversion();
307  switch (formatConversion)
308  {
311  *graphicsXVal = width * videoXval;
312  *graphicsYVal = height * videoYval;
313  break;
315  *graphicsXVal = width * (8 * videoXval - SD_WIDTH) / 6;
316  *graphicsYVal = height * videoYval;
317  break;
319  *graphicsXVal = width * videoXval;
320  *graphicsYVal = height * (6 * videoYval + SD_HEIGHT) / 8;
321  break;
323  *graphicsXVal = width * (16 * videoXval - SD_WIDTH) / 14;
324  *graphicsYVal = height * (12 * videoYval + SD_HEIGHT) / 14;
325  break;
327  *graphicsXVal = width * (6 * videoXval + SD_WIDTH) / 8;
328  *graphicsYVal = height * videoYval;
329  break;
331  *graphicsXVal = width * videoXval;
332  *graphicsYVal = height * (8 * videoYval - SD_HEIGHT) / 6;
333  break;
335  *graphicsXVal = width * (8 * videoXval - SD_WIDTH) / 6;
336  *graphicsYVal = height * (8 * videoYval - SD_HEIGHT) / 6;
337  break;
339  *graphicsXVal = width * (14 * videoXval + SD_WIDTH) / 16;
340  *graphicsYVal = height * (14 * videoYval - SD_HEIGHT) / 12;
341  break;
343  *graphicsXVal = width * (14 * videoXval - SD_WIDTH) / 12;
344  *graphicsYVal = height * (14 * videoYval - SD_HEIGHT) / 12;
345  break;
347  *graphicsXVal = width * (16 * videoXval - SD_WIDTH) / 14;
348  *graphicsYVal = height * (16 * videoYval - SD_HEIGHT) / 14;
349  break;
350 #ifdef INCLUDE_USER_DEFINED_VTG
351  case FORMAT_CONVERSION_USER_DEFINED:
352  tmMHEG5VideoToGraphics(videoXval, videoYval, &xVal, &yVal);
353  *graphicsXVal = ((xVal * mg_ctxt.vid_x.div + mg_ctxt.vid_x.mlt / 2) /
354  mg_ctxt.vid_x.mlt);
355  *graphicsYVal = ((yVal * mg_ctxt.vid_y.div + mg_ctxt.vid_y.mlt / 2) /
356  mg_ctxt.vid_y.mlt);
357  scaled = FALSE;
358  break;
359 #endif /* INCLUDE_USER_DEFINED_VTG */
360  default:
361  *graphicsXVal = width * videoXval;
362  *graphicsYVal = height * videoYval;
363  }
364 
365  if (scaled)
366  {
367  *graphicsXVal = ((*graphicsXVal + SD_WIDTH / 2) / SD_WIDTH +
368  mg_video_scaling.left);
369  *graphicsYVal = ((*graphicsYVal + SD_HEIGHT / 2) / SD_HEIGHT +
370  mg_video_scaling.top);
371  }
372 }
373 
375 {
376  memset(&mg_video_scaling, 0, sizeof(S_RECTANGLE));
377  /* do not set mg_full_screen to either MHEG5TRUE or MHEG5FALSE,
378  * so that MG_SetVideoPosition() will be forced to call DVB_MhegSubtitleSetVisibility() */
379  mg_full_screen = TRUE;
380 }
381 
MHEG5Int xScale
Definition: mh5video.h:53
MHEG5Int boxSize[2]
Definition: mh5visible.h:58
#define DBGTRACE(...)
Definition: glue_debug.h:126
U16BIT mlt
Definition: mg_ctxt.h:73
void MG_SetSubtitleMode(MHEG5Bool subtitleOn)
Set the current subtitle display mode to be either On or Off, Should only have an impact if subtitles...
Definition: mg_video.c:89
U32BIT height
Definition: osdtype.h:59
S32BIT left
Definition: osdtype.h:56
void MG_SetVideoPosition(MHEG5Video *video, MHEG5Int contentHook)
Definition: mg_video.c:105
U32BIT width
Definition: osdtype.h:58
#define SD_HEIGHT
Definition: osdtype.h:30
void DVB_MhegSetVideoScaling(S_RECTANGLE *scaling)
Set Mheg video scaling.
S_RATIO vid_y
Definition: mg_ctxt.h:88
void MG_VideoPositionReset(void)
Definition: mg_video.c:374
MHEG5Bool scaleSet
Definition: mh5video.h:52
S32BIT top
Definition: osdtype.h:57
E_MhegErr DVB_MhegSubtitleSetVisibility(E_DvbSubtitleShowState showState)
Show or hide DVB subtitles. This operation remains in force until set again by another call to this f...
long MHEG5Int
Definition: mh5base.h:73
DVB Video functions are required by MHEG5 engine. All required functions should be non-blocking...
MHEG5Int yScale
Definition: mh5video.h:54
S_RATIO vid_x
Definition: mg_ctxt.h:87
This file defines the profile for the MHEG engine.
struct _S_Region S_Region
MHEG5Int yOffset
Definition: mh5video.h:58
MHEG5Int xOffset
Definition: mh5video.h:57
short MHEG5Bool
Definition: mh5base.h:71
S_MGContext mg_ctxt
Definition: mg_osd.c:144
Interface to OSD.
U16BIT input_height
Definition: mg_ctxt.h:84
int32_t S32BIT
Definition: techtype.h:87
E_FORMAT_CONVERSION DVB_MhegGetDecoderFormatConversion(void)
#define MHEG5TRUE
Definition: mh5base.h:49
S32BIT bottom
Definition: mg_video.c:47
uint16_t U16BIT
Definition: techtype.h:84
Mheg5 logging and debug printing.
S32BIT left
Definition: mg_video.c:44
MHEG5Bool runningStatus
Definition: mh5root.h:51
E_FORMAT_CONVERSION
Definition: vtctype.h:42
MHEG5Ingredient ingredient
Definition: mh5visible.h:49
MHEG5Visible visible
Definition: mh5video.h:49
#define FALSE
Definition: techtype.h:68
#define SD_WIDTH
Definition: osdtype.h:31
U16BIT div
Definition: mg_ctxt.h:74
void MG_DisplayVideoToGraphics(MHEG5Int videoXval, MHEG5Int videoYval, MHEG5Int *graphicsXVal, MHEG5Int *graphicsYVal)
Calculate the graphical co-ordinate from a given video coordinate (should take into account the curre...
Definition: mg_video.c:294
Interaction Channel Streaming functions required by MHEG5 engine References: [1] UK1 Profile - Digita...
U8BIT BOOLEAN
Definition: techtype.h:99
#define TRUE
Definition: techtype.h:69
S32BIT right
Definition: mg_video.c:46
S32BIT top
Definition: mg_video.c:45
Video Scaling / Positioning functionality.
MHEG5Int position[2]
Definition: mh5visible.h:59
#define MHEG5FALSE
Definition: mh5base.h:48
U16BIT input_width
Definition: mg_ctxt.h:83
#define TRACE(t, x)
Definition: glue_debug.h:118