MythTV  0.26-pre
ig_decode.c
Go to the documentation of this file.
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 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends