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