No puede seleccionar más de 25 temas Los temas deben comenzar con una letra o número, pueden incluir guiones ('-') y pueden tener hasta 35 caracteres de largo.

78 líneas
3.1KB

  1. #include "mov-internal.h"
  2. #include <assert.h>
  3. #include <stdlib.h>
  4. #include <string.h>
  5. #include <errno.h>
  6. // http://www.opus-codec.org/docs/opus_in_isobmff.html
  7. // 4.3.2 Opus Specific Box
  8. /*
  9. class ChannelMappingTable (unsigned int(8) OutputChannelCount){
  10. unsigned int(8) StreamCount;
  11. unsigned int(8) CoupledCount;
  12. unsigned int(8 * OutputChannelCount) ChannelMapping;
  13. }
  14. aligned(8) class OpusSpecificBox extends Box('dOps'){
  15. unsigned int(8) Version;
  16. unsigned int(8) OutputChannelCount;
  17. unsigned int(16) PreSkip;
  18. unsigned int(32) InputSampleRate;
  19. signed int(16) OutputGain;
  20. unsigned int(8) ChannelMappingFamily;
  21. if (ChannelMappingFamily != 0) {
  22. ChannelMappingTable(OutputChannelCount);
  23. }
  24. }
  25. */
  26. int mov_read_dops(struct mov_t* mov, const struct mov_box_t* box)
  27. {
  28. struct mov_track_t* track = mov->track;
  29. struct mov_sample_entry_t* entry = track->stsd.current;
  30. if(box->size >= 10)
  31. {
  32. if (entry->extra_data_size < box->size + 8)
  33. {
  34. void* p = realloc(entry->extra_data, (size_t)box->size + 8);
  35. if (NULL == p) return -ENOMEM;
  36. entry->extra_data = p;
  37. }
  38. memcpy(entry->extra_data, "OpusHead", 8);
  39. entry->extra_data[8] = 1; // OpusHead version
  40. mov_buffer_r8(&mov->io); // version 0
  41. entry->extra_data[9] = mov_buffer_r8(&mov->io); // channel
  42. entry->extra_data[11] = mov_buffer_r8(&mov->io); // PreSkip (MSB -> LSB)
  43. entry->extra_data[10] = mov_buffer_r8(&mov->io);
  44. entry->extra_data[15] = mov_buffer_r8(&mov->io); // InputSampleRate (LSB -> MSB)
  45. entry->extra_data[14] = mov_buffer_r8(&mov->io);
  46. entry->extra_data[13] = mov_buffer_r8(&mov->io);
  47. entry->extra_data[12] = mov_buffer_r8(&mov->io);
  48. entry->extra_data[17] = mov_buffer_r8(&mov->io); // OutputGain (LSB -> MSB)
  49. entry->extra_data[16] = mov_buffer_r8(&mov->io);
  50. mov_buffer_read(&mov->io, entry->extra_data + 18, (size_t)box->size - 10);
  51. entry->extra_data_size = (int)box->size + 8;
  52. }
  53. return mov_buffer_error(&mov->io);
  54. }
  55. size_t mov_write_dops(const struct mov_t* mov)
  56. {
  57. const struct mov_track_t* track = mov->track;
  58. const struct mov_sample_entry_t* entry = track->stsd.current;
  59. if (entry->extra_data_size < 18)
  60. return 0;
  61. assert(0 == memcmp(entry->extra_data, "OpusHead", 8));
  62. mov_buffer_w32(&mov->io, entry->extra_data_size); /* size */
  63. mov_buffer_write(&mov->io, "dOps", 4);
  64. mov_buffer_w8(&mov->io, 0); // The Version field shall be set to 0.
  65. mov_buffer_w8(&mov->io, entry->extra_data[9]); // channel count
  66. mov_buffer_w16(&mov->io, (entry->extra_data[11]<<8) | entry->extra_data[10]); // PreSkip (LSB -> MSB)
  67. mov_buffer_w32(&mov->io, (entry->extra_data[15]<<8) | (entry->extra_data[14]<<8) | (entry->extra_data[13]<<8) | entry->extra_data[12]); // InputSampleRate (LSB -> MSB)
  68. mov_buffer_w16(&mov->io, (entry->extra_data[17]<<8) | entry->extra_data[16]); // OutputGain (LSB -> MSB)
  69. mov_buffer_write(&mov->io, entry->extra_data + 18, entry->extra_data_size - 18);
  70. return entry->extra_data_size;
  71. }