|
MythTV
0.26-pre
|
00001 /* 00002 * This file is part of libbluray 00003 * Copyright (C) 2009-2010 John Stebbins 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 "util/macro.h" 00021 #include "file/file.h" 00022 #include "util/bits.h" 00023 #include "clpi_parse.h" 00024 00025 #include <stdlib.h> 00026 #include <string.h> 00027 00028 #define CLPI_SIG1 ('H' << 24 | 'D' << 16 | 'M' << 8 | 'V') 00029 #define CLPI_SIG2A ('0' << 24 | '2' << 16 | '0' << 8 | '0') 00030 #define CLPI_SIG2B ('0' << 24 | '1' << 16 | '0' << 8 | '0') 00031 00032 static int clpi_verbose = 0; 00033 00034 static void 00035 _human_readable_sig(char *sig, uint32_t s1, uint32_t s2) 00036 { 00037 sig[0] = (s1 >> 24) & 0xFF; 00038 sig[1] = (s1 >> 16) & 0xFF; 00039 sig[2] = (s1 >> 8) & 0xFF; 00040 sig[3] = (s1 ) & 0xFF; 00041 sig[4] = (s2 >> 24) & 0xFF; 00042 sig[5] = (s2 >> 16) & 0xFF; 00043 sig[6] = (s2 >> 8) & 0xFF; 00044 sig[7] = (s2 ) & 0xFF; 00045 sig[8] = 0; 00046 } 00047 00048 static int 00049 _parse_stream_attr(BITSTREAM *bits, CLPI_PROG_STREAM *ss) 00050 { 00051 int len, pos; 00052 00053 if (!bs_is_align(bits, 0x07)) { 00054 fprintf(stderr, "_parse_stream_attr: Stream alignment error\n"); 00055 } 00056 00057 len = bs_read(bits, 8); 00058 pos = bs_pos(bits) >> 3; 00059 00060 ss->lang[0] = '\0'; 00061 ss->coding_type = bs_read(bits, 8); 00062 switch (ss->coding_type) { 00063 case 0x01: 00064 case 0x02: 00065 case 0xea: 00066 case 0x1b: 00067 ss->format = bs_read(bits, 4); 00068 ss->rate = bs_read(bits, 4); 00069 ss->aspect = bs_read(bits, 4); 00070 bs_skip(bits, 2); 00071 ss->oc_flag = bs_read(bits, 1); 00072 bs_skip(bits, 1); 00073 break; 00074 00075 case 0x03: 00076 case 0x04: 00077 case 0x80: 00078 case 0x81: 00079 case 0x82: 00080 case 0x83: 00081 case 0x84: 00082 case 0x85: 00083 case 0x86: 00084 case 0xa1: 00085 case 0xa2: 00086 ss->format = bs_read(bits, 4); 00087 ss->rate = bs_read(bits, 4); 00088 bs_read_bytes(bits, ss->lang, 3); 00089 break; 00090 00091 case 0x90: 00092 case 0x91: 00093 case 0xa0: 00094 bs_read_bytes(bits, ss->lang, 3); 00095 break; 00096 00097 case 0x92: 00098 ss->char_code = bs_read(bits, 8); 00099 bs_read_bytes(bits, ss->lang, 3); 00100 break; 00101 00102 default: 00103 fprintf(stderr, "stream attr: unrecognized coding type %02x\n", ss->coding_type); 00104 break; 00105 }; 00106 ss->lang[3] = '\0'; 00107 00108 // Skip over any padding 00109 bs_seek_byte(bits, pos + len); 00110 return 1; 00111 } 00112 00113 static int 00114 _parse_header(BITSTREAM *bits, CLPI_CL *cl) 00115 { 00116 bs_seek_byte(bits, 0); 00117 cl->type_indicator = bs_read(bits, 32); 00118 cl->type_indicator2 = bs_read(bits, 32); 00119 if (cl->type_indicator != CLPI_SIG1 || 00120 (cl->type_indicator2 != CLPI_SIG2A && 00121 cl->type_indicator2 != CLPI_SIG2B)) { 00122 00123 char sig[9]; 00124 char expect[9]; 00125 00126 _human_readable_sig(sig, cl->type_indicator, cl->type_indicator2); 00127 _human_readable_sig(expect, CLPI_SIG1, CLPI_SIG2A); 00128 fprintf(stderr, "failed signature match expected (%s) got (%s)\n", 00129 expect, sig); 00130 return 0; 00131 } 00132 cl->sequence_info_start_addr = bs_read(bits, 32); 00133 cl->program_info_start_addr = bs_read(bits, 32); 00134 cl->cpi_start_addr = bs_read(bits, 32); 00135 cl->clip_mark_start_addr = bs_read(bits, 32); 00136 cl->ext_data_start_addr = bs_read(bits, 32); 00137 return 1; 00138 } 00139 00140 static int 00141 _parse_clipinfo(BITSTREAM *bits, CLPI_CL *cl) 00142 { 00143 int len, pos; 00144 int ii; 00145 00146 bs_seek_byte(bits, 40); 00147 // ClipInfo len 00148 bs_skip(bits, 32); 00149 // reserved 00150 bs_skip(bits, 16); 00151 cl->clip.clip_stream_type = bs_read(bits, 8); 00152 cl->clip.application_type = bs_read(bits, 8); 00153 // skip reserved 31 bits 00154 bs_skip(bits, 31); 00155 cl->clip.is_atc_delta = bs_read(bits, 1); 00156 cl->clip.ts_recording_rate = bs_read(bits, 32); 00157 cl->clip.num_source_packets = bs_read(bits, 32); 00158 00159 // Skip reserved 128 bytes 00160 bs_skip(bits, 128 * 8); 00161 00162 // ts type info block 00163 len = bs_read(bits, 16); 00164 pos = bs_pos(bits) >> 3; 00165 if (len) { 00166 cl->clip.ts_type_info.validity = bs_read(bits, 8); 00167 bs_read_bytes(bits, cl->clip.ts_type_info.format_id, 4); 00168 cl->clip.ts_type_info.format_id[4] = '\0'; 00169 // Seek past the stuff we don't know anything about 00170 bs_seek_byte(bits, pos + len); 00171 } 00172 if (cl->clip.is_atc_delta) { 00173 // Skip reserved bytes 00174 bs_skip(bits, 8); 00175 cl->clip.atc_delta_count = bs_read(bits, 8); 00176 cl->clip.atc_delta = 00177 malloc(cl->clip.atc_delta_count * sizeof(CLPI_ATC_DELTA)); 00178 for (ii = 0; ii < cl->clip.atc_delta_count; ii++) { 00179 cl->clip.atc_delta[ii].delta = bs_read(bits, 32); 00180 bs_read_bytes(bits, cl->clip.atc_delta[ii].file_id, 5); 00181 cl->clip.atc_delta[ii].file_id[5] = '\0'; 00182 bs_read_bytes(bits, cl->clip.atc_delta[ii].file_code, 4); 00183 cl->clip.atc_delta[ii].file_code[4] = '\0'; 00184 bs_skip(bits, 8); 00185 } 00186 } 00187 return 1; 00188 } 00189 00190 static int 00191 _parse_sequence(BITSTREAM *bits, CLPI_CL *cl) 00192 { 00193 int ii, jj; 00194 00195 bs_seek_byte(bits, cl->sequence_info_start_addr); 00196 00197 // Skip the length field, and a reserved byte 00198 bs_skip(bits, 5 * 8); 00199 // Then get the number of sequences 00200 cl->sequence.num_atc_seq = bs_read(bits, 8); 00201 00202 CLPI_ATC_SEQ *atc_seq; 00203 atc_seq = malloc(cl->sequence.num_atc_seq * sizeof(CLPI_ATC_SEQ)); 00204 cl->sequence.atc_seq = atc_seq; 00205 for (ii = 0; ii < cl->sequence.num_atc_seq; ii++) { 00206 atc_seq[ii].spn_atc_start = bs_read(bits, 32); 00207 atc_seq[ii].num_stc_seq = bs_read(bits, 8); 00208 atc_seq[ii].offset_stc_id = bs_read(bits, 8); 00209 00210 CLPI_STC_SEQ *stc_seq; 00211 stc_seq = malloc(atc_seq[ii].num_stc_seq * sizeof(CLPI_STC_SEQ)); 00212 atc_seq[ii].stc_seq = stc_seq; 00213 for (jj = 0; jj < atc_seq[ii].num_stc_seq; jj++) { 00214 stc_seq[jj].pcr_pid = bs_read(bits, 16); 00215 stc_seq[jj].spn_stc_start = bs_read(bits, 32); 00216 stc_seq[jj].presentation_start_time = bs_read(bits, 32); 00217 stc_seq[jj].presentation_end_time = bs_read(bits, 32); 00218 } 00219 } 00220 return 1; 00221 } 00222 00223 static int 00224 _parse_program(BITSTREAM *bits, CLPI_CL *cl) 00225 { 00226 int ii, jj; 00227 00228 bs_seek_byte(bits, cl->program_info_start_addr); 00229 // Skip the length field, and a reserved byte 00230 bs_skip(bits, 5 * 8); 00231 // Then get the number of sequences 00232 cl->program.num_prog = bs_read(bits, 8); 00233 00234 CLPI_PROG *progs; 00235 progs = malloc(cl->program.num_prog * sizeof(CLPI_PROG)); 00236 cl->program.progs = progs; 00237 for (ii = 0; ii < cl->program.num_prog; ii++) { 00238 progs[ii].spn_program_sequence_start = bs_read(bits, 32); 00239 progs[ii].program_map_pid = bs_read(bits, 16); 00240 progs[ii].num_streams = bs_read(bits, 8); 00241 progs[ii].num_groups = bs_read(bits, 8); 00242 00243 CLPI_PROG_STREAM *ps; 00244 ps = malloc(progs[ii].num_streams * sizeof(CLPI_PROG_STREAM)); 00245 progs[ii].streams = ps; 00246 for (jj = 0; jj < progs[ii].num_streams; jj++) { 00247 ps[jj].pid = bs_read(bits, 16); 00248 if (!_parse_stream_attr(bits, &ps[jj])) { 00249 return 0; 00250 } 00251 } 00252 } 00253 return 1; 00254 } 00255 00256 static int 00257 _parse_ep_map_stream(BITSTREAM *bits, CLPI_EP_MAP_ENTRY *ee) 00258 { 00259 uint32_t fine_start; 00260 int ii; 00261 CLPI_EP_COARSE * coarse; 00262 CLPI_EP_FINE * fine; 00263 00264 bs_seek_byte(bits, ee->ep_map_stream_start_addr); 00265 fine_start = bs_read(bits, 32); 00266 00267 coarse = malloc(ee->num_ep_coarse * sizeof(CLPI_EP_COARSE)); 00268 ee->coarse = coarse; 00269 for (ii = 0; ii < ee->num_ep_coarse; ii++) { 00270 coarse[ii].ref_ep_fine_id = bs_read(bits, 18); 00271 coarse[ii].pts_ep = bs_read(bits, 14); 00272 coarse[ii].spn_ep = bs_read(bits, 32); 00273 } 00274 00275 bs_seek_byte(bits, ee->ep_map_stream_start_addr+fine_start); 00276 00277 fine = malloc(ee->num_ep_fine * sizeof(CLPI_EP_FINE)); 00278 ee->fine = fine; 00279 for (ii = 0; ii < ee->num_ep_fine; ii++) { 00280 fine[ii].is_angle_change_point = bs_read(bits, 1); 00281 fine[ii].i_end_position_offset = bs_read(bits, 3); 00282 fine[ii].pts_ep = bs_read(bits, 11); 00283 fine[ii].spn_ep = bs_read(bits, 17); 00284 } 00285 return 1; 00286 } 00287 00288 static int 00289 _parse_cpi(BITSTREAM *bits, CLPI_CL *cl) 00290 { 00291 int ii; 00292 uint32_t ep_map_pos, len; 00293 00294 bs_seek_byte(bits, cl->cpi_start_addr); 00295 len = bs_read(bits, 32); 00296 if (len == 0) { 00297 return 1; 00298 } 00299 00300 bs_skip(bits, 12); 00301 cl->cpi.type = bs_read(bits, 4); 00302 ep_map_pos = bs_pos(bits) >> 3; 00303 00304 // EP Map starts here 00305 bs_skip(bits, 8); 00306 cl->cpi.num_stream_pid = bs_read(bits, 8); 00307 00308 CLPI_EP_MAP_ENTRY *entry; 00309 entry = malloc(cl->cpi.num_stream_pid * sizeof(CLPI_EP_MAP_ENTRY)); 00310 cl->cpi.entry = entry; 00311 for (ii = 0; ii < cl->cpi.num_stream_pid; ii++) { 00312 entry[ii].pid = bs_read(bits, 16); 00313 bs_skip(bits, 10); 00314 entry[ii].ep_stream_type = bs_read(bits, 4); 00315 entry[ii].num_ep_coarse = bs_read(bits, 16); 00316 entry[ii].num_ep_fine = bs_read(bits, 18); 00317 entry[ii].ep_map_stream_start_addr = bs_read(bits, 32) + ep_map_pos; 00318 } 00319 for (ii = 0; ii < cl->cpi.num_stream_pid; ii++) { 00320 _parse_ep_map_stream(bits, &cl->cpi.entry[ii]); 00321 } 00322 return 1; 00323 } 00324 00325 static uint32_t 00326 _find_stc_spn(CLPI_CL *cl, uint8_t stc_id) 00327 { 00328 int ii; 00329 CLPI_ATC_SEQ *atc; 00330 00331 for (ii = 0; ii < cl->sequence.num_atc_seq; ii++) { 00332 atc = &cl->sequence.atc_seq[ii]; 00333 if (stc_id < atc->offset_stc_id + atc->num_stc_seq) { 00334 return atc->stc_seq[stc_id - atc->offset_stc_id].spn_stc_start; 00335 } 00336 } 00337 return 0; 00338 } 00339 00340 // Looks up the start packet number for the timestamp 00341 // Returns the spn for the entry that is closest to but 00342 // before the given timestamp 00343 uint32_t 00344 clpi_lookup_spn(CLPI_CL *cl, uint32_t timestamp, int before, uint8_t stc_id) 00345 { 00346 CLPI_EP_MAP_ENTRY *entry; 00347 CLPI_CPI *cpi = &cl->cpi; 00348 int ii, jj; 00349 uint32_t coarse_pts, pts; // 45khz timestamps 00350 uint32_t spn, coarse_spn, stc_spn; 00351 int start, end; 00352 int ref; 00353 00354 if (cpi->num_stream_pid < 1 || !cpi->entry) { 00355 if (before) { 00356 return 0; 00357 } 00358 return cl->clip.num_source_packets; 00359 } 00360 00361 // Assumes that there is only one pid of interest 00362 entry = &cpi->entry[0]; 00363 00364 // Use sequence info to find spn_stc_start before doing 00365 // PTS search. The spn_stc_start defines the point in 00366 // the EP map to start searching. 00367 stc_spn = _find_stc_spn(cl, stc_id); 00368 for (ii = 0; ii < entry->num_ep_coarse; ii++) { 00369 ref = entry->coarse[ii].ref_ep_fine_id; 00370 if (entry->coarse[ii].spn_ep >= stc_spn) { 00371 // The desired starting point is either after this point 00372 // or in the middle of the previous coarse entry 00373 break; 00374 } 00375 } 00376 if (ii >= entry->num_ep_coarse) { 00377 return cl->clip.num_source_packets; 00378 } 00379 pts = ((uint64_t)(entry->coarse[ii].pts_ep & ~0x01) << 18) + 00380 ((uint64_t)entry->fine[ref].pts_ep << 8); 00381 if (pts > timestamp && ii) { 00382 // The starting point and desired PTS is in the previous coarse entry 00383 ii--; 00384 coarse_pts = (uint32_t)(entry->coarse[ii].pts_ep & ~0x01) << 18; 00385 coarse_spn = entry->coarse[ii].spn_ep; 00386 start = entry->coarse[ii].ref_ep_fine_id; 00387 end = entry->coarse[ii+1].ref_ep_fine_id; 00388 // Find a fine entry that has bothe spn > stc_spn and ptc > timestamp 00389 for (jj = start; jj < end; jj++) { 00390 00391 pts = coarse_pts + ((uint32_t)entry->fine[jj].pts_ep << 8); 00392 spn = (coarse_spn & ~0x1FFFF) + entry->fine[jj].spn_ep; 00393 if (stc_spn >= spn && pts > timestamp) 00394 break; 00395 } 00396 goto done; 00397 } 00398 00399 // If we've gotten this far, the desired timestamp is somewhere 00400 // after the coarse entry we found the stc_spn in. 00401 start = ii; 00402 for (ii = start; ii < entry->num_ep_coarse; ii++) { 00403 ref = entry->coarse[ii].ref_ep_fine_id; 00404 pts = ((uint64_t)(entry->coarse[ii].pts_ep & ~0x01) << 18) + 00405 ((uint64_t)entry->fine[ref].pts_ep << 8); 00406 if (pts > timestamp) { 00407 break; 00408 } 00409 } 00410 // If the timestamp is before the first entry, then return 00411 // the beginning of the clip 00412 if (ii == 0) { 00413 return 0; 00414 } 00415 ii--; 00416 coarse_pts = (uint32_t)(entry->coarse[ii].pts_ep & ~0x01) << 18; 00417 start = entry->coarse[ii].ref_ep_fine_id; 00418 if (ii < entry->num_ep_coarse - 1) { 00419 end = entry->coarse[ii+1].ref_ep_fine_id; 00420 } else { 00421 end = entry->num_ep_fine; 00422 } 00423 for (jj = start; jj < end; jj++) { 00424 00425 pts = coarse_pts + ((uint32_t)entry->fine[jj].pts_ep << 8); 00426 if (pts > timestamp) 00427 break; 00428 } 00429 00430 done: 00431 if (before) { 00432 jj--; 00433 } 00434 if (jj == end) { 00435 ii++; 00436 if (ii >= entry->num_ep_coarse) { 00437 // End of file 00438 return cl->clip.num_source_packets; 00439 } 00440 jj = entry->coarse[ii].ref_ep_fine_id; 00441 } 00442 spn = (entry->coarse[ii].spn_ep & ~0x1FFFF) + entry->fine[jj].spn_ep; 00443 return spn; 00444 } 00445 00446 // Looks up the start packet number that is closest to the requested packet 00447 // Returns the spn for the entry that is closest to but 00448 // before the given packet 00449 uint32_t 00450 clpi_access_point(CLPI_CL *cl, uint32_t pkt, int next, int angle_change, uint32_t *time) 00451 { 00452 CLPI_EP_MAP_ENTRY *entry; 00453 CLPI_CPI *cpi = &cl->cpi; 00454 int ii, jj; 00455 uint32_t coarse_spn, spn; 00456 int start, end; 00457 int ref; 00458 00459 // Assumes that there is only one pid of interest 00460 entry = &cpi->entry[0]; 00461 00462 for (ii = 0; ii < entry->num_ep_coarse; ii++) { 00463 ref = entry->coarse[ii].ref_ep_fine_id; 00464 spn = (entry->coarse[ii].spn_ep & ~0x1FFFF) + entry->fine[ref].spn_ep; 00465 if (spn > pkt) { 00466 break; 00467 } 00468 } 00469 // If the timestamp is before the first entry, then return 00470 // the beginning of the clip 00471 if (ii == 0) { 00472 *time = 0; 00473 return 0; 00474 } 00475 ii--; 00476 coarse_spn = (entry->coarse[ii].spn_ep & ~0x1FFFF); 00477 start = entry->coarse[ii].ref_ep_fine_id; 00478 if (ii < entry->num_ep_coarse - 1) { 00479 end = entry->coarse[ii+1].ref_ep_fine_id; 00480 } else { 00481 end = entry->num_ep_fine; 00482 } 00483 for (jj = start; jj < end; jj++) { 00484 00485 spn = coarse_spn + entry->fine[jj].spn_ep; 00486 if (spn >= pkt) { 00487 break; 00488 } 00489 } 00490 if (jj == end && next) { 00491 ii++; 00492 jj = 0; 00493 } else if (spn != pkt && !next) { 00494 jj--; 00495 } 00496 if (ii == entry->num_ep_coarse) { 00497 *time = 0; 00498 return cl->clip.num_source_packets; 00499 } 00500 coarse_spn = (entry->coarse[ii].spn_ep & ~0x1FFFF); 00501 if (angle_change) { 00502 // Keep looking till there's an angle change point 00503 for (; jj < end; jj++) { 00504 00505 if (entry->fine[jj].is_angle_change_point) { 00506 *time = ((uint64_t)(entry->coarse[ii].pts_ep & ~0x01) << 18) + 00507 ((uint64_t)entry->fine[jj].pts_ep << 8); 00508 return coarse_spn + entry->fine[jj].spn_ep; 00509 } 00510 } 00511 for (ii++; ii < entry->num_ep_coarse; ii++) { 00512 start = entry->coarse[ii].ref_ep_fine_id; 00513 if (ii < entry->num_ep_coarse - 1) { 00514 end = entry->coarse[ii+1].ref_ep_fine_id; 00515 } else { 00516 end = entry->num_ep_fine; 00517 } 00518 for (jj = start; jj < end; jj++) { 00519 00520 if (entry->fine[jj].is_angle_change_point) { 00521 *time = ((uint64_t)(entry->coarse[ii].pts_ep & ~0x01) << 18) + 00522 ((uint64_t)entry->fine[jj].pts_ep << 8); 00523 return coarse_spn + entry->fine[jj].spn_ep; 00524 } 00525 } 00526 } 00527 *time = 0; 00528 return cl->clip.num_source_packets; 00529 } 00530 *time = ((uint64_t)(entry->coarse[ii].pts_ep & ~0x01) << 18) + 00531 ((uint64_t)entry->fine[jj].pts_ep << 8); 00532 return coarse_spn + entry->fine[jj].spn_ep; 00533 } 00534 00535 void 00536 clpi_free(CLPI_CL *cl) 00537 { 00538 int ii; 00539 00540 if (cl == NULL) { 00541 return; 00542 } 00543 if (cl->clip.atc_delta != NULL) { 00544 X_FREE(cl->clip.atc_delta); 00545 } 00546 for (ii = 0; ii < cl->sequence.num_atc_seq; ii++) { 00547 if (cl->sequence.atc_seq[ii].stc_seq != NULL) { 00548 X_FREE(cl->sequence.atc_seq[ii].stc_seq); 00549 } 00550 } 00551 if (cl->sequence.atc_seq != NULL) { 00552 X_FREE(cl->sequence.atc_seq); 00553 } 00554 00555 for (ii = 0; ii < cl->program.num_prog; ii++) { 00556 if (cl->program.progs[ii].streams != NULL) { 00557 X_FREE(cl->program.progs[ii].streams); 00558 } 00559 } 00560 if (cl->program.progs != NULL) { 00561 X_FREE(cl->program.progs); 00562 } 00563 00564 for (ii = 0; ii < cl->cpi.num_stream_pid; ii++) { 00565 if (cl->cpi.entry[ii].coarse != NULL) { 00566 X_FREE(cl->cpi.entry[ii].coarse); 00567 } 00568 if (cl->cpi.entry[ii].fine != NULL) { 00569 X_FREE(cl->cpi.entry[ii].fine); 00570 } 00571 } 00572 if (cl->cpi.entry != NULL) { 00573 X_FREE(cl->cpi.entry); 00574 } 00575 X_FREE(cl); 00576 } 00577 00578 CLPI_CL* 00579 clpi_parse(char *path, int verbose) 00580 { 00581 BITSTREAM bits; 00582 BD_FILE_H *fp; 00583 CLPI_CL *cl; 00584 00585 clpi_verbose = verbose; 00586 00587 cl = calloc(1, sizeof(CLPI_CL)); 00588 if (cl == NULL) { 00589 return NULL; 00590 } 00591 00592 fp = file_open(path, "rb"); 00593 if (fp == NULL) { 00594 fprintf(stderr, "Failed to open %s\n", path); 00595 X_FREE(cl); 00596 return NULL; 00597 } 00598 00599 bs_init(&bits, fp); 00600 if (!_parse_header(&bits, cl)) { 00601 file_close(fp); 00602 clpi_free(cl); 00603 return NULL; 00604 } 00605 if (!_parse_clipinfo(&bits, cl)) { 00606 file_close(fp); 00607 clpi_free(cl); 00608 return NULL; 00609 } 00610 if (!_parse_sequence(&bits, cl)) { 00611 file_close(fp); 00612 clpi_free(cl); 00613 return NULL; 00614 } 00615 if (!_parse_program(&bits, cl)) { 00616 file_close(fp); 00617 clpi_free(cl); 00618 return NULL; 00619 } 00620 if (!_parse_cpi(&bits, cl)) { 00621 file_close(fp); 00622 clpi_free(cl); 00623 return NULL; 00624 } 00625 file_close(fp); 00626 return cl; 00627 } 00628 00629 CLPI_CL* 00630 clpi_copy(CLPI_CL* dest_cl, CLPI_CL* src_cl) 00631 { 00632 int ii, jj; 00633 if (dest_cl && src_cl) { 00634 dest_cl->clip.clip_stream_type = src_cl->clip.clip_stream_type; 00635 dest_cl->clip.application_type = src_cl->clip.application_type; 00636 dest_cl->clip.is_atc_delta = src_cl->clip.is_atc_delta; 00637 dest_cl->clip.atc_delta_count = src_cl->clip.atc_delta_count; 00638 dest_cl->clip.ts_recording_rate = src_cl->clip.ts_recording_rate; 00639 dest_cl->clip.num_source_packets = src_cl->clip.num_source_packets; 00640 dest_cl->clip.ts_type_info.validity = src_cl->clip.ts_type_info.validity; 00641 memcpy(dest_cl->clip.ts_type_info.format_id, src_cl->clip.ts_type_info.format_id, 5); 00642 dest_cl->clip.atc_delta = malloc(src_cl->clip.atc_delta_count * sizeof(CLPI_ATC_DELTA)); 00643 for (ii = 0; ii < src_cl->clip.atc_delta_count; ii++) { 00644 dest_cl->clip.atc_delta[ii].delta = src_cl->clip.atc_delta[ii].delta; 00645 memcpy(dest_cl->clip.atc_delta[ii].file_id, src_cl->clip.atc_delta[ii].file_id, 6); 00646 memcpy(dest_cl->clip.atc_delta[ii].file_code, src_cl->clip.atc_delta[ii].file_code, 5); 00647 } 00648 00649 dest_cl->sequence.num_atc_seq = src_cl->sequence.num_atc_seq; 00650 dest_cl->sequence.atc_seq = malloc(src_cl->sequence.num_atc_seq * sizeof(CLPI_ATC_SEQ)); 00651 for (ii = 0; ii < src_cl->sequence.num_atc_seq; ii++) { 00652 dest_cl->sequence.atc_seq[ii].spn_atc_start = src_cl->sequence.atc_seq[ii].spn_atc_start; 00653 dest_cl->sequence.atc_seq[ii].offset_stc_id = src_cl->sequence.atc_seq[ii].offset_stc_id; 00654 dest_cl->sequence.atc_seq[ii].num_stc_seq = src_cl->sequence.atc_seq[ii].num_stc_seq; 00655 dest_cl->sequence.atc_seq[ii].stc_seq = malloc(src_cl->sequence.atc_seq[ii].num_stc_seq * sizeof(CLPI_STC_SEQ)); 00656 for (jj = 0; jj < src_cl->sequence.atc_seq[ii].num_stc_seq; jj++) { 00657 dest_cl->sequence.atc_seq[ii].stc_seq[jj].spn_stc_start = src_cl->sequence.atc_seq[ii].stc_seq[jj].spn_stc_start; 00658 dest_cl->sequence.atc_seq[ii].stc_seq[jj].pcr_pid = src_cl->sequence.atc_seq[ii].stc_seq[jj].pcr_pid; 00659 dest_cl->sequence.atc_seq[ii].stc_seq[jj].presentation_start_time = src_cl->sequence.atc_seq[ii].stc_seq[jj].presentation_start_time; 00660 dest_cl->sequence.atc_seq[ii].stc_seq[jj].presentation_end_time = src_cl->sequence.atc_seq[ii].stc_seq[jj].presentation_end_time; 00661 } 00662 } 00663 00664 dest_cl->program.num_prog = src_cl->program.num_prog; 00665 dest_cl->program.progs = malloc(src_cl->program.num_prog * sizeof(CLPI_PROG)); 00666 for (ii = 0; ii < src_cl->program.num_prog; ii++) { 00667 dest_cl->program.progs[ii].spn_program_sequence_start = src_cl->program.progs[ii].spn_program_sequence_start; 00668 dest_cl->program.progs[ii].program_map_pid = src_cl->program.progs[ii].program_map_pid; 00669 dest_cl->program.progs[ii].num_streams = src_cl->program.progs[ii].num_streams; 00670 dest_cl->program.progs[ii].num_groups = src_cl->program.progs[ii].num_groups; 00671 dest_cl->program.progs[ii].streams = malloc(src_cl->program.progs[ii].num_streams * sizeof(CLPI_PROG_STREAM)); 00672 for (jj = 0; jj < src_cl->program.progs[ii].num_streams; jj++) { 00673 dest_cl->program.progs[ii].streams[jj].coding_type = src_cl->program.progs[ii].streams[jj].coding_type; 00674 dest_cl->program.progs[ii].streams[jj].pid = src_cl->program.progs[ii].streams[jj].pid; 00675 dest_cl->program.progs[ii].streams[jj].format = src_cl->program.progs[ii].streams[jj].format; 00676 dest_cl->program.progs[ii].streams[jj].rate = src_cl->program.progs[ii].streams[jj].rate; 00677 dest_cl->program.progs[ii].streams[jj].aspect = src_cl->program.progs[ii].streams[jj].aspect; 00678 dest_cl->program.progs[ii].streams[jj].oc_flag = src_cl->program.progs[ii].streams[jj].oc_flag; 00679 dest_cl->program.progs[ii].streams[jj].char_code = src_cl->program.progs[ii].streams[jj].char_code; 00680 memcpy(dest_cl->program.progs[ii].streams[jj].lang,src_cl->program.progs[ii].streams[jj].lang,4); 00681 } 00682 } 00683 00684 dest_cl->cpi.num_stream_pid = src_cl->cpi.num_stream_pid; 00685 dest_cl->cpi.entry = malloc(src_cl->cpi.num_stream_pid * sizeof(CLPI_EP_MAP_ENTRY)); 00686 for (ii = 0; ii < dest_cl->cpi.num_stream_pid; ii++) { 00687 dest_cl->cpi.entry[ii].pid = src_cl->cpi.entry[ii].pid; 00688 dest_cl->cpi.entry[ii].ep_stream_type = src_cl->cpi.entry[ii].ep_stream_type; 00689 dest_cl->cpi.entry[ii].num_ep_coarse = src_cl->cpi.entry[ii].num_ep_coarse; 00690 dest_cl->cpi.entry[ii].num_ep_fine = src_cl->cpi.entry[ii].num_ep_fine; 00691 dest_cl->cpi.entry[ii].ep_map_stream_start_addr = src_cl->cpi.entry[ii].ep_map_stream_start_addr; 00692 dest_cl->cpi.entry[ii].coarse = malloc(src_cl->cpi.entry[ii].num_ep_coarse * sizeof(CLPI_EP_COARSE)); 00693 for (jj = 0; jj < src_cl->cpi.entry[ii].num_ep_coarse; jj++) { 00694 dest_cl->cpi.entry[ii].coarse[jj].ref_ep_fine_id = src_cl->cpi.entry[ii].coarse[jj].ref_ep_fine_id; 00695 dest_cl->cpi.entry[ii].coarse[jj].pts_ep = src_cl->cpi.entry[ii].coarse[jj].pts_ep; 00696 dest_cl->cpi.entry[ii].coarse[jj].spn_ep = src_cl->cpi.entry[ii].coarse[jj].spn_ep; 00697 } 00698 dest_cl->cpi.entry[ii].fine = malloc(src_cl->cpi.entry[ii].num_ep_fine * sizeof(CLPI_EP_FINE)); 00699 for (jj = 0; jj < src_cl->cpi.entry[ii].num_ep_fine; jj++) { 00700 dest_cl->cpi.entry[ii].fine[jj].is_angle_change_point = src_cl->cpi.entry[ii].fine[jj].is_angle_change_point; 00701 dest_cl->cpi.entry[ii].fine[jj].i_end_position_offset = src_cl->cpi.entry[ii].fine[jj].i_end_position_offset; 00702 dest_cl->cpi.entry[ii].fine[jj].pts_ep = src_cl->cpi.entry[ii].fine[jj].pts_ep; 00703 dest_cl->cpi.entry[ii].fine[jj].spn_ep = src_cl->cpi.entry[ii].fine[jj].spn_ep; 00704 } 00705 } 00706 return dest_cl; 00707 } 00708 clpi_free(dest_cl); 00709 return NULL; 00710 }
1.7.6.1