odsmt_section.h 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224
  1. /*
  2. * section and descriptor parser
  3. *
  4. * Copyright (C) 2005 Kenneth Aafloy (kenneth@linuxtv.org)
  5. * Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
  6. *
  7. * This library is free software; you can redistribute it and/or
  8. * modify it under the terms of the GNU Lesser General Public
  9. * License as published by the Free Software Foundation; either
  10. * version 2.1 of the License, or (at your option) any later version.
  11. *
  12. * This library is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  15. * Lesser General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU Lesser General Public
  18. * License along with this library; if not, write to the Free Software
  19. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
  20. */
  21. #ifndef _UCSI_MPEG_ODSMT_SECTION_H
  22. #define _UCSI_MPEG_ODSMT_SECTION_H 1
  23. #ifdef __cplusplus
  24. extern "C"
  25. {
  26. #endif
  27. #include <libucsi/section.h>
  28. /**
  29. * mpeg_odsmt_section structure.
  30. */
  31. struct mpeg_odsmt_section {
  32. struct section_ext head;
  33. uint8_t stream_count;
  34. /* stream_count==0 => struct mpeg_odsmt_stream_single streams
  35. stream_count>0 => struct mpeg_odsmt_stream_multi streams[] */
  36. /* uint8_t object_descriptors[] */
  37. } __ucsi_packed;
  38. struct mpeg_odsmt_stream_single
  39. {
  40. uint16_t esid;
  41. uint8_t es_info_length;
  42. /* struct descriptor descriptors[] */
  43. } __ucsi_packed;
  44. struct mpeg_odsmt_stream_multi
  45. {
  46. uint16_t esid;
  47. uint8_t fmc;
  48. uint8_t es_info_length;
  49. /* struct descriptor descriptors[] */
  50. } __ucsi_packed;
  51. /**
  52. * Structure describing the stream information held in an mpeg_odsmt_section.
  53. */
  54. struct mpeg_odsmt_stream {
  55. union {
  56. struct mpeg_odsmt_stream_single single;
  57. struct mpeg_odsmt_stream_multi multi;
  58. } u;
  59. } __ucsi_packed;
  60. /**
  61. * Process an mpeg_odsmt_section.
  62. *
  63. * @param section Pointer to the generic section_ext structure.
  64. * @return Pointer to a mpeg_odsmt_section structure, or NULL on error.
  65. */
  66. extern struct mpeg_odsmt_section *mpeg_odsmt_section_codec(struct section_ext *section);
  67. /**
  68. * Accessor for the PID field of an ODSMT.
  69. *
  70. * @param odsmt odsmt pointer.
  71. * @return The pid.
  72. */
  73. static inline uint16_t mpeg_odsmt_section_pid(struct mpeg_odsmt_section *odsmt)
  74. {
  75. return odsmt->head.table_id_ext & 0x1fff;
  76. }
  77. /**
  78. * Convenience iterator for the streams field of an mpeg_odsmt_section.
  79. *
  80. * @param osdmt Pointer to the mpeg_odsmt_section structure.
  81. * @param pos Variable holding pointer to the current mpeg_odsmt_stream structure.
  82. * @param index Variable holding the stream index.
  83. */
  84. #define mpeg_odsmt_section_streams_for_each(osdmt, pos, index) \
  85. for (index=0, (pos) = mpeg_odsmt_section_streams_first(odsmt); \
  86. (pos); \
  87. (pos) = mpeg_odsmt_section_streams_next(odsmt, pos, ++index))
  88. /**
  89. * Convenience iterator for the descriptors field of an mpeg_odsmt_stream.
  90. *
  91. * @param osdmt Pointer to the mpeg_odsmt_section structure.
  92. * @param stream Pointer to the mpeg_odsmt_stream structure.
  93. * @param pos Variable holding pointer to the current descriptor structure.
  94. */
  95. #define mpeg_odsmt_stream_descriptors_for_each(osdmt, stream, pos) \
  96. for ((pos) = mpeg_odsmt_stream_descriptors_first(odsmt, stream); \
  97. (pos); \
  98. (pos) = mpeg_odsmt_stream_descriptors_next(odsmt, stream, pos))
  99. /**
  100. * Retrieve a pointer to the object_descriptors field of an mpeg_odsmt_section.
  101. *
  102. * @param osdmt Pointer to the mpeg_odsmt_section structure.
  103. * @param len On return, will contain the number of bytes in the object descriptors field.
  104. * @return Pointer to the object_descriptors field, or NULL on error.
  105. */
  106. static inline uint8_t*
  107. mpeg_odsmt_section_object_descriptors(struct mpeg_odsmt_section * odsmt,
  108. size_t* len);
  109. /******************************** PRIVATE CODE ********************************/
  110. static inline struct mpeg_odsmt_stream *
  111. mpeg_odsmt_section_streams_first(struct mpeg_odsmt_section *odsmt)
  112. {
  113. size_t pos = sizeof(struct mpeg_odsmt_section);
  114. if (pos >= section_ext_length(&odsmt->head))
  115. return NULL;
  116. return (struct mpeg_odsmt_stream *) ((uint8_t *) odsmt + pos);
  117. }
  118. static inline struct mpeg_odsmt_stream *
  119. mpeg_odsmt_section_streams_next(struct mpeg_odsmt_section *odsmt,
  120. struct mpeg_odsmt_stream *pos,
  121. int _index)
  122. {
  123. uint8_t *end = (uint8_t*) odsmt + section_ext_length(&odsmt->head);
  124. uint8_t *next;
  125. if (_index > odsmt->stream_count)
  126. return NULL;
  127. next = (uint8_t *) pos + sizeof(struct mpeg_odsmt_stream_multi) +
  128. pos->u.multi.es_info_length;
  129. if (next >= end)
  130. return NULL;
  131. return (struct mpeg_odsmt_stream *) next;
  132. }
  133. static inline struct descriptor *
  134. mpeg_odsmt_stream_descriptors_first(struct mpeg_odsmt_section *odsmt,
  135. struct mpeg_odsmt_stream *stream)
  136. {
  137. if (odsmt->stream_count == 0) {
  138. if (stream->u.single.es_info_length == 0)
  139. return NULL;
  140. return (struct descriptor *)
  141. ((uint8_t*) stream + sizeof(struct mpeg_odsmt_stream_single));
  142. } else {
  143. if (stream->u.multi.es_info_length == 0)
  144. return NULL;
  145. return (struct descriptor *)
  146. ((uint8_t*) stream + sizeof(struct mpeg_odsmt_stream_multi));
  147. }
  148. }
  149. static inline struct descriptor *
  150. mpeg_odsmt_stream_descriptors_next(struct mpeg_odsmt_section *odsmt,
  151. struct mpeg_odsmt_stream *stream,
  152. struct descriptor* pos)
  153. {
  154. if (odsmt->stream_count == 0) {
  155. return next_descriptor((uint8_t *) stream + sizeof(struct mpeg_odsmt_stream_single),
  156. stream->u.single.es_info_length,
  157. pos);
  158. } else {
  159. return next_descriptor((uint8_t *) stream + sizeof(struct mpeg_odsmt_stream_multi),
  160. stream->u.multi.es_info_length,
  161. pos);
  162. }
  163. }
  164. static inline uint8_t*
  165. mpeg_odsmt_section_object_descriptors(struct mpeg_odsmt_section * odsmt,
  166. size_t* len)
  167. {
  168. struct mpeg_odsmt_stream* pos;
  169. size_t size = sizeof(struct mpeg_odsmt_section);
  170. int _index;
  171. mpeg_odsmt_section_streams_for_each(odsmt, pos, _index) {
  172. if (odsmt->stream_count == 0)
  173. size += sizeof(struct mpeg_odsmt_stream_single) +
  174. pos->u.single.es_info_length;
  175. else
  176. size += sizeof(struct mpeg_odsmt_stream_multi) +
  177. pos->u.multi.es_info_length;
  178. }
  179. *len = section_ext_length(&odsmt->head) - size;
  180. return (uint8_t*) odsmt + size;
  181. }
  182. #ifdef __cplusplus
  183. }
  184. #endif
  185. #endif