正在显示
11 个修改的文件
包含
715 行增加
和
616 行删除
| @@ -469,7 +469,7 @@ MODULE_FILES=("srs_app_server" "srs_app_conn" "srs_app_rtmp_conn" "srs_app_socke | @@ -469,7 +469,7 @@ MODULE_FILES=("srs_app_server" "srs_app_conn" "srs_app_rtmp_conn" "srs_app_socke | ||
| 469 | "srs_app_thread" "srs_app_bandwidth" "srs_app_st" "srs_app_log" "srs_app_config" | 469 | "srs_app_thread" "srs_app_bandwidth" "srs_app_st" "srs_app_log" "srs_app_config" |
| 470 | "srs_app_pithy_print" "srs_app_reload" "srs_app_http_api" "srs_app_http_conn" "srs_app_http_hooks" | 470 | "srs_app_pithy_print" "srs_app_reload" "srs_app_http_api" "srs_app_http_conn" "srs_app_http_hooks" |
| 471 | "srs_app_json" "srs_app_ingest" "srs_app_ffmpeg" "srs_app_utility" "srs_app_dvr" "srs_app_edge" | 471 | "srs_app_json" "srs_app_ingest" "srs_app_ffmpeg" "srs_app_utility" "srs_app_dvr" "srs_app_edge" |
| 472 | - "srs_app_kbps" "srs_app_heartbeat" "srs_app_empty" "srs_app_http_client") | 472 | + "srs_app_kbps" "srs_app_heartbeat" "srs_app_empty" "srs_app_http_client" "srs_app_avc_aac") |
| 473 | APP_INCS="src/app"; MODULE_DIR=${APP_INCS} . auto/modules.sh | 473 | APP_INCS="src/app"; MODULE_DIR=${APP_INCS} . auto/modules.sh |
| 474 | APP_OBJS="${MODULE_OBJS[@]}" | 474 | APP_OBJS="${MODULE_OBJS[@]}" |
| 475 | # | 475 | # |
trunk/src/app/srs_app_avc_aac.cpp
0 → 100644
| 1 | +/* | ||
| 2 | +The MIT License (MIT) | ||
| 3 | + | ||
| 4 | +Copyright (c) 2013-2014 winlin | ||
| 5 | + | ||
| 6 | +Permission is hereby granted, free of charge, to any person obtaining a copy of | ||
| 7 | +this software and associated documentation files (the "Software"), to deal in | ||
| 8 | +the Software without restriction, including without limitation the rights to | ||
| 9 | +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of | ||
| 10 | +the Software, and to permit persons to whom the Software is furnished to do so, | ||
| 11 | +subject to the following conditions: | ||
| 12 | + | ||
| 13 | +The above copyright notice and this permission notice shall be included in all | ||
| 14 | +copies or substantial portions of the Software. | ||
| 15 | + | ||
| 16 | +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
| 17 | +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS | ||
| 18 | +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR | ||
| 19 | +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER | ||
| 20 | +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | ||
| 21 | +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||
| 22 | +*/ | ||
| 23 | + | ||
| 24 | +#include <srs_app_avc_aac.hpp> | ||
| 25 | + | ||
| 26 | +#include <stdlib.h> | ||
| 27 | + | ||
| 28 | +#include <srs_kernel_error.hpp> | ||
| 29 | +#include <srs_kernel_log.hpp> | ||
| 30 | +#include <srs_kernel_codec.hpp> | ||
| 31 | +#include <srs_kernel_stream.hpp> | ||
| 32 | + | ||
| 33 | +SrsCodecBuffer::SrsCodecBuffer() | ||
| 34 | +{ | ||
| 35 | + size = 0; | ||
| 36 | + bytes = NULL; | ||
| 37 | +} | ||
| 38 | + | ||
| 39 | +void SrsCodecBuffer::append(void* data, int len) | ||
| 40 | +{ | ||
| 41 | + srs_assert(data); | ||
| 42 | + srs_assert(len > 0); | ||
| 43 | + | ||
| 44 | + bytes = (char*)realloc(bytes, size + len); | ||
| 45 | + memcpy(bytes + size, data, len); | ||
| 46 | + size += len; | ||
| 47 | +} | ||
| 48 | + | ||
| 49 | +void SrsCodecBuffer::free() | ||
| 50 | +{ | ||
| 51 | + size = 0; | ||
| 52 | + srs_freep(bytes); | ||
| 53 | +} | ||
| 54 | + | ||
| 55 | +SrsCodecSample::SrsCodecSample() | ||
| 56 | +{ | ||
| 57 | + clear(); | ||
| 58 | +} | ||
| 59 | + | ||
| 60 | +SrsCodecSample::~SrsCodecSample() | ||
| 61 | +{ | ||
| 62 | +} | ||
| 63 | + | ||
| 64 | +void SrsCodecSample::clear() | ||
| 65 | +{ | ||
| 66 | + is_video = false; | ||
| 67 | + nb_buffers = 0; | ||
| 68 | + | ||
| 69 | + cts = 0; | ||
| 70 | + frame_type = SrsCodecVideoAVCFrameReserved; | ||
| 71 | + avc_packet_type = SrsCodecVideoAVCTypeReserved; | ||
| 72 | + | ||
| 73 | + sound_rate = SrsCodecAudioSampleRateReserved; | ||
| 74 | + sound_size = SrsCodecAudioSampleSizeReserved; | ||
| 75 | + sound_type = SrsCodecAudioSoundTypeReserved; | ||
| 76 | + aac_packet_type = SrsCodecAudioTypeReserved; | ||
| 77 | +} | ||
| 78 | + | ||
| 79 | +int SrsCodecSample::add_sample(char* bytes, int size) | ||
| 80 | +{ | ||
| 81 | + int ret = ERROR_SUCCESS; | ||
| 82 | + | ||
| 83 | + if (nb_buffers >= SRS_MAX_CODEC_SAMPLE) { | ||
| 84 | + ret = ERROR_HLS_DECODE_ERROR; | ||
| 85 | + srs_error("hls decode samples error, " | ||
| 86 | + "exceed the max count: %d, ret=%d", SRS_MAX_CODEC_SAMPLE, ret); | ||
| 87 | + return ret; | ||
| 88 | + } | ||
| 89 | + | ||
| 90 | + SrsCodecBuffer* buf = &buffers[nb_buffers++]; | ||
| 91 | + buf->bytes = bytes; | ||
| 92 | + buf->size = size; | ||
| 93 | + | ||
| 94 | + return ret; | ||
| 95 | +} | ||
| 96 | + | ||
| 97 | +SrsAvcAacCodec::SrsAvcAacCodec() | ||
| 98 | +{ | ||
| 99 | + width = 0; | ||
| 100 | + height = 0; | ||
| 101 | + duration = 0; | ||
| 102 | + NAL_unit_length = 0; | ||
| 103 | + frame_rate = 0; | ||
| 104 | + video_data_rate = 0; | ||
| 105 | + video_codec_id = 0; | ||
| 106 | + audio_data_rate = 0; | ||
| 107 | + audio_codec_id = 0; | ||
| 108 | + avc_profile = 0; | ||
| 109 | + avc_level = 0; | ||
| 110 | + aac_profile = 0; | ||
| 111 | + aac_sample_rate = 0; | ||
| 112 | + aac_channels = 0; | ||
| 113 | + avc_extra_size = 0; | ||
| 114 | + avc_extra_data = NULL; | ||
| 115 | + aac_extra_size = 0; | ||
| 116 | + aac_extra_data = NULL; | ||
| 117 | + sequenceParameterSetLength = 0; | ||
| 118 | + sequenceParameterSetNALUnit = NULL; | ||
| 119 | + pictureParameterSetLength = 0; | ||
| 120 | + pictureParameterSetNALUnit = NULL; | ||
| 121 | + | ||
| 122 | + stream = new SrsStream(); | ||
| 123 | +} | ||
| 124 | + | ||
| 125 | +SrsAvcAacCodec::~SrsAvcAacCodec() | ||
| 126 | +{ | ||
| 127 | + srs_freep(avc_extra_data); | ||
| 128 | + srs_freep(aac_extra_data); | ||
| 129 | + | ||
| 130 | + srs_freep(stream); | ||
| 131 | + srs_freep(sequenceParameterSetNALUnit); | ||
| 132 | + srs_freep(pictureParameterSetNALUnit); | ||
| 133 | +} | ||
| 134 | + | ||
| 135 | +int SrsAvcAacCodec::audio_aac_demux(int8_t* data, int size, SrsCodecSample* sample) | ||
| 136 | +{ | ||
| 137 | + int ret = ERROR_SUCCESS; | ||
| 138 | + | ||
| 139 | + sample->is_video = false; | ||
| 140 | + | ||
| 141 | + if (!data || size <= 0) { | ||
| 142 | + srs_trace("no audio present, hls ignore it."); | ||
| 143 | + return ret; | ||
| 144 | + } | ||
| 145 | + | ||
| 146 | + if ((ret = stream->initialize((char*)data, size)) != ERROR_SUCCESS) { | ||
| 147 | + return ret; | ||
| 148 | + } | ||
| 149 | + | ||
| 150 | + // audio decode | ||
| 151 | + if (!stream->require(1)) { | ||
| 152 | + ret = ERROR_HLS_DECODE_ERROR; | ||
| 153 | + srs_error("hls decode audio sound_format failed. ret=%d", ret); | ||
| 154 | + return ret; | ||
| 155 | + } | ||
| 156 | + | ||
| 157 | + int8_t sound_format = stream->read_1bytes(); | ||
| 158 | + | ||
| 159 | + int8_t sound_type = sound_format & 0x01; | ||
| 160 | + int8_t sound_size = (sound_format >> 1) & 0x01; | ||
| 161 | + int8_t sound_rate = (sound_format >> 2) & 0x03; | ||
| 162 | + sound_format = (sound_format >> 4) & 0x0f; | ||
| 163 | + | ||
| 164 | + audio_codec_id = sound_format; | ||
| 165 | + sample->sound_type = (SrsCodecAudioSoundType)sound_type; | ||
| 166 | + sample->sound_rate = (SrsCodecAudioSampleRate)sound_rate; | ||
| 167 | + sample->sound_size = (SrsCodecAudioSampleSize)sound_size; | ||
| 168 | + | ||
| 169 | + // reset the sample rate by sequence header | ||
| 170 | + static int aac_sample_rates[] = { | ||
| 171 | + 96000, 88200, 64000, 48000, | ||
| 172 | + 44100, 32000, 24000, 22050, | ||
| 173 | + 16000, 12000, 11025, 8000, | ||
| 174 | + 7350, 0, 0, 0 | ||
| 175 | + }; | ||
| 176 | + switch (aac_sample_rates[aac_sample_rate]) { | ||
| 177 | + case 11025: | ||
| 178 | + sample->sound_rate = SrsCodecAudioSampleRate11025; | ||
| 179 | + break; | ||
| 180 | + case 22050: | ||
| 181 | + sample->sound_rate = SrsCodecAudioSampleRate22050; | ||
| 182 | + break; | ||
| 183 | + case 44100: | ||
| 184 | + sample->sound_rate = SrsCodecAudioSampleRate44100; | ||
| 185 | + break; | ||
| 186 | + }; | ||
| 187 | + | ||
| 188 | + // only support aac | ||
| 189 | + if (audio_codec_id != SrsCodecAudioAAC) { | ||
| 190 | + ret = ERROR_HLS_DECODE_ERROR; | ||
| 191 | + srs_error("hls only support audio aac codec. actual=%d, ret=%d", audio_codec_id, ret); | ||
| 192 | + return ret; | ||
| 193 | + } | ||
| 194 | + | ||
| 195 | + if (!stream->require(1)) { | ||
| 196 | + ret = ERROR_HLS_DECODE_ERROR; | ||
| 197 | + srs_error("hls decode audio aac_packet_type failed. ret=%d", ret); | ||
| 198 | + return ret; | ||
| 199 | + } | ||
| 200 | + | ||
| 201 | + int8_t aac_packet_type = stream->read_1bytes(); | ||
| 202 | + sample->aac_packet_type = (SrsCodecAudioType)aac_packet_type; | ||
| 203 | + | ||
| 204 | + if (aac_packet_type == SrsCodecAudioTypeSequenceHeader) { | ||
| 205 | + // AudioSpecificConfig | ||
| 206 | + // 1.6.2.1 AudioSpecificConfig, in aac-mp4a-format-ISO_IEC_14496-3+2001.pdf, page 33. | ||
| 207 | + aac_extra_size = stream->left(); | ||
| 208 | + if (aac_extra_size > 0) { | ||
| 209 | + srs_freep(aac_extra_data); | ||
| 210 | + aac_extra_data = new char[aac_extra_size]; | ||
| 211 | + memcpy(aac_extra_data, stream->current(), aac_extra_size); | ||
| 212 | + } | ||
| 213 | + | ||
| 214 | + // only need to decode the first 2bytes: | ||
| 215 | + // audioObjectType, aac_profile, 5bits. | ||
| 216 | + // samplingFrequencyIndex, aac_sample_rate, 4bits. | ||
| 217 | + // channelConfiguration, aac_channels, 4bits | ||
| 218 | + if (!stream->require(2)) { | ||
| 219 | + ret = ERROR_HLS_DECODE_ERROR; | ||
| 220 | + srs_error("hls decode audio aac sequence header failed. ret=%d", ret); | ||
| 221 | + return ret; | ||
| 222 | + } | ||
| 223 | + aac_profile = stream->read_1bytes(); | ||
| 224 | + aac_sample_rate = stream->read_1bytes(); | ||
| 225 | + | ||
| 226 | + aac_channels = (aac_sample_rate >> 3) & 0x0f; | ||
| 227 | + aac_sample_rate = ((aac_profile << 1) & 0x0e) | ((aac_sample_rate >> 7) & 0x01); | ||
| 228 | + aac_profile = (aac_profile >> 3) & 0x1f; | ||
| 229 | + | ||
| 230 | + if (aac_profile == 0 || aac_profile == 0x1f) { | ||
| 231 | + ret = ERROR_HLS_DECODE_ERROR; | ||
| 232 | + srs_error("hls decode audio aac sequence header failed, " | ||
| 233 | + "adts object=%d invalid. ret=%d", aac_profile, ret); | ||
| 234 | + return ret; | ||
| 235 | + } | ||
| 236 | + | ||
| 237 | + // aac_profile = audioObjectType - 1 | ||
| 238 | + aac_profile--; | ||
| 239 | + | ||
| 240 | + if (aac_profile > 3) { | ||
| 241 | + // Mark all extended profiles as LC | ||
| 242 | + // to make Android as happy as possible. | ||
| 243 | + // @see: ngx_rtmp_hls_parse_aac_header | ||
| 244 | + aac_profile = 1; | ||
| 245 | + } | ||
| 246 | + } else if (aac_packet_type == SrsCodecAudioTypeRawData) { | ||
| 247 | + // ensure the sequence header demuxed | ||
| 248 | + if (aac_extra_size <= 0 || !aac_extra_data) { | ||
| 249 | + ret = ERROR_HLS_DECODE_ERROR; | ||
| 250 | + srs_error("hls decode audio aac failed, sequence header not found. ret=%d", ret); | ||
| 251 | + return ret; | ||
| 252 | + } | ||
| 253 | + | ||
| 254 | + // Raw AAC frame data in UI8 [] | ||
| 255 | + // 6.3 Raw Data, aac-iso-13818-7.pdf, page 28 | ||
| 256 | + if ((ret = sample->add_sample(stream->current(), stream->left())) != ERROR_SUCCESS) { | ||
| 257 | + srs_error("hls add audio sample failed. ret=%d", ret); | ||
| 258 | + return ret; | ||
| 259 | + } | ||
| 260 | + } else { | ||
| 261 | + // ignored. | ||
| 262 | + } | ||
| 263 | + | ||
| 264 | + srs_info("audio decoded, type=%d, codec=%d, asize=%d, rate=%d, format=%d, size=%d", | ||
| 265 | + sound_type, audio_codec_id, sound_size, sound_rate, sound_format, size); | ||
| 266 | + | ||
| 267 | + return ret; | ||
| 268 | +} | ||
| 269 | + | ||
| 270 | +int SrsAvcAacCodec::video_avc_demux(int8_t* data, int size, SrsCodecSample* sample) | ||
| 271 | +{ | ||
| 272 | + int ret = ERROR_SUCCESS; | ||
| 273 | + | ||
| 274 | + sample->is_video = true; | ||
| 275 | + | ||
| 276 | + if (!data || size <= 0) { | ||
| 277 | + srs_trace("no video present, hls ignore it."); | ||
| 278 | + return ret; | ||
| 279 | + } | ||
| 280 | + | ||
| 281 | + if ((ret = stream->initialize((char*)data, size)) != ERROR_SUCCESS) { | ||
| 282 | + return ret; | ||
| 283 | + } | ||
| 284 | + | ||
| 285 | + // video decode | ||
| 286 | + if (!stream->require(1)) { | ||
| 287 | + ret = ERROR_HLS_DECODE_ERROR; | ||
| 288 | + srs_error("hls decode video frame_type failed. ret=%d", ret); | ||
| 289 | + return ret; | ||
| 290 | + } | ||
| 291 | + | ||
| 292 | + int8_t frame_type = stream->read_1bytes(); | ||
| 293 | + int8_t codec_id = frame_type & 0x0f; | ||
| 294 | + frame_type = (frame_type >> 4) & 0x0f; | ||
| 295 | + | ||
| 296 | + sample->frame_type = (SrsCodecVideoAVCFrame)frame_type; | ||
| 297 | + | ||
| 298 | + // only support h.264/avc | ||
| 299 | + if (codec_id != SrsCodecVideoAVC) { | ||
| 300 | + ret = ERROR_HLS_DECODE_ERROR; | ||
| 301 | + srs_error("hls only support video h.264/avc codec. actual=%d, ret=%d", codec_id, ret); | ||
| 302 | + return ret; | ||
| 303 | + } | ||
| 304 | + video_codec_id = codec_id; | ||
| 305 | + | ||
| 306 | + if (!stream->require(4)) { | ||
| 307 | + ret = ERROR_HLS_DECODE_ERROR; | ||
| 308 | + srs_error("hls decode video avc_packet_type failed. ret=%d", ret); | ||
| 309 | + return ret; | ||
| 310 | + } | ||
| 311 | + int8_t avc_packet_type = stream->read_1bytes(); | ||
| 312 | + int32_t composition_time = stream->read_3bytes(); | ||
| 313 | + | ||
| 314 | + // pts = dts + cts. | ||
| 315 | + sample->cts = composition_time; | ||
| 316 | + sample->avc_packet_type = (SrsCodecVideoAVCType)avc_packet_type; | ||
| 317 | + | ||
| 318 | + if (avc_packet_type == SrsCodecVideoAVCTypeSequenceHeader) { | ||
| 319 | + // AVCDecoderConfigurationRecord | ||
| 320 | + // 5.2.4.1.1 Syntax, H.264-AVC-ISO_IEC_14496-15.pdf, page 16 | ||
| 321 | + avc_extra_size = stream->left(); | ||
| 322 | + if (avc_extra_size > 0) { | ||
| 323 | + srs_freep(avc_extra_data); | ||
| 324 | + avc_extra_data = new char[avc_extra_size]; | ||
| 325 | + memcpy(avc_extra_data, stream->current(), avc_extra_size); | ||
| 326 | + } | ||
| 327 | + | ||
| 328 | + if (!stream->require(6)) { | ||
| 329 | + ret = ERROR_HLS_DECODE_ERROR; | ||
| 330 | + srs_error("hls decode video avc sequenc header failed. ret=%d", ret); | ||
| 331 | + return ret; | ||
| 332 | + } | ||
| 333 | + //int8_t configurationVersion = stream->read_1bytes(); | ||
| 334 | + //int8_t AVCProfileIndication = stream->read_1bytes(); | ||
| 335 | + //int8_t profile_compatibility = stream->read_1bytes(); | ||
| 336 | + //int8_t AVCLevelIndication = stream->read_1bytes(); | ||
| 337 | + stream->skip(4); | ||
| 338 | + // parse the NALU size. | ||
| 339 | + int8_t lengthSizeMinusOne = stream->read_1bytes(); | ||
| 340 | + lengthSizeMinusOne &= 0x03; | ||
| 341 | + NAL_unit_length = lengthSizeMinusOne; | ||
| 342 | + | ||
| 343 | + // 1 sps | ||
| 344 | + if (!stream->require(1)) { | ||
| 345 | + ret = ERROR_HLS_DECODE_ERROR; | ||
| 346 | + srs_error("hls decode video avc sequenc header sps failed. ret=%d", ret); | ||
| 347 | + return ret; | ||
| 348 | + } | ||
| 349 | + int8_t numOfSequenceParameterSets = stream->read_1bytes(); | ||
| 350 | + numOfSequenceParameterSets &= 0x1f; | ||
| 351 | + if (numOfSequenceParameterSets != 1) { | ||
| 352 | + ret = ERROR_HLS_DECODE_ERROR; | ||
| 353 | + srs_error("hls decode video avc sequenc header sps failed. ret=%d", ret); | ||
| 354 | + return ret; | ||
| 355 | + } | ||
| 356 | + if (!stream->require(2)) { | ||
| 357 | + ret = ERROR_HLS_DECODE_ERROR; | ||
| 358 | + srs_error("hls decode video avc sequenc header sps size failed. ret=%d", ret); | ||
| 359 | + return ret; | ||
| 360 | + } | ||
| 361 | + sequenceParameterSetLength = stream->read_2bytes(); | ||
| 362 | + if (!stream->require(sequenceParameterSetLength)) { | ||
| 363 | + ret = ERROR_HLS_DECODE_ERROR; | ||
| 364 | + srs_error("hls decode video avc sequenc header sps data failed. ret=%d", ret); | ||
| 365 | + return ret; | ||
| 366 | + } | ||
| 367 | + if (sequenceParameterSetLength > 0) { | ||
| 368 | + srs_freep(sequenceParameterSetNALUnit); | ||
| 369 | + sequenceParameterSetNALUnit = new char[sequenceParameterSetLength]; | ||
| 370 | + memcpy(sequenceParameterSetNALUnit, stream->current(), sequenceParameterSetLength); | ||
| 371 | + stream->skip(sequenceParameterSetLength); | ||
| 372 | + } | ||
| 373 | + // 1 pps | ||
| 374 | + if (!stream->require(1)) { | ||
| 375 | + ret = ERROR_HLS_DECODE_ERROR; | ||
| 376 | + srs_error("hls decode video avc sequenc header pps failed. ret=%d", ret); | ||
| 377 | + return ret; | ||
| 378 | + } | ||
| 379 | + int8_t numOfPictureParameterSets = stream->read_1bytes(); | ||
| 380 | + numOfPictureParameterSets &= 0x1f; | ||
| 381 | + if (numOfPictureParameterSets != 1) { | ||
| 382 | + ret = ERROR_HLS_DECODE_ERROR; | ||
| 383 | + srs_error("hls decode video avc sequenc header pps failed. ret=%d", ret); | ||
| 384 | + return ret; | ||
| 385 | + } | ||
| 386 | + if (!stream->require(2)) { | ||
| 387 | + ret = ERROR_HLS_DECODE_ERROR; | ||
| 388 | + srs_error("hls decode video avc sequenc header pps size failed. ret=%d", ret); | ||
| 389 | + return ret; | ||
| 390 | + } | ||
| 391 | + pictureParameterSetLength = stream->read_2bytes(); | ||
| 392 | + if (!stream->require(pictureParameterSetLength)) { | ||
| 393 | + ret = ERROR_HLS_DECODE_ERROR; | ||
| 394 | + srs_error("hls decode video avc sequenc header pps data failed. ret=%d", ret); | ||
| 395 | + return ret; | ||
| 396 | + } | ||
| 397 | + if (pictureParameterSetLength > 0) { | ||
| 398 | + srs_freep(pictureParameterSetNALUnit); | ||
| 399 | + pictureParameterSetNALUnit = new char[pictureParameterSetLength]; | ||
| 400 | + memcpy(pictureParameterSetNALUnit, stream->current(), pictureParameterSetLength); | ||
| 401 | + stream->skip(pictureParameterSetLength); | ||
| 402 | + } | ||
| 403 | + } else if (avc_packet_type == SrsCodecVideoAVCTypeNALU){ | ||
| 404 | + // ensure the sequence header demuxed | ||
| 405 | + if (avc_extra_size <= 0 || !avc_extra_data) { | ||
| 406 | + ret = ERROR_HLS_DECODE_ERROR; | ||
| 407 | + srs_error("hls decode video avc failed, sequence header not found. ret=%d", ret); | ||
| 408 | + return ret; | ||
| 409 | + } | ||
| 410 | + | ||
| 411 | + // One or more NALUs (Full frames are required) | ||
| 412 | + // 5.3.4.2.1 Syntax, H.264-AVC-ISO_IEC_14496-15.pdf, page 20 | ||
| 413 | + int PictureLength = stream->left(); | ||
| 414 | + for (int i = 0; i < PictureLength;) { | ||
| 415 | + if (!stream->require(NAL_unit_length + 1)) { | ||
| 416 | + ret = ERROR_HLS_DECODE_ERROR; | ||
| 417 | + srs_error("hls decode video avc NALU size failed. ret=%d", ret); | ||
| 418 | + return ret; | ||
| 419 | + } | ||
| 420 | + int32_t NALUnitLength = 0; | ||
| 421 | + if (NAL_unit_length == 3) { | ||
| 422 | + NALUnitLength = stream->read_4bytes(); | ||
| 423 | + } else if (NALUnitLength == 2) { | ||
| 424 | + NALUnitLength = stream->read_3bytes(); | ||
| 425 | + } else if (NALUnitLength == 1) { | ||
| 426 | + NALUnitLength = stream->read_2bytes(); | ||
| 427 | + } else { | ||
| 428 | + NALUnitLength = stream->read_1bytes(); | ||
| 429 | + } | ||
| 430 | + // NALUnit | ||
| 431 | + if (!stream->require(NALUnitLength)) { | ||
| 432 | + ret = ERROR_HLS_DECODE_ERROR; | ||
| 433 | + srs_error("hls decode video avc NALU data failed. ret=%d", ret); | ||
| 434 | + return ret; | ||
| 435 | + } | ||
| 436 | + // 7.3.1 NAL unit syntax, H.264-AVC-ISO_IEC_14496-10.pdf, page 44. | ||
| 437 | + if ((ret = sample->add_sample(stream->current(), NALUnitLength)) != ERROR_SUCCESS) { | ||
| 438 | + srs_error("hls add video sample failed. ret=%d", ret); | ||
| 439 | + return ret; | ||
| 440 | + } | ||
| 441 | + stream->skip(NALUnitLength); | ||
| 442 | + | ||
| 443 | + i += NAL_unit_length + 1 + NALUnitLength; | ||
| 444 | + } | ||
| 445 | + } else { | ||
| 446 | + // ignored. | ||
| 447 | + } | ||
| 448 | + | ||
| 449 | + srs_info("video decoded, type=%d, codec=%d, avc=%d, time=%d, size=%d", | ||
| 450 | + frame_type, video_codec_id, avc_packet_type, composition_time, size); | ||
| 451 | + | ||
| 452 | + return ret; | ||
| 453 | +} |
trunk/src/app/srs_app_avc_aac.hpp
0 → 100644
| 1 | +/* | ||
| 2 | +The MIT License (MIT) | ||
| 3 | + | ||
| 4 | +Copyright (c) 2013-2014 winlin | ||
| 5 | + | ||
| 6 | +Permission is hereby granted, free of charge, to any person obtaining a copy of | ||
| 7 | +this software and associated documentation files (the "Software"), to deal in | ||
| 8 | +the Software without restriction, including without limitation the rights to | ||
| 9 | +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of | ||
| 10 | +the Software, and to permit persons to whom the Software is furnished to do so, | ||
| 11 | +subject to the following conditions: | ||
| 12 | + | ||
| 13 | +The above copyright notice and this permission notice shall be included in all | ||
| 14 | +copies or substantial portions of the Software. | ||
| 15 | + | ||
| 16 | +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
| 17 | +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS | ||
| 18 | +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR | ||
| 19 | +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER | ||
| 20 | +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | ||
| 21 | +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||
| 22 | +*/ | ||
| 23 | + | ||
| 24 | +#ifndef SRS_APP_AVC_AAC_HPP | ||
| 25 | +#define SRS_APP_AVC_AAC_HPP | ||
| 26 | + | ||
| 27 | +/* | ||
| 28 | +#include <srs_app_avc_aac.hpp> | ||
| 29 | +*/ | ||
| 30 | + | ||
| 31 | +#include <srs_core.hpp> | ||
| 32 | + | ||
| 33 | +#include <srs_kernel_codec.hpp> | ||
| 34 | + | ||
| 35 | +#define SRS_MAX_CODEC_SAMPLE 128 | ||
| 36 | + | ||
| 37 | +// Sampling rate. The following values are defined: | ||
| 38 | +// 0 = 5.5 kHz = 5512 Hz | ||
| 39 | +// 1 = 11 kHz = 11025 Hz | ||
| 40 | +// 2 = 22 kHz = 22050 Hz | ||
| 41 | +// 3 = 44 kHz = 44100 Hz | ||
| 42 | +enum SrsCodecAudioSampleRate | ||
| 43 | +{ | ||
| 44 | + SrsCodecAudioSampleRateReserved = -1, | ||
| 45 | + | ||
| 46 | + SrsCodecAudioSampleRate5512 = 0, | ||
| 47 | + SrsCodecAudioSampleRate11025 = 1, | ||
| 48 | + SrsCodecAudioSampleRate22050 = 2, | ||
| 49 | + SrsCodecAudioSampleRate44100 = 3, | ||
| 50 | +}; | ||
| 51 | + | ||
| 52 | +// Size of each audio sample. This parameter only pertains to | ||
| 53 | +// uncompressed formats. Compressed formats always decode | ||
| 54 | +// to 16 bits internally. | ||
| 55 | +// 0 = 8-bit samples | ||
| 56 | +// 1 = 16-bit samples | ||
| 57 | +enum SrsCodecAudioSampleSize | ||
| 58 | +{ | ||
| 59 | + SrsCodecAudioSampleSizeReserved = -1, | ||
| 60 | + | ||
| 61 | + SrsCodecAudioSampleSize8bit = 0, | ||
| 62 | + SrsCodecAudioSampleSize16bit = 1, | ||
| 63 | +}; | ||
| 64 | + | ||
| 65 | +// Mono or stereo sound | ||
| 66 | +// 0 = Mono sound | ||
| 67 | +// 1 = Stereo sound | ||
| 68 | +enum SrsCodecAudioSoundType | ||
| 69 | +{ | ||
| 70 | + SrsCodecAudioSoundTypeReserved = -1, | ||
| 71 | + | ||
| 72 | + SrsCodecAudioSoundTypeMono = 0, | ||
| 73 | + SrsCodecAudioSoundTypeStereo = 1, | ||
| 74 | +}; | ||
| 75 | + | ||
| 76 | +/** | ||
| 77 | +* buffer indicates the position and size. | ||
| 78 | +*/ | ||
| 79 | +class SrsCodecBuffer | ||
| 80 | +{ | ||
| 81 | +public: | ||
| 82 | + /** | ||
| 83 | + * @remark user must manage the bytes. | ||
| 84 | + */ | ||
| 85 | + int size; | ||
| 86 | + char* bytes; | ||
| 87 | + | ||
| 88 | + SrsCodecBuffer(); | ||
| 89 | + void append(void* data, int len); | ||
| 90 | + | ||
| 91 | + /** | ||
| 92 | + * free the bytes, | ||
| 93 | + * user can invoke it to free the bytes, | ||
| 94 | + * the SrsCodecBuffer never free automatically. | ||
| 95 | + */ | ||
| 96 | + void free(); | ||
| 97 | +}; | ||
| 98 | + | ||
| 99 | +/** | ||
| 100 | +* the samples in the flv audio/video packet. | ||
| 101 | +*/ | ||
| 102 | +class SrsCodecSample | ||
| 103 | +{ | ||
| 104 | +public: | ||
| 105 | + /** | ||
| 106 | + * each audio/video raw data packet will dumps to one or multiple buffers, | ||
| 107 | + * the buffers will write to hls and clear to reset. | ||
| 108 | + * generally, aac audio packet corresponding to one buffer, | ||
| 109 | + * where avc/h264 video packet may contains multiple buffer. | ||
| 110 | + */ | ||
| 111 | + int nb_buffers; | ||
| 112 | + SrsCodecBuffer buffers[SRS_MAX_CODEC_SAMPLE]; | ||
| 113 | +public: | ||
| 114 | + bool is_video; | ||
| 115 | + // CompositionTime, video_file_format_spec_v10_1.pdf, page 78. | ||
| 116 | + // cts = pts - dts, where dts = flvheader->timestamp. | ||
| 117 | + int32_t cts; | ||
| 118 | +public: | ||
| 119 | + // video specified | ||
| 120 | + SrsCodecVideoAVCFrame frame_type; | ||
| 121 | + SrsCodecVideoAVCType avc_packet_type; | ||
| 122 | +public: | ||
| 123 | + // audio specified | ||
| 124 | + SrsCodecAudioSampleRate sound_rate; | ||
| 125 | + SrsCodecAudioSampleSize sound_size; | ||
| 126 | + SrsCodecAudioSoundType sound_type; | ||
| 127 | + SrsCodecAudioType aac_packet_type; | ||
| 128 | +public: | ||
| 129 | + SrsCodecSample(); | ||
| 130 | + virtual ~SrsCodecSample(); | ||
| 131 | + void clear(); | ||
| 132 | + int add_sample(char* bytes, int size); | ||
| 133 | +}; | ||
| 134 | + | ||
| 135 | +/** | ||
| 136 | +* the h264/avc and aac codec, for media stream. | ||
| 137 | +* to decode the stream of avc/aac for hls. | ||
| 138 | +*/ | ||
| 139 | +class SrsAvcAacCodec | ||
| 140 | +{ | ||
| 141 | +private: | ||
| 142 | + SrsStream* stream; | ||
| 143 | +public: | ||
| 144 | + /** | ||
| 145 | + * video specified | ||
| 146 | + */ | ||
| 147 | + // @see: SrsCodecVideo | ||
| 148 | + int video_codec_id; | ||
| 149 | + // profile_idc, H.264-AVC-ISO_IEC_14496-10.pdf, page 45. | ||
| 150 | + u_int8_t avc_profile; | ||
| 151 | + // level_idc, H.264-AVC-ISO_IEC_14496-10.pdf, page 45. | ||
| 152 | + u_int8_t avc_level; | ||
| 153 | + int width; | ||
| 154 | + int height; | ||
| 155 | + int video_data_rate; // in bps | ||
| 156 | + int frame_rate; | ||
| 157 | + int duration; | ||
| 158 | + // lengthSizeMinusOne, H.264-AVC-ISO_IEC_14496-15.pdf, page 16 | ||
| 159 | + int8_t NAL_unit_length; | ||
| 160 | + u_int16_t sequenceParameterSetLength; | ||
| 161 | + char* sequenceParameterSetNALUnit; | ||
| 162 | + u_int16_t pictureParameterSetLength; | ||
| 163 | + char* pictureParameterSetNALUnit; | ||
| 164 | +public: | ||
| 165 | + /** | ||
| 166 | + * audio specified | ||
| 167 | + */ | ||
| 168 | + // @see: SrsCodecAudioType | ||
| 169 | + int audio_codec_id; | ||
| 170 | + int audio_data_rate; // in bps | ||
| 171 | + // 1.6.2.1 AudioSpecificConfig, in aac-mp4a-format-ISO_IEC_14496-3+2001.pdf, page 33. | ||
| 172 | + // audioObjectType, value defines in 7.1 Profiles, aac-iso-13818-7.pdf, page 40. | ||
| 173 | + u_int8_t aac_profile; | ||
| 174 | + // samplingFrequencyIndex | ||
| 175 | + u_int8_t aac_sample_rate; | ||
| 176 | + // channelConfiguration | ||
| 177 | + u_int8_t aac_channels; | ||
| 178 | +public: | ||
| 179 | + // the avc extra data, the AVC sequence header, | ||
| 180 | + // without the flv codec header, | ||
| 181 | + // @see: ffmpeg, AVCodecContext::extradata | ||
| 182 | + int avc_extra_size; | ||
| 183 | + char* avc_extra_data; | ||
| 184 | + // the aac extra data, the AAC sequence header, | ||
| 185 | + // without the flv codec header, | ||
| 186 | + // @see: ffmpeg, AVCodecContext::extradata | ||
| 187 | + int aac_extra_size; | ||
| 188 | + char* aac_extra_data; | ||
| 189 | +public: | ||
| 190 | + SrsAvcAacCodec(); | ||
| 191 | + virtual ~SrsAvcAacCodec(); | ||
| 192 | +// the following function used for hls to build the codec info. | ||
| 193 | +public: | ||
| 194 | + virtual int audio_aac_demux(int8_t* data, int size, SrsCodecSample* sample); | ||
| 195 | + virtual int video_avc_demux(int8_t* data, int size, SrsCodecSample* sample); | ||
| 196 | +}; | ||
| 197 | + | ||
| 198 | +#endif |
| @@ -228,9 +228,9 @@ int SrsDvrPlan::on_video(SrsSharedPtrMessage* video) | @@ -228,9 +228,9 @@ int SrsDvrPlan::on_video(SrsSharedPtrMessage* video) | ||
| 228 | int size = (int)video->size; | 228 | int size = (int)video->size; |
| 229 | 229 | ||
| 230 | #ifdef SRS_AUTO_HTTP_CALLBACK | 230 | #ifdef SRS_AUTO_HTTP_CALLBACK |
| 231 | - bool is_key_frame = SrsCodec::video_is_h264((int8_t*)payload, size) | ||
| 232 | - && SrsCodec::video_is_keyframe((int8_t*)payload, size) | ||
| 233 | - && !SrsCodec::video_is_sequence_header((int8_t*)payload, size); | 231 | + bool is_key_frame = SrsFlvCodec::video_is_h264((int8_t*)payload, size) |
| 232 | + && SrsFlvCodec::video_is_keyframe((int8_t*)payload, size) | ||
| 233 | + && !SrsFlvCodec::video_is_sequence_header((int8_t*)payload, size); | ||
| 234 | if (is_key_frame) { | 234 | if (is_key_frame) { |
| 235 | segment->has_keyframe = true; | 235 | segment->has_keyframe = true; |
| 236 | if ((ret = on_video_keyframe()) != ERROR_SUCCESS) { | 236 | if ((ret = on_video_keyframe()) != ERROR_SUCCESS) { |
| @@ -44,6 +44,7 @@ using namespace std; | @@ -44,6 +44,7 @@ using namespace std; | ||
| 44 | #include <srs_protocol_rtmp.hpp> | 44 | #include <srs_protocol_rtmp.hpp> |
| 45 | #include <srs_app_pithy_print.hpp> | 45 | #include <srs_app_pithy_print.hpp> |
| 46 | #include <srs_kernel_utility.hpp> | 46 | #include <srs_kernel_utility.hpp> |
| 47 | +#include <srs_app_avc_aac.hpp> | ||
| 47 | 48 | ||
| 48 | // max PES packets size to flush the video. | 49 | // max PES packets size to flush the video. |
| 49 | #define SRS_AUTO_HLS_AUDIO_CACHE_SIZE 1024 * 1024 | 50 | #define SRS_AUTO_HLS_AUDIO_CACHE_SIZE 1024 * 1024 |
| @@ -1014,7 +1015,7 @@ int SrsHlsCache::on_sequence_header(SrsHlsMuxer* muxer) | @@ -1014,7 +1015,7 @@ int SrsHlsCache::on_sequence_header(SrsHlsMuxer* muxer) | ||
| 1014 | return muxer->on_sequence_header(); | 1015 | return muxer->on_sequence_header(); |
| 1015 | } | 1016 | } |
| 1016 | 1017 | ||
| 1017 | -int SrsHlsCache::write_audio(SrsCodec* codec, SrsHlsMuxer* muxer, int64_t pts, SrsCodecSample* sample) | 1018 | +int SrsHlsCache::write_audio(SrsAvcAacCodec* codec, SrsHlsMuxer* muxer, int64_t pts, SrsCodecSample* sample) |
| 1018 | { | 1019 | { |
| 1019 | int ret = ERROR_SUCCESS; | 1020 | int ret = ERROR_SUCCESS; |
| 1020 | 1021 | ||
| @@ -1062,7 +1063,7 @@ int SrsHlsCache::write_audio(SrsCodec* codec, SrsHlsMuxer* muxer, int64_t pts, S | @@ -1062,7 +1063,7 @@ int SrsHlsCache::write_audio(SrsCodec* codec, SrsHlsMuxer* muxer, int64_t pts, S | ||
| 1062 | } | 1063 | } |
| 1063 | 1064 | ||
| 1064 | int SrsHlsCache::write_video( | 1065 | int SrsHlsCache::write_video( |
| 1065 | - SrsCodec* codec, SrsHlsMuxer* muxer, int64_t dts, SrsCodecSample* sample) | 1066 | + SrsAvcAacCodec* codec, SrsHlsMuxer* muxer, int64_t dts, SrsCodecSample* sample) |
| 1066 | { | 1067 | { |
| 1067 | int ret = ERROR_SUCCESS; | 1068 | int ret = ERROR_SUCCESS; |
| 1068 | 1069 | ||
| @@ -1123,7 +1124,7 @@ int SrsHlsCache::reap_segment(string log_desc, SrsHlsMuxer* muxer, int64_t segme | @@ -1123,7 +1124,7 @@ int SrsHlsCache::reap_segment(string log_desc, SrsHlsMuxer* muxer, int64_t segme | ||
| 1123 | return ret; | 1124 | return ret; |
| 1124 | } | 1125 | } |
| 1125 | 1126 | ||
| 1126 | -int SrsHlsCache::cache_audio(SrsCodec* codec, SrsCodecSample* sample) | 1127 | +int SrsHlsCache::cache_audio(SrsAvcAacCodec* codec, SrsCodecSample* sample) |
| 1127 | { | 1128 | { |
| 1128 | int ret = ERROR_SUCCESS; | 1129 | int ret = ERROR_SUCCESS; |
| 1129 | 1130 | ||
| @@ -1190,7 +1191,7 @@ int SrsHlsCache::cache_audio(SrsCodec* codec, SrsCodecSample* sample) | @@ -1190,7 +1191,7 @@ int SrsHlsCache::cache_audio(SrsCodec* codec, SrsCodecSample* sample) | ||
| 1190 | return ret; | 1191 | return ret; |
| 1191 | } | 1192 | } |
| 1192 | 1193 | ||
| 1193 | -int SrsHlsCache::cache_video(SrsCodec* codec, SrsCodecSample* sample) | 1194 | +int SrsHlsCache::cache_video(SrsAvcAacCodec* codec, SrsCodecSample* sample) |
| 1194 | { | 1195 | { |
| 1195 | int ret = ERROR_SUCCESS; | 1196 | int ret = ERROR_SUCCESS; |
| 1196 | 1197 | ||
| @@ -1262,7 +1263,7 @@ SrsHls::SrsHls(SrsSource* _source) | @@ -1262,7 +1263,7 @@ SrsHls::SrsHls(SrsSource* _source) | ||
| 1262 | hls_enabled = false; | 1263 | hls_enabled = false; |
| 1263 | 1264 | ||
| 1264 | source = _source; | 1265 | source = _source; |
| 1265 | - codec = new SrsCodec(); | 1266 | + codec = new SrsAvcAacCodec(); |
| 1266 | sample = new SrsCodecSample(); | 1267 | sample = new SrsCodecSample(); |
| 1267 | jitter = new SrsRtmpJitter(); | 1268 | jitter = new SrsRtmpJitter(); |
| 1268 | 1269 |
| @@ -41,7 +41,7 @@ class SrsMpegtsFrame; | @@ -41,7 +41,7 @@ class SrsMpegtsFrame; | ||
| 41 | class SrsAmf0Object; | 41 | class SrsAmf0Object; |
| 42 | class SrsRtmpJitter; | 42 | class SrsRtmpJitter; |
| 43 | class SrsTSMuxer; | 43 | class SrsTSMuxer; |
| 44 | -class SrsCodec; | 44 | +class SrsAvcAacCodec; |
| 45 | class SrsRequest; | 45 | class SrsRequest; |
| 46 | class SrsPithyPrint; | 46 | class SrsPithyPrint; |
| 47 | class SrsSource; | 47 | class SrsSource; |
| @@ -247,11 +247,11 @@ public: | @@ -247,11 +247,11 @@ public: | ||
| 247 | /** | 247 | /** |
| 248 | * write audio to cache, if need to flush, flush to muxer. | 248 | * write audio to cache, if need to flush, flush to muxer. |
| 249 | */ | 249 | */ |
| 250 | - virtual int write_audio(SrsCodec* codec, SrsHlsMuxer* muxer, int64_t pts, SrsCodecSample* sample); | 250 | + virtual int write_audio(SrsAvcAacCodec* codec, SrsHlsMuxer* muxer, int64_t pts, SrsCodecSample* sample); |
| 251 | /** | 251 | /** |
| 252 | * write video to muxer. | 252 | * write video to muxer. |
| 253 | */ | 253 | */ |
| 254 | - virtual int write_video(SrsCodec* codec, SrsHlsMuxer* muxer, int64_t dts, SrsCodecSample* sample); | 254 | + virtual int write_video(SrsAvcAacCodec* codec, SrsHlsMuxer* muxer, int64_t dts, SrsCodecSample* sample); |
| 255 | private: | 255 | private: |
| 256 | /** | 256 | /** |
| 257 | * reopen the muxer for a new hls segment, | 257 | * reopen the muxer for a new hls segment, |
| @@ -260,8 +260,8 @@ private: | @@ -260,8 +260,8 @@ private: | ||
| 260 | * so, user must reap_segment then flush_video to hls muxer. | 260 | * so, user must reap_segment then flush_video to hls muxer. |
| 261 | */ | 261 | */ |
| 262 | virtual int reap_segment(std::string log_desc, SrsHlsMuxer* muxer, int64_t segment_start_dts); | 262 | virtual int reap_segment(std::string log_desc, SrsHlsMuxer* muxer, int64_t segment_start_dts); |
| 263 | - virtual int cache_audio(SrsCodec* codec, SrsCodecSample* sample); | ||
| 264 | - virtual int cache_video(SrsCodec* codec, SrsCodecSample* sample); | 263 | + virtual int cache_audio(SrsAvcAacCodec* codec, SrsCodecSample* sample); |
| 264 | + virtual int cache_video(SrsAvcAacCodec* codec, SrsCodecSample* sample); | ||
| 265 | }; | 265 | }; |
| 266 | 266 | ||
| 267 | /** | 267 | /** |
| @@ -277,7 +277,7 @@ private: | @@ -277,7 +277,7 @@ private: | ||
| 277 | private: | 277 | private: |
| 278 | bool hls_enabled; | 278 | bool hls_enabled; |
| 279 | SrsSource* source; | 279 | SrsSource* source; |
| 280 | - SrsCodec* codec; | 280 | + SrsAvcAacCodec* codec; |
| 281 | SrsCodecSample* sample; | 281 | SrsCodecSample* sample; |
| 282 | SrsRtmpJitter* jitter; | 282 | SrsRtmpJitter* jitter; |
| 283 | SrsPithyPrint* pithy_print; | 283 | SrsPithyPrint* pithy_print; |
| @@ -201,7 +201,7 @@ void SrsMessageQueue::shrink() | @@ -201,7 +201,7 @@ void SrsMessageQueue::shrink() | ||
| 201 | SrsSharedPtrMessage* msg = msgs[i]; | 201 | SrsSharedPtrMessage* msg = msgs[i]; |
| 202 | 202 | ||
| 203 | if (msg->header.is_video()) { | 203 | if (msg->header.is_video()) { |
| 204 | - if (SrsCodec::video_is_keyframe(msg->payload, msg->size)) { | 204 | + if (SrsFlvCodec::video_is_keyframe(msg->payload, msg->size)) { |
| 205 | // the max frame index to remove. | 205 | // the max frame index to remove. |
| 206 | iframe_index = i; | 206 | iframe_index = i; |
| 207 | 207 | ||
| @@ -363,7 +363,7 @@ int SrsGopCache::cache(SrsSharedPtrMessage* msg) | @@ -363,7 +363,7 @@ int SrsGopCache::cache(SrsSharedPtrMessage* msg) | ||
| 363 | } | 363 | } |
| 364 | 364 | ||
| 365 | // clear gop cache when got key frame | 365 | // clear gop cache when got key frame |
| 366 | - if (msg->header.is_video() && SrsCodec::video_is_keyframe(msg->payload, msg->size)) { | 366 | + if (msg->header.is_video() && SrsFlvCodec::video_is_keyframe(msg->payload, msg->size)) { |
| 367 | srs_info("clear gop cache when got keyframe. vcount=%d, count=%d", | 367 | srs_info("clear gop cache when got keyframe. vcount=%d, count=%d", |
| 368 | cached_video_count, (int)gop_cache.size()); | 368 | cached_video_count, (int)gop_cache.size()); |
| 369 | 369 | ||
| @@ -1012,7 +1012,7 @@ int SrsSource::on_audio(SrsMessage* audio) | @@ -1012,7 +1012,7 @@ int SrsSource::on_audio(SrsMessage* audio) | ||
| 1012 | 1012 | ||
| 1013 | // cache the sequence header if h264 | 1013 | // cache the sequence header if h264 |
| 1014 | // donot cache the sequence header to gop_cache, return here. | 1014 | // donot cache the sequence header to gop_cache, return here. |
| 1015 | - if (SrsCodec::audio_is_sequence_header(msg->payload, msg->size)) { | 1015 | + if (SrsFlvCodec::audio_is_sequence_header(msg->payload, msg->size)) { |
| 1016 | srs_freep(cache_sh_audio); | 1016 | srs_freep(cache_sh_audio); |
| 1017 | cache_sh_audio = msg->copy(); | 1017 | cache_sh_audio = msg->copy(); |
| 1018 | srs_trace("got audio sh, size=%d", msg->header.payload_length); | 1018 | srs_trace("got audio sh, size=%d", msg->header.payload_length); |
| @@ -1102,7 +1102,7 @@ int SrsSource::on_video(SrsMessage* video) | @@ -1102,7 +1102,7 @@ int SrsSource::on_video(SrsMessage* video) | ||
| 1102 | 1102 | ||
| 1103 | // cache the sequence header if h264 | 1103 | // cache the sequence header if h264 |
| 1104 | // donot cache the sequence header to gop_cache, return here. | 1104 | // donot cache the sequence header to gop_cache, return here. |
| 1105 | - if (SrsCodec::video_is_sequence_header(msg->payload, msg->size)) { | 1105 | + if (SrsFlvCodec::video_is_sequence_header(msg->payload, msg->size)) { |
| 1106 | srs_freep(cache_sh_video); | 1106 | srs_freep(cache_sh_video); |
| 1107 | cache_sh_video = msg->copy(); | 1107 | cache_sh_video = msg->copy(); |
| 1108 | srs_trace("got video sh, size=%d", msg->header.payload_length); | 1108 | srs_trace("got video sh, size=%d", msg->header.payload_length); |
| @@ -31,429 +31,15 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | @@ -31,429 +31,15 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||
| 31 | #include <srs_kernel_log.hpp> | 31 | #include <srs_kernel_log.hpp> |
| 32 | #include <srs_core_autofree.hpp> | 32 | #include <srs_core_autofree.hpp> |
| 33 | 33 | ||
| 34 | -SrsCodecBuffer::SrsCodecBuffer() | 34 | +SrsFlvCodec::SrsFlvCodec() |
| 35 | { | 35 | { |
| 36 | - size = 0; | ||
| 37 | - bytes = NULL; | ||
| 38 | } | 36 | } |
| 39 | 37 | ||
| 40 | -void SrsCodecBuffer::append(void* data, int len) | 38 | +SrsFlvCodec::~SrsFlvCodec() |
| 41 | { | 39 | { |
| 42 | - srs_assert(data); | ||
| 43 | - srs_assert(len > 0); | ||
| 44 | - | ||
| 45 | - bytes = (char*)realloc(bytes, size + len); | ||
| 46 | - memcpy(bytes + size, data, len); | ||
| 47 | - size += len; | ||
| 48 | -} | ||
| 49 | - | ||
| 50 | -void SrsCodecBuffer::free() | ||
| 51 | -{ | ||
| 52 | - size = 0; | ||
| 53 | - srs_freep(bytes); | ||
| 54 | -} | ||
| 55 | - | ||
| 56 | -SrsCodecSample::SrsCodecSample() | ||
| 57 | -{ | ||
| 58 | - clear(); | ||
| 59 | -} | ||
| 60 | - | ||
| 61 | -SrsCodecSample::~SrsCodecSample() | ||
| 62 | -{ | ||
| 63 | -} | ||
| 64 | - | ||
| 65 | -void SrsCodecSample::clear() | ||
| 66 | -{ | ||
| 67 | - is_video = false; | ||
| 68 | - nb_buffers = 0; | ||
| 69 | - | ||
| 70 | - cts = 0; | ||
| 71 | - frame_type = SrsCodecVideoAVCFrameReserved; | ||
| 72 | - avc_packet_type = SrsCodecVideoAVCTypeReserved; | ||
| 73 | - | ||
| 74 | - sound_rate = SrsCodecAudioSampleRateReserved; | ||
| 75 | - sound_size = SrsCodecAudioSampleSizeReserved; | ||
| 76 | - sound_type = SrsCodecAudioSoundTypeReserved; | ||
| 77 | - aac_packet_type = SrsCodecAudioTypeReserved; | ||
| 78 | -} | ||
| 79 | - | ||
| 80 | -int SrsCodecSample::add_sample(char* bytes, int size) | ||
| 81 | -{ | ||
| 82 | - int ret = ERROR_SUCCESS; | ||
| 83 | - | ||
| 84 | - if (nb_buffers >= SRS_MAX_CODEC_SAMPLE) { | ||
| 85 | - ret = ERROR_HLS_DECODE_ERROR; | ||
| 86 | - srs_error("hls decode samples error, " | ||
| 87 | - "exceed the max count: %d, ret=%d", SRS_MAX_CODEC_SAMPLE, ret); | ||
| 88 | - return ret; | ||
| 89 | - } | ||
| 90 | - | ||
| 91 | - SrsCodecBuffer* buf = &buffers[nb_buffers++]; | ||
| 92 | - buf->bytes = bytes; | ||
| 93 | - buf->size = size; | ||
| 94 | - | ||
| 95 | - return ret; | ||
| 96 | -} | ||
| 97 | - | ||
| 98 | -SrsCodec::SrsCodec() | ||
| 99 | -{ | ||
| 100 | - width = 0; | ||
| 101 | - height = 0; | ||
| 102 | - duration = 0; | ||
| 103 | - NAL_unit_length = 0; | ||
| 104 | - frame_rate = 0; | ||
| 105 | - video_data_rate = 0; | ||
| 106 | - video_codec_id = 0; | ||
| 107 | - audio_data_rate = 0; | ||
| 108 | - audio_codec_id = 0; | ||
| 109 | - avc_profile = 0; | ||
| 110 | - avc_level = 0; | ||
| 111 | - aac_profile = 0; | ||
| 112 | - aac_sample_rate = 0; | ||
| 113 | - aac_channels = 0; | ||
| 114 | - avc_extra_size = 0; | ||
| 115 | - avc_extra_data = NULL; | ||
| 116 | - aac_extra_size = 0; | ||
| 117 | - aac_extra_data = NULL; | ||
| 118 | - sequenceParameterSetLength = 0; | ||
| 119 | - sequenceParameterSetNALUnit = NULL; | ||
| 120 | - pictureParameterSetLength = 0; | ||
| 121 | - pictureParameterSetNALUnit = NULL; | ||
| 122 | - | ||
| 123 | - stream = new SrsStream(); | ||
| 124 | -} | ||
| 125 | - | ||
| 126 | -SrsCodec::~SrsCodec() | ||
| 127 | -{ | ||
| 128 | - srs_freep(avc_extra_data); | ||
| 129 | - srs_freep(aac_extra_data); | ||
| 130 | - | ||
| 131 | - srs_freep(stream); | ||
| 132 | - srs_freep(sequenceParameterSetNALUnit); | ||
| 133 | - srs_freep(pictureParameterSetNALUnit); | ||
| 134 | -} | ||
| 135 | - | ||
| 136 | -int SrsCodec::audio_aac_demux(int8_t* data, int size, SrsCodecSample* sample) | ||
| 137 | -{ | ||
| 138 | - int ret = ERROR_SUCCESS; | ||
| 139 | - | ||
| 140 | - sample->is_video = false; | ||
| 141 | - | ||
| 142 | - if (!data || size <= 0) { | ||
| 143 | - srs_trace("no audio present, hls ignore it."); | ||
| 144 | - return ret; | ||
| 145 | - } | ||
| 146 | - | ||
| 147 | - if ((ret = stream->initialize((char*)data, size)) != ERROR_SUCCESS) { | ||
| 148 | - return ret; | ||
| 149 | - } | ||
| 150 | - | ||
| 151 | - // audio decode | ||
| 152 | - if (!stream->require(1)) { | ||
| 153 | - ret = ERROR_HLS_DECODE_ERROR; | ||
| 154 | - srs_error("hls decode audio sound_format failed. ret=%d", ret); | ||
| 155 | - return ret; | ||
| 156 | - } | ||
| 157 | - | ||
| 158 | - int8_t sound_format = stream->read_1bytes(); | ||
| 159 | - | ||
| 160 | - int8_t sound_type = sound_format & 0x01; | ||
| 161 | - int8_t sound_size = (sound_format >> 1) & 0x01; | ||
| 162 | - int8_t sound_rate = (sound_format >> 2) & 0x03; | ||
| 163 | - sound_format = (sound_format >> 4) & 0x0f; | ||
| 164 | - | ||
| 165 | - audio_codec_id = sound_format; | ||
| 166 | - sample->sound_type = (SrsCodecAudioSoundType)sound_type; | ||
| 167 | - sample->sound_rate = (SrsCodecAudioSampleRate)sound_rate; | ||
| 168 | - sample->sound_size = (SrsCodecAudioSampleSize)sound_size; | ||
| 169 | - | ||
| 170 | - // reset the sample rate by sequence header | ||
| 171 | - static int aac_sample_rates[] = { | ||
| 172 | - 96000, 88200, 64000, 48000, | ||
| 173 | - 44100, 32000, 24000, 22050, | ||
| 174 | - 16000, 12000, 11025, 8000, | ||
| 175 | - 7350, 0, 0, 0 | ||
| 176 | - }; | ||
| 177 | - switch (aac_sample_rates[aac_sample_rate]) { | ||
| 178 | - case 11025: | ||
| 179 | - sample->sound_rate = SrsCodecAudioSampleRate11025; | ||
| 180 | - break; | ||
| 181 | - case 22050: | ||
| 182 | - sample->sound_rate = SrsCodecAudioSampleRate22050; | ||
| 183 | - break; | ||
| 184 | - case 44100: | ||
| 185 | - sample->sound_rate = SrsCodecAudioSampleRate44100; | ||
| 186 | - break; | ||
| 187 | - }; | ||
| 188 | - | ||
| 189 | - // only support aac | ||
| 190 | - if (audio_codec_id != SrsCodecAudioAAC) { | ||
| 191 | - ret = ERROR_HLS_DECODE_ERROR; | ||
| 192 | - srs_error("hls only support audio aac codec. actual=%d, ret=%d", audio_codec_id, ret); | ||
| 193 | - return ret; | ||
| 194 | - } | ||
| 195 | - | ||
| 196 | - if (!stream->require(1)) { | ||
| 197 | - ret = ERROR_HLS_DECODE_ERROR; | ||
| 198 | - srs_error("hls decode audio aac_packet_type failed. ret=%d", ret); | ||
| 199 | - return ret; | ||
| 200 | - } | ||
| 201 | - | ||
| 202 | - int8_t aac_packet_type = stream->read_1bytes(); | ||
| 203 | - sample->aac_packet_type = (SrsCodecAudioType)aac_packet_type; | ||
| 204 | - | ||
| 205 | - if (aac_packet_type == SrsCodecAudioTypeSequenceHeader) { | ||
| 206 | - // AudioSpecificConfig | ||
| 207 | - // 1.6.2.1 AudioSpecificConfig, in aac-mp4a-format-ISO_IEC_14496-3+2001.pdf, page 33. | ||
| 208 | - aac_extra_size = stream->left(); | ||
| 209 | - if (aac_extra_size > 0) { | ||
| 210 | - srs_freep(aac_extra_data); | ||
| 211 | - aac_extra_data = new char[aac_extra_size]; | ||
| 212 | - memcpy(aac_extra_data, stream->current(), aac_extra_size); | ||
| 213 | - } | ||
| 214 | - | ||
| 215 | - // only need to decode the first 2bytes: | ||
| 216 | - // audioObjectType, aac_profile, 5bits. | ||
| 217 | - // samplingFrequencyIndex, aac_sample_rate, 4bits. | ||
| 218 | - // channelConfiguration, aac_channels, 4bits | ||
| 219 | - if (!stream->require(2)) { | ||
| 220 | - ret = ERROR_HLS_DECODE_ERROR; | ||
| 221 | - srs_error("hls decode audio aac sequence header failed. ret=%d", ret); | ||
| 222 | - return ret; | ||
| 223 | - } | ||
| 224 | - aac_profile = stream->read_1bytes(); | ||
| 225 | - aac_sample_rate = stream->read_1bytes(); | ||
| 226 | - | ||
| 227 | - aac_channels = (aac_sample_rate >> 3) & 0x0f; | ||
| 228 | - aac_sample_rate = ((aac_profile << 1) & 0x0e) | ((aac_sample_rate >> 7) & 0x01); | ||
| 229 | - aac_profile = (aac_profile >> 3) & 0x1f; | ||
| 230 | - | ||
| 231 | - if (aac_profile == 0 || aac_profile == 0x1f) { | ||
| 232 | - ret = ERROR_HLS_DECODE_ERROR; | ||
| 233 | - srs_error("hls decode audio aac sequence header failed, " | ||
| 234 | - "adts object=%d invalid. ret=%d", aac_profile, ret); | ||
| 235 | - return ret; | ||
| 236 | - } | ||
| 237 | - | ||
| 238 | - // aac_profile = audioObjectType - 1 | ||
| 239 | - aac_profile--; | ||
| 240 | - | ||
| 241 | - if (aac_profile > 3) { | ||
| 242 | - // Mark all extended profiles as LC | ||
| 243 | - // to make Android as happy as possible. | ||
| 244 | - // @see: ngx_rtmp_hls_parse_aac_header | ||
| 245 | - aac_profile = 1; | ||
| 246 | - } | ||
| 247 | - } else if (aac_packet_type == SrsCodecAudioTypeRawData) { | ||
| 248 | - // ensure the sequence header demuxed | ||
| 249 | - if (aac_extra_size <= 0 || !aac_extra_data) { | ||
| 250 | - ret = ERROR_HLS_DECODE_ERROR; | ||
| 251 | - srs_error("hls decode audio aac failed, sequence header not found. ret=%d", ret); | ||
| 252 | - return ret; | ||
| 253 | - } | ||
| 254 | - | ||
| 255 | - // Raw AAC frame data in UI8 [] | ||
| 256 | - // 6.3 Raw Data, aac-iso-13818-7.pdf, page 28 | ||
| 257 | - if ((ret = sample->add_sample(stream->current(), stream->left())) != ERROR_SUCCESS) { | ||
| 258 | - srs_error("hls add audio sample failed. ret=%d", ret); | ||
| 259 | - return ret; | ||
| 260 | - } | ||
| 261 | - } else { | ||
| 262 | - // ignored. | ||
| 263 | - } | ||
| 264 | - | ||
| 265 | - srs_info("audio decoded, type=%d, codec=%d, asize=%d, rate=%d, format=%d, size=%d", | ||
| 266 | - sound_type, audio_codec_id, sound_size, sound_rate, sound_format, size); | ||
| 267 | - | ||
| 268 | - return ret; | ||
| 269 | -} | ||
| 270 | - | ||
| 271 | -int SrsCodec::video_avc_demux(int8_t* data, int size, SrsCodecSample* sample) | ||
| 272 | -{ | ||
| 273 | - int ret = ERROR_SUCCESS; | ||
| 274 | - | ||
| 275 | - sample->is_video = true; | ||
| 276 | - | ||
| 277 | - if (!data || size <= 0) { | ||
| 278 | - srs_trace("no video present, hls ignore it."); | ||
| 279 | - return ret; | ||
| 280 | - } | ||
| 281 | - | ||
| 282 | - if ((ret = stream->initialize((char*)data, size)) != ERROR_SUCCESS) { | ||
| 283 | - return ret; | ||
| 284 | - } | ||
| 285 | - | ||
| 286 | - // video decode | ||
| 287 | - if (!stream->require(1)) { | ||
| 288 | - ret = ERROR_HLS_DECODE_ERROR; | ||
| 289 | - srs_error("hls decode video frame_type failed. ret=%d", ret); | ||
| 290 | - return ret; | ||
| 291 | - } | ||
| 292 | - | ||
| 293 | - int8_t frame_type = stream->read_1bytes(); | ||
| 294 | - int8_t codec_id = frame_type & 0x0f; | ||
| 295 | - frame_type = (frame_type >> 4) & 0x0f; | ||
| 296 | - | ||
| 297 | - sample->frame_type = (SrsCodecVideoAVCFrame)frame_type; | ||
| 298 | - | ||
| 299 | - // only support h.264/avc | ||
| 300 | - if (codec_id != SrsCodecVideoAVC) { | ||
| 301 | - ret = ERROR_HLS_DECODE_ERROR; | ||
| 302 | - srs_error("hls only support video h.264/avc codec. actual=%d, ret=%d", codec_id, ret); | ||
| 303 | - return ret; | ||
| 304 | - } | ||
| 305 | - video_codec_id = codec_id; | ||
| 306 | - | ||
| 307 | - if (!stream->require(4)) { | ||
| 308 | - ret = ERROR_HLS_DECODE_ERROR; | ||
| 309 | - srs_error("hls decode video avc_packet_type failed. ret=%d", ret); | ||
| 310 | - return ret; | ||
| 311 | - } | ||
| 312 | - int8_t avc_packet_type = stream->read_1bytes(); | ||
| 313 | - int32_t composition_time = stream->read_3bytes(); | ||
| 314 | - | ||
| 315 | - // pts = dts + cts. | ||
| 316 | - sample->cts = composition_time; | ||
| 317 | - sample->avc_packet_type = (SrsCodecVideoAVCType)avc_packet_type; | ||
| 318 | - | ||
| 319 | - if (avc_packet_type == SrsCodecVideoAVCTypeSequenceHeader) { | ||
| 320 | - // AVCDecoderConfigurationRecord | ||
| 321 | - // 5.2.4.1.1 Syntax, H.264-AVC-ISO_IEC_14496-15.pdf, page 16 | ||
| 322 | - avc_extra_size = stream->left(); | ||
| 323 | - if (avc_extra_size > 0) { | ||
| 324 | - srs_freep(avc_extra_data); | ||
| 325 | - avc_extra_data = new char[avc_extra_size]; | ||
| 326 | - memcpy(avc_extra_data, stream->current(), avc_extra_size); | ||
| 327 | - } | ||
| 328 | - | ||
| 329 | - if (!stream->require(6)) { | ||
| 330 | - ret = ERROR_HLS_DECODE_ERROR; | ||
| 331 | - srs_error("hls decode video avc sequenc header failed. ret=%d", ret); | ||
| 332 | - return ret; | ||
| 333 | - } | ||
| 334 | - //int8_t configurationVersion = stream->read_1bytes(); | ||
| 335 | - //int8_t AVCProfileIndication = stream->read_1bytes(); | ||
| 336 | - //int8_t profile_compatibility = stream->read_1bytes(); | ||
| 337 | - //int8_t AVCLevelIndication = stream->read_1bytes(); | ||
| 338 | - stream->skip(4); | ||
| 339 | - // parse the NALU size. | ||
| 340 | - int8_t lengthSizeMinusOne = stream->read_1bytes(); | ||
| 341 | - lengthSizeMinusOne &= 0x03; | ||
| 342 | - NAL_unit_length = lengthSizeMinusOne; | ||
| 343 | - | ||
| 344 | - // 1 sps | ||
| 345 | - if (!stream->require(1)) { | ||
| 346 | - ret = ERROR_HLS_DECODE_ERROR; | ||
| 347 | - srs_error("hls decode video avc sequenc header sps failed. ret=%d", ret); | ||
| 348 | - return ret; | ||
| 349 | - } | ||
| 350 | - int8_t numOfSequenceParameterSets = stream->read_1bytes(); | ||
| 351 | - numOfSequenceParameterSets &= 0x1f; | ||
| 352 | - if (numOfSequenceParameterSets != 1) { | ||
| 353 | - ret = ERROR_HLS_DECODE_ERROR; | ||
| 354 | - srs_error("hls decode video avc sequenc header sps failed. ret=%d", ret); | ||
| 355 | - return ret; | ||
| 356 | - } | ||
| 357 | - if (!stream->require(2)) { | ||
| 358 | - ret = ERROR_HLS_DECODE_ERROR; | ||
| 359 | - srs_error("hls decode video avc sequenc header sps size failed. ret=%d", ret); | ||
| 360 | - return ret; | ||
| 361 | - } | ||
| 362 | - sequenceParameterSetLength = stream->read_2bytes(); | ||
| 363 | - if (!stream->require(sequenceParameterSetLength)) { | ||
| 364 | - ret = ERROR_HLS_DECODE_ERROR; | ||
| 365 | - srs_error("hls decode video avc sequenc header sps data failed. ret=%d", ret); | ||
| 366 | - return ret; | ||
| 367 | - } | ||
| 368 | - if (sequenceParameterSetLength > 0) { | ||
| 369 | - srs_freep(sequenceParameterSetNALUnit); | ||
| 370 | - sequenceParameterSetNALUnit = new char[sequenceParameterSetLength]; | ||
| 371 | - memcpy(sequenceParameterSetNALUnit, stream->current(), sequenceParameterSetLength); | ||
| 372 | - stream->skip(sequenceParameterSetLength); | ||
| 373 | - } | ||
| 374 | - // 1 pps | ||
| 375 | - if (!stream->require(1)) { | ||
| 376 | - ret = ERROR_HLS_DECODE_ERROR; | ||
| 377 | - srs_error("hls decode video avc sequenc header pps failed. ret=%d", ret); | ||
| 378 | - return ret; | ||
| 379 | - } | ||
| 380 | - int8_t numOfPictureParameterSets = stream->read_1bytes(); | ||
| 381 | - numOfPictureParameterSets &= 0x1f; | ||
| 382 | - if (numOfPictureParameterSets != 1) { | ||
| 383 | - ret = ERROR_HLS_DECODE_ERROR; | ||
| 384 | - srs_error("hls decode video avc sequenc header pps failed. ret=%d", ret); | ||
| 385 | - return ret; | ||
| 386 | - } | ||
| 387 | - if (!stream->require(2)) { | ||
| 388 | - ret = ERROR_HLS_DECODE_ERROR; | ||
| 389 | - srs_error("hls decode video avc sequenc header pps size failed. ret=%d", ret); | ||
| 390 | - return ret; | ||
| 391 | - } | ||
| 392 | - pictureParameterSetLength = stream->read_2bytes(); | ||
| 393 | - if (!stream->require(pictureParameterSetLength)) { | ||
| 394 | - ret = ERROR_HLS_DECODE_ERROR; | ||
| 395 | - srs_error("hls decode video avc sequenc header pps data failed. ret=%d", ret); | ||
| 396 | - return ret; | ||
| 397 | - } | ||
| 398 | - if (pictureParameterSetLength > 0) { | ||
| 399 | - srs_freep(pictureParameterSetNALUnit); | ||
| 400 | - pictureParameterSetNALUnit = new char[pictureParameterSetLength]; | ||
| 401 | - memcpy(pictureParameterSetNALUnit, stream->current(), pictureParameterSetLength); | ||
| 402 | - stream->skip(pictureParameterSetLength); | ||
| 403 | - } | ||
| 404 | - } else if (avc_packet_type == SrsCodecVideoAVCTypeNALU){ | ||
| 405 | - // ensure the sequence header demuxed | ||
| 406 | - if (avc_extra_size <= 0 || !avc_extra_data) { | ||
| 407 | - ret = ERROR_HLS_DECODE_ERROR; | ||
| 408 | - srs_error("hls decode video avc failed, sequence header not found. ret=%d", ret); | ||
| 409 | - return ret; | ||
| 410 | - } | ||
| 411 | - | ||
| 412 | - // One or more NALUs (Full frames are required) | ||
| 413 | - // 5.3.4.2.1 Syntax, H.264-AVC-ISO_IEC_14496-15.pdf, page 20 | ||
| 414 | - int PictureLength = stream->left(); | ||
| 415 | - for (int i = 0; i < PictureLength;) { | ||
| 416 | - if (!stream->require(NAL_unit_length + 1)) { | ||
| 417 | - ret = ERROR_HLS_DECODE_ERROR; | ||
| 418 | - srs_error("hls decode video avc NALU size failed. ret=%d", ret); | ||
| 419 | - return ret; | ||
| 420 | - } | ||
| 421 | - int32_t NALUnitLength = 0; | ||
| 422 | - if (NAL_unit_length == 3) { | ||
| 423 | - NALUnitLength = stream->read_4bytes(); | ||
| 424 | - } else if (NALUnitLength == 2) { | ||
| 425 | - NALUnitLength = stream->read_3bytes(); | ||
| 426 | - } else if (NALUnitLength == 1) { | ||
| 427 | - NALUnitLength = stream->read_2bytes(); | ||
| 428 | - } else { | ||
| 429 | - NALUnitLength = stream->read_1bytes(); | ||
| 430 | - } | ||
| 431 | - // NALUnit | ||
| 432 | - if (!stream->require(NALUnitLength)) { | ||
| 433 | - ret = ERROR_HLS_DECODE_ERROR; | ||
| 434 | - srs_error("hls decode video avc NALU data failed. ret=%d", ret); | ||
| 435 | - return ret; | ||
| 436 | - } | ||
| 437 | - // 7.3.1 NAL unit syntax, H.264-AVC-ISO_IEC_14496-10.pdf, page 44. | ||
| 438 | - if ((ret = sample->add_sample(stream->current(), NALUnitLength)) != ERROR_SUCCESS) { | ||
| 439 | - srs_error("hls add video sample failed. ret=%d", ret); | ||
| 440 | - return ret; | ||
| 441 | - } | ||
| 442 | - stream->skip(NALUnitLength); | ||
| 443 | - | ||
| 444 | - i += NAL_unit_length + 1 + NALUnitLength; | ||
| 445 | - } | ||
| 446 | - } else { | ||
| 447 | - // ignored. | ||
| 448 | - } | ||
| 449 | - | ||
| 450 | - srs_info("video decoded, type=%d, codec=%d, avc=%d, time=%d, size=%d", | ||
| 451 | - frame_type, video_codec_id, avc_packet_type, composition_time, size); | ||
| 452 | - | ||
| 453 | - return ret; | ||
| 454 | } | 40 | } |
| 455 | 41 | ||
| 456 | -bool SrsCodec::video_is_keyframe(int8_t* data, int size) | 42 | +bool SrsFlvCodec::video_is_keyframe(int8_t* data, int size) |
| 457 | { | 43 | { |
| 458 | // 2bytes required. | 44 | // 2bytes required. |
| 459 | if (size < 1) { | 45 | if (size < 1) { |
| @@ -466,7 +52,7 @@ bool SrsCodec::video_is_keyframe(int8_t* data, int size) | @@ -466,7 +52,7 @@ bool SrsCodec::video_is_keyframe(int8_t* data, int size) | ||
| 466 | return frame_type == SrsCodecVideoAVCFrameKeyFrame; | 52 | return frame_type == SrsCodecVideoAVCFrameKeyFrame; |
| 467 | } | 53 | } |
| 468 | 54 | ||
| 469 | -bool SrsCodec::video_is_sequence_header(int8_t* data, int size) | 55 | +bool SrsFlvCodec::video_is_sequence_header(int8_t* data, int size) |
| 470 | { | 56 | { |
| 471 | // sequence header only for h264 | 57 | // sequence header only for h264 |
| 472 | if (!video_is_h264(data, size)) { | 58 | if (!video_is_h264(data, size)) { |
| @@ -487,7 +73,7 @@ bool SrsCodec::video_is_sequence_header(int8_t* data, int size) | @@ -487,7 +73,7 @@ bool SrsCodec::video_is_sequence_header(int8_t* data, int size) | ||
| 487 | && avc_packet_type == SrsCodecVideoAVCTypeSequenceHeader; | 73 | && avc_packet_type == SrsCodecVideoAVCTypeSequenceHeader; |
| 488 | } | 74 | } |
| 489 | 75 | ||
| 490 | -bool SrsCodec::audio_is_sequence_header(int8_t* data, int size) | 76 | +bool SrsFlvCodec::audio_is_sequence_header(int8_t* data, int size) |
| 491 | { | 77 | { |
| 492 | // sequence header only for aac | 78 | // sequence header only for aac |
| 493 | if (!audio_is_aac(data, size)) { | 79 | if (!audio_is_aac(data, size)) { |
| @@ -504,7 +90,7 @@ bool SrsCodec::audio_is_sequence_header(int8_t* data, int size) | @@ -504,7 +90,7 @@ bool SrsCodec::audio_is_sequence_header(int8_t* data, int size) | ||
| 504 | return aac_packet_type == SrsCodecAudioTypeSequenceHeader; | 90 | return aac_packet_type == SrsCodecAudioTypeSequenceHeader; |
| 505 | } | 91 | } |
| 506 | 92 | ||
| 507 | -bool SrsCodec::video_is_h264(int8_t* data, int size) | 93 | +bool SrsFlvCodec::video_is_h264(int8_t* data, int size) |
| 508 | { | 94 | { |
| 509 | // 1bytes required. | 95 | // 1bytes required. |
| 510 | if (size < 1) { | 96 | if (size < 1) { |
| @@ -517,7 +103,7 @@ bool SrsCodec::video_is_h264(int8_t* data, int size) | @@ -517,7 +103,7 @@ bool SrsCodec::video_is_h264(int8_t* data, int size) | ||
| 517 | return codec_id == SrsCodecVideoAVC; | 103 | return codec_id == SrsCodecVideoAVC; |
| 518 | } | 104 | } |
| 519 | 105 | ||
| 520 | -bool SrsCodec::audio_is_aac(int8_t* data, int size) | 106 | +bool SrsFlvCodec::audio_is_aac(int8_t* data, int size) |
| 521 | { | 107 | { |
| 522 | // 1bytes required. | 108 | // 1bytes required. |
| 523 | if (size < 1) { | 109 | if (size < 1) { |
| @@ -30,29 +30,17 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | @@ -30,29 +30,17 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||
| 30 | 30 | ||
| 31 | #include <srs_core.hpp> | 31 | #include <srs_core.hpp> |
| 32 | 32 | ||
| 33 | -#define SRS_MAX_CODEC_SAMPLE 128 | ||
| 34 | - | ||
| 35 | class SrsStream; | 33 | class SrsStream; |
| 36 | 34 | ||
| 37 | -// E.4.3.1 VIDEODATA | ||
| 38 | -// CodecID UB [4] | ||
| 39 | -// Codec Identifier. The following values are defined: | ||
| 40 | -// 2 = Sorenson H.263 | ||
| 41 | -// 3 = Screen video | ||
| 42 | -// 4 = On2 VP6 | ||
| 43 | -// 5 = On2 VP6 with alpha channel | ||
| 44 | -// 6 = Screen video version 2 | ||
| 45 | -// 7 = AVC | ||
| 46 | -enum SrsCodecVideo | 35 | +// AACPacketType IF SoundFormat == 10 UI8 |
| 36 | +// The following values are defined: | ||
| 37 | +// 0 = AAC sequence header | ||
| 38 | +// 1 = AAC raw | ||
| 39 | +enum SrsCodecAudioType | ||
| 47 | { | 40 | { |
| 48 | - SrsCodecVideoReserved = 0, | ||
| 49 | - | ||
| 50 | - SrsCodecVideoSorensonH263 = 2, | ||
| 51 | - SrsCodecVideoScreenVideo = 3, | ||
| 52 | - SrsCodecVideoOn2VP6 = 4, | ||
| 53 | - SrsCodecVideoOn2VP6WithAlphaChannel = 5, | ||
| 54 | - SrsCodecVideoScreenVideoVersion2 = 6, | ||
| 55 | - SrsCodecVideoAVC = 7, | 41 | + SrsCodecAudioTypeReserved = -1, |
| 42 | + SrsCodecAudioTypeSequenceHeader = 0, | ||
| 43 | + SrsCodecAudioTypeRawData = 1, | ||
| 56 | }; | 44 | }; |
| 57 | 45 | ||
| 58 | // E.4.3.1 VIDEODATA | 46 | // E.4.3.1 VIDEODATA |
| @@ -89,6 +77,27 @@ enum SrsCodecVideoAVCType | @@ -89,6 +77,27 @@ enum SrsCodecVideoAVCType | ||
| 89 | SrsCodecVideoAVCTypeSequenceHeaderEOF = 2, | 77 | SrsCodecVideoAVCTypeSequenceHeaderEOF = 2, |
| 90 | }; | 78 | }; |
| 91 | 79 | ||
| 80 | +// E.4.3.1 VIDEODATA | ||
| 81 | +// CodecID UB [4] | ||
| 82 | +// Codec Identifier. The following values are defined: | ||
| 83 | +// 2 = Sorenson H.263 | ||
| 84 | +// 3 = Screen video | ||
| 85 | +// 4 = On2 VP6 | ||
| 86 | +// 5 = On2 VP6 with alpha channel | ||
| 87 | +// 6 = Screen video version 2 | ||
| 88 | +// 7 = AVC | ||
| 89 | +enum SrsCodecVideo | ||
| 90 | +{ | ||
| 91 | + SrsCodecVideoReserved = 0, | ||
| 92 | + | ||
| 93 | + SrsCodecVideoSorensonH263 = 2, | ||
| 94 | + SrsCodecVideoScreenVideo = 3, | ||
| 95 | + SrsCodecVideoOn2VP6 = 4, | ||
| 96 | + SrsCodecVideoOn2VP6WithAlphaChannel = 5, | ||
| 97 | + SrsCodecVideoScreenVideoVersion2 = 6, | ||
| 98 | + SrsCodecVideoAVC = 7, | ||
| 99 | +}; | ||
| 100 | + | ||
| 92 | // SoundFormat UB [4] | 101 | // SoundFormat UB [4] |
| 93 | // Format of SoundData. The following values are defined: | 102 | // Format of SoundData. The following values are defined: |
| 94 | // 0 = Linear PCM, platform endian | 103 | // 0 = Linear PCM, platform endian |
| @@ -126,165 +135,15 @@ enum SrsCodecAudio | @@ -126,165 +135,15 @@ enum SrsCodecAudio | ||
| 126 | SrsCodecAudioReservedDeviceSpecificSound = 15, | 135 | SrsCodecAudioReservedDeviceSpecificSound = 15, |
| 127 | }; | 136 | }; |
| 128 | 137 | ||
| 129 | -// AACPacketType IF SoundFormat == 10 UI8 | ||
| 130 | -// The following values are defined: | ||
| 131 | -// 0 = AAC sequence header | ||
| 132 | -// 1 = AAC raw | ||
| 133 | -enum SrsCodecAudioType | ||
| 134 | -{ | ||
| 135 | - SrsCodecAudioTypeReserved = -1, | ||
| 136 | - SrsCodecAudioTypeSequenceHeader = 0, | ||
| 137 | - SrsCodecAudioTypeRawData = 1, | ||
| 138 | -}; | ||
| 139 | - | ||
| 140 | -// Sampling rate. The following values are defined: | ||
| 141 | -// 0 = 5.5 kHz = 5512 Hz | ||
| 142 | -// 1 = 11 kHz = 11025 Hz | ||
| 143 | -// 2 = 22 kHz = 22050 Hz | ||
| 144 | -// 3 = 44 kHz = 44100 Hz | ||
| 145 | -enum SrsCodecAudioSampleRate | ||
| 146 | -{ | ||
| 147 | - SrsCodecAudioSampleRateReserved = -1, | ||
| 148 | - | ||
| 149 | - SrsCodecAudioSampleRate5512 = 0, | ||
| 150 | - SrsCodecAudioSampleRate11025 = 1, | ||
| 151 | - SrsCodecAudioSampleRate22050 = 2, | ||
| 152 | - SrsCodecAudioSampleRate44100 = 3, | ||
| 153 | -}; | ||
| 154 | - | ||
| 155 | -// Size of each audio sample. This parameter only pertains to | ||
| 156 | -// uncompressed formats. Compressed formats always decode | ||
| 157 | -// to 16 bits internally. | ||
| 158 | -// 0 = 8-bit samples | ||
| 159 | -// 1 = 16-bit samples | ||
| 160 | -enum SrsCodecAudioSampleSize | ||
| 161 | -{ | ||
| 162 | - SrsCodecAudioSampleSizeReserved = -1, | ||
| 163 | - | ||
| 164 | - SrsCodecAudioSampleSize8bit = 0, | ||
| 165 | - SrsCodecAudioSampleSize16bit = 1, | ||
| 166 | -}; | ||
| 167 | - | ||
| 168 | -// Mono or stereo sound | ||
| 169 | -// 0 = Mono sound | ||
| 170 | -// 1 = Stereo sound | ||
| 171 | -enum SrsCodecAudioSoundType | ||
| 172 | -{ | ||
| 173 | - SrsCodecAudioSoundTypeReserved = -1, | ||
| 174 | - | ||
| 175 | - SrsCodecAudioSoundTypeMono = 0, | ||
| 176 | - SrsCodecAudioSoundTypeStereo = 1, | ||
| 177 | -}; | ||
| 178 | - | ||
| 179 | -/** | ||
| 180 | -* buffer indicates the position and size. | ||
| 181 | -*/ | ||
| 182 | -class SrsCodecBuffer | ||
| 183 | -{ | ||
| 184 | -public: | ||
| 185 | - /** | ||
| 186 | - * @remark user must manage the bytes. | ||
| 187 | - */ | ||
| 188 | - int size; | ||
| 189 | - char* bytes; | ||
| 190 | - | ||
| 191 | - SrsCodecBuffer(); | ||
| 192 | - void append(void* data, int len); | ||
| 193 | - | ||
| 194 | - /** | ||
| 195 | - * free the bytes, | ||
| 196 | - * user can invoke it to free the bytes, | ||
| 197 | - * the SrsCodecBuffer never free automatically. | ||
| 198 | - */ | ||
| 199 | - void free(); | ||
| 200 | -}; | ||
| 201 | - | ||
| 202 | -/** | ||
| 203 | -* the samples in the flv audio/video packet. | ||
| 204 | -*/ | ||
| 205 | -class SrsCodecSample | ||
| 206 | -{ | ||
| 207 | -public: | ||
| 208 | - int nb_buffers; | ||
| 209 | - SrsCodecBuffer buffers[SRS_MAX_CODEC_SAMPLE]; | ||
| 210 | -public: | ||
| 211 | - bool is_video; | ||
| 212 | - // video specified | ||
| 213 | - SrsCodecVideoAVCFrame frame_type; | ||
| 214 | - SrsCodecVideoAVCType avc_packet_type; | ||
| 215 | - // CompositionTime, video_file_format_spec_v10_1.pdf, page 78. | ||
| 216 | - // cts = pts - dts, where dts = flvheader->timestamp. | ||
| 217 | - int32_t cts; | ||
| 218 | - // audio specified | ||
| 219 | - SrsCodecAudioSampleRate sound_rate; | ||
| 220 | - SrsCodecAudioSampleSize sound_size; | ||
| 221 | - SrsCodecAudioSoundType sound_type; | ||
| 222 | - SrsCodecAudioType aac_packet_type; | ||
| 223 | -public: | ||
| 224 | - SrsCodecSample(); | ||
| 225 | - virtual ~SrsCodecSample(); | ||
| 226 | - void clear(); | ||
| 227 | - int add_sample(char* bytes, int size); | ||
| 228 | -}; | ||
| 229 | - | ||
| 230 | /** | 138 | /** |
| 231 | * Annex E. The FLV File Format | 139 | * Annex E. The FLV File Format |
| 140 | +* @see SrsAvcAacCodec for the media stream codec. | ||
| 232 | */ | 141 | */ |
| 233 | -class SrsCodec | 142 | +class SrsFlvCodec |
| 234 | { | 143 | { |
| 235 | -private: | ||
| 236 | - SrsStream* stream; | ||
| 237 | -public: | ||
| 238 | - /** | ||
| 239 | - * video specified | ||
| 240 | - */ | ||
| 241 | - // @see: SrsCodecVideo | ||
| 242 | - int video_codec_id; | ||
| 243 | - // profile_idc, H.264-AVC-ISO_IEC_14496-10.pdf, page 45. | ||
| 244 | - u_int8_t avc_profile; | ||
| 245 | - // level_idc, H.264-AVC-ISO_IEC_14496-10.pdf, page 45. | ||
| 246 | - u_int8_t avc_level; | ||
| 247 | - int width; | ||
| 248 | - int height; | ||
| 249 | - int video_data_rate; // in bps | ||
| 250 | - int frame_rate; | ||
| 251 | - int duration; | ||
| 252 | - // lengthSizeMinusOne, H.264-AVC-ISO_IEC_14496-15.pdf, page 16 | ||
| 253 | - int8_t NAL_unit_length; | ||
| 254 | - u_int16_t sequenceParameterSetLength; | ||
| 255 | - char* sequenceParameterSetNALUnit; | ||
| 256 | - u_int16_t pictureParameterSetLength; | ||
| 257 | - char* pictureParameterSetNALUnit; | ||
| 258 | - /** | ||
| 259 | - * audio specified | ||
| 260 | - */ | ||
| 261 | - // @see: SrsCodecAudioType | ||
| 262 | - int audio_codec_id; | ||
| 263 | - int audio_data_rate; // in bps | ||
| 264 | - // 1.6.2.1 AudioSpecificConfig, in aac-mp4a-format-ISO_IEC_14496-3+2001.pdf, page 33. | ||
| 265 | - // audioObjectType, value defines in 7.1 Profiles, aac-iso-13818-7.pdf, page 40. | ||
| 266 | - u_int8_t aac_profile; | ||
| 267 | - // samplingFrequencyIndex | ||
| 268 | - u_int8_t aac_sample_rate; | ||
| 269 | - // channelConfiguration | ||
| 270 | - u_int8_t aac_channels; | ||
| 271 | - // the avc extra data, the AVC sequence header, | ||
| 272 | - // without the flv codec header, | ||
| 273 | - // @see: ffmpeg, AVCodecContext::extradata | ||
| 274 | - int avc_extra_size; | ||
| 275 | - char* avc_extra_data; | ||
| 276 | - // the aac extra data, the AAC sequence header, | ||
| 277 | - // without the flv codec header, | ||
| 278 | - // @see: ffmpeg, AVCodecContext::extradata | ||
| 279 | - int aac_extra_size; | ||
| 280 | - char* aac_extra_data; | ||
| 281 | -public: | ||
| 282 | - SrsCodec(); | ||
| 283 | - virtual ~SrsCodec(); | ||
| 284 | -// the following function used for hls to build the codec info. | ||
| 285 | public: | 144 | public: |
| 286 | - virtual int audio_aac_demux(int8_t* data, int size, SrsCodecSample* sample); | ||
| 287 | - virtual int video_avc_demux(int8_t* data, int size, SrsCodecSample* sample); | 145 | + SrsFlvCodec(); |
| 146 | + virtual ~SrsFlvCodec(); | ||
| 288 | // the following function used to finger out the flv/rtmp packet detail. | 147 | // the following function used to finger out the flv/rtmp packet detail. |
| 289 | public: | 148 | public: |
| 290 | /** | 149 | /** |
| @@ -540,12 +540,12 @@ flv_bool srs_flv_is_eof(int error_code) | @@ -540,12 +540,12 @@ flv_bool srs_flv_is_eof(int error_code) | ||
| 540 | 540 | ||
| 541 | flv_bool srs_flv_is_sequence_header(char* data, int32_t size) | 541 | flv_bool srs_flv_is_sequence_header(char* data, int32_t size) |
| 542 | { | 542 | { |
| 543 | - return SrsCodec::video_is_sequence_header((int8_t*)data, (int)size); | 543 | + return SrsFlvCodec::video_is_sequence_header((int8_t*)data, (int)size); |
| 544 | } | 544 | } |
| 545 | 545 | ||
| 546 | flv_bool srs_flv_is_keyframe(char* data, int32_t size) | 546 | flv_bool srs_flv_is_keyframe(char* data, int32_t size) |
| 547 | { | 547 | { |
| 548 | - return SrsCodec::video_is_keyframe((int8_t*)data, (int)size); | 548 | + return SrsFlvCodec::video_is_keyframe((int8_t*)data, (int)size); |
| 549 | } | 549 | } |
| 550 | 550 | ||
| 551 | srs_amf0_t srs_amf0_parse(char* data, int size, int* nparsed) | 551 | srs_amf0_t srs_amf0_parse(char* data, int size, int* nparsed) |
| @@ -43,6 +43,8 @@ file | @@ -43,6 +43,8 @@ file | ||
| 43 | ..\rtmp\srs_protocol_utility.hpp, | 43 | ..\rtmp\srs_protocol_utility.hpp, |
| 44 | ..\rtmp\srs_protocol_utility.cpp, | 44 | ..\rtmp\srs_protocol_utility.cpp, |
| 45 | app readonly separator, | 45 | app readonly separator, |
| 46 | + ..\app\srs_app_avc_aac.hpp, | ||
| 47 | + ..\app\srs_app_avc_aac.cpp, | ||
| 46 | ..\app\srs_app_bandwidth.hpp, | 48 | ..\app\srs_app_bandwidth.hpp, |
| 47 | ..\app\srs_app_bandwidth.cpp, | 49 | ..\app\srs_app_bandwidth.cpp, |
| 48 | ..\app\srs_app_conn.hpp, | 50 | ..\app\srs_app_conn.hpp, |
-
请 注册 或 登录 后发表评论