From af2faf2076b96ab85cc51d5e970574079373c396 Mon Sep 17 00:00:00 2001 From: "Ronald S. Bultje" Date: Thu, 9 Jun 2011 18:13:53 -0400 Subject: [PATCH 01/20] swscale: split YUYV output out of yuv2packed[12X]_c(). This is part of the Great Evil Plan to simplify swscale. --- libswscale/swscale.c | 181 ++++++++++++++++++++++++++++++++----------- 1 file changed, 137 insertions(+), 44 deletions(-) diff --git a/libswscale/swscale.c b/libswscale/swscale.c index 39aac0c67b..bc076dd3f2 100644 --- a/libswscale/swscale.c +++ b/libswscale/swscale.c @@ -626,7 +626,117 @@ yuv2mono_1_c_template(SwsContext *c, const uint16_t *buf0, YUV2PACKEDWRAPPER(yuv2mono, white, PIX_FMT_MONOWHITE); YUV2PACKEDWRAPPER(yuv2mono, black, PIX_FMT_MONOBLACK); -#define YSCALE_YUV_2_PACKEDX_C(type,alpha) \ +static av_always_inline void +yuv2422_X_c_template(SwsContext *c, const int16_t *lumFilter, + const int16_t **lumSrc, int lumFilterSize, + const int16_t *chrFilter, const int16_t **chrUSrc, + const int16_t **chrVSrc, int chrFilterSize, + const int16_t **alpSrc, uint8_t *dest, int dstW, + int y, enum PixelFormat target) +{ + int i; + +#define output_pixels(pos, Y1, U, Y2, V) \ + if (target == PIX_FMT_YUYV422) { \ + dest[pos + 0] = Y1; \ + dest[pos + 1] = U; \ + dest[pos + 2] = Y2; \ + dest[pos + 3] = V; \ + } else { \ + dest[pos + 0] = U; \ + dest[pos + 1] = Y1; \ + dest[pos + 2] = V; \ + dest[pos + 3] = Y2; \ + } + + for (i = 0; i < (dstW >> 1); i++) { + int j; + int Y1 = 1 << 18; + int Y2 = 1 << 18; + int U = 1 << 18; + int V = 1 << 18; + + for (j = 0; j < lumFilterSize; j++) { + Y1 += lumSrc[j][i * 2] * lumFilter[j]; + Y2 += lumSrc[j][i * 2 + 1] * lumFilter[j]; + } + for (j = 0; j < chrFilterSize; j++) { + U += chrUSrc[j][i] * chrFilter[j]; + V += chrVSrc[j][i] * chrFilter[j]; + } + Y1 >>= 19; + Y2 >>= 19; + U >>= 19; + V >>= 19; + if ((Y1 | Y2 | U | V) & 0x100) { + Y1 = av_clip_uint8(Y1); + Y2 = av_clip_uint8(Y2); + U = av_clip_uint8(U); + V = av_clip_uint8(V); + } + output_pixels(4*i, Y1, U, Y2, V); + } +} + +static av_always_inline void +yuv2422_2_c_template(SwsContext *c, const uint16_t *buf0, + const uint16_t *buf1, const uint16_t *ubuf0, + const uint16_t *ubuf1, const uint16_t *vbuf0, + const uint16_t *vbuf1, const uint16_t *abuf0, + const uint16_t *abuf1, uint8_t *dest, int dstW, + int yalpha, int uvalpha, int y, + enum PixelFormat target) +{ + int yalpha1 = 4095 - yalpha; + int uvalpha1 = 4095 - uvalpha; + int i; + + for (i = 0; i < (dstW >> 1); i++) { + int Y1 = (buf0[i * 2] * yalpha1 + buf1[i * 2] * yalpha) >> 19; + int Y2 = (buf0[i * 2 + 1] * yalpha1 + buf1[i * 2 + 1] * yalpha) >> 19; + int U = (ubuf0[i] * uvalpha1 + ubuf1[i] * uvalpha) >> 19; + int V = (vbuf0[i] * uvalpha1 + vbuf1[i] * uvalpha) >> 19; + + output_pixels(i * 4, Y1, U, Y2, V); + } +} + +static av_always_inline void +yuv2422_1_c_template(SwsContext *c, const uint16_t *buf0, + const uint16_t *ubuf0, const uint16_t *ubuf1, + const uint16_t *vbuf0, const uint16_t *vbuf1, + const uint16_t *abuf0, uint8_t *dest, int dstW, + int uvalpha, enum PixelFormat dstFormat, + int flags, int y, enum PixelFormat target) +{ + int i; + + if (uvalpha < 2048) { + for (i = 0; i < (dstW >> 1); i++) { + int Y1 = buf0[i * 2] >> 7; + int Y2 = buf0[i * 2 + 1] >> 7; + int U = ubuf1[i] >> 7; + int V = vbuf1[i] >> 7; + + output_pixels(i * 4, Y1, U, Y2, V); + } + } else { + for (i = 0; i < (dstW >> 1); i++) { + int Y1 = buf0[i * 2] >> 7; + int Y2 = buf0[i * 2 + 1] >> 7; + int U = (ubuf0[i] + ubuf1[i]) >> 8; + int V = (vbuf0[i] + vbuf1[i]) >> 8; + + output_pixels(i * 4, Y1, U, Y2, V); + } + } +#undef output_pixels +} + +YUV2PACKEDWRAPPER(yuv2422, yuyv, PIX_FMT_YUYV422); +YUV2PACKEDWRAPPER(yuv2422, uyvy, PIX_FMT_UYVY422); + +#define YSCALE_YUV_2_RGBX_C(type,alpha) \ for (i=0; i<(dstW>>1); i++) {\ int j;\ int Y1 = 1<<18;\ @@ -668,7 +778,11 @@ YUV2PACKEDWRAPPER(yuv2mono, black, PIX_FMT_MONOBLACK); A1 = av_clip_uint8(A1); \ A2 = av_clip_uint8(A2); \ }\ - } + }\ + /* FIXME fix tables so that clipping is not needed and then use _NOCLIP*/\ + r = (type *)c->table_rV[V]; \ + g = (type *)(c->table_gU[U] + c->table_gV[V]); \ + b = (type *)c->table_bU[U]; #define YSCALE_YUV_2_RGBX_FULL_C(rnd,alpha) \ for (i=0; itable_rV[V]; \ - g = (type *)(c->table_gU[U] + c->table_gV[V]); \ - b = (type *)c->table_bU[U]; - -#define YSCALE_YUV_2_PACKED2_C(type,alpha) \ +#define YSCALE_YUV_2_RGB2_C(type,alpha) \ for (i=0; i<(dstW>>1); i++) { \ const int i2= 2*i; \ int Y1= (buf0[i2 ]*yalpha1+buf1[i2 ]*yalpha)>>19; \ @@ -727,15 +835,12 @@ YUV2PACKEDWRAPPER(yuv2mono, black, PIX_FMT_MONOBLACK); if (alpha) {\ A1= (abuf0[i2 ]*yalpha1+abuf1[i2 ]*yalpha)>>19; \ A2= (abuf0[i2+1]*yalpha1+abuf1[i2+1]*yalpha)>>19; \ - } - -#define YSCALE_YUV_2_RGB2_C(type,alpha) \ - YSCALE_YUV_2_PACKED2_C(type,alpha)\ + }\ r = (type *)c->table_rV[V];\ g = (type *)(c->table_gU[U] + c->table_gV[V]);\ b = (type *)c->table_bU[U]; -#define YSCALE_YUV_2_PACKED1_C(type,alpha) \ +#define YSCALE_YUV_2_RGB1_C(type,alpha) \ for (i=0; i<(dstW>>1); i++) {\ const int i2= 2*i;\ int Y1= buf0[i2 ]>>7;\ @@ -747,15 +852,12 @@ YUV2PACKEDWRAPPER(yuv2mono, black, PIX_FMT_MONOBLACK); if (alpha) {\ A1= abuf0[i2 ]>>7;\ A2= abuf0[i2+1]>>7;\ - } - -#define YSCALE_YUV_2_RGB1_C(type,alpha) \ - YSCALE_YUV_2_PACKED1_C(type,alpha)\ + }\ r = (type *)c->table_rV[V];\ g = (type *)(c->table_gU[U] + c->table_gV[V]);\ b = (type *)c->table_bU[U]; -#define YSCALE_YUV_2_PACKED1B_C(type,alpha) \ +#define YSCALE_YUV_2_RGB1B_C(type,alpha) \ for (i=0; i<(dstW>>1); i++) {\ const int i2= 2*i;\ int Y1= buf0[i2 ]>>7;\ @@ -767,15 +869,12 @@ YUV2PACKEDWRAPPER(yuv2mono, black, PIX_FMT_MONOBLACK); if (alpha) {\ A1= abuf0[i2 ]>>7;\ A2= abuf0[i2+1]>>7;\ - } - -#define YSCALE_YUV_2_RGB1B_C(type,alpha) \ - YSCALE_YUV_2_PACKED1B_C(type,alpha)\ + }\ r = (type *)c->table_rV[V];\ g = (type *)(c->table_gU[U] + c->table_gV[V]);\ b = (type *)c->table_bU[U]; -#define YSCALE_YUV_2_ANYRGB_C(func, func2)\ +#define YSCALE_YUV_2_ANYRGB_C(func)\ switch(c->dstFormat) {\ case PIX_FMT_RGB48BE:\ case PIX_FMT_RGB48LE:\ @@ -951,22 +1050,6 @@ YUV2PACKEDWRAPPER(yuv2mono, black, PIX_FMT_MONOBLACK); }\ }\ break;\ - case PIX_FMT_YUYV422:\ - func2\ - ((uint8_t*)dest)[2*i2+0]= Y1;\ - ((uint8_t*)dest)[2*i2+1]= U;\ - ((uint8_t*)dest)[2*i2+2]= Y2;\ - ((uint8_t*)dest)[2*i2+3]= V;\ - } \ - break;\ - case PIX_FMT_UYVY422:\ - func2\ - ((uint8_t*)dest)[2*i2+0]= U;\ - ((uint8_t*)dest)[2*i2+1]= Y1;\ - ((uint8_t*)dest)[2*i2+2]= V;\ - ((uint8_t*)dest)[2*i2+3]= Y2;\ - } \ - break;\ } static void yuv2packedX_c(SwsContext *c, const int16_t *lumFilter, @@ -976,7 +1059,7 @@ static void yuv2packedX_c(SwsContext *c, const int16_t *lumFilter, const int16_t **alpSrc, uint8_t *dest, int dstW, int y) { int i; - YSCALE_YUV_2_ANYRGB_C(YSCALE_YUV_2_RGBX_C, YSCALE_YUV_2_PACKEDX_C(void,0)) + YSCALE_YUV_2_ANYRGB_C(YSCALE_YUV_2_RGBX_C) } static void yuv2rgbX_c_full(SwsContext *c, const int16_t *lumFilter, @@ -1079,7 +1162,7 @@ static void yuv2packed2_c(SwsContext *c, const uint16_t *buf0, int uvalpha1=4095-uvalpha; int i; - YSCALE_YUV_2_ANYRGB_C(YSCALE_YUV_2_RGB2_C, YSCALE_YUV_2_PACKED2_C(void,0)) + YSCALE_YUV_2_ANYRGB_C(YSCALE_YUV_2_RGB2_C) } /** @@ -1095,9 +1178,9 @@ static void yuv2packed1_c(SwsContext *c, const uint16_t *buf0, int i; if (uvalpha < 2048) { - YSCALE_YUV_2_ANYRGB_C(YSCALE_YUV_2_RGB1_C, YSCALE_YUV_2_PACKED1_C(void,0)) + YSCALE_YUV_2_ANYRGB_C(YSCALE_YUV_2_RGB1_C) } else { - YSCALE_YUV_2_ANYRGB_C(YSCALE_YUV_2_RGB1B_C, YSCALE_YUV_2_PACKED1B_C(void,0)) + YSCALE_YUV_2_ANYRGB_C(YSCALE_YUV_2_RGB1B_C) } } @@ -1771,6 +1854,16 @@ find_c_packed_planar_out_funcs(SwsContext *c, *yuv2packed2 = yuv2monoblack_2_c; *yuv2packedX = yuv2monoblack_X_c; break; + case PIX_FMT_YUYV422: + *yuv2packed1 = yuv2422yuyv_1_c; + *yuv2packed2 = yuv2422yuyv_2_c; + *yuv2packedX = yuv2422yuyv_X_c; + break; + case PIX_FMT_UYVY422: + *yuv2packed1 = yuv2422uyvy_1_c; + *yuv2packed2 = yuv2422uyvy_2_c; + *yuv2packedX = yuv2422uyvy_X_c; + break; default: *yuv2packed1 = yuv2packed1_c; *yuv2packed2 = yuv2packed2_c; From d8999306e516663de2b46aed0c79f7bcc77eb5a1 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Fri, 25 Mar 2011 01:13:08 +0100 Subject: [PATCH 02/20] mpeg12: more advanced ffmpeg mpeg2 aspect guessing code. Fixes issue1613, 621, 562 simultaneously Signed-off-by: Michael Niedermayer Signed-off-by: Anton Khirnov --- libavcodec/mpeg12.c | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/libavcodec/mpeg12.c b/libavcodec/mpeg12.c index 0e1536f7ab..03c95c191d 100644 --- a/libavcodec/mpeg12.c +++ b/libavcodec/mpeg12.c @@ -1293,9 +1293,17 @@ static int mpeg_decode_postinit(AVCodecContext *avctx){ avctx->ticks_per_frame=2; //MPEG-2 aspect if(s->aspect_ratio_info > 1){ - //we ignore the spec here as reality does not match the spec, see for example + AVRational dar = + av_mul_q( + av_div_q(ff_mpeg2_aspect[s->aspect_ratio_info], + (AVRational){s1->pan_scan.width, s1->pan_scan.height}), + (AVRational){s->width, s->height}); + + // we ignore the spec here and guess a bit as reality does not match the spec, see for example // res_change_ffmpeg_aspect.ts and sequence-display-aspect.mpg - if( (s1->pan_scan.width == 0 )||(s1->pan_scan.height == 0) || 1){ + // issue1613, 621, 562 + if((s1->pan_scan.width == 0 ) || (s1->pan_scan.height == 0) || + (av_cmp_q(dar,(AVRational){4,3}) && av_cmp_q(dar,(AVRational){16,9}))) { s->avctx->sample_aspect_ratio= av_div_q( ff_mpeg2_aspect[s->aspect_ratio_info], @@ -1307,6 +1315,12 @@ static int mpeg_decode_postinit(AVCodecContext *avctx){ ff_mpeg2_aspect[s->aspect_ratio_info], (AVRational){s1->pan_scan.width, s1->pan_scan.height} ); +//issue1613 4/3 16/9 -> 16/9 +//res_change_ffmpeg_aspect.ts 4/3 225/44 ->4/3 +//widescreen-issue562.mpg 4/3 16/9 -> 16/9 +// s->avctx->sample_aspect_ratio= av_mul_q(s->avctx->sample_aspect_ratio, (AVRational){s->width, s->height}); +//av_log(NULL, AV_LOG_ERROR, "A %d/%d\n",ff_mpeg2_aspect[s->aspect_ratio_info].num, ff_mpeg2_aspect[s->aspect_ratio_info].den); +//av_log(NULL, AV_LOG_ERROR, "B %d/%d\n",s->avctx->sample_aspect_ratio.num, s->avctx->sample_aspect_ratio.den); } }else{ s->avctx->sample_aspect_ratio= From f33a6a22b4f2382a5113194335ae2a22ae957fed Mon Sep 17 00:00:00 2001 From: Yusuke Nakamura Date: Fri, 13 May 2011 23:46:48 +0900 Subject: [PATCH 03/20] mov: Fix wrong timestamp generation for fragmented movies that have time offset caused by the first edit list entry. Signed-off-by: Anton Khirnov --- libavformat/mov.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/libavformat/mov.c b/libavformat/mov.c index 4d3f4f69d2..ab5c4e2db9 100644 --- a/libavformat/mov.c +++ b/libavformat/mov.c @@ -1532,8 +1532,9 @@ static void mov_build_index(MOVContext *mov, AVStream *st) /* adjust first dts according to edit list */ if (sc->time_offset && mov->time_scale > 0) { - int rescaled = sc->time_offset < 0 ? av_rescale(sc->time_offset, sc->time_scale, mov->time_scale) : sc->time_offset; - current_dts = -rescaled; + if (sc->time_offset < 0) + sc->time_offset = av_rescale(sc->time_offset, sc->time_scale, mov->time_scale); + current_dts = -sc->time_offset; if (sc->ctts_data && sc->stts_data && sc->ctts_data[0].duration / sc->stts_data[0].duration > 16) { /* more than 16 frames delay, dts are likely wrong @@ -2063,7 +2064,7 @@ static int mov_read_trun(MOVContext *c, AVIOContext *pb, MOVAtom atom) if (flags & 0x001) data_offset = avio_rb32(pb); if (flags & 0x004) first_sample_flags = avio_rb32(pb); - dts = st->duration; + dts = st->duration - sc->time_offset; offset = frag->base_data_offset + data_offset; distance = 0; av_dlog(c->fc, "first sample flags 0x%x\n", first_sample_flags); @@ -2092,7 +2093,7 @@ static int mov_read_trun(MOVContext *c, AVIOContext *pb, MOVAtom atom) offset += sample_size; } frag->moof_offset = offset; - st->duration = dts; + st->duration = dts + sc->time_offset; return 0; } From 0558e266a267b5d90d3be1d8d86e60db2c303773 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Wed, 18 May 2011 15:41:06 +0300 Subject: [PATCH 04/20] sdp: Allow passing an AVFormatContext to the SDP generation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Options from the AVFormatContext can be read for modifying the generated SDP. Signed-off-by: Martin Storsjö --- libavformat/internal.h | 4 +++- libavformat/movenc.c | 2 +- libavformat/sdp.c | 11 ++++++----- 3 files changed, 10 insertions(+), 7 deletions(-) diff --git a/libavformat/internal.h b/libavformat/internal.h index ad3d9c91c2..7413b0906a 100644 --- a/libavformat/internal.h +++ b/libavformat/internal.h @@ -124,10 +124,12 @@ int ff_url_join(char *str, int size, const char *proto, * @param dest_type the destination address type, may be NULL * @param port the destination port of the media stream, 0 if unknown * @param ttl the time to live of the stream, 0 if not multicast + * @param fmt the AVFormatContext, which might contain options modifying + * the generated SDP */ void ff_sdp_write_media(char *buff, int size, AVCodecContext *c, const char *dest_addr, const char *dest_type, - int port, int ttl); + int port, int ttl, AVFormatContext *fmt); /** * Write a packet to another muxer than the one the user originally diff --git a/libavformat/movenc.c b/libavformat/movenc.c index 5f4eea49fc..b313510b25 100644 --- a/libavformat/movenc.c +++ b/libavformat/movenc.c @@ -1359,7 +1359,7 @@ static int mov_write_udta_sdp(AVIOContext *pb, AVCodecContext *ctx, int index) char buf[1000] = ""; int len; - ff_sdp_write_media(buf, sizeof(buf), ctx, NULL, NULL, 0, 0); + ff_sdp_write_media(buf, sizeof(buf), ctx, NULL, NULL, 0, 0, NULL); av_strlcatf(buf, sizeof(buf), "a=control:streamid=%d\r\n", index); len = strlen(buf); diff --git a/libavformat/sdp.c b/libavformat/sdp.c index f72e2c567f..b996bf65f5 100644 --- a/libavformat/sdp.c +++ b/libavformat/sdp.c @@ -300,7 +300,7 @@ xiph_fail: return NULL; } -static char *sdp_write_media_attributes(char *buff, int size, AVCodecContext *c, int payload_type) +static char *sdp_write_media_attributes(char *buff, int size, AVCodecContext *c, int payload_type, AVFormatContext *fmt) { char *config = NULL; @@ -449,7 +449,7 @@ static char *sdp_write_media_attributes(char *buff, int size, AVCodecContext *c, return buff; } -void ff_sdp_write_media(char *buff, int size, AVCodecContext *c, const char *dest_addr, const char *dest_type, int port, int ttl) +void ff_sdp_write_media(char *buff, int size, AVCodecContext *c, const char *dest_addr, const char *dest_type, int port, int ttl, AVFormatContext *fmt) { const char *type; int payload_type; @@ -472,7 +472,7 @@ void ff_sdp_write_media(char *buff, int size, AVCodecContext *c, const char *des av_strlcatf(buff, size, "b=AS:%d\r\n", c->bit_rate / 1000); } - sdp_write_media_attributes(buff, size, c, payload_type); + sdp_write_media_attributes(buff, size, c, payload_type, fmt); } int av_sdp_create(AVFormatContext *ac[], int n_files, char *buf, int size) @@ -521,7 +521,8 @@ int av_sdp_create(AVFormatContext *ac[], int n_files, char *buf, int size) for (j = 0; j < ac[i]->nb_streams; j++) { ff_sdp_write_media(buf, size, ac[i]->streams[j]->codec, dst[0] ? dst : NULL, - dst_type, (port > 0) ? port + j * 2 : 0, ttl); + dst_type, (port > 0) ? port + j * 2 : 0, ttl, + ac[i]); if (port <= 0) { av_strlcatf(buf, size, "a=control:streamid=%d\r\n", i + j); @@ -537,7 +538,7 @@ int av_sdp_create(AVFormatContext *ac[], int n_files, char *buf, int size) return AVERROR(ENOSYS); } -void ff_sdp_write_media(char *buff, int size, AVCodecContext *c, const char *dest_addr, const char *dest_type, int port, int ttl) +void ff_sdp_write_media(char *buff, int size, AVCodecContext *c, const char *dest_addr, const char *dest_type, int port, int ttl, AVFormatContext *fmt) { } #endif From cb7c11cc9e7e05c819fff487a3f486f11ab4b860 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Fri, 27 May 2011 22:21:40 +0300 Subject: [PATCH 05/20] avoptions: Add an av_opt_flag_is_set function for inspecting flag fields MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Martin Storsjö --- doc/APIchanges | 3 +++ libavutil/avutil.h | 2 +- libavutil/opt.c | 10 ++++++++++ libavutil/opt.h | 10 ++++++++++ 4 files changed, 24 insertions(+), 1 deletion(-) diff --git a/doc/APIchanges b/doc/APIchanges index b57868dfdf..0ab658d89c 100644 --- a/doc/APIchanges +++ b/doc/APIchanges @@ -13,6 +13,9 @@ libavutil: 2011-04-18 API changes, most recent first: +2011-06-xx - xxxxxxx - lavu 51.6.0 - opt.h + Add av_opt_flag_is_set(). + 2011-06-xx - xxxxxxx - lavu 51.5.0 - AVMetadata Move AVMetadata from lavf to lavu and rename it to AVDictionary -- new installed header dict.h. diff --git a/libavutil/avutil.h b/libavutil/avutil.h index 9c660f3a99..0299bdf797 100644 --- a/libavutil/avutil.h +++ b/libavutil/avutil.h @@ -40,7 +40,7 @@ #define AV_VERSION(a, b, c) AV_VERSION_DOT(a, b, c) #define LIBAVUTIL_VERSION_MAJOR 51 -#define LIBAVUTIL_VERSION_MINOR 5 +#define LIBAVUTIL_VERSION_MINOR 6 #define LIBAVUTIL_VERSION_MICRO 0 #define LIBAVUTIL_VERSION_INT AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \ diff --git a/libavutil/opt.c b/libavutil/opt.c index 172fcec456..7775bb2af3 100644 --- a/libavutil/opt.c +++ b/libavutil/opt.c @@ -320,6 +320,16 @@ int64_t av_get_int(void *obj, const char *name, const AVOption **o_out) return num*intnum/den; } +int av_opt_flag_is_set(void *obj, const char *field_name, const char *flag_name) +{ + const AVOption *field = av_find_opt(obj, field_name, NULL, 0, 0); + const AVOption *flag = av_find_opt(obj, flag_name, NULL, 0, 0); + + if (!field || !flag || flag->type != FF_OPT_TYPE_CONST) + return 0; + return av_get_int(obj, field_name, NULL) & (int) flag->default_val.dbl; +} + static void opt_list(void *obj, void *av_log_obj, const char *unit, int req_flags, int rej_flags) { diff --git a/libavutil/opt.h b/libavutil/opt.h index 8c3b6c1c36..46ad8acce1 100644 --- a/libavutil/opt.h +++ b/libavutil/opt.h @@ -181,4 +181,14 @@ int av_set_options_string(void *ctx, const char *opts, */ void av_opt_free(void *obj); +/** + * Check whether a particular flag is set in a flags field. + * + * @param field_name the name of the flag field option + * @param flag_name the name of the flag to check + * @return non-zero if the flag is set, zero if the flag isn't set, + * isn't of the right type, or the flags field doesn't exist. + */ +int av_opt_flag_is_set(void *obj, const char *field_name, const char *flag_name); + #endif /* AVUTIL_OPT_H */ From 0832122880fa50e66dfd62eb6aa5c814f83f68d9 Mon Sep 17 00:00:00 2001 From: Juan Carlos Rodriguez Date: Wed, 18 May 2011 15:00:03 +0300 Subject: [PATCH 06/20] rtpenc: MP4A-LATM payload support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is enabled with an AVOption on the RTP muxer. The SDP generator looks for a latm flag in the rtpflags field. Signed-off-by: Martin Storsjö --- libavcodec/Makefile | 2 +- libavformat/Makefile | 1 + libavformat/rtpenc.c | 20 +++++++++- libavformat/rtpenc.h | 6 +++ libavformat/rtpenc_latm.c | 61 ++++++++++++++++++++++++++++++ libavformat/sdp.c | 78 +++++++++++++++++++++++++++++++++++++++ libavformat/version.h | 2 +- 7 files changed, 167 insertions(+), 3 deletions(-) create mode 100644 libavformat/rtpenc_latm.c diff --git a/libavcodec/Makefile b/libavcodec/Makefile index 7fd6b49d32..581d6bf399 100644 --- a/libavcodec/Makefile +++ b/libavcodec/Makefile @@ -545,7 +545,7 @@ OBJS-$(CONFIG_NUT_MUXER) += mpegaudiodata.o OBJS-$(CONFIG_OGG_DEMUXER) += flacdec.o flacdata.o flac.o \ dirac.o mpeg12data.o OBJS-$(CONFIG_OGG_MUXER) += xiph.o flacdec.o flacdata.o flac.o -OBJS-$(CONFIG_RTP_MUXER) += mpegvideo.o xiph.o +OBJS-$(CONFIG_RTP_MUXER) += mpeg4audio.o mpegvideo.o xiph.o OBJS-$(CONFIG_SPDIF_DEMUXER) += aacadtsdec.o mpeg4audio.o OBJS-$(CONFIG_WEBM_MUXER) += xiph.o mpeg4audio.o \ flacdec.o flacdata.o flac.o \ diff --git a/libavformat/Makefile b/libavformat/Makefile index ba978af7a4..c2fa8af466 100644 --- a/libavformat/Makefile +++ b/libavformat/Makefile @@ -228,6 +228,7 @@ OBJS-$(CONFIG_RSO_MUXER) += rsoenc.o rso.o OBJS-$(CONFIG_RPL_DEMUXER) += rpl.o OBJS-$(CONFIG_RTP_MUXER) += rtp.o \ rtpenc_aac.o \ + rtpenc_latm.o \ rtpenc_amr.o \ rtpenc_h263.o \ rtpenc_mpv.o \ diff --git a/libavformat/rtpenc.c b/libavformat/rtpenc.c index 7cedff382e..c264b30a07 100644 --- a/libavformat/rtpenc.c +++ b/libavformat/rtpenc.c @@ -23,11 +23,25 @@ #include "mpegts.h" #include "internal.h" #include "libavutil/random_seed.h" +#include "libavutil/opt.h" #include "rtpenc.h" //#define DEBUG +static const AVOption options[] = { + { "rtpflags", "RTP muxer flags", offsetof(RTPMuxContext, flags), FF_OPT_TYPE_FLAGS, {.dbl = 0}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, "rtpflags" }, + { "latm", "Use MP4A-LATM packetization instead of MPEG4-GENERIC for AAC", 0, FF_OPT_TYPE_CONST, {.dbl = FF_RTP_FLAG_MP4A_LATM}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, "rtpflags" }, + { NULL }, +}; + +static const AVClass rtp_muxer_class = { + .class_name = "RTP muxer", + .item_name = av_default_item_name, + .option = options, + .version = LIBAVUTIL_VERSION_INT, +}; + #define RTCP_SR_SIZE 28 static int is_supported(enum CodecID id) @@ -404,7 +418,10 @@ static int rtp_write_packet(AVFormatContext *s1, AVPacket *pkt) ff_rtp_send_mpegvideo(s1, pkt->data, size); break; case CODEC_ID_AAC: - ff_rtp_send_aac(s1, pkt->data, size); + if (s->flags & FF_RTP_FLAG_MP4A_LATM) + ff_rtp_send_latm(s1, pkt->data, size); + else + ff_rtp_send_aac(s1, pkt->data, size); break; case CODEC_ID_AMR_NB: case CODEC_ID_AMR_WB: @@ -455,4 +472,5 @@ AVOutputFormat ff_rtp_muxer = { rtp_write_header, rtp_write_packet, rtp_write_trailer, + .priv_class = &rtp_muxer_class, }; diff --git a/libavformat/rtpenc.h b/libavformat/rtpenc.h index 21c5c312a4..ac5a62242d 100644 --- a/libavformat/rtpenc.h +++ b/libavformat/rtpenc.h @@ -25,6 +25,7 @@ #include "rtp.h" struct RTPMuxContext { + const AVClass *av_class; AVFormatContext *ic; AVStream *st; int payload_type; @@ -56,15 +57,20 @@ struct RTPMuxContext { * (1, 2 or 4) */ int nal_length_size; + + int flags; }; typedef struct RTPMuxContext RTPMuxContext; +#define FF_RTP_FLAG_MP4A_LATM 1 + void ff_rtp_send_data(AVFormatContext *s1, const uint8_t *buf1, int len, int m); void ff_rtp_send_h264(AVFormatContext *s1, const uint8_t *buf1, int size); void ff_rtp_send_h263(AVFormatContext *s1, const uint8_t *buf1, int size); void ff_rtp_send_aac(AVFormatContext *s1, const uint8_t *buff, int size); +void ff_rtp_send_latm(AVFormatContext *s1, const uint8_t *buff, int size); void ff_rtp_send_amr(AVFormatContext *s1, const uint8_t *buff, int size); void ff_rtp_send_mpegvideo(AVFormatContext *s1, const uint8_t *buf1, int size); void ff_rtp_send_xiph(AVFormatContext *s1, const uint8_t *buff, int size); diff --git a/libavformat/rtpenc_latm.c b/libavformat/rtpenc_latm.c new file mode 100644 index 0000000000..aa6e29117f --- /dev/null +++ b/libavformat/rtpenc_latm.c @@ -0,0 +1,61 @@ +/* + * RTP Packetization of MPEG-4 Audio (RFC 3016) + * Copyright (c) 2011 Juan Carlos Rodriguez + * + * This file is part of Libav. + * + * Libav is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "avformat.h" +#include "rtpenc.h" + +void ff_rtp_send_latm(AVFormatContext *s1, const uint8_t *buff, int size) +{ + /* MP4A-LATM + * The RTP payload format specification is described in RFC 3016 + * The encoding specifications are provided in ISO/IEC 14496-3 */ + + RTPMuxContext *s = s1->priv_data; + int header_size; + int offset = 0; + int len = 0; + + /* skip ADTS header, if present */ + if ((s1->streams[0]->codec->extradata_size) == 0) { + size -= 7; + buff += 7; + } + + /* PayloadLengthInfo() */ + header_size = size/0xFF + 1; + memset(s->buf, 0xFF, header_size - 1); + s->buf[header_size - 1] = size % 0xFF; + + s->timestamp = s->cur_timestamp; + + /* PayloadMux() */ + while (size > 0) { + len = FFMIN(size, s->max_payload_size - (!offset ? header_size : 0)); + size -= len; + if (!offset) { + memcpy(s->buf + header_size, buff, len); + ff_rtp_send_data(s1, s->buf, header_size + len, !size); + } else { + ff_rtp_send_data(s1, buff + offset, len, !size); + } + offset += len; + } +} diff --git a/libavformat/sdp.c b/libavformat/sdp.c index b996bf65f5..92690f58a3 100644 --- a/libavformat/sdp.c +++ b/libavformat/sdp.c @@ -23,7 +23,9 @@ #include "libavutil/base64.h" #include "libavutil/dict.h" #include "libavutil/parseutils.h" +#include "libavutil/opt.h" #include "libavcodec/xiph.h" +#include "libavcodec/mpeg4audio.h" #include "avformat.h" #include "internal.h" #include "avc.h" @@ -300,6 +302,71 @@ xiph_fail: return NULL; } +static int latm_context2profilelevel(AVCodecContext *c) +{ + /* MP4A-LATM + * The RTP payload format specification is described in RFC 3016 + * The encoding specifications are provided in ISO/IEC 14496-3 */ + + int profile_level = 0x2B; + + /* TODO: AAC Profile only supports AAC LC Object Type. + * Different Object Types should implement different Profile Levels */ + + if (c->sample_rate <= 24000) { + if (c->channels <= 2) + profile_level = 0x28; // AAC Profile, Level 1 + } else if (c->sample_rate <= 48000) { + if (c->channels <= 2) { + profile_level = 0x29; // AAC Profile, Level 2 + } else if (c->channels <= 5) { + profile_level = 0x2A; // AAC Profile, Level 4 + } + } else if (c->sample_rate <= 96000) { + if (c->channels <= 5) { + profile_level = 0x2B; // AAC Profile, Level 5 + } + } + + return profile_level; +} + +static char *latm_context2config(AVCodecContext *c) +{ + /* MP4A-LATM + * The RTP payload format specification is described in RFC 3016 + * The encoding specifications are provided in ISO/IEC 14496-3 */ + + uint8_t config_byte[6]; + int rate_index; + char *config; + + for (rate_index = 0; rate_index < 16; rate_index++) + if (ff_mpeg4audio_sample_rates[rate_index] == c->sample_rate) + break; + if (rate_index == 16) { + av_log(c, AV_LOG_ERROR, "Unsupported sample rate\n"); + return NULL; + } + + config_byte[0] = 0x40; + config_byte[1] = 0; + config_byte[2] = 0x20 | rate_index; + config_byte[3] = c->channels << 4; + config_byte[4] = 0x3f; + config_byte[5] = 0xc0; + + config = av_malloc(6*2+1); + if (!config) { + av_log(c, AV_LOG_ERROR, "Cannot allocate memory for the config info.\n"); + return NULL; + } + ff_data_to_hex(config, config_byte, 6, 1); + config[12] = 0; + + return config; +} + static char *sdp_write_media_attributes(char *buff, int size, AVCodecContext *c, int payload_type, AVFormatContext *fmt) { char *config = NULL; @@ -335,6 +402,16 @@ static char *sdp_write_media_attributes(char *buff, int size, AVCodecContext *c, payload_type, config ? config : ""); break; case CODEC_ID_AAC: + if (fmt && fmt->oformat->priv_class && + av_opt_flag_is_set(fmt->priv_data, "rtpflags", "latm")) { + config = latm_context2config(c); + if (!config) + return NULL; + av_strlcatf(buff, size, "a=rtpmap:%d MP4A-LATM/%d/%d\r\n" + "a=fmtp:%d profile-level-id=%d;cpresent=0;config=%s\r\n", + payload_type, c->sample_rate, c->channels, + payload_type, latm_context2profilelevel(c), config); + } else { if (c->extradata_size) { config = extradata2config(c); } else { @@ -353,6 +430,7 @@ static char *sdp_write_media_attributes(char *buff, int size, AVCodecContext *c, "indexdeltalength=3%s\r\n", payload_type, c->sample_rate, c->channels, payload_type, config); + } break; case CODEC_ID_PCM_S16BE: if (payload_type >= RTP_PT_PRIVATE) diff --git a/libavformat/version.h b/libavformat/version.h index 0b53005a6f..ca61ab165f 100644 --- a/libavformat/version.h +++ b/libavformat/version.h @@ -25,7 +25,7 @@ #define LIBAVFORMAT_VERSION_MAJOR 53 #define LIBAVFORMAT_VERSION_MINOR 1 -#define LIBAVFORMAT_VERSION_MICRO 0 +#define LIBAVFORMAT_VERSION_MICRO 1 #define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \ LIBAVFORMAT_VERSION_MINOR, \ From 9c434ce8263097bd17e6a59461041f846edc2701 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Wed, 18 May 2011 15:48:20 +0300 Subject: [PATCH 07/20] sdp: Reindent after the previous commit MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Martin Storsjö --- libavformat/sdp.c | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/libavformat/sdp.c b/libavformat/sdp.c index 92690f58a3..c227c7f603 100644 --- a/libavformat/sdp.c +++ b/libavformat/sdp.c @@ -412,24 +412,24 @@ static char *sdp_write_media_attributes(char *buff, int size, AVCodecContext *c, payload_type, c->sample_rate, c->channels, payload_type, latm_context2profilelevel(c), config); } else { - if (c->extradata_size) { - config = extradata2config(c); - } else { - /* FIXME: maybe we can forge config information based on the - * codec parameters... - */ - av_log(c, AV_LOG_ERROR, "AAC with no global headers is currently not supported.\n"); - return NULL; - } - if (config == NULL) { - return NULL; - } - av_strlcatf(buff, size, "a=rtpmap:%d MPEG4-GENERIC/%d/%d\r\n" - "a=fmtp:%d profile-level-id=1;" - "mode=AAC-hbr;sizelength=13;indexlength=3;" - "indexdeltalength=3%s\r\n", - payload_type, c->sample_rate, c->channels, - payload_type, config); + if (c->extradata_size) { + config = extradata2config(c); + } else { + /* FIXME: maybe we can forge config information based on the + * codec parameters... + */ + av_log(c, AV_LOG_ERROR, "AAC with no global headers is currently not supported.\n"); + return NULL; + } + if (config == NULL) { + return NULL; + } + av_strlcatf(buff, size, "a=rtpmap:%d MPEG4-GENERIC/%d/%d\r\n" + "a=fmtp:%d profile-level-id=1;" + "mode=AAC-hbr;sizelength=13;indexlength=3;" + "indexdeltalength=3%s\r\n", + payload_type, c->sample_rate, c->channels, + payload_type, config); } break; case CODEC_ID_PCM_S16BE: From 635fac9af10092b0d5780a7d1b422b3044f9abd9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Fri, 27 May 2011 22:38:36 +0300 Subject: [PATCH 08/20] rtpenc: Declare the rtp flags private AVOptions in rtpenc.h MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This allows other muxers that chain a RTP muxer to declare the same options easily. Signed-off-by: Martin Storsjö --- libavformat/rtpenc.c | 3 +-- libavformat/rtpenc.h | 4 ++++ 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/libavformat/rtpenc.c b/libavformat/rtpenc.c index c264b30a07..3da6dfb3a9 100644 --- a/libavformat/rtpenc.c +++ b/libavformat/rtpenc.c @@ -30,8 +30,7 @@ //#define DEBUG static const AVOption options[] = { - { "rtpflags", "RTP muxer flags", offsetof(RTPMuxContext, flags), FF_OPT_TYPE_FLAGS, {.dbl = 0}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, "rtpflags" }, - { "latm", "Use MP4A-LATM packetization instead of MPEG4-GENERIC for AAC", 0, FF_OPT_TYPE_CONST, {.dbl = FF_RTP_FLAG_MP4A_LATM}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, "rtpflags" }, + FF_RTP_FLAG_OPTS(RTPMuxContext, flags), { NULL }, }; diff --git a/libavformat/rtpenc.h b/libavformat/rtpenc.h index ac5a62242d..3a9e19be06 100644 --- a/libavformat/rtpenc.h +++ b/libavformat/rtpenc.h @@ -65,6 +65,10 @@ typedef struct RTPMuxContext RTPMuxContext; #define FF_RTP_FLAG_MP4A_LATM 1 +#define FF_RTP_FLAG_OPTS(ctx, fieldname) \ + { "rtpflags", "RTP muxer flags", offsetof(ctx, fieldname), FF_OPT_TYPE_FLAGS, {.dbl = 0}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, "rtpflags" }, \ + { "latm", "Use MP4A-LATM packetization instead of MPEG4-GENERIC for AAC", 0, FF_OPT_TYPE_CONST, {.dbl = FF_RTP_FLAG_MP4A_LATM}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, "rtpflags" } \ + void ff_rtp_send_data(AVFormatContext *s1, const uint8_t *buf1, int len, int m); void ff_rtp_send_h264(AVFormatContext *s1, const uint8_t *buf1, int size); From ff0824f72c25787b6ad60b5c90a25473995e68c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Wed, 18 May 2011 15:42:53 +0300 Subject: [PATCH 09/20] rtpenc_chain: Pass the rtpflags options through to the chained muxer MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Martin Storsjö --- libavformat/rtpenc_chain.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/libavformat/rtpenc_chain.c b/libavformat/rtpenc_chain.c index 1727740f0f..87c1688dfc 100644 --- a/libavformat/rtpenc_chain.c +++ b/libavformat/rtpenc_chain.c @@ -23,6 +23,7 @@ #include "avio_internal.h" #include "rtpenc_chain.h" #include "avio_internal.h" +#include "libavutil/opt.h" AVFormatContext *ff_rtp_chain_mux_open(AVFormatContext *s, AVStream *st, URLContext *handle, int packet_size) @@ -49,6 +50,13 @@ AVFormatContext *ff_rtp_chain_mux_open(AVFormatContext *s, AVStream *st, /* Copy other stream parameters. */ rtpctx->streams[0]->sample_aspect_ratio = st->sample_aspect_ratio; + av_set_parameters(rtpctx, NULL); + /* Copy the rtpflags values straight through */ + if (s->oformat->priv_class && + av_find_opt(s->priv_data, "rtpflags", NULL, 0, 0)) + av_set_int(rtpctx->priv_data, "rtpflags", + av_get_int(s->priv_data, "rtpflags", NULL)); + /* Set the synchronized start time. */ rtpctx->start_time_realtime = s->start_time_realtime; From 6cf09bb7ef5a52b9d9b589067d94a5c80f9fe848 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Sat, 21 May 2011 15:03:35 +0300 Subject: [PATCH 10/20] rtspenc: Add an AVClass for setting muxer specific options MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Martin Storsjö --- libavformat/rtspenc.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/libavformat/rtspenc.c b/libavformat/rtspenc.c index c1fc97ca8f..b7fa330f53 100644 --- a/libavformat/rtspenc.c +++ b/libavformat/rtspenc.c @@ -33,9 +33,21 @@ #include "libavutil/intreadwrite.h" #include "libavutil/avstring.h" #include "url.h" +#include "libavutil/opt.h" #define SDP_MAX_SIZE 16384 +static const AVOption options[] = { + { NULL }, +}; + +static const AVClass rtsp_muxer_class = { + .class_name = "RTSP muxer", + .item_name = av_default_item_name, + .option = options, + .version = LIBAVUTIL_VERSION_INT, +}; + int ff_rtsp_setup_output_streams(AVFormatContext *s, const char *addr) { RTSPState *rt = s->priv_data; @@ -238,5 +250,6 @@ AVOutputFormat ff_rtsp_muxer = { rtsp_write_packet, rtsp_write_close, .flags = AVFMT_NOFILE | AVFMT_GLOBALHEADER, + .priv_class = &rtsp_muxer_class, }; From e2e29c62476f7d8f8851d0d51809ce2a152362f5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Sat, 21 May 2011 15:03:48 +0300 Subject: [PATCH 11/20] rtspenc: Add RTP muxer options MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Martin Storsjö --- libavformat/rtsp.h | 5 +++++ libavformat/rtspenc.c | 2 ++ libavformat/version.h | 2 +- 3 files changed, 8 insertions(+), 1 deletion(-) diff --git a/libavformat/rtsp.h b/libavformat/rtsp.h index f5a7fada21..5eae6bf4f3 100644 --- a/libavformat/rtsp.h +++ b/libavformat/rtsp.h @@ -344,6 +344,11 @@ typedef struct RTSPState { * Do not begin to play the stream immediately. */ int initial_pause; + + /** + * Option flags for the chained RTP muxer. + */ + int rtp_muxer_flags; } RTSPState; /** diff --git a/libavformat/rtspenc.c b/libavformat/rtspenc.c index b7fa330f53..b76b6adb99 100644 --- a/libavformat/rtspenc.c +++ b/libavformat/rtspenc.c @@ -34,10 +34,12 @@ #include "libavutil/avstring.h" #include "url.h" #include "libavutil/opt.h" +#include "rtpenc.h" #define SDP_MAX_SIZE 16384 static const AVOption options[] = { + FF_RTP_FLAG_OPTS(RTSPState, rtp_muxer_flags), { NULL }, }; diff --git a/libavformat/version.h b/libavformat/version.h index ca61ab165f..bd7f3c0e48 100644 --- a/libavformat/version.h +++ b/libavformat/version.h @@ -25,7 +25,7 @@ #define LIBAVFORMAT_VERSION_MAJOR 53 #define LIBAVFORMAT_VERSION_MINOR 1 -#define LIBAVFORMAT_VERSION_MICRO 1 +#define LIBAVFORMAT_VERSION_MICRO 2 #define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \ LIBAVFORMAT_VERSION_MINOR, \ From f3f82296a407d3c4eada161aaec45b21a5334fc3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Wed, 18 May 2011 15:41:38 +0300 Subject: [PATCH 12/20] movenc: Pass the RTP AVFormatContext to the SDP generation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Martin Storsjö --- libavformat/movenc.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/libavformat/movenc.c b/libavformat/movenc.c index b313510b25..ccd39ffa84 100644 --- a/libavformat/movenc.c +++ b/libavformat/movenc.c @@ -1354,12 +1354,12 @@ static int mov_write_uuid_tag_psp(AVIOContext *pb, MOVTrack *mov) return 0x34; } -static int mov_write_udta_sdp(AVIOContext *pb, AVCodecContext *ctx, int index) +static int mov_write_udta_sdp(AVIOContext *pb, AVFormatContext *ctx, int index) { char buf[1000] = ""; int len; - ff_sdp_write_media(buf, sizeof(buf), ctx, NULL, NULL, 0, 0, NULL); + ff_sdp_write_media(buf, sizeof(buf), ctx->streams[0]->codec, NULL, NULL, 0, 0, ctx); av_strlcatf(buf, sizeof(buf), "a=control:streamid=%d\r\n", index); len = strlen(buf); @@ -1387,7 +1387,7 @@ static int mov_write_trak_tag(AVIOContext *pb, MOVTrack *track, AVStream *st) if (track->mode == MODE_PSP) mov_write_uuid_tag_psp(pb,track); // PSP Movies require this uuid box if (track->tag == MKTAG('r','t','p',' ')) - mov_write_udta_sdp(pb, track->rtp_ctx->streams[0]->codec, track->trackID); + mov_write_udta_sdp(pb, track->rtp_ctx, track->trackID); if (track->enc->codec_type == AVMEDIA_TYPE_VIDEO && track->mode == MODE_MOV) { double sample_aspect_ratio = av_q2d(st->sample_aspect_ratio); if (0.0 != sample_aspect_ratio && 1.0 != sample_aspect_ratio) From d16cccac98a250d53827fa0c82e429bf17070d0f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Sat, 21 May 2011 14:58:43 +0300 Subject: [PATCH 13/20] movenc: Add RTP muxer/hinter options MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Martin Storsjö --- libavformat/movenc.c | 2 ++ libavformat/movenc.h | 1 + libavformat/version.h | 2 +- 3 files changed, 4 insertions(+), 1 deletion(-) diff --git a/libavformat/movenc.c b/libavformat/movenc.c index ccd39ffa84..dcc5581443 100644 --- a/libavformat/movenc.c +++ b/libavformat/movenc.c @@ -34,6 +34,7 @@ #include "libavutil/avstring.h" #include "libavutil/opt.h" #include "libavutil/dict.h" +#include "rtpenc.h" #undef NDEBUG #include @@ -41,6 +42,7 @@ static const AVOption options[] = { { "movflags", "MOV muxer flags", offsetof(MOVMuxContext, flags), FF_OPT_TYPE_FLAGS, {.dbl = 0}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, "movflags" }, { "rtphint", "Add RTP hint tracks", 0, FF_OPT_TYPE_CONST, {.dbl = FF_MOV_FLAG_RTP_HINT}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, "movflags" }, + FF_RTP_FLAG_OPTS(MOVMuxContext, rtp_flags), { NULL }, }; diff --git a/libavformat/movenc.h b/libavformat/movenc.h index 69b6621711..39cdb39284 100644 --- a/libavformat/movenc.h +++ b/libavformat/movenc.h @@ -111,6 +111,7 @@ typedef struct MOVMuxContext { MOVTrack *tracks; int flags; + int rtp_flags; } MOVMuxContext; #define FF_MOV_FLAG_RTP_HINT 1 diff --git a/libavformat/version.h b/libavformat/version.h index bd7f3c0e48..83fa431246 100644 --- a/libavformat/version.h +++ b/libavformat/version.h @@ -25,7 +25,7 @@ #define LIBAVFORMAT_VERSION_MAJOR 53 #define LIBAVFORMAT_VERSION_MINOR 1 -#define LIBAVFORMAT_VERSION_MICRO 2 +#define LIBAVFORMAT_VERSION_MICRO 3 #define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \ LIBAVFORMAT_VERSION_MINOR, \ From f74e5b76b1033e5224d6a7b5906e05cecd2b3302 Mon Sep 17 00:00:00 2001 From: Kieran Kunhya Date: Wed, 8 Jun 2011 01:26:20 -0500 Subject: [PATCH 14/20] adts: Adjust frame size mask to follow the specification. This fixes ADTS detection for at least one sample. Signed-off-by: Diego Biurrun --- libavformat/aacdec.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavformat/aacdec.c b/libavformat/aacdec.c index 0dc1c5ce0f..6a184c77d7 100644 --- a/libavformat/aacdec.c +++ b/libavformat/aacdec.c @@ -44,7 +44,7 @@ static int adts_aac_probe(AVProbeData *p) uint32_t header = AV_RB16(buf2); if((header&0xFFF6) != 0xFFF0) break; - fsize = (AV_RB32(buf2+3)>>13) & 0x8FFF; + fsize = (AV_RB32(buf2 + 3) >> 13) & 0x1FFF; if(fsize < 7) break; buf2 += fsize; From aecc596a651b981256f91ee619aaf282e455d99e Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Fri, 10 Jun 2011 12:58:08 -0400 Subject: [PATCH 15/20] Update copyright year for ac3enc_opts_template.c. The code was originally committed to Libav on March 25, 2011. --- libavcodec/ac3enc_opts_template.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavcodec/ac3enc_opts_template.c b/libavcodec/ac3enc_opts_template.c index 699c1b5982..e16e0d0878 100644 --- a/libavcodec/ac3enc_opts_template.c +++ b/libavcodec/ac3enc_opts_template.c @@ -1,6 +1,6 @@ /* * AC-3 encoder options - * Copyright (c) 2010 Justin Ruggles + * Copyright (c) 2011 Justin Ruggles * * This file is part of Libav. * From 919d7a345a7e9044c3cdc89cf06dc521a1b01c6c Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Tue, 7 Jun 2011 13:18:12 +0200 Subject: [PATCH 16/20] Replace DEBUG_SEEK/DEBUG_SI + av_log combinations by av_dlog. --- libavformat/avidec.c | 43 ++++++++++++++------------------------- libavformat/ffmdec.c | 14 +++---------- libavformat/mpeg.c | 12 +++-------- libavformat/mpegenc.c | 1 - libavformat/mpegts.c | 2 -- libavformat/nsvdec.c | 2 -- libavformat/utils.c | 47 ++++++++++++++----------------------------- 7 files changed, 36 insertions(+), 85 deletions(-) diff --git a/libavformat/avidec.c b/libavformat/avidec.c index a915cc6588..dacd230613 100644 --- a/libavformat/avidec.c +++ b/libavformat/avidec.c @@ -19,9 +19,6 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -//#define DEBUG -//#define DEBUG_SEEK - #include #include "libavutil/intreadwrite.h" #include "libavutil/bswap.h" @@ -141,10 +138,8 @@ static int read_braindead_odml_indx(AVFormatContext *s, int frame_num){ int64_t last_pos= -1; int64_t filesize= avio_size(s->pb); -#ifdef DEBUG_SEEK - av_log(s, AV_LOG_ERROR, "longs_pre_entry:%d index_type:%d entries_in_use:%d chunk_id:%X base:%16"PRIX64"\n", - longs_pre_entry,index_type, entries_in_use, chunk_id, base); -#endif + av_dlog(s, "longs_pre_entry:%d index_type:%d entries_in_use:%d chunk_id:%X base:%16"PRIX64"\n", + longs_pre_entry,index_type, entries_in_use, chunk_id, base); if(stream_id >= s->nb_streams || stream_id < 0) return -1; @@ -176,9 +171,8 @@ static int read_braindead_odml_indx(AVFormatContext *s, int frame_num){ int key= len >= 0; len &= 0x7FFFFFFF; -#ifdef DEBUG_SEEK - av_log(s, AV_LOG_ERROR, "pos:%"PRId64", len:%X\n", pos, len); -#endif + av_dlog(s, "pos:%"PRId64", len:%X\n", pos, len); + if(pb->eof_reached) return -1; @@ -1134,10 +1128,8 @@ static int avi_read_idx1(AVFormatContext *s, int size) flags = avio_rl32(pb); pos = avio_rl32(pb); len = avio_rl32(pb); -#if defined(DEBUG_SEEK) - av_log(s, AV_LOG_DEBUG, "%d: tag=0x%x flags=0x%x pos=0x%x len=%d/", - i, tag, flags, pos, len); -#endif + av_dlog(s, "%d: tag=0x%x flags=0x%x pos=0x%x len=%d/", + i, tag, flags, pos, len); if(i==0 && pos > avi->movi_list) avi->movi_list= 0; //FIXME better check pos += avi->movi_list; @@ -1149,9 +1141,8 @@ static int avi_read_idx1(AVFormatContext *s, int size) st = s->streams[index]; ast = st->priv_data; -#if defined(DEBUG_SEEK) - av_log(s, AV_LOG_DEBUG, "%d cum_len=%"PRId64"\n", len, ast->cum_len); -#endif + av_dlog(s, "%d cum_len=%"PRId64"\n", len, ast->cum_len); + if(pb->eof_reached) return -1; @@ -1206,22 +1197,18 @@ static int avi_load_index(AVFormatContext *s) if (avio_seek(pb, avi->movi_end, SEEK_SET) < 0) goto the_end; // maybe truncated file -#ifdef DEBUG_SEEK - av_log(s, AV_LOG_DEBUG, "movi_end=0x%"PRIx64"\n", avi->movi_end); -#endif + av_dlog(s, "movi_end=0x%"PRIx64"\n", avi->movi_end); for(;;) { if (pb->eof_reached) break; tag = avio_rl32(pb); size = avio_rl32(pb); -#ifdef DEBUG_SEEK - av_log(s, AV_LOG_DEBUG, "tag=%c%c%c%c size=0x%x\n", - tag & 0xff, - (tag >> 8) & 0xff, - (tag >> 16) & 0xff, - (tag >> 24) & 0xff, - size); -#endif + av_dlog(s, "tag=%c%c%c%c size=0x%x\n", + tag & 0xff, + (tag >> 8) & 0xff, + (tag >> 16) & 0xff, + (tag >> 24) & 0xff, + size); switch(tag) { case MKTAG('i', 'd', 'x', '1'): if (avi_read_idx1(s, size) < 0) diff --git a/libavformat/ffmdec.c b/libavformat/ffmdec.c index 8a6226a104..dfd86cb28b 100644 --- a/libavformat/ffmdec.c +++ b/libavformat/ffmdec.c @@ -163,8 +163,6 @@ static int ffm_read_data(AVFormatContext *s, return size1 - size; } -//#define DEBUG_SEEK - /* ensure that acutal seeking happens between FFM_PACKET_SIZE and file_size - FFM_PACKET_SIZE */ static void ffm_seek1(AVFormatContext *s, int64_t pos1) @@ -175,9 +173,7 @@ static void ffm_seek1(AVFormatContext *s, int64_t pos1) pos = FFMIN(pos1, ffm->file_size - FFM_PACKET_SIZE); pos = FFMAX(pos, FFM_PACKET_SIZE); -#ifdef DEBUG_SEEK - av_log(s, AV_LOG_DEBUG, "seek to %"PRIx64" -> %"PRIx64"\n", pos1, pos); -#endif + av_dlog(s, "seek to %"PRIx64" -> %"PRIx64"\n", pos1, pos); avio_seek(pb, pos, SEEK_SET); } @@ -189,9 +185,7 @@ static int64_t get_dts(AVFormatContext *s, int64_t pos) ffm_seek1(s, pos); avio_skip(pb, 4); dts = avio_rb64(pb); -#ifdef DEBUG_SEEK - av_log(s, AV_LOG_DEBUG, "dts=%0.6f\n", dts / 1000000.0); -#endif + av_dlog(s, "dts=%0.6f\n", dts / 1000000.0); return dts; } @@ -465,9 +459,7 @@ static int ffm_seek(AVFormatContext *s, int stream_index, int64_t wanted_pts, in int64_t pts_min, pts_max, pts; double pos1; -#ifdef DEBUG_SEEK - av_log(s, AV_LOG_DEBUG, "wanted_pts=%0.6f\n", wanted_pts / 1000000.0); -#endif + av_dlog(s, "wanted_pts=%0.6f\n", wanted_pts / 1000000.0); /* find the position using linear interpolation (better than dichotomy in typical cases) */ pos_min = FFM_PACKET_SIZE; diff --git a/libavformat/mpeg.c b/libavformat/mpeg.c index 5b4996e825..496b9d45f5 100644 --- a/libavformat/mpeg.c +++ b/libavformat/mpeg.c @@ -23,8 +23,6 @@ #include "internal.h" #include "mpeg.h" -//#define DEBUG_SEEK - #undef NDEBUG #include @@ -589,9 +587,7 @@ static int64_t mpegps_read_dts(AVFormatContext *s, int stream_index, for(;;) { len = mpegps_read_pes_header(s, &pos, &startcode, &pts, &dts); if (len < 0) { -#ifdef DEBUG_SEEK - av_log(s, AV_LOG_DEBUG, "none (ret=%d)\n", len); -#endif + av_dlog(s, "none (ret=%d)\n", len); return AV_NOPTS_VALUE; } if (startcode == s->streams[stream_index]->id && @@ -600,10 +596,8 @@ static int64_t mpegps_read_dts(AVFormatContext *s, int stream_index, } avio_skip(s->pb, len); } -#ifdef DEBUG_SEEK - av_log(s, AV_LOG_DEBUG, "pos=0x%"PRIx64" dts=0x%"PRIx64" %0.3f\n", - pos, dts, dts / 90000.0); -#endif + av_dlog(s, "pos=0x%"PRIx64" dts=0x%"PRIx64" %0.3f\n", + pos, dts, dts / 90000.0); *ppos = pos; return dts; } diff --git a/libavformat/mpegenc.c b/libavformat/mpegenc.c index 98169abcf5..820c5bd5e1 100644 --- a/libavformat/mpegenc.c +++ b/libavformat/mpegenc.c @@ -25,7 +25,6 @@ #include "mpeg.h" #define MAX_PAYLOAD_SIZE 4096 -//#define DEBUG_SEEK #undef NDEBUG #include diff --git a/libavformat/mpegts.c b/libavformat/mpegts.c index bf81b20b5c..e9b8b3513a 100644 --- a/libavformat/mpegts.c +++ b/libavformat/mpegts.c @@ -19,8 +19,6 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -//#define DEBUG -//#define DEBUG_SEEK //#define USE_SYNCPOINT_SEARCH #include "libavutil/crc.h" diff --git a/libavformat/nsvdec.c b/libavformat/nsvdec.c index 08338c4609..9adb2f4729 100644 --- a/libavformat/nsvdec.c +++ b/libavformat/nsvdec.c @@ -22,9 +22,7 @@ #include "riff.h" #include "libavutil/dict.h" -//#define DEBUG //#define DEBUG_DUMP_INDEX // XXX dumbdriving-271.nsv breaks with it commented!! -//#define DEBUG_SEEK #define CHECK_SUBSEQUENT_NSVS //#define DISABLE_AUDIO diff --git a/libavformat/utils.c b/libavformat/utils.c index b189bfb622..dc3b9d8fb8 100644 --- a/libavformat/utils.c +++ b/libavformat/utils.c @@ -1421,8 +1421,6 @@ int av_index_search_timestamp(AVStream *st, int64_t wanted_timestamp, wanted_timestamp, flags); } -#define DEBUG_SEEK - int av_seek_frame_binary(AVFormatContext *s, int stream_index, int64_t target_ts, int flags){ AVInputFormat *avif= s->iformat; int64_t av_uninit(pos_min), av_uninit(pos_max), pos, pos_limit; @@ -1434,9 +1432,7 @@ int av_seek_frame_binary(AVFormatContext *s, int stream_index, int64_t target_ts if (stream_index < 0) return -1; -#ifdef DEBUG_SEEK - av_log(s, AV_LOG_DEBUG, "read_seek: %d %"PRId64"\n", stream_index, target_ts); -#endif + av_dlog(s, "read_seek: %d %"PRId64"\n", stream_index, target_ts); ts_max= ts_min= AV_NOPTS_VALUE; @@ -1453,10 +1449,8 @@ int av_seek_frame_binary(AVFormatContext *s, int stream_index, int64_t target_ts if(e->timestamp <= target_ts || e->pos == e->min_distance){ pos_min= e->pos; ts_min= e->timestamp; -#ifdef DEBUG_SEEK - av_log(s, AV_LOG_DEBUG, "using cached pos_min=0x%"PRIx64" dts_min=%"PRId64"\n", - pos_min,ts_min); -#endif + av_dlog(s, "using cached pos_min=0x%"PRIx64" dts_min=%"PRId64"\n", + pos_min,ts_min); }else{ assert(index==0); } @@ -1469,10 +1463,8 @@ int av_seek_frame_binary(AVFormatContext *s, int stream_index, int64_t target_ts pos_max= e->pos; ts_max= e->timestamp; pos_limit= pos_max - e->min_distance; -#ifdef DEBUG_SEEK - av_log(s, AV_LOG_DEBUG, "using cached pos_max=0x%"PRIx64" pos_limit=0x%"PRIx64" dts_max=%"PRId64"\n", - pos_max,pos_limit, ts_max); -#endif + av_dlog(s, "using cached pos_max=0x%"PRIx64" pos_limit=0x%"PRIx64" dts_max=%"PRId64"\n", + pos_max,pos_limit, ts_max); } } @@ -1494,9 +1486,7 @@ int64_t av_gen_search(AVFormatContext *s, int stream_index, int64_t target_ts, i int64_t start_pos, filesize; int no_change; -#ifdef DEBUG_SEEK - av_log(s, AV_LOG_DEBUG, "gen_seek: %d %"PRId64"\n", stream_index, target_ts); -#endif + av_dlog(s, "gen_seek: %d %"PRId64"\n", stream_index, target_ts); if(ts_min == AV_NOPTS_VALUE){ pos_min = s->data_offset; @@ -1538,11 +1528,8 @@ int64_t av_gen_search(AVFormatContext *s, int stream_index, int64_t target_ts, i no_change=0; while (pos_min < pos_limit) { -#ifdef DEBUG_SEEK - av_log(s, AV_LOG_DEBUG, "pos_min=0x%"PRIx64" pos_max=0x%"PRIx64" dts_min=%"PRId64" dts_max=%"PRId64"\n", - pos_min, pos_max, - ts_min, ts_max); -#endif + av_dlog(s, "pos_min=0x%"PRIx64" pos_max=0x%"PRIx64" dts_min=%"PRId64" dts_max=%"PRId64"\n", + pos_min, pos_max, ts_min, ts_max); assert(pos_limit <= pos_max); if(no_change==0){ @@ -1569,11 +1556,9 @@ int64_t av_gen_search(AVFormatContext *s, int stream_index, int64_t target_ts, i no_change++; else no_change=0; -#ifdef DEBUG_SEEK - av_log(s, AV_LOG_DEBUG, "%"PRId64" %"PRId64" %"PRId64" / %"PRId64" %"PRId64" %"PRId64" target:%"PRId64" limit:%"PRId64" start:%"PRId64" noc:%d\n", - pos_min, pos, pos_max, ts_min, ts, ts_max, target_ts, pos_limit, - start_pos, no_change); -#endif + av_dlog(s, "%"PRId64" %"PRId64" %"PRId64" / %"PRId64" %"PRId64" %"PRId64" target:%"PRId64" limit:%"PRId64" start:%"PRId64" noc:%d\n", + pos_min, pos, pos_max, ts_min, ts, ts_max, target_ts, + pos_limit, start_pos, no_change); if(ts == AV_NOPTS_VALUE){ av_log(s, AV_LOG_ERROR, "read_timestamp() failed in the middle\n"); return -1; @@ -1592,13 +1577,13 @@ int64_t av_gen_search(AVFormatContext *s, int stream_index, int64_t target_ts, i pos = (flags & AVSEEK_FLAG_BACKWARD) ? pos_min : pos_max; ts = (flags & AVSEEK_FLAG_BACKWARD) ? ts_min : ts_max; -#ifdef DEBUG_SEEK +#if 1 pos_min = pos; ts_min = read_timestamp(s, stream_index, &pos_min, INT64_MAX); pos_min++; ts_max = read_timestamp(s, stream_index, &pos_min, INT64_MAX); - av_log(s, AV_LOG_DEBUG, "pos=0x%"PRIx64" %"PRId64"<=%"PRId64"<=%"PRId64"\n", - pos, ts_min, target_ts, ts_max); + av_dlog(s, "pos=0x%"PRIx64" %"PRId64"<=%"PRId64"<=%"PRId64"\n", + pos, ts_min, target_ts, ts_max); #endif *ts_ret= ts; return pos; @@ -2651,9 +2636,7 @@ AVProgram *av_new_program(AVFormatContext *ac, int id) AVProgram *program=NULL; int i; -#ifdef DEBUG_SI - av_log(ac, AV_LOG_DEBUG, "new_program: id=0x%04x\n", id); -#endif + av_dlog(ac, "new_program: id=0x%04x\n", id); for(i=0; inb_programs; i++) if(ac->programs[i]->id == id) From 6c031a3338d49dd61cf34fd703631f5a47205912 Mon Sep 17 00:00:00 2001 From: Oskar Arvidsson Date: Fri, 10 Jun 2011 02:40:10 +0200 Subject: [PATCH 17/20] h264: Fix 10-bit H.264 x86 chroma v loopfilter asm. The tc variable was not splatted correctly. Signed-off-by: Ronald S. Bultje --- libavcodec/x86/h264_deblock_10bit.asm | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/libavcodec/x86/h264_deblock_10bit.asm b/libavcodec/x86/h264_deblock_10bit.asm index f5a13f1250..baac725eec 100644 --- a/libavcodec/x86/h264_deblock_10bit.asm +++ b/libavcodec/x86/h264_deblock_10bit.asm @@ -836,6 +836,13 @@ DEBLOCK_LUMA_INTRA avx mova [r0+2*r1], m2 %endmacro +%macro CHROMA_V_LOAD_TC 2 + movd %1, [%2] + punpcklbw %1, %1 + punpcklwd %1, %1 + psraw %1, 6 +%endmacro + %macro DEBLOCK_CHROMA 1 ;----------------------------------------------------------------------------- ; void deblock_v_chroma( uint16_t *pix, int stride, int alpha, int beta, int8_t *tc0 ) @@ -854,7 +861,7 @@ cglobal deblock_v_chroma_10_%1, 5,7-(mmsize/16),8*(mmsize/16) LOAD_AB m4, m5, r2, r3 LOAD_MASK m0, m1, m2, m3, m4, m5, m7, m6, m4 pxor m4, m4 - LOAD_TC m6, r4 + CHROMA_V_LOAD_TC m6, r4 psubw m6, [pw_3] pmaxsw m6, m4 pand m7, m6 From c149843b5a484e73baffa0e070cfa08fe05943dd Mon Sep 17 00:00:00 2001 From: Jason Garrett-Glaser Date: Thu, 9 Jun 2011 18:20:19 -0700 Subject: [PATCH 18/20] H.264: Fix high bit depth explicit biweight Signed-off-by: Ronald S. Bultje --- libavcodec/h264dsp_template.c | 1 + 1 file changed, 1 insertion(+) diff --git a/libavcodec/h264dsp_template.c b/libavcodec/h264dsp_template.c index 91162ea900..be88f7487f 100644 --- a/libavcodec/h264dsp_template.c +++ b/libavcodec/h264dsp_template.c @@ -63,6 +63,7 @@ static void FUNCC(biweight_h264_pixels ## W ## x ## H)(uint8_t *_dst, uint8_t *_ pixel *dst = (pixel*)_dst; \ pixel *src = (pixel*)_src; \ stride /= sizeof(pixel); \ + offset <<= (BIT_DEPTH-8); \ offset = ((offset + 1) | 1) << log2_denom; \ for(y=0; y Date: Wed, 8 Jun 2011 19:16:39 -0700 Subject: [PATCH 19/20] libavutil/swscale: YUV444P10/YUV444P9 support. Also add missing glue code for recently added YUV422P10 formats to swscale. Signed-off-by: Ronald S. Bultje --- libavutil/pixdesc.c | 46 +++++++++++++++++++++++++++++++++++ libavutil/pixfmt.h | 6 +++++ libswscale/swscale.c | 14 ++++++++++- libswscale/swscale_internal.h | 12 +++++++++ libswscale/utils.c | 6 +++++ 5 files changed, 83 insertions(+), 1 deletion(-) diff --git a/libavutil/pixdesc.c b/libavutil/pixdesc.c index 77584755d6..efc7c7ea0e 100644 --- a/libavutil/pixdesc.c +++ b/libavutil/pixdesc.c @@ -878,6 +878,52 @@ const AVPixFmtDescriptor av_pix_fmt_descriptors[PIX_FMT_NB] = { }, .flags = PIX_FMT_BE, }, + [PIX_FMT_YUV444P10LE] = { + .name = "yuv444p10le", + .nb_components= 3, + .log2_chroma_w= 0, + .log2_chroma_h= 0, + .comp = { + {0,1,1,0,9}, /* Y */ + {1,1,1,0,9}, /* U */ + {2,1,1,0,9}, /* V */ + }, + }, + [PIX_FMT_YUV444P10BE] = { + .name = "yuv444p10be", + .nb_components= 3, + .log2_chroma_w= 0, + .log2_chroma_h= 0, + .comp = { + {0,1,1,0,9}, /* Y */ + {1,1,1,0,9}, /* U */ + {2,1,1,0,9}, /* V */ + }, + .flags = PIX_FMT_BE, + }, + [PIX_FMT_YUV444P9LE] = { + .name = "yuv444p9le", + .nb_components= 3, + .log2_chroma_w= 0, + .log2_chroma_h= 0, + .comp = { + {0,1,1,0,8}, /* Y */ + {1,1,1,0,8}, /* U */ + {2,1,1,0,8}, /* V */ + }, + }, + [PIX_FMT_YUV444P9BE] = { + .name = "yuv444p9be", + .nb_components= 3, + .log2_chroma_w= 0, + .log2_chroma_h= 0, + .comp = { + {0,1,1,0,9}, /* Y */ + {1,1,1,0,9}, /* U */ + {2,1,1,0,9}, /* V */ + }, + .flags = PIX_FMT_BE, + }, [PIX_FMT_DXVA2_VLD] = { .name = "dxva2_vld", .log2_chroma_w = 1, diff --git a/libavutil/pixfmt.h b/libavutil/pixfmt.h index d88775f462..e852d85519 100644 --- a/libavutil/pixfmt.h +++ b/libavutil/pixfmt.h @@ -141,6 +141,10 @@ enum PixelFormat { PIX_FMT_YUV420P10LE,///< planar YUV 4:2:0, 15bpp, (1 Cr & Cb sample per 2x2 Y samples), little-endian PIX_FMT_YUV422P10BE,///< planar YUV 4:2:2, 20bpp, (1 Cr & Cb sample per 2x1 Y samples), little-endian PIX_FMT_YUV422P10LE,///< planar YUV 4:2:2, 20bpp, (1 Cr & Cb sample per 2x1 Y samples), big-endian + PIX_FMT_YUV444P9BE, ///< planar YUV 4:4:4, 27bpp, (1 Cr & Cb sample per 1x1 Y samples), little-endian + PIX_FMT_YUV444P9LE, ///< planar YUV 4:4:4, 27bpp, (1 Cr & Cb sample per 1x1 Y samples), big-endian + PIX_FMT_YUV444P10BE,///< planar YUV 4:4:4, 30bpp, (1 Cr & Cb sample per 1x1 Y samples), little-endian + PIX_FMT_YUV444P10LE,///< planar YUV 4:4:4, 30bpp, (1 Cr & Cb sample per 1x1 Y samples), big-endian PIX_FMT_NB, ///< number of pixel formats, DO NOT USE THIS if you want to link with shared libav* because the number of formats might differ between versions }; @@ -166,8 +170,10 @@ enum PixelFormat { #define PIX_FMT_BGR444 PIX_FMT_NE(BGR444BE, BGR444LE) #define PIX_FMT_YUV420P9 PIX_FMT_NE(YUV420P9BE , YUV420P9LE) +#define PIX_FMT_YUV444P9 PIX_FMT_NE(YUV444P9BE , YUV444P9LE) #define PIX_FMT_YUV420P10 PIX_FMT_NE(YUV420P10BE, YUV420P10LE) #define PIX_FMT_YUV422P10 PIX_FMT_NE(YUV422P10BE, YUV422P10LE) +#define PIX_FMT_YUV444P10 PIX_FMT_NE(YUV444P10BE, YUV444P10LE) #define PIX_FMT_YUV420P16 PIX_FMT_NE(YUV420P16BE, YUV420P16LE) #define PIX_FMT_YUV422P16 PIX_FMT_NE(YUV422P16BE, YUV422P16LE) #define PIX_FMT_YUV444P16 PIX_FMT_NE(YUV444P16BE, YUV444P16LE) diff --git a/libswscale/swscale.c b/libswscale/swscale.c index bc076dd3f2..ba89a0f4be 100644 --- a/libswscale/swscale.c +++ b/libswscale/swscale.c @@ -1821,7 +1821,7 @@ find_c_packed_planar_out_funcs(SwsContext *c, } else if (is16BPS(dstFormat)) { *yuv2yuvX = isBE(dstFormat) ? yuv2yuvX16BE_c : yuv2yuvX16LE_c; } else if (is9_OR_10BPS(dstFormat)) { - if (dstFormat == PIX_FMT_YUV420P9BE || dstFormat == PIX_FMT_YUV420P9LE) { + if (av_pix_fmt_descriptors[dstFormat].comp[0].depth_minus1 == 8) { *yuv2yuvX = isBE(dstFormat) ? yuv2yuvX9BE_c : yuv2yuvX9LE_c; } else { *yuv2yuvX = isBE(dstFormat) ? yuv2yuvX10BE_c : yuv2yuvX10LE_c; @@ -2161,9 +2161,15 @@ static av_cold void sws_init_swScale_c(SwsContext *c) case PIX_FMT_PAL8 : case PIX_FMT_BGR4_BYTE: case PIX_FMT_RGB4_BYTE: c->chrToYV12 = palToUV_c; break; + case PIX_FMT_YUV444P9BE: case PIX_FMT_YUV420P9BE: c->chrToYV12 = BE9ToUV_c; break; + case PIX_FMT_YUV444P9LE: case PIX_FMT_YUV420P9LE: c->chrToYV12 = LE9ToUV_c; break; + case PIX_FMT_YUV444P10BE: + case PIX_FMT_YUV422P10BE: case PIX_FMT_YUV420P10BE: c->chrToYV12 = BE10ToUV_c; break; + case PIX_FMT_YUV422P10LE: + case PIX_FMT_YUV444P10LE: case PIX_FMT_YUV420P10LE: c->chrToYV12 = LE10ToUV_c; break; case PIX_FMT_YUV420P16BE: case PIX_FMT_YUV422P16BE: @@ -2219,9 +2225,15 @@ static av_cold void sws_init_swScale_c(SwsContext *c) c->lumToYV12 = NULL; c->alpToYV12 = NULL; switch (srcFormat) { + case PIX_FMT_YUV444P9BE: case PIX_FMT_YUV420P9BE: c->lumToYV12 = BE9ToY_c; break; + case PIX_FMT_YUV444P9LE: case PIX_FMT_YUV420P9LE: c->lumToYV12 = LE9ToY_c; break; + case PIX_FMT_YUV444P10BE: + case PIX_FMT_YUV422P10BE: case PIX_FMT_YUV420P10BE: c->lumToYV12 = BE10ToY_c; break; + case PIX_FMT_YUV444P10LE: + case PIX_FMT_YUV422P10LE: case PIX_FMT_YUV420P10LE: c->lumToYV12 = LE10ToY_c; break; case PIX_FMT_YUYV422 : case PIX_FMT_YUV420P16BE: diff --git a/libswscale/swscale_internal.h b/libswscale/swscale_internal.h index 013eef9e31..483842e866 100644 --- a/libswscale/swscale_internal.h +++ b/libswscale/swscale_internal.h @@ -355,6 +355,12 @@ const char *sws_format_name(enum PixelFormat format); #define is9_OR_10BPS(x) ( \ (x)==PIX_FMT_YUV420P9LE \ || (x)==PIX_FMT_YUV420P9BE \ + || (x)==PIX_FMT_YUV444P9BE \ + || (x)==PIX_FMT_YUV444P9LE \ + || (x)==PIX_FMT_YUV422P10BE \ + || (x)==PIX_FMT_YUV422P10LE \ + || (x)==PIX_FMT_YUV444P10BE \ + || (x)==PIX_FMT_YUV444P10LE \ || (x)==PIX_FMT_YUV420P10LE \ || (x)==PIX_FMT_YUV420P10BE \ ) @@ -373,12 +379,18 @@ const char *sws_format_name(enum PixelFormat format); #define isPlanarYUV(x) ( \ isPlanar8YUV(x) \ || (x)==PIX_FMT_YUV420P9LE \ + || (x)==PIX_FMT_YUV444P9LE \ || (x)==PIX_FMT_YUV420P10LE \ + || (x)==PIX_FMT_YUV422P10LE \ + || (x)==PIX_FMT_YUV444P10LE \ || (x)==PIX_FMT_YUV420P16LE \ || (x)==PIX_FMT_YUV422P16LE \ || (x)==PIX_FMT_YUV444P16LE \ || (x)==PIX_FMT_YUV420P9BE \ + || (x)==PIX_FMT_YUV444P9BE \ || (x)==PIX_FMT_YUV420P10BE \ + || (x)==PIX_FMT_YUV422P10BE \ + || (x)==PIX_FMT_YUV444P10BE \ || (x)==PIX_FMT_YUV420P16BE \ || (x)==PIX_FMT_YUV422P16BE \ || (x)==PIX_FMT_YUV444P16BE \ diff --git a/libswscale/utils.c b/libswscale/utils.c index d552330ec5..213bf3a043 100644 --- a/libswscale/utils.c +++ b/libswscale/utils.c @@ -110,12 +110,18 @@ const char *swscale_license(void) || (x)==PIX_FMT_MONOWHITE \ || (x)==PIX_FMT_MONOBLACK \ || (x)==PIX_FMT_YUV420P9LE \ + || (x)==PIX_FMT_YUV444P9LE \ || (x)==PIX_FMT_YUV420P10LE \ + || (x)==PIX_FMT_YUV422P10LE \ + || (x)==PIX_FMT_YUV444P10LE \ || (x)==PIX_FMT_YUV420P16LE \ || (x)==PIX_FMT_YUV422P16LE \ || (x)==PIX_FMT_YUV444P16LE \ || (x)==PIX_FMT_YUV420P9BE \ + || (x)==PIX_FMT_YUV444P9BE \ || (x)==PIX_FMT_YUV420P10BE \ + || (x)==PIX_FMT_YUV444P10BE \ + || (x)==PIX_FMT_YUV422P10BE \ || (x)==PIX_FMT_YUV420P16BE \ || (x)==PIX_FMT_YUV422P16BE \ || (x)==PIX_FMT_YUV444P16BE \ From 19d824e47373594739bb9a05cd4e7edbc441b173 Mon Sep 17 00:00:00 2001 From: Alex Converse Date: Tue, 26 Apr 2011 09:08:26 -0700 Subject: [PATCH 20/20] bitstream: Properly promote av_reverse values before shifting. --- libavcodec/bitstream.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/libavcodec/bitstream.c b/libavcodec/bitstream.c index 97d5b49105..b593db55ce 100644 --- a/libavcodec/bitstream.c +++ b/libavcodec/bitstream.c @@ -116,10 +116,10 @@ static int alloc_table(VLC *vlc, int size, int use_static) } static av_always_inline uint32_t bitswap_32(uint32_t x) { - return av_reverse[x&0xFF]<<24 - | av_reverse[(x>>8)&0xFF]<<16 - | av_reverse[(x>>16)&0xFF]<<8 - | av_reverse[x>>24]; + return (uint32_t)av_reverse[x&0xFF]<<24 + | (uint32_t)av_reverse[(x>>8)&0xFF]<<16 + | (uint32_t)av_reverse[(x>>16)&0xFF]<<8 + | (uint32_t)av_reverse[x>>24]; } typedef struct {