From 494bce6224c7da6a174fb16a49ed26e5aab32af1 Mon Sep 17 00:00:00 2001 From: Kostya Shishkov Date: Sat, 24 Mar 2012 07:29:51 +0100 Subject: [PATCH 1/8] ralf: read Huffman code lengths without GetBitContext Those descriptions are stored in nibbles, so they are easy to extract. And this way we don't need to pad tables for possible bit reader overreads. --- libavcodec/ralf.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/libavcodec/ralf.c b/libavcodec/ralf.c index 38e7e69cb7..0e5b04663f 100644 --- a/libavcodec/ralf.c +++ b/libavcodec/ralf.c @@ -80,17 +80,17 @@ static int init_ralf_vlc(VLC *vlc, const uint8_t *data, int elems) int counts[17], prefixes[18]; int i, cur_len; int max_bits = 0; - GetBitContext gb; - - init_get_bits(&gb, data, elems * 4); + int nb = 0; for (i = 0; i <= 16; i++) counts[i] = 0; for (i = 0; i < elems; i++) { - cur_len = get_bits(&gb, 4) + 1; + cur_len = (nb ? *data & 0xF : *data >> 4) + 1; counts[cur_len]++; max_bits = FFMAX(max_bits, cur_len); lens[i] = cur_len; + data += nb; + nb ^= 1; } prefixes[1] = 0; for (i = 1; i <= 16; i++) From 14ba7472dca38323104d05a3eacd0eb2890b00c6 Mon Sep 17 00:00:00 2001 From: Janne Salonen Date: Mon, 19 Mar 2012 09:35:09 +0200 Subject: [PATCH 2/8] vp8: fix update_lf_deltas in libavcodec/vp8.c lf_delta.ref[i] and lf_delta.mode[i] were incorrectly reset to 0 if specific delta value was not updated. Fixed to keep the previous value if flag indicates that element in question is not updated. Signed-off-by: Janne Salonen Signed-off-by: Ronald S. Bultje --- libavcodec/vp8.c | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/libavcodec/vp8.c b/libavcodec/vp8.c index 36518d5f7e..6da835b2d1 100644 --- a/libavcodec/vp8.c +++ b/libavcodec/vp8.c @@ -162,11 +162,23 @@ static void update_lf_deltas(VP8Context *s) VP56RangeCoder *c = &s->c; int i; - for (i = 0; i < 4; i++) - s->lf_delta.ref[i] = vp8_rac_get_sint(c, 6); + for (i = 0; i < 4; i++) { + if (vp8_rac_get(c)) { + s->lf_delta.ref[i] = vp8_rac_get_uint(c, 6); - for (i = MODE_I4x4; i <= VP8_MVMODE_SPLIT; i++) - s->lf_delta.mode[i] = vp8_rac_get_sint(c, 6); + if (vp8_rac_get(c)) + s->lf_delta.ref[i] = -s->lf_delta.ref[i]; + } + } + + for (i = MODE_I4x4; i <= VP8_MVMODE_SPLIT; i++) { + if (vp8_rac_get(c)) { + s->lf_delta.mode[i] = vp8_rac_get_uint(c, 6); + + if (vp8_rac_get(c)) + s->lf_delta.mode[i] = -s->lf_delta.mode[i]; + } + } } static int setup_partitions(VP8Context *s, const uint8_t *buf, int buf_size) From cc965300cb504ce452df1d37041b81c6ee6a5964 Mon Sep 17 00:00:00 2001 From: Aneesh Dogra Date: Fri, 23 Mar 2012 23:24:00 +0530 Subject: [PATCH 3/8] sunrast: Add support for negative linesize. Signed-off-by: Justin Ruggles --- libavcodec/sunrastenc.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/libavcodec/sunrastenc.c b/libavcodec/sunrastenc.c index a9b4749758..1ed1d6eddb 100644 --- a/libavcodec/sunrastenc.c +++ b/libavcodec/sunrastenc.c @@ -83,15 +83,18 @@ static void sunrast_image_write_image(AVCodecContext *avctx, if (s->type == RT_BYTE_ENCODED) { uint8_t value, value2; int run; - const uint8_t *end = pixels + avctx->height * linesize; + const uint8_t *start = linesize < 0 ? pixels + (avctx->height - 1) * linesize + : pixels; + const uint8_t *end = linesize < 0 ? pixels - linesize + : pixels + avctx->height * linesize; ptr = pixels; -#define GET_VALUE ptr >= end ? 0 : x >= len ? ptr[len-1] : ptr[x] +#define GET_VALUE ptr >= end || ptr < start ? 0 : x >= len ? ptr[len-1] : ptr[x] x = 0; value2 = GET_VALUE; - while (ptr < end) { + while (ptr < end && ptr >= start) { run = 1; value = value2; x++; @@ -101,7 +104,7 @@ static void sunrast_image_write_image(AVCodecContext *avctx, } value2 = GET_VALUE; - while (value2 == value && run < 256 && ptr < end) { + while (value2 == value && run < 256 && ptr < end && ptr >= start) { x++; run++; if (x >= alen) { From 72dadaa9579faaf94de8df13442f84a09c09594e Mon Sep 17 00:00:00 2001 From: Kostya Shishkov Date: Sat, 24 Mar 2012 19:54:31 +0100 Subject: [PATCH 4/8] utvideo: mark output picture as keyframe. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Spotted by Антон. --- libavcodec/utvideo.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libavcodec/utvideo.c b/libavcodec/utvideo.c index 884b16e9be..ebde38de17 100644 --- a/libavcodec/utvideo.c +++ b/libavcodec/utvideo.c @@ -492,6 +492,8 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPac break; } + c->pic.key_frame = 1; + c->pic.pict_type = AV_PICTURE_TYPE_I; *data_size = sizeof(AVFrame); *(AVFrame*)data = c->pic; From e20ad71ebbf9fe1f1a0dbc0c4e98afa8a28dc88c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Thu, 22 Mar 2012 17:05:08 +0200 Subject: [PATCH 5/8] libavformat: Document who sets the AVStream.id field MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Martin Storsjö --- libavformat/avformat.h | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/libavformat/avformat.h b/libavformat/avformat.h index 073ca67afc..2bf03e1bd8 100644 --- a/libavformat/avformat.h +++ b/libavformat/avformat.h @@ -547,7 +547,12 @@ typedef struct AVIndexEntry { */ typedef struct AVStream { int index; /**< stream index in AVFormatContext */ - int id; /**< format-specific stream ID */ + /** + * Format-specific stream ID. + * decoding: set by libavformat + * encoding: set by the user + */ + int id; AVCodecContext *codec; /**< codec context */ /** * Real base framerate of the stream. From bc1ef85520b6b5adc1361841c24218a9d74454e8 Mon Sep 17 00:00:00 2001 From: "Ronald S. Bultje" Date: Fri, 23 Mar 2012 15:03:03 -0700 Subject: [PATCH 6/8] lavc/avconv: support changing frame sizes in codecs with frame mt. Signed-off-by: Anton Khirnov --- avconv.c | 11 +++++++---- libavcodec/pthread.c | 4 ---- libavcodec/utils.c | 9 ++++----- 3 files changed, 11 insertions(+), 13 deletions(-) diff --git a/avconv.c b/avconv.c index b83662c893..af73f0810a 100644 --- a/avconv.c +++ b/avconv.c @@ -424,9 +424,8 @@ static void reset_options(OptionsContext *o) init_opts(); } -static int alloc_buffer(InputStream *ist, FrameBuffer **pbuf) +static int alloc_buffer(InputStream *ist, AVCodecContext *s, FrameBuffer **pbuf) { - AVCodecContext *s = ist->st->codec; FrameBuffer *buf = av_mallocz(sizeof(*buf)); int i, ret; const int pixel_size = av_pix_fmt_descriptors[s->pix_fmt].comp[0].step_minus1+1; @@ -502,7 +501,7 @@ static int codec_get_buffer(AVCodecContext *s, AVFrame *frame) FrameBuffer *buf; int ret, i; - if (!ist->buffer_pool && (ret = alloc_buffer(ist, &ist->buffer_pool)) < 0) + if (!ist->buffer_pool && (ret = alloc_buffer(ist, s, &ist->buffer_pool)) < 0) return ret; buf = ist->buffer_pool; @@ -511,7 +510,7 @@ static int codec_get_buffer(AVCodecContext *s, AVFrame *frame) if (buf->w != s->width || buf->h != s->height || buf->pix_fmt != s->pix_fmt) { av_freep(&buf->base[0]); av_free(buf); - if ((ret = alloc_buffer(ist, &buf)) < 0) + if ((ret = alloc_buffer(ist, s, &buf)) < 0) return ret; } buf->refcount++; @@ -520,6 +519,10 @@ static int codec_get_buffer(AVCodecContext *s, AVFrame *frame) frame->type = FF_BUFFER_TYPE_USER; frame->extended_data = frame->data; frame->pkt_pts = s->pkt ? s->pkt->pts : AV_NOPTS_VALUE; + frame->width = buf->w; + frame->height = buf->h; + frame->format = buf->pix_fmt; + frame->sample_aspect_ratio = s->sample_aspect_ratio; for (i = 0; i < FF_ARRAY_ELEMS(buf->data); i++) { frame->base[i] = buf->base[i]; // XXX h264.c uses base though it shouldn't diff --git a/libavcodec/pthread.c b/libavcodec/pthread.c index 2e4c6a880e..bbbc4829ec 100644 --- a/libavcodec/pthread.c +++ b/libavcodec/pthread.c @@ -630,10 +630,6 @@ int ff_thread_decode_frame(AVCodecContext *avctx, *picture = p->frame; *got_picture_ptr = p->got_frame; picture->pkt_dts = p->avpkt.dts; - picture->sample_aspect_ratio = avctx->sample_aspect_ratio; - picture->width = avctx->width; - picture->height = avctx->height; - picture->format = avctx->pix_fmt; /* * A later call with avkpt->size == 0 may loop over all threads, diff --git a/libavcodec/utils.c b/libavcodec/utils.c index a638bbfc91..7d50bd51d0 100644 --- a/libavcodec/utils.c +++ b/libavcodec/utils.c @@ -392,11 +392,6 @@ static int video_get_buffer(AVCodecContext *s, AVFrame *pic) buf = &avci->buffer[avci->buffer_count]; if(buf->base[0] && (buf->width != w || buf->height != h || buf->pix_fmt != s->pix_fmt)){ - if(s->active_thread_type&FF_THREAD_FRAME) { - av_log_missing_feature(s, "Width/height changing with frame threads is", 0); - return -1; - } - for (i = 0; i < AV_NUM_DATA_POINTERS; i++) { av_freep(&buf->base[i]); buf->data[i]= NULL; @@ -480,6 +475,10 @@ static int video_get_buffer(AVCodecContext *s, AVFrame *pic) } pic->extended_data = pic->data; avci->buffer_count++; + pic->width = buf->width; + pic->height = buf->height; + pic->format = buf->pix_fmt; + pic->sample_aspect_ratio = s->sample_aspect_ratio; if(s->pkt) pic->pkt_pts= s->pkt->pts; else pic->pkt_pts= AV_NOPTS_VALUE; From 2ee01fbded0a6b35b55d125dfd5807219837cf30 Mon Sep 17 00:00:00 2001 From: "Ronald S. Bultje" Date: Sat, 24 Mar 2012 20:19:19 +0100 Subject: [PATCH 7/8] pthread: free progress if buffer allocation failed. Else we run out of progress variables after a few failed buffer allocations. Signed-off-by: Anton Khirnov --- libavcodec/pthread.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/libavcodec/pthread.c b/libavcodec/pthread.c index bbbc4829ec..2a11195e78 100644 --- a/libavcodec/pthread.c +++ b/libavcodec/pthread.c @@ -951,6 +951,10 @@ int ff_thread_get_buffer(AVCodecContext *avctx, AVFrame *f) ff_thread_finish_setup(avctx); } + if (err) { + free_progress(f); + f->thread_opaque = NULL; + } pthread_mutex_unlock(&p->parent->buffer_mutex); return err; From d5ed5e7d0c1fa46de348db0de4c82b0f621db3d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Thu, 22 Mar 2012 13:25:58 +0200 Subject: [PATCH 8/8] avc: Add a function for converting mp4 style extradata to annex b MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Make movenc use this function instead of the current custom conversion function. Signed-off-by: Martin Storsjö --- libavformat/avc.c | 31 +++++++++++++++++++++++++++++++ libavformat/avc.h | 1 + libavformat/movenc.c | 34 ++++++++++------------------------ 3 files changed, 42 insertions(+), 24 deletions(-) diff --git a/libavformat/avc.c b/libavformat/avc.c index b0c511e7b5..2fd5ac807b 100644 --- a/libavformat/avc.c +++ b/libavformat/avc.c @@ -160,3 +160,34 @@ int ff_isom_write_avcc(AVIOContext *pb, const uint8_t *data, int len) } return 0; } + +int ff_avc_write_annexb_extradata(const uint8_t *in, uint8_t **buf, int *size) +{ + uint16_t sps_size, pps_size; + uint8_t *out; + int out_size; + + *buf = NULL; + if (*size >= 4 && (AV_RB32(in) == 0x00000001 || AV_RB24(in) == 0x000001)) + return 0; + if (*size < 11 || in[0] != 1) + return AVERROR_INVALIDDATA; + + sps_size = AV_RB16(&in[6]); + if (11 + sps_size > *size) + return AVERROR_INVALIDDATA; + pps_size = AV_RB16(&in[9 + sps_size]); + if (11 + sps_size + pps_size > *size) + return AVERROR_INVALIDDATA; + out_size = 8 + sps_size + pps_size; + out = av_mallocz(out_size); + if (!out) + return AVERROR(ENOMEM); + AV_WB32(&out[0], 0x00000001); + memcpy(out + 4, &in[8], sps_size); + AV_WB32(&out[4 + sps_size], 0x00000001); + memcpy(out + 8 + sps_size, &in[11 + sps_size], pps_size); + *buf = out; + *size = out_size; + return 0; +} diff --git a/libavformat/avc.h b/libavformat/avc.h index 56122125a9..579756ec0f 100644 --- a/libavformat/avc.h +++ b/libavformat/avc.h @@ -29,5 +29,6 @@ int ff_avc_parse_nal_units(AVIOContext *s, const uint8_t *buf, int size); int ff_avc_parse_nal_units_buf(const uint8_t *buf_in, uint8_t **buf, int *size); int ff_isom_write_avcc(AVIOContext *pb, const uint8_t *data, int len); const uint8_t *ff_avc_find_startcode(const uint8_t *p, const uint8_t *end); +int ff_avc_write_annexb_extradata(const uint8_t *in, uint8_t **buf, int *size); #endif /* AVFORMAT_AVC_H */ diff --git a/libavformat/movenc.c b/libavformat/movenc.c index 1209b7b114..a832c1d102 100644 --- a/libavformat/movenc.c +++ b/libavformat/movenc.c @@ -2096,26 +2096,6 @@ static void param_write_hex(AVIOContext *pb, const char *name, const uint8_t *va avio_printf(pb, "\n", name, buf); } -static void write_h264_extradata(AVIOContext *pb, AVCodecContext *enc) -{ - uint16_t sps_size, pps_size, len; - char buf[150]; - sps_size = AV_RB16(&enc->extradata[6]); - if (11 + sps_size > enc->extradata_size) - return; - pps_size = AV_RB16(&enc->extradata[9 + sps_size]); - if (11 + sps_size + pps_size > enc->extradata_size) - return; - len = FFMIN(sizeof(buf)/2 - 1, sps_size); - ff_data_to_hex(buf, &enc->extradata[8], len, 0); - buf[2*len] = '\0'; - avio_printf(pb, "extradata[11 + sps_size], len, 0); - buf[2*len] = '\0'; - avio_printf(pb, "00000001%s\" valuetype=\"data\"/>\n", buf); -} - static int mov_write_isml_manifest(AVIOContext *pb, MOVMuxContext *mov) { int64_t pos = avio_tell(pb); @@ -2157,10 +2137,16 @@ static int mov_write_isml_manifest(AVIOContext *pb, MOVMuxContext *mov) param_write_int(pb, "systemBitrate", track->enc->bit_rate); param_write_int(pb, "trackID", track_id); if (track->enc->codec_type == AVMEDIA_TYPE_VIDEO) { - if (track->enc->codec_id == CODEC_ID_H264 && - track->enc->extradata_size >= 11 && - track->enc->extradata[0] == 1) { - write_h264_extradata(pb, track->enc); + if (track->enc->codec_id == CODEC_ID_H264) { + uint8_t *ptr; + int size = track->enc->extradata_size; + if (!ff_avc_write_annexb_extradata(track->enc->extradata, &ptr, + &size)) { + param_write_hex(pb, "CodecPrivateData", + ptr ? ptr : track->enc->extradata, + size); + av_free(ptr); + } } else { param_write_hex(pb, "CodecPrivateData", track->enc->extradata, track->enc->extradata_size);