diff options
author | Michael Niedermayer <michaelni@gmx.at> | 2012-05-06 21:31:08 +0200 |
---|---|---|
committer | Michael Niedermayer <michaelni@gmx.at> | 2012-05-06 21:53:19 +0200 |
commit | 715c8a5a5052d67423f27192444474a3d61dce60 (patch) | |
tree | 4d96bf6fdbbbebef82f0263d2fde088cd4ee9a09 /libavformat/rtpdec_h264.c | |
parent | cbbc4724672ec5839427f9b4129051fac9de390b (diff) | |
parent | fb5c1aaea60a714dab3d4e6e71228855fd816222 (diff) | |
download | ffmpeg-715c8a5a5052d67423f27192444474a3d61dce60.tar.gz |
Merge remote-tracking branch 'qatar/master'
* qatar/master: (28 commits)
dfa: use more meaningful return codes
eatgv: check vector_bits
eatgv: check motion vectors
Mark a number of variables only used in av_dlog() calls as av_unused.
dvdec: drop const qualifier from variable to eliminate a warning
avcodec: Improve comment for thread_safe_callbacks to avoid misinterpretation.
tests/utils: don't ignore the return value of fwrite()
lavfi/formats: use sizeof(var) instead of sizeof(type).
lavfi: remove avfilter_default_config_input_link() declaration
lavfi: always enable the scale filter and depend on sws.
vf_split: support user-specifiable number of outputs.
avconv: remove stray useless comment.
mpegmux: add stuffing to avoid incomplete PCM frames
rtsp: avoid const warnings from strtol() call
avserver: check return value of ftruncate()
lagarith: make offset array type unsigned
dfa: add some checks to ensure that decoder won't write past frame end
aacps: NEON optimisations
aacps: align some arrays
aacps: move some loops to function pointers
...
Conflicts:
configure
doc/filters.texi
libavcodec/dfa.c
libavcodec/eatgv.c
libavfilter/Makefile
libavfilter/allfilters.c
libavfilter/avfilter.h
libavfilter/formats.c
libavfilter/vf_split.c
Merged-by: Michael Niedermayer <michaelni@gmx.at>
Diffstat (limited to 'libavformat/rtpdec_h264.c')
-rw-r--r-- | libavformat/rtpdec_h264.c | 227 |
1 files changed, 119 insertions, 108 deletions
diff --git a/libavformat/rtpdec_h264.c b/libavformat/rtpdec_h264.c index 6ec4075a7c..096b35f20a 100644 --- a/libavformat/rtpdec_h264.c +++ b/libavformat/rtpdec_h264.c @@ -20,7 +20,7 @@ */ /** -* @file + * @file * @brief H.264 / RTP Code (RFC3984) * @author Ryan Martell <rdm4@martellventures.com> * @@ -29,7 +29,8 @@ * This currently supports packetization mode: * Single Nal Unit Mode (0), or * Non-Interleaved Mode (1). It currently does not support - * Interleaved Mode (2). (This requires implementing STAP-B, MTAP16, MTAP24, FU-B packet types) + * Interleaved Mode (2). (This requires implementing STAP-B, MTAP16, MTAP24, + * FU-B packet types) */ #include "libavutil/base64.h" @@ -46,7 +47,7 @@ #include "rtpdec_formats.h" struct PayloadContext { - //sdp setup parameters + // sdp setup parameters uint8_t profile_idc; uint8_t profile_iop; uint8_t level_idc; @@ -56,8 +57,16 @@ struct PayloadContext { #endif }; -static int sdp_parse_fmtp_config_h264(AVStream * stream, - PayloadContext * h264_data, +#ifdef DEBUG +#define COUNT_NAL_TYPE(data, nal) data->packet_types_received[(nal) & 0x1f]++ +#else +#define COUNT_NAL_TYPE(data, nal) do { } while (0) +#endif + +static const uint8_t start_sequence[] = { 0, 0, 0, 1 }; + +static int sdp_parse_fmtp_config_h264(AVStream *stream, + PayloadContext *h264_data, char *attr, char *value) { AVCodecContext *codec = stream->codec; @@ -68,14 +77,15 @@ static int sdp_parse_fmtp_config_h264(AVStream * stream, av_log(codec, AV_LOG_DEBUG, "RTP Packetization Mode: %d\n", atoi(value)); h264_data->packetization_mode = atoi(value); /* - Packetization Mode: - 0 or not present: Single NAL mode (Only nals from 1-23 are allowed) - 1: Non-interleaved Mode: 1-23, 24 (STAP-A), 28 (FU-A) are allowed. - 2: Interleaved Mode: 25 (STAP-B), 26 (MTAP16), 27 (MTAP24), 28 (FU-A), and 29 (FU-B) are allowed. + * Packetization Mode: + * 0 or not present: Single NAL mode (Only nals from 1-23 are allowed) + * 1: Non-interleaved Mode: 1-23, 24 (STAP-A), 28 (FU-A) are allowed. + * 2: Interleaved Mode: 25 (STAP-B), 26 (MTAP16), 27 (MTAP24), 28 (FU-A), + * and 29 (FU-B) are allowed. */ if (h264_data->packetization_mode > 1) av_log(codec, AV_LOG_ERROR, - "Interleaved RTP mode is not supported yet."); + "Interleaved RTP mode is not supported yet.\n"); } else if (!strcmp(attr, "profile-level-id")) { if (strlen(value) == 6) { char buffer[3]; @@ -84,24 +94,27 @@ static int sdp_parse_fmtp_config_h264(AVStream * stream, uint8_t profile_iop; uint8_t level_idc; - buffer[0] = value[0]; buffer[1] = value[1]; buffer[2] = '\0'; + buffer[0] = value[0]; + buffer[1] = value[1]; + buffer[2] = '\0'; profile_idc = strtol(buffer, NULL, 16); - buffer[0] = value[2]; buffer[1] = value[3]; + buffer[0] = value[2]; + buffer[1] = value[3]; profile_iop = strtol(buffer, NULL, 16); - buffer[0] = value[4]; buffer[1] = value[5]; - level_idc = strtol(buffer, NULL, 16); + buffer[0] = value[4]; + buffer[1] = value[5]; + level_idc = strtol(buffer, NULL, 16); av_log(codec, AV_LOG_DEBUG, "RTP Profile IDC: %x Profile IOP: %x Level: %x\n", profile_idc, profile_iop, level_idc); h264_data->profile_idc = profile_idc; h264_data->profile_iop = profile_iop; - h264_data->level_idc = level_idc; + h264_data->level_idc = level_idc; } - } else if (!strcmp(attr, "sprop-parameter-sets")) { - uint8_t start_sequence[] = { 0, 0, 0, 1 }; - codec->extradata_size= 0; - codec->extradata= NULL; + } else if (!strcmp(attr, "sprop-parameter-sets")) { + codec->extradata_size = 0; + av_freep(&codec->extradata); while (*value) { char base64packet[1024]; @@ -118,50 +131,47 @@ static int sdp_parse_fmtp_config_h264(AVStream * stream, if (*value == ',') value++; - packet_size= av_base64_decode(decoded_packet, base64packet, sizeof(decoded_packet)); + packet_size = av_base64_decode(decoded_packet, base64packet, + sizeof(decoded_packet)); if (packet_size > 0) { uint8_t *dest = av_malloc(packet_size + sizeof(start_sequence) + - codec->extradata_size + - FF_INPUT_BUFFER_PADDING_SIZE); - if(dest) - { - if(codec->extradata_size) - { - memcpy(dest, codec->extradata, codec->extradata_size); - av_free(codec->extradata); - } - - memcpy(dest+codec->extradata_size, start_sequence, sizeof(start_sequence)); - memcpy(dest+codec->extradata_size+sizeof(start_sequence), decoded_packet, packet_size); - memset(dest+codec->extradata_size+sizeof(start_sequence)+ - packet_size, 0, FF_INPUT_BUFFER_PADDING_SIZE); - - codec->extradata= dest; - codec->extradata_size+= sizeof(start_sequence)+packet_size; - } else { - av_log(codec, AV_LOG_ERROR, "Unable to allocate memory for extradata!"); + codec->extradata_size + + FF_INPUT_BUFFER_PADDING_SIZE); + if (!dest) { + av_log(codec, AV_LOG_ERROR, + "Unable to allocate memory for extradata!\n"); return AVERROR(ENOMEM); } + if (codec->extradata_size) { + memcpy(dest, codec->extradata, codec->extradata_size); + av_free(codec->extradata); + } + + memcpy(dest + codec->extradata_size, start_sequence, + sizeof(start_sequence)); + memcpy(dest + codec->extradata_size + sizeof(start_sequence), + decoded_packet, packet_size); + memset(dest + codec->extradata_size + sizeof(start_sequence) + + packet_size, 0, FF_INPUT_BUFFER_PADDING_SIZE); + + codec->extradata = dest; + codec->extradata_size += sizeof(start_sequence) + packet_size; } } - av_log(codec, AV_LOG_DEBUG, "Extradata set to %p (size: %d)!", codec->extradata, codec->extradata_size); + av_log(codec, AV_LOG_DEBUG, "Extradata set to %p (size: %d)!\n", + codec->extradata, codec->extradata_size); } return 0; } -// return 0 on packet, no more left, 1 on packet, 1 on partial packet... -static int h264_handle_packet(AVFormatContext *ctx, - PayloadContext *data, - AVStream *st, - AVPacket * pkt, - uint32_t * timestamp, - const uint8_t * buf, - int len, int flags) +// return 0 on packet, no more left, 1 on packet, 1 on partial packet +static int h264_handle_packet(AVFormatContext *ctx, PayloadContext *data, + AVStream *st, AVPacket *pkt, uint32_t *timestamp, + const uint8_t *buf, int len, int flags) { uint8_t nal; uint8_t type; - int result= 0; - uint8_t start_sequence[] = { 0, 0, 0, 1 }; + int result = 0; if (!len) { av_log(ctx, AV_LOG_ERROR, "Empty H264 RTP packet\n"); @@ -173,62 +183,60 @@ static int h264_handle_packet(AVFormatContext *ctx, assert(data); assert(buf); + /* Simplify the case (these are all the nal types used internally by + * the h264 codec). */ if (type >= 1 && type <= 23) - type = 1; // simplify the case. (these are all the nal types used internally by the h264 codec) + type = 1; switch (type) { case 0: // undefined, but pass them through case 1: - av_new_packet(pkt, len+sizeof(start_sequence)); + av_new_packet(pkt, len + sizeof(start_sequence)); memcpy(pkt->data, start_sequence, sizeof(start_sequence)); - memcpy(pkt->data+sizeof(start_sequence), buf, len); -#ifdef DEBUG - data->packet_types_received[nal & 0x1f]++; -#endif + memcpy(pkt->data + sizeof(start_sequence), buf, len); + COUNT_NAL_TYPE(data, nal); break; case 24: // STAP-A (one packet, multiple nals) // consume the STAP-A NAL buf++; 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; + 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; + 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; + // 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; + 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); + dst += sizeof(start_sequence); memcpy(dst, src, nal_size); -#ifdef DEBUG - data->packet_types_received[*src & 0x1f]++; -#endif - dst+= 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; + // eat what we handled + src += nal_size; src_len -= nal_size; if (src_len < 0) @@ -236,12 +244,13 @@ static int h264_handle_packet(AVFormatContext *ctx, "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 (pass == 0) { + /* now we know the total size of the packet (with the + * start sequences added) */ av_new_packet(pkt, total_length); - dst= pkt->data; + dst = pkt->data; } else { - assert(dst-pkt->data==total_length); + assert(dst - pkt->data == total_length); } } } @@ -259,34 +268,34 @@ static int h264_handle_packet(AVFormatContext *ctx, case 28: // FU-A (fragmented nal) buf++; - len--; // skip the fu_indicator + len--; // skip the fu_indicator if (len > 1) { - // these are the same as above, we just redo them here for clarity... - uint8_t fu_indicator = nal; - uint8_t fu_header = *buf; - uint8_t start_bit = fu_header >> 7; -// uint8_t end_bit = (fu_header & 0x40) >> 6; - uint8_t nal_type = (fu_header & 0x1f); + // these are the same as above, we just redo them here for clarity + uint8_t fu_indicator = nal; + uint8_t fu_header = *buf; + uint8_t start_bit = fu_header >> 7; + uint8_t av_unused end_bit = (fu_header & 0x40) >> 6; + uint8_t nal_type = fu_header & 0x1f; uint8_t reconstructed_nal; - // reconstruct this packet's true nal; only the data follows.. - reconstructed_nal = fu_indicator & (0xe0); // the original nal forbidden bit and NRI are stored in this packet's nal; + // Reconstruct this packet's true nal; only the data follows. + /* The original nal forbidden bit and NRI are stored in this + * packet's nal. */ + reconstructed_nal = fu_indicator & 0xe0; reconstructed_nal |= nal_type; - // skip the fu_header... + // skip the fu_header buf++; len--; -#ifdef DEBUG if (start_bit) - data->packet_types_received[nal_type]++; -#endif - if(start_bit) { - // copy in the start sequence, and the reconstructed nal.... - av_new_packet(pkt, sizeof(start_sequence)+sizeof(nal)+len); + COUNT_NAL_TYPE(data, nal_type); + if (start_bit) { + /* copy in the start sequence, and the reconstructed nal */ + av_new_packet(pkt, sizeof(start_sequence) + sizeof(nal) + len); memcpy(pkt->data, start_sequence, sizeof(start_sequence)); - pkt->data[sizeof(start_sequence)]= reconstructed_nal; - memcpy(pkt->data+sizeof(start_sequence)+sizeof(nal), buf, len); + pkt->data[sizeof(start_sequence)] = reconstructed_nal; + memcpy(pkt->data + sizeof(start_sequence) + sizeof(nal), buf, len); } else { av_new_packet(pkt, len); memcpy(pkt->data, buf, len); @@ -300,7 +309,7 @@ static int h264_handle_packet(AVFormatContext *ctx, case 30: // undefined case 31: // undefined default: - av_log(ctx, AV_LOG_ERROR, "Undefined type (%d)", type); + av_log(ctx, AV_LOG_ERROR, "Undefined type (%d)\n", type); result = AVERROR_INVALIDDATA; break; } @@ -341,25 +350,27 @@ static int parse_h264_sdp_line(AVFormatContext *s, int st_index, return 0; stream = s->streams[st_index]; - codec = stream->codec; + codec = stream->codec; if (av_strstart(p, "framesize:", &p)) { char buf1[50]; char *dst = buf1; - // remove the protocol identifier.. - while (*p && *p == ' ') p++; // strip spaces. - while (*p && *p != ' ') p++; // eat protocol identifier - while (*p && *p == ' ') p++; // strip trailing spaces. - while (*p && *p != '-' && (dst - buf1) < sizeof(buf1) - 1) { + // remove the protocol identifier + while (*p && *p == ' ') + p++; // strip spaces. + while (*p && *p != ' ') + p++; // eat protocol identifier + while (*p && *p == ' ') + p++; // strip trailing spaces. + while (*p && *p != '-' && (dst - buf1) < sizeof(buf1) - 1) *dst++ = *p++; - } *dst = '\0'; // a='framesize:96 320-240' - // set our parameters.. - codec->width = atoi(buf1); - codec->height = atoi(p + 1); // skip the - + // set our parameters + codec->width = atoi(buf1); + codec->height = atoi(p + 1); // skip the - codec->pix_fmt = PIX_FMT_YUV420P; } else if (av_strstart(p, "fmtp:", &p)) { return ff_parse_fmtp(stream, h264_data, p, sdp_parse_fmtp_config_h264); |