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