You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

136 lines
4.3KB

  1. /*
  2. * AVC helper functions for muxers
  3. * Copyright (c) 2006 Baptiste Coudurier <baptiste.coudurier@smartjog.com>
  4. *
  5. * This file is part of FFmpeg.
  6. *
  7. * FFmpeg 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. * FFmpeg 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 FFmpeg; if not, write to the Free Software
  19. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  20. */
  21. #include "avformat.h"
  22. #include "avio.h"
  23. const uint8_t *ff_avc_find_startcode(const uint8_t *p, const uint8_t *end)
  24. {
  25. const uint8_t *a = p + 4 - ((long)p & 3);
  26. for( end -= 3; p < a && p < end; p++ ) {
  27. if( p[0] == 0 && p[1] == 0 && p[2] == 1 )
  28. return p;
  29. }
  30. for( end -= 3; p < end; p += 4 ) {
  31. uint32_t x = *(const uint32_t*)p;
  32. // if( (x - 0x01000100) & (~x) & 0x80008000 ) // little endian
  33. // if( (x - 0x00010001) & (~x) & 0x00800080 ) // big endian
  34. if( (x - 0x01010101) & (~x) & 0x80808080 ) { // generic
  35. if( p[1] == 0 ) {
  36. if( p[0] == 0 && p[2] == 1 )
  37. return p-1;
  38. if( p[2] == 0 && p[3] == 1 )
  39. return p;
  40. }
  41. if( p[3] == 0 ) {
  42. if( p[2] == 0 && p[4] == 1 )
  43. return p+1;
  44. if( p[4] == 0 && p[5] == 1 )
  45. return p+2;
  46. }
  47. }
  48. }
  49. for( end += 3; p < end; p++ ) {
  50. if( p[0] == 0 && p[1] == 0 && p[2] == 1 )
  51. return p;
  52. }
  53. return end + 3;
  54. }
  55. int ff_avc_parse_nal_units(const uint8_t *buf_in, uint8_t **buf, int *size)
  56. {
  57. ByteIOContext *pb;
  58. const uint8_t *p = buf_in;
  59. const uint8_t *end = p + *size;
  60. const uint8_t *nal_start, *nal_end;
  61. int ret = url_open_dyn_buf(&pb);
  62. if(ret < 0)
  63. return ret;
  64. nal_start = ff_avc_find_startcode(p, end);
  65. while (nal_start < end) {
  66. while(!*(nal_start++));
  67. nal_end = ff_avc_find_startcode(nal_start, end);
  68. put_be32(pb, nal_end - nal_start);
  69. put_buffer(pb, nal_start, nal_end - nal_start);
  70. nal_start = nal_end;
  71. }
  72. av_freep(buf);
  73. *size = url_close_dyn_buf(pb, buf);
  74. return 0;
  75. }
  76. int ff_isom_write_avcc(ByteIOContext *pb, const uint8_t *data, int len)
  77. {
  78. if (len > 6) {
  79. /* check for h264 start code */
  80. if (AV_RB32(data) == 0x00000001) {
  81. uint8_t *buf=NULL, *end, *start;
  82. uint32_t sps_size=0, pps_size=0;
  83. uint8_t *sps=0, *pps=0;
  84. int ret = ff_avc_parse_nal_units(data, &buf, &len);
  85. if (ret < 0)
  86. return ret;
  87. start = buf;
  88. end = buf + len;
  89. /* look for sps and pps */
  90. while (buf < end) {
  91. unsigned int size;
  92. uint8_t nal_type;
  93. size = AV_RB32(buf);
  94. nal_type = buf[4] & 0x1f;
  95. if (nal_type == 7) { /* SPS */
  96. sps = buf + 4;
  97. sps_size = size;
  98. } else if (nal_type == 8) { /* PPS */
  99. pps = buf + 4;
  100. pps_size = size;
  101. }
  102. buf += size + 4;
  103. }
  104. assert(sps);
  105. assert(pps);
  106. put_byte(pb, 1); /* version */
  107. put_byte(pb, sps[1]); /* profile */
  108. put_byte(pb, sps[2]); /* profile compat */
  109. put_byte(pb, sps[3]); /* level */
  110. put_byte(pb, 0xff); /* 6 bits reserved (111111) + 2 bits nal size length - 1 (11) */
  111. put_byte(pb, 0xe1); /* 3 bits reserved (111) + 5 bits number of sps (00001) */
  112. put_be16(pb, sps_size);
  113. put_buffer(pb, sps, sps_size);
  114. put_byte(pb, 1); /* number of pps */
  115. put_be16(pb, pps_size);
  116. put_buffer(pb, pps, pps_size);
  117. av_free(start);
  118. } else {
  119. put_buffer(pb, data, len);
  120. }
  121. }
  122. return 0;
  123. }