"Fossies" - the Fresh Open Source Software Archive  

Source code changes of the file "libavcodec/h2645_parse.c" between
libav-12.tar.gz and libav-12.1.tar.gz

About: libav provides cross-platform tools ("avconv") and libraries to convert, manipulate and stream a wide range of multimedia (audio and video) formats and protocols.

h2645_parse.c  (libav-12):h2645_parse.c  (libav-12.1)
skipping to change at line 29 skipping to change at line 29
*/ */
#include <string.h> #include <string.h>
#include "config.h" #include "config.h"
#include "libavutil/intmath.h" #include "libavutil/intmath.h"
#include "libavutil/intreadwrite.h" #include "libavutil/intreadwrite.h"
#include "libavutil/mem.h" #include "libavutil/mem.h"
#include "bytestream.h"
#include "h2645_parse.h" #include "h2645_parse.h"
int ff_h2645_extract_rbsp(const uint8_t *src, int length, int ff_h2645_extract_rbsp(const uint8_t *src, int length,
H2645NAL *nal) H2645NAL *nal)
{ {
int i, si, di; int i, si, di;
uint8_t *dst; uint8_t *dst;
#define STARTCODE_TEST \ #define STARTCODE_TEST \
if (i + 2 < length && src[i + 1] == 0 && src[i + 2] <= 3) { \ if (i + 2 < length && src[i + 1] == 0 && src[i + 2] <= 3) { \
skipping to change at line 217 skipping to change at line 218
break; break;
i++; i++;
} }
return i + 3; return i + 3;
} }
int ff_h2645_packet_split(H2645Packet *pkt, const uint8_t *buf, int length, int ff_h2645_packet_split(H2645Packet *pkt, const uint8_t *buf, int length,
void *logctx, int is_nalff, int nal_length_size, void *logctx, int is_nalff, int nal_length_size,
enum AVCodecID codec_id) enum AVCodecID codec_id)
{ {
GetByteContext bc;
int consumed, ret = 0; int consumed, ret = 0;
const uint8_t *next_avc = buf + (is_nalff ? 0 : length); size_t next_avc = is_nalff ? 0 : length;
bytestream2_init(&bc, buf, length);
pkt->nb_nals = 0; pkt->nb_nals = 0;
while (length >= 4) { while (bytestream2_get_bytes_left(&bc) >= 4) {
H2645NAL *nal; H2645NAL *nal;
int extract_length = 0; int extract_length = 0;
int skip_trailing_zeros = 1; int skip_trailing_zeros = 1;
/* /*
* Only parse an AVC1 length field if one is expected at the current * Only parse an AVC1 length field if one is expected at the current
* buffer position. There are unfortunately streams with multiple * buffer position. There are unfortunately streams with multiple
* NAL units covered by the length field. Those NAL units are delimited * NAL units covered by the length field. Those NAL units are delimited
* by Annex B start code prefixes. ff_h2645_extract_rbsp() detects it * by Annex B start code prefixes. ff_h2645_extract_rbsp() detects it
* correctly and consumes only the first NAL unit. The additional NAL * correctly and consumes only the first NAL unit. The additional NAL
* units are handled here in the Annex B parsing code. * units are handled here in the Annex B parsing code.
*/ */
if (buf == next_avc) { if (bytestream2_tell(&bc) == next_avc) {
int i; int i;
for (i = 0; i < nal_length_size; i++) for (i = 0; i < nal_length_size; i++)
extract_length = (extract_length << 8) | buf[i]; extract_length = (extract_length << 8) | bytestream2_get_byte(&b c);
if (extract_length > length) { if (extract_length > bytestream2_get_bytes_left(&bc)) {
av_log(logctx, AV_LOG_ERROR, av_log(logctx, AV_LOG_ERROR,
"Invalid NAL unit size (%d > %d).\n", "Invalid NAL unit size (%d > %d).\n",
extract_length, length); extract_length, bytestream2_get_bytes_left(&bc));
return AVERROR_INVALIDDATA; return AVERROR_INVALIDDATA;
} }
buf += nal_length_size;
length -= nal_length_size;
// keep track of the next AVC1 length field // keep track of the next AVC1 length field
next_avc = buf + extract_length; next_avc = bytestream2_tell(&bc) + extract_length;
} else { } else {
/* /*
* expected to return immediately except for streams with mixed * expected to return immediately except for streams with mixed
* NAL unit coding * NAL unit coding
*/ */
int buf_index = find_next_start_code(buf, next_avc); int buf_index = find_next_start_code(bc.buffer, buf + next_avc);
buf += buf_index; bytestream2_skip(&bc, buf_index);
length -= buf_index;
/* /*
* break if an AVC1 length field is expected at the current buffer * break if an AVC1 length field is expected at the current buffer
* position * position
*/ */
if (buf == next_avc) if (bytestream2_tell(&bc) == next_avc)
continue; continue;
if (length > 0) { if (bytestream2_get_bytes_left(&bc) > 0) {
extract_length = length; extract_length = bytestream2_get_bytes_left(&bc);
} else if (pkt->nb_nals == 0) { } else if (pkt->nb_nals == 0) {
av_log(logctx, AV_LOG_ERROR, "No NAL unit found\n"); av_log(logctx, AV_LOG_ERROR, "No NAL unit found\n");
return AVERROR_INVALIDDATA; return AVERROR_INVALIDDATA;
} else { } else {
break; break;
} }
} }
if (pkt->nals_allocated < pkt->nb_nals + 1) { if (pkt->nals_allocated < pkt->nb_nals + 1) {
int new_size = pkt->nals_allocated + 1; int new_size = pkt->nals_allocated + 1;
skipping to change at line 289 skipping to change at line 290
if (!tmp) if (!tmp)
return AVERROR(ENOMEM); return AVERROR(ENOMEM);
pkt->nals = tmp; pkt->nals = tmp;
memset(pkt->nals + pkt->nals_allocated, 0, memset(pkt->nals + pkt->nals_allocated, 0,
(new_size - pkt->nals_allocated) * sizeof(*tmp)); (new_size - pkt->nals_allocated) * sizeof(*tmp));
pkt->nals_allocated = new_size; pkt->nals_allocated = new_size;
} }
nal = &pkt->nals[pkt->nb_nals++]; nal = &pkt->nals[pkt->nb_nals++];
consumed = ff_h2645_extract_rbsp(buf, extract_length, nal); consumed = ff_h2645_extract_rbsp(bc.buffer, extract_length, nal);
if (consumed < 0) if (consumed < 0)
return consumed; return consumed;
bytestream2_skip(&bc, consumed);
/* see commit 3566042a0 */ /* see commit 3566042a0 */
if (consumed < length - 3 && if (bytestream2_get_bytes_left(&bc) >= 4 &&
buf[consumed] == 0x00 && buf[consumed + 1] == 0x00 && bytestream2_peek_be32(&bc) == 0x000001E0)
buf[consumed + 2] == 0x01 && buf[consumed + 3] == 0xE0)
skip_trailing_zeros = 0; skip_trailing_zeros = 0;
nal->size_bits = get_bit_length(nal, skip_trailing_zeros); nal->size_bits = get_bit_length(nal, skip_trailing_zeros);
ret = init_get_bits(&nal->gb, nal->data, nal->size_bits); ret = init_get_bits(&nal->gb, nal->data, nal->size_bits);
if (ret < 0) if (ret < 0)
return ret; return ret;
if (codec_id == AV_CODEC_ID_HEVC) if (codec_id == AV_CODEC_ID_HEVC)
ret = hevc_parse_nal_header(nal, logctx); ret = hevc_parse_nal_header(nal, logctx);
else else
ret = h264_parse_nal_header(nal, logctx); ret = h264_parse_nal_header(nal, logctx);
if (ret <= 0) { if (ret <= 0) {
if (ret < 0) { if (ret < 0) {
av_log(logctx, AV_LOG_ERROR, "Invalid NAL unit %d, skipping.\n", av_log(logctx, AV_LOG_ERROR, "Invalid NAL unit %d, skipping.\n",
nal->type); nal->type);
} }
pkt->nb_nals--; pkt->nb_nals--;
} }
buf += consumed;
length -= consumed;
} }
return 0; return 0;
} }
void ff_h2645_packet_uninit(H2645Packet *pkt) void ff_h2645_packet_uninit(H2645Packet *pkt)
{ {
int i; int i;
for (i = 0; i < pkt->nals_allocated; i++) for (i = 0; i < pkt->nals_allocated; i++)
av_freep(&pkt->nals[i].rbsp_buffer); av_freep(&pkt->nals[i].rbsp_buffer);
 End of changes. 18 change blocks. 
22 lines changed or deleted 21 lines changed or added

Home  |  About  |  All  |  Newest  |  Fossies Dox  |  Screenshots  |  Comments  |  Imprint  |  Privacy  |  HTTPS