|
MythTV
0.26-pre
|
00001 /* 00002 * This file is part of libbluray 00003 * Copyright (C) 2010 hpi1 00004 * 00005 * This library is free software; you can redistribute it and/or 00006 * modify it under the terms of the GNU Lesser General Public 00007 * License as published by the Free Software Foundation; either 00008 * version 2.1 of the License, or (at your option) any later version. 00009 * 00010 * This library is distributed in the hope that it will be useful, 00011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00013 * Lesser General Public License for more details. 00014 * 00015 * You should have received a copy of the GNU Lesser General Public 00016 * License along with this library. If not, see 00017 * <http://www.gnu.org/licenses/>. 00018 */ 00019 00020 #include "ig_decode.h" 00021 00022 #include "pg_decode.h" // pg_decode_*() 00023 #include "../hdmv/mobj_parse.h" // mobj_parse_cmd() 00024 #include "../bdnav/mpls_parse.h" // mpls_parse_uo() 00025 00026 #include "util/macro.h" 00027 #include "util/logging.h" 00028 #include "util/bits.h" 00029 00030 #include <string.h> 00031 #include <stdlib.h> 00032 00033 00034 static void _decode_button(BITBUFFER *bb, BD_IG_BUTTON *p) 00035 { 00036 unsigned ii; 00037 00038 p->id = bb_read(bb, 16); 00039 00040 p->numeric_select_value = bb_read(bb, 16); 00041 p->auto_action_flag = bb_read(bb, 1); 00042 bb_skip(bb, 7); 00043 00044 p->x_pos = bb_read(bb, 16); 00045 p->y_pos = bb_read(bb, 16); 00046 00047 p->upper_button_id_ref = bb_read(bb, 16); 00048 p->lower_button_id_ref = bb_read(bb, 16); 00049 p->left_button_id_ref = bb_read(bb, 16); 00050 p->right_button_id_ref = bb_read(bb, 16); 00051 00052 p->normal_start_object_id_ref = bb_read(bb, 16); 00053 p->normal_end_object_id_ref = bb_read(bb, 16); 00054 p->normal_repeat_flag = bb_read(bb, 1); 00055 bb_skip(bb, 7); 00056 00057 p->selected_sound_id_ref = bb_read(bb, 8); 00058 p->selected_start_object_id_ref = bb_read(bb, 16); 00059 p->selected_end_object_id_ref = bb_read(bb, 16); 00060 p->selected_repeat_flag = bb_read(bb, 1); 00061 bb_skip(bb, 7); 00062 00063 p->activated_sound_id_ref = bb_read(bb, 8); 00064 p->activated_start_object_id_ref = bb_read(bb, 16); 00065 p->activated_end_object_id_ref = bb_read(bb, 16); 00066 00067 p->num_nav_cmds = bb_read(bb, 16); 00068 p->nav_cmds = calloc(p->num_nav_cmds, sizeof(MOBJ_CMD)); 00069 00070 for (ii = 0; ii < p->num_nav_cmds; ii++) { 00071 uint8_t buf[12]; 00072 bb_read_bytes(bb, buf, 12); 00073 00074 mobj_parse_cmd(buf, &p->nav_cmds[ii]); 00075 } 00076 } 00077 00078 static void _clean_button(BD_IG_BUTTON *p) 00079 { 00080 X_FREE(p->nav_cmds); 00081 } 00082 00083 static void _decode_bog(BITBUFFER *bb, BD_IG_BOG *p) 00084 { 00085 unsigned ii; 00086 00087 p->default_valid_button_id_ref = bb_read(bb, 16); 00088 00089 p->num_buttons = bb_read(bb, 8); 00090 p->button = calloc(p->num_buttons, sizeof(BD_IG_BUTTON)); 00091 00092 for (ii = 0; ii < p->num_buttons; ii++) { 00093 _decode_button(bb, &p->button[ii]); 00094 } 00095 } 00096 00097 static void _clean_bog(BD_IG_BOG *p) 00098 { 00099 unsigned ii; 00100 00101 for (ii = 0; ii < p->num_buttons; ii++) { 00102 _clean_button(&p->button[ii]); 00103 } 00104 X_FREE(p->button); 00105 } 00106 00107 static void _decode_effect(BITBUFFER *bb, BD_IG_EFFECT *p) 00108 { 00109 unsigned ii; 00110 00111 p->duration = bb_read(bb, 24); 00112 p->palette_id_ref = bb_read(bb, 8); 00113 00114 p->num_composition_objects = bb_read(bb, 8); 00115 p->composition_object = calloc(p->num_composition_objects, sizeof(BD_PG_COMPOSITION_OBJECT)); 00116 00117 for (ii = 0; ii < p->num_composition_objects; ii++) { 00118 pg_decode_composition_object(bb, &p->composition_object[ii]); 00119 } 00120 } 00121 00122 static void _clean_effect(BD_IG_EFFECT *p) 00123 { 00124 X_FREE(p->composition_object); 00125 } 00126 00127 static void _decode_effect_sequence(BITBUFFER *bb, BD_IG_EFFECT_SEQUENCE *p) 00128 { 00129 unsigned ii; 00130 00131 p->num_windows = bb_read(bb, 8); 00132 p->window = calloc(p->num_windows, sizeof(BD_PG_WINDOW)); 00133 00134 for (ii = 0; ii < p->num_windows; ii++) { 00135 pg_decode_window(bb, &p->window[ii]); 00136 } 00137 00138 p->num_effects = bb_read(bb, 8); 00139 p->effect = calloc(p->num_effects, sizeof(BD_IG_EFFECT)); 00140 00141 for (ii = 0; ii < p->num_effects; ii++) { 00142 _decode_effect(bb, &p->effect[ii]); 00143 } 00144 } 00145 00146 static void _clean_effect_sequence(BD_IG_EFFECT_SEQUENCE *p) 00147 { 00148 unsigned ii; 00149 00150 for (ii = 0; ii < p->num_effects; ii++) { 00151 _clean_effect(&p->effect[ii]); 00152 } 00153 X_FREE(p->effect); 00154 00155 X_FREE(p->window); 00156 } 00157 00158 00159 static int _decode_uo_mask_table(BITBUFFER *bb, BD_UO_MASK *p) 00160 { 00161 uint8_t buf[8]; 00162 bb_read_bytes(bb, buf, 8); 00163 00164 return mpls_parse_uo(buf, p); 00165 } 00166 00167 static void _decode_page(BITBUFFER *bb, BD_IG_PAGE *p) 00168 { 00169 unsigned ii; 00170 00171 p->id = bb_read(bb, 8); 00172 p->version = bb_read(bb, 8); 00173 00174 _decode_uo_mask_table(bb, &p->uo_mask_table); 00175 00176 _decode_effect_sequence(bb, &p->in_effects); 00177 _decode_effect_sequence(bb, &p->out_effects); 00178 00179 p->animation_frame_rate_code = bb_read(bb, 8); 00180 p->default_selected_button_id_ref = bb_read(bb, 16); 00181 p->default_activated_button_id_ref = bb_read(bb, 16); 00182 p->palette_id_ref = bb_read(bb, 8); 00183 00184 p->num_bogs = bb_read(bb, 8); 00185 p->bog = calloc(p->num_bogs, sizeof(BD_IG_BOG)); 00186 00187 for (ii = 0; ii < p->num_bogs; ii++) { 00188 _decode_bog(bb, &p->bog[ii]); 00189 } 00190 } 00191 00192 static void _clean_page(BD_IG_PAGE *p) 00193 { 00194 unsigned ii; 00195 00196 _clean_effect_sequence(&p->in_effects); 00197 _clean_effect_sequence(&p->out_effects); 00198 00199 for (ii = 0; ii < p->num_bogs; ii++) { 00200 _clean_bog(&p->bog[ii]); 00201 } 00202 X_FREE(p->bog); 00203 } 00204 00205 static inline uint64_t bb_read_u64(BITBUFFER *bb, int i_count) 00206 { 00207 uint64_t result = 0; 00208 if (i_count > 32) { 00209 i_count -= 32; 00210 result = (uint64_t)bb_read(bb, 32) << i_count; 00211 } 00212 result |= bb_read(bb, i_count); 00213 return result; 00214 } 00215 00216 static int _decode_interactive_composition(BITBUFFER *bb, BD_IG_INTERACTIVE_COMPOSITION *p) 00217 { 00218 unsigned ii; 00219 00220 uint32_t data_len = bb_read(bb, 24); 00221 uint32_t buf_len = bb->p_end - bb->p; 00222 if (data_len != buf_len) { 00223 BD_DEBUG(DBG_DECODE, "ig_decode_interactive(): buffer size mismatch (expected %d, have %d)\n", data_len, buf_len); 00224 return 0; 00225 } 00226 00227 p->stream_model = bb_read(bb, 1); 00228 p->ui_model = bb_read(bb, 1); 00229 bb_skip(bb, 6); 00230 00231 if (p->stream_model == 0) { 00232 bb_skip(bb, 7); 00233 p->composition_timeout_pts = bb_read_u64(bb, 33); 00234 bb_skip(bb, 7); 00235 p->selection_timeout_pts = bb_read_u64(bb, 33); 00236 } 00237 00238 p->user_timeout_duration = bb_read(bb, 24); 00239 00240 p->num_pages = bb_read(bb, 8); 00241 p->page = calloc(p->num_pages, sizeof(BD_IG_PAGE)); 00242 00243 for (ii = 0; ii < p->num_pages; ii++) { 00244 _decode_page(bb, &p->page[ii]); 00245 } 00246 00247 return 1; 00248 } 00249 00250 static void _clean_interactive_composition(BD_IG_INTERACTIVE_COMPOSITION *p) 00251 { 00252 unsigned ii; 00253 00254 for (ii = 0; ii < p->num_pages; ii++) { 00255 _clean_page(&p->page[ii]); 00256 } 00257 X_FREE(p->page); 00258 } 00259 00260 /* 00261 * segment 00262 */ 00263 00264 int ig_decode_interactive(BITBUFFER *bb, BD_IG_INTERACTIVE *p) 00265 { 00266 BD_PG_SEQUENCE_DESCRIPTOR sd; 00267 00268 pg_decode_video_descriptor(bb, &p->video_descriptor); 00269 pg_decode_composition_descriptor(bb, &p->composition_descriptor); 00270 pg_decode_sequence_descriptor(bb, &sd); 00271 00272 if (!sd.first_in_seq) { 00273 BD_DEBUG(DBG_DECODE, "ig_decode_interactive(): not first in seq\n"); 00274 return 0; 00275 } 00276 if (!sd.last_in_seq) { 00277 BD_DEBUG(DBG_DECODE, "ig_decode_interactive(): not last in seq\n"); 00278 return 0; 00279 } 00280 if (!bb_is_align(bb, 0x07)) { 00281 BD_DEBUG(DBG_DECODE, "ig_decode_interactive(): alignment error\n"); 00282 return 0; 00283 } 00284 00285 return _decode_interactive_composition(bb, &p->interactive_composition); 00286 } 00287 00288 void ig_clean_interactive(BD_IG_INTERACTIVE *p) 00289 { 00290 _clean_interactive_composition(&p->interactive_composition); 00291 } 00292 00293 void ig_free_interactive(BD_IG_INTERACTIVE **p) 00294 { 00295 if (p && *p) { 00296 _clean_interactive_composition(&(*p)->interactive_composition); 00297 X_FREE(*p); 00298 } 00299 }
1.7.6.1