| @@ -180,6 +180,66 @@ static int sdp_parse_fmtp_config_h264(AVFormatContext *s, | |||||
| return 0; | return 0; | ||||
| } | } | ||||
| static int h264_handle_packet_stap_a(AVFormatContext *ctx, AVPacket *pkt, | |||||
| const uint8_t *buf, int len) | |||||
| { | |||||
| int pass = 0; | |||||
| int total_length = 0; | |||||
| uint8_t *dst = NULL; | |||||
| int ret; | |||||
| for (pass = 0; pass < 2; pass++) { | |||||
| const uint8_t *src = buf; | |||||
| int src_len = len; | |||||
| while (src_len > 2) { | |||||
| uint16_t nal_size = AV_RB16(src); | |||||
| // consume the length of the aggregate | |||||
| src += 2; | |||||
| src_len -= 2; | |||||
| if (nal_size <= src_len) { | |||||
| if (pass == 0) { | |||||
| // counting | |||||
| total_length += sizeof(start_sequence) + nal_size; | |||||
| } else { | |||||
| // copying | |||||
| assert(dst); | |||||
| memcpy(dst, start_sequence, sizeof(start_sequence)); | |||||
| dst += sizeof(start_sequence); | |||||
| memcpy(dst, src, nal_size); | |||||
| COUNT_NAL_TYPE(data, *src); | |||||
| dst += nal_size; | |||||
| } | |||||
| } else { | |||||
| av_log(ctx, AV_LOG_ERROR, | |||||
| "nal size exceeds length: %d %d\n", nal_size, src_len); | |||||
| } | |||||
| // eat what we handled | |||||
| src += nal_size; | |||||
| src_len -= nal_size; | |||||
| if (src_len < 0) | |||||
| av_log(ctx, AV_LOG_ERROR, | |||||
| "Consumed more bytes than we got! (%d)\n", src_len); | |||||
| } | |||||
| if (pass == 0) { | |||||
| /* now we know the total size of the packet (with the | |||||
| * start sequences added) */ | |||||
| if ((ret = av_new_packet(pkt, total_length)) < 0) | |||||
| return ret; | |||||
| dst = pkt->data; | |||||
| } else { | |||||
| assert(dst - pkt->data == total_length); | |||||
| } | |||||
| } | |||||
| return 0; | |||||
| } | |||||
| // return 0 on packet, no more left, 1 on packet, 1 on partial packet | // return 0 on packet, no more left, 1 on packet, 1 on partial packet | ||||
| static int h264_handle_packet(AVFormatContext *ctx, PayloadContext *data, | static int h264_handle_packet(AVFormatContext *ctx, PayloadContext *data, | ||||
| AVStream *st, AVPacket *pkt, uint32_t *timestamp, | AVStream *st, AVPacket *pkt, uint32_t *timestamp, | ||||
| @@ -219,60 +279,7 @@ static int h264_handle_packet(AVFormatContext *ctx, PayloadContext *data, | |||||
| buf++; | buf++; | ||||
| len--; | len--; | ||||
| // first we are going to figure out the total size | // first we are going to figure out the total size | ||||
| { | |||||
| int pass = 0; | |||||
| int total_length = 0; | |||||
| uint8_t *dst = NULL; | |||||
| for (pass = 0; pass < 2; pass++) { | |||||
| const uint8_t *src = buf; | |||||
| int src_len = len; | |||||
| while (src_len > 2) { | |||||
| uint16_t nal_size = AV_RB16(src); | |||||
| // consume the length of the aggregate | |||||
| src += 2; | |||||
| src_len -= 2; | |||||
| if (nal_size <= src_len) { | |||||
| if (pass == 0) { | |||||
| // counting | |||||
| total_length += sizeof(start_sequence) + nal_size; | |||||
| } else { | |||||
| // copying | |||||
| assert(dst); | |||||
| memcpy(dst, start_sequence, sizeof(start_sequence)); | |||||
| dst += sizeof(start_sequence); | |||||
| memcpy(dst, src, nal_size); | |||||
| COUNT_NAL_TYPE(data, *src); | |||||
| dst += nal_size; | |||||
| } | |||||
| } else { | |||||
| av_log(ctx, AV_LOG_ERROR, | |||||
| "nal size exceeds length: %d %d\n", nal_size, src_len); | |||||
| } | |||||
| // eat what we handled | |||||
| src += nal_size; | |||||
| src_len -= nal_size; | |||||
| if (src_len < 0) | |||||
| av_log(ctx, AV_LOG_ERROR, | |||||
| "Consumed more bytes than we got! (%d)\n", src_len); | |||||
| } | |||||
| if (pass == 0) { | |||||
| /* now we know the total size of the packet (with the | |||||
| * start sequences added) */ | |||||
| if ((result = av_new_packet(pkt, total_length)) < 0) | |||||
| return result; | |||||
| dst = pkt->data; | |||||
| } else { | |||||
| assert(dst - pkt->data == total_length); | |||||
| } | |||||
| } | |||||
| } | |||||
| result = h264_handle_packet_stap_a(ctx, pkt, buf, len); | |||||
| break; | break; | ||||
| case 25: // STAP-B | case 25: // STAP-B | ||||