|
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 "graphics_processor.h" 00021 00022 #include "ig_decode.h" 00023 #include "pg_decode.h" 00024 #include "pes_buffer.h" 00025 #include "m2ts_demux.h" 00026 00027 #include "util/macro.h" 00028 #include "util/logging.h" 00029 #include "util/bits.h" 00030 00031 #include <string.h> 00032 #include <stdlib.h> 00033 #include <inttypes.h> 00034 00035 #define GP_TRACE(...) do {} while (0) 00036 00037 00038 /* 00039 * segment types 00040 */ 00041 00042 typedef enum { 00043 PGS_PALETTE = 0x14, 00044 PGS_OBJECT = 0x15, 00045 PGS_PG_COMPOSITION = 0x16, 00046 PGS_WINDOW = 0x17, 00047 PGS_IG_COMPOSITION = 0x18, 00048 PGS_END_OF_DISPLAY = 0x80, 00049 } pgs_segment_type_e; 00050 00051 /* 00052 * PG_DISPLAY_SET 00053 */ 00054 00055 void pg_display_set_free(PG_DISPLAY_SET **s) 00056 { 00057 if (s && *s) { 00058 unsigned ii; 00059 for (ii = 0; ii < (*s)->num_object; ii++) { 00060 pg_clean_object(&(*s)->object[ii]); 00061 } 00062 ig_free_interactive(&(*s)->ics); 00063 00064 X_FREE((*s)->window); 00065 X_FREE((*s)->object); 00066 X_FREE((*s)->palette); 00067 00068 X_FREE(*s); 00069 } 00070 } 00071 00072 /* 00073 * segment handling 00074 */ 00075 00076 static PES_BUFFER *_find_segment_by_idv(PES_BUFFER *p, 00077 uint8_t seg_type, unsigned idv_pos, 00078 uint8_t *idv, unsigned idv_len) 00079 { 00080 while (p && (p->buf[0] != seg_type || memcmp(p->buf + idv_pos, idv, idv_len))) { 00081 p = p->next; 00082 } 00083 return p; 00084 } 00085 00086 static void _join_fragments(PES_BUFFER *p1, PES_BUFFER *p2, int data_pos) 00087 { 00088 unsigned new_len = p1->len + p2->len - data_pos; 00089 00090 if (p1->size < new_len) { 00091 p1->size = new_len + 1; 00092 p1->buf = realloc(p1->buf, p1->size); 00093 } 00094 00095 memcpy(p1->buf + p1->len, p2->buf + data_pos, p2->len - data_pos); 00096 p1->len = new_len; 00097 p2->len = 0; 00098 } 00099 00100 /* return 1 if segment is ready for decoding, 0 if more data is needed */ 00101 static int _join_segment_fragments(struct pes_buffer_s *p) 00102 { 00103 uint8_t type = p->buf[0]; 00104 unsigned id_pos = 0, id_len = 3, sd_pos = 6, data_pos = 0; 00105 00106 if (p->len < 3) { 00107 return 1; 00108 } 00109 00110 /* check segment type */ 00111 00112 if (type == PGS_OBJECT) { 00113 id_pos = 3; 00114 sd_pos = 6; 00115 data_pos = 7; 00116 } 00117 else if (type == PGS_IG_COMPOSITION) { 00118 id_pos = 8; 00119 sd_pos = 11; 00120 data_pos = 12; 00121 } 00122 else { 00123 return 1; 00124 } 00125 00126 /* check sequence descriptor - is segment complete ? */ 00127 00128 BD_PG_SEQUENCE_DESCRIPTOR sd; 00129 BITBUFFER bb; 00130 bb_init(&bb, p->buf + sd_pos, 3); 00131 pg_decode_sequence_descriptor(&bb, &sd); 00132 00133 if (sd.last_in_seq) { 00134 return 1; 00135 } 00136 if (!sd.first_in_seq) { 00137 return 1; 00138 } 00139 00140 /* find next fragment(s) */ 00141 00142 PES_BUFFER *next; 00143 while (NULL != (next = _find_segment_by_idv(p->next, p->buf[0], id_pos, p->buf + id_pos, id_len))) { 00144 00145 bb_init(&bb, next->buf + sd_pos, 3); 00146 pg_decode_sequence_descriptor(&bb, &sd); 00147 00148 _join_fragments(p, next, data_pos); 00149 00150 pes_buffer_remove(&p, next); 00151 00152 if (sd.last_in_seq) { 00153 /* set first + last in sequence descriptor */ 00154 p->buf[sd_pos] = 0xff; 00155 return 1; 00156 } 00157 } 00158 00159 /* do not delay decoding if there are other segments queued (missing fragment ?) */ 00160 return !!p->next; 00161 } 00162 00163 /* 00164 * segment decoding 00165 */ 00166 00167 static int _decode_wds(PG_DISPLAY_SET *s, BITBUFFER *bb, PES_BUFFER *p) 00168 { 00169 (void)s; 00170 (void)bb; 00171 (void)p; 00172 00173 BD_DEBUG(DBG_DECODE | DBG_CRIT, "unhandled segment type (PGS_WINDOW)\n"); 00174 return 0; 00175 } 00176 00177 static int _decode_ods(PG_DISPLAY_SET *s, BITBUFFER *bb, PES_BUFFER *p) 00178 { 00179 /* search for object to be updated */ 00180 00181 if (s->object) { 00182 BITBUFFER bb_tmp = *bb; 00183 uint16_t id = bb_read(&bb_tmp, 16); 00184 unsigned ii; 00185 00186 for (ii = 0; ii < s->num_object; ii++) { 00187 if (s->object[ii].id == id) { 00188 if (pg_decode_object(bb, &s->object[ii])) { 00189 s->object[ii].pts = p->pts; 00190 return 1; 00191 } 00192 return 0; 00193 } 00194 } 00195 } 00196 00197 /* add and decode new object */ 00198 00199 s->object = realloc(s->object, sizeof(s->object[0]) * (s->num_object + 1)); 00200 memset(&s->object[s->num_object], 0, sizeof(s->object[0])); 00201 00202 if (pg_decode_object(bb, &s->object[s->num_object])) { 00203 s->object[s->num_object].pts = p->pts; 00204 s->num_object++; 00205 return 1; 00206 } 00207 00208 return 0; 00209 } 00210 00211 static int _decode_pds(PG_DISPLAY_SET *s, BITBUFFER *bb, PES_BUFFER *p) 00212 { 00213 /* search for palette to be updated */ 00214 00215 if (s->palette) { 00216 BITBUFFER bb_tmp = *bb; 00217 uint8_t id = bb_read(&bb_tmp, 8); 00218 unsigned ii; 00219 00220 for (ii = 0; ii < s->num_palette; ii++) { 00221 if (s->palette[ii].id == id) { 00222 int rr; 00223 if ( (s->ics && s->ics->composition_descriptor.state == 0) || 00224 (s->pcs && s->pcs->composition_descriptor.state == 0)) { 00225 /* 8.8.3.1.1 */ 00226 rr = pg_decode_palette_update(bb, &s->palette[ii]); 00227 } else { 00228 rr = pg_decode_palette(bb, &s->palette[ii]); 00229 } 00230 if (rr) { 00231 s->palette[ii].pts = p->pts; 00232 return 1; 00233 } 00234 return 0; 00235 } 00236 } 00237 } 00238 00239 /* add and decode new palette */ 00240 00241 s->palette = realloc(s->palette, sizeof(s->palette[0]) * (s->num_palette + 1)); 00242 memset(&s->palette[s->num_palette], 0, sizeof(s->palette[0])); 00243 00244 if (pg_decode_palette(bb, &s->palette[s->num_palette])) { 00245 s->palette[s->num_palette].pts = p->pts; 00246 s->num_palette++; 00247 return 1; 00248 } 00249 00250 return 0; 00251 } 00252 00253 static void _check_epoch_start(PG_DISPLAY_SET *s) 00254 { 00255 if ((s->pcs && s->pcs->composition_descriptor.state == 2) || 00256 (s->ics && s->ics->composition_descriptor.state == 2)) { 00257 /* epoch start, drop all cached data */ 00258 00259 unsigned ii; 00260 for (ii = 0; ii < s->num_object; ii++) { 00261 pg_clean_object(&s->object[ii]); 00262 } 00263 00264 s->num_palette = 0; 00265 s->num_window = 0; 00266 s->num_object = 0; 00267 00268 s->epoch_start = 1; 00269 00270 } else { 00271 s->epoch_start = 0; 00272 } 00273 } 00274 00275 static int _decode_pcs(PG_DISPLAY_SET *s, BITBUFFER *bb, PES_BUFFER *p) 00276 { 00277 pg_free_composition(&s->pcs); 00278 s->pcs = calloc(1, sizeof(*s->pcs)); 00279 00280 if (!pg_decode_composition(bb, s->pcs)) { 00281 pg_free_composition(&s->pcs); 00282 return 0; 00283 } 00284 00285 s->pcs->pts = p->pts; 00286 s->valid_pts = p->pts; 00287 00288 _check_epoch_start(s); 00289 00290 return 1; 00291 } 00292 00293 static int _decode_ics(PG_DISPLAY_SET *s, BITBUFFER *bb, PES_BUFFER *p) 00294 { 00295 ig_free_interactive(&s->ics); 00296 s->ics = calloc(1, sizeof(*s->ics)); 00297 00298 if (!ig_decode_interactive(bb, s->ics)) { 00299 ig_free_interactive(&s->ics); 00300 return 0; 00301 } 00302 00303 s->ics->pts = p->pts; 00304 s->valid_pts = p->pts; 00305 00306 _check_epoch_start(s); 00307 00308 return 1; 00309 } 00310 00311 static int _decode_segment(PG_DISPLAY_SET *s, PES_BUFFER *p) 00312 { 00313 BITBUFFER bb; 00314 bb_init(&bb, p->buf, p->len); 00315 00316 uint8_t type = bb_read(&bb, 8); 00317 /*uint16_t len = */ bb_read(&bb, 16); 00318 00319 switch (type) { 00320 case PGS_OBJECT: 00321 return _decode_ods(s, &bb, p); 00322 00323 case PGS_PALETTE: 00324 return _decode_pds(s, &bb, p); 00325 00326 case PGS_WINDOW: 00327 return _decode_wds(s, &bb, p); 00328 00329 case PGS_PG_COMPOSITION: 00330 return _decode_pcs(s, &bb, p); 00331 00332 case PGS_IG_COMPOSITION: 00333 return _decode_ics(s, &bb, p); 00334 00335 case PGS_END_OF_DISPLAY: 00336 s->complete = 1; 00337 return 1; 00338 00339 default: 00340 BD_DEBUG(DBG_DECODE | DBG_CRIT, "unknown segment type 0x%x\n", type); 00341 break; 00342 } 00343 00344 return 0; 00345 } 00346 00347 /* 00348 * mpeg-pes interface 00349 */ 00350 00351 int graphics_processor_decode_pes(PG_DISPLAY_SET **s, PES_BUFFER **p, int64_t stc) 00352 { 00353 if (!s) { 00354 return 0; 00355 } 00356 00357 if (*s == NULL) { 00358 *s = calloc(1, sizeof(PG_DISPLAY_SET)); 00359 } 00360 00361 while (*p) { 00362 00363 /* time to decode next segment ? */ 00364 if (stc >= 0 && (*p)->dts > stc) { 00365 GP_TRACE("Segment dts > stc (%"PRId64" > %"PRId64" ; diff %"PRId64")\n", 00366 (*p)->dts, stc, (*p)->dts - stc); 00367 return 0; 00368 } 00369 00370 /* all fragments present ? */ 00371 if (!_join_segment_fragments(*p)) { 00372 GP_TRACE("splitted segment not complete, waiting for next fragment\n"); 00373 return 0; 00374 } 00375 00376 if ((*p)->len <= 2) { 00377 BD_DEBUG(DBG_DECODE, "segment too short, skipping (%d bytes)\n", (*p)->len); 00378 pes_buffer_remove(p, *p); 00379 continue; 00380 } 00381 00382 /* decode segment */ 00383 00384 GP_TRACE("Decoding segment, dts %010"PRId64" pts %010"PRId64" len %d\n", 00385 (*p)->dts, (*p)->pts, (*p)->len); 00386 00387 (*s)->complete = 0; 00388 00389 _decode_segment(*s, *p); 00390 00391 pes_buffer_remove(p, *p); 00392 00393 if ((*s)->complete) { 00394 return 1; 00395 } 00396 00397 } 00398 00399 return 0; 00400 } 00401 00402 /* 00403 * mpeg-ts interface 00404 */ 00405 00406 struct graphics_processor_s { 00407 uint16_t pid; 00408 M2TS_DEMUX *demux; 00409 PES_BUFFER *queue; 00410 }; 00411 00412 GRAPHICS_PROCESSOR *graphics_processor_init(void) 00413 { 00414 GRAPHICS_PROCESSOR *p = calloc(1, sizeof(*p)); 00415 00416 return p; 00417 } 00418 00419 void graphics_processor_free(GRAPHICS_PROCESSOR **p) 00420 { 00421 if (p && *p) { 00422 m2ts_demux_free(&(*p)->demux); 00423 pes_buffer_free(&(*p)->queue); 00424 00425 X_FREE(*p); 00426 } 00427 } 00428 00429 int graphics_processor_decode_ts(GRAPHICS_PROCESSOR *p, 00430 PG_DISPLAY_SET **s, 00431 uint16_t pid, uint8_t *unit, unsigned num_units, 00432 int64_t stc) 00433 { 00434 unsigned ii; 00435 00436 if (pid != p->pid) { 00437 m2ts_demux_free(&p->demux); 00438 pes_buffer_free(&p->queue); 00439 } 00440 if (!p->demux) { 00441 p->demux = m2ts_demux_init(pid); 00442 p->pid = pid; 00443 } 00444 00445 for (ii = 0; ii < num_units; ii++) { 00446 pes_buffer_append(&p->queue, m2ts_demux(p->demux, unit)); 00447 unit += 6144; 00448 } 00449 00450 if (p->queue) { 00451 return graphics_processor_decode_pes(s, &p->queue, stc); 00452 } 00453 00454 return 0; 00455 }
1.7.6.1