Make movenc use this function instead of the current custom
conversion function.
Signed-off-by: Martin Storsjö <martin@martin.st>
... | ... |
@@ -160,3 +160,34 @@ int ff_isom_write_avcc(AVIOContext *pb, const uint8_t *data, int len) |
160 | 160 |
} |
161 | 161 |
return 0; |
162 | 162 |
} |
163 |
+ |
|
164 |
+int ff_avc_write_annexb_extradata(const uint8_t *in, uint8_t **buf, int *size) |
|
165 |
+{ |
|
166 |
+ uint16_t sps_size, pps_size; |
|
167 |
+ uint8_t *out; |
|
168 |
+ int out_size; |
|
169 |
+ |
|
170 |
+ *buf = NULL; |
|
171 |
+ if (*size >= 4 && (AV_RB32(in) == 0x00000001 || AV_RB24(in) == 0x000001)) |
|
172 |
+ return 0; |
|
173 |
+ if (*size < 11 || in[0] != 1) |
|
174 |
+ return AVERROR_INVALIDDATA; |
|
175 |
+ |
|
176 |
+ sps_size = AV_RB16(&in[6]); |
|
177 |
+ if (11 + sps_size > *size) |
|
178 |
+ return AVERROR_INVALIDDATA; |
|
179 |
+ pps_size = AV_RB16(&in[9 + sps_size]); |
|
180 |
+ if (11 + sps_size + pps_size > *size) |
|
181 |
+ return AVERROR_INVALIDDATA; |
|
182 |
+ out_size = 8 + sps_size + pps_size; |
|
183 |
+ out = av_mallocz(out_size); |
|
184 |
+ if (!out) |
|
185 |
+ return AVERROR(ENOMEM); |
|
186 |
+ AV_WB32(&out[0], 0x00000001); |
|
187 |
+ memcpy(out + 4, &in[8], sps_size); |
|
188 |
+ AV_WB32(&out[4 + sps_size], 0x00000001); |
|
189 |
+ memcpy(out + 8 + sps_size, &in[11 + sps_size], pps_size); |
|
190 |
+ *buf = out; |
|
191 |
+ *size = out_size; |
|
192 |
+ return 0; |
|
193 |
+} |
... | ... |
@@ -29,5 +29,6 @@ int ff_avc_parse_nal_units(AVIOContext *s, const uint8_t *buf, int size); |
29 | 29 |
int ff_avc_parse_nal_units_buf(const uint8_t *buf_in, uint8_t **buf, int *size); |
30 | 30 |
int ff_isom_write_avcc(AVIOContext *pb, const uint8_t *data, int len); |
31 | 31 |
const uint8_t *ff_avc_find_startcode(const uint8_t *p, const uint8_t *end); |
32 |
+int ff_avc_write_annexb_extradata(const uint8_t *in, uint8_t **buf, int *size); |
|
32 | 33 |
|
33 | 34 |
#endif /* AVFORMAT_AVC_H */ |
... | ... |
@@ -2096,26 +2096,6 @@ static void param_write_hex(AVIOContext *pb, const char *name, const uint8_t *va |
2096 | 2096 |
avio_printf(pb, "<param name=\"%s\" value=\"%s\" valuetype=\"data\"/>\n", name, buf); |
2097 | 2097 |
} |
2098 | 2098 |
|
2099 |
-static void write_h264_extradata(AVIOContext *pb, AVCodecContext *enc) |
|
2100 |
-{ |
|
2101 |
- uint16_t sps_size, pps_size, len; |
|
2102 |
- char buf[150]; |
|
2103 |
- sps_size = AV_RB16(&enc->extradata[6]); |
|
2104 |
- if (11 + sps_size > enc->extradata_size) |
|
2105 |
- return; |
|
2106 |
- pps_size = AV_RB16(&enc->extradata[9 + sps_size]); |
|
2107 |
- if (11 + sps_size + pps_size > enc->extradata_size) |
|
2108 |
- return; |
|
2109 |
- len = FFMIN(sizeof(buf)/2 - 1, sps_size); |
|
2110 |
- ff_data_to_hex(buf, &enc->extradata[8], len, 0); |
|
2111 |
- buf[2*len] = '\0'; |
|
2112 |
- avio_printf(pb, "<param name=\"CodecPrivateData\" value=\"00000001%s", buf); |
|
2113 |
- len = FFMIN(sizeof(buf)/2 - 1, pps_size); |
|
2114 |
- ff_data_to_hex(buf, &enc->extradata[11 + sps_size], len, 0); |
|
2115 |
- buf[2*len] = '\0'; |
|
2116 |
- avio_printf(pb, "00000001%s\" valuetype=\"data\"/>\n", buf); |
|
2117 |
-} |
|
2118 |
- |
|
2119 | 2099 |
static int mov_write_isml_manifest(AVIOContext *pb, MOVMuxContext *mov) |
2120 | 2100 |
{ |
2121 | 2101 |
int64_t pos = avio_tell(pb); |
... | ... |
@@ -2157,10 +2137,16 @@ static int mov_write_isml_manifest(AVIOContext *pb, MOVMuxContext *mov) |
2157 | 2157 |
param_write_int(pb, "systemBitrate", track->enc->bit_rate); |
2158 | 2158 |
param_write_int(pb, "trackID", track_id); |
2159 | 2159 |
if (track->enc->codec_type == AVMEDIA_TYPE_VIDEO) { |
2160 |
- if (track->enc->codec_id == CODEC_ID_H264 && |
|
2161 |
- track->enc->extradata_size >= 11 && |
|
2162 |
- track->enc->extradata[0] == 1) { |
|
2163 |
- write_h264_extradata(pb, track->enc); |
|
2160 |
+ if (track->enc->codec_id == CODEC_ID_H264) { |
|
2161 |
+ uint8_t *ptr; |
|
2162 |
+ int size = track->enc->extradata_size; |
|
2163 |
+ if (!ff_avc_write_annexb_extradata(track->enc->extradata, &ptr, |
|
2164 |
+ &size)) { |
|
2165 |
+ param_write_hex(pb, "CodecPrivateData", |
|
2166 |
+ ptr ? ptr : track->enc->extradata, |
|
2167 |
+ size); |
|
2168 |
+ av_free(ptr); |
|
2169 |
+ } |
|
2164 | 2170 |
} else { |
2165 | 2171 |
param_write_hex(pb, "CodecPrivateData", track->enc->extradata, |
2166 | 2172 |
track->enc->extradata_size); |