00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "libavutil/intreadwrite.h"
00023 #include "avformat.h"
00024 #include "avio.h"
00025
00026 const uint8_t *ff_avc_find_startcode(const uint8_t *p, const uint8_t *end)
00027 {
00028 const uint8_t *a = p + 4 - ((long)p & 3);
00029
00030 for( end -= 3; p < a && p < end; p++ ) {
00031 if( p[0] == 0 && p[1] == 0 && p[2] == 1 )
00032 return p;
00033 }
00034
00035 for( end -= 3; p < end; p += 4 ) {
00036 uint32_t x = *(const uint32_t*)p;
00037
00038
00039 if( (x - 0x01010101) & (~x) & 0x80808080 ) {
00040 if( p[1] == 0 ) {
00041 if( p[0] == 0 && p[2] == 1 )
00042 return p-1;
00043 if( p[2] == 0 && p[3] == 1 )
00044 return p;
00045 }
00046 if( p[3] == 0 ) {
00047 if( p[2] == 0 && p[4] == 1 )
00048 return p+1;
00049 if( p[4] == 0 && p[5] == 1 )
00050 return p+2;
00051 }
00052 }
00053 }
00054
00055 for( end += 3; p < end; p++ ) {
00056 if( p[0] == 0 && p[1] == 0 && p[2] == 1 )
00057 return p;
00058 }
00059
00060 return end + 3;
00061 }
00062
00063 int ff_avc_parse_nal_units(ByteIOContext *pb, const uint8_t *buf_in, int size)
00064 {
00065 const uint8_t *p = buf_in;
00066 const uint8_t *end = p + size;
00067 const uint8_t *nal_start, *nal_end;
00068
00069 size = 0;
00070 nal_start = ff_avc_find_startcode(p, end);
00071 while (nal_start < end) {
00072 while(!*(nal_start++));
00073 nal_end = ff_avc_find_startcode(nal_start, end);
00074 put_be32(pb, nal_end - nal_start);
00075 put_buffer(pb, nal_start, nal_end - nal_start);
00076 size += 4 + nal_end - nal_start;
00077 nal_start = nal_end;
00078 }
00079 return size;
00080 }
00081
00082 int ff_avc_parse_nal_units_buf(const uint8_t *buf_in, uint8_t **buf, int *size)
00083 {
00084 ByteIOContext *pb;
00085 int ret = url_open_dyn_buf(&pb);
00086 if(ret < 0)
00087 return ret;
00088
00089 ff_avc_parse_nal_units(pb, buf_in, *size);
00090
00091 av_freep(buf);
00092 *size = url_close_dyn_buf(pb, buf);
00093 return 0;
00094 }
00095
00096 int ff_isom_write_avcc(ByteIOContext *pb, const uint8_t *data, int len)
00097 {
00098 if (len > 6) {
00099
00100 if (AV_RB32(data) == 0x00000001 ||
00101 AV_RB24(data) == 0x000001) {
00102 uint8_t *buf=NULL, *end, *start;
00103 uint32_t sps_size=0, pps_size=0;
00104 uint8_t *sps=0, *pps=0;
00105
00106 int ret = ff_avc_parse_nal_units_buf(data, &buf, &len);
00107 if (ret < 0)
00108 return ret;
00109 start = buf;
00110 end = buf + len;
00111
00112
00113 while (buf < end) {
00114 unsigned int size;
00115 uint8_t nal_type;
00116 size = AV_RB32(buf);
00117 nal_type = buf[4] & 0x1f;
00118 if (nal_type == 7) {
00119 sps = buf + 4;
00120 sps_size = size;
00121 } else if (nal_type == 8) {
00122 pps = buf + 4;
00123 pps_size = size;
00124 }
00125 buf += size + 4;
00126 }
00127 assert(sps);
00128 assert(pps);
00129
00130 put_byte(pb, 1);
00131 put_byte(pb, sps[1]);
00132 put_byte(pb, sps[2]);
00133 put_byte(pb, sps[3]);
00134 put_byte(pb, 0xff);
00135 put_byte(pb, 0xe1);
00136
00137 put_be16(pb, sps_size);
00138 put_buffer(pb, sps, sps_size);
00139 put_byte(pb, 1);
00140 put_be16(pb, pps_size);
00141 put_buffer(pb, pps, pps_size);
00142 av_free(start);
00143 } else {
00144 put_buffer(pb, data, len);
00145 }
00146 }
00147 return 0;
00148 }