From 72cb904453ccb8c42f93a4a02ce9ba9915688722 Mon Sep 17 00:00:00 2001 From: Janne Grunau Date: Fri, 16 Dec 2011 00:44:26 +0100 Subject: swscale: add unscaled packed 16 bit per component endianess conversion --- libswscale/swscale_unscaled.c | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/libswscale/swscale_unscaled.c b/libswscale/swscale_unscaled.c index 86bc5acda6..ec8f1bb552 100644 --- a/libswscale/swscale_unscaled.c +++ b/libswscale/swscale_unscaled.c @@ -252,6 +252,27 @@ static void gray8aToPacked24(const uint8_t *src, uint8_t *dst, int num_pixels, c } } +static int packed_16bpc_bswap(SwsContext *c, const uint8_t* src[], + int srcStride[], int srcSliceY, int srcSliceH, + uint8_t* dst[], int dstStride[]) +{ + int i, j; + int srcstr = srcStride[0] >> 1; + int dststr = dstStride[0] >> 1; + uint16_t *dstPtr = (uint16_t *)dst[0]; + const uint16_t *srcPtr = (const uint16_t *)src[0]; + + for (i = 0; i < srcSliceH; i++) { + for (j = 0; j < srcstr; j++) { + dstPtr[j] = av_bswap16(srcPtr[j]); + } + srcPtr += srcstr; + dstPtr += dststr; + } + + return srcSliceH; +} + static int palToRgbWrapper(SwsContext *c, const uint8_t* src[], int srcStride[], int srcSliceY, int srcSliceH, uint8_t* dst[], int dstStride[]) { @@ -697,6 +718,15 @@ void ff_get_unscaled_swscale(SwsContext *c) if (srcFormat==PIX_FMT_BGR24 && (dstFormat==PIX_FMT_YUV420P || dstFormat==PIX_FMT_YUVA420P) && !(flags & SWS_ACCURATE_RND)) c->swScale= bgr24ToYv12Wrapper; + /* bswap 16 bits per component packed formats */ + if ((srcFormat == PIX_FMT_RGB48LE && dstFormat == PIX_FMT_RGB48BE) || + (srcFormat == PIX_FMT_RGB48BE && dstFormat == PIX_FMT_RGB48LE) || + (srcFormat == PIX_FMT_BGR48LE && dstFormat == PIX_FMT_BGR48BE) || + (srcFormat == PIX_FMT_BGR48BE && dstFormat == PIX_FMT_BGR48LE) || + (srcFormat == PIX_FMT_GRAY16LE && dstFormat == PIX_FMT_GRAY16BE) || + (srcFormat == PIX_FMT_GRAY16BE && dstFormat == PIX_FMT_GRAY16LE)) + c->swScale = packed_16bpc_bswap; + /* RGB/BGR -> RGB/BGR (no dither needed forms) */ if ( isAnyRGB(srcFormat) && isAnyRGB(dstFormat) -- cgit v1.2.3 From 65a25adc97406adaab9ed0c6244fbb69c5cbcc93 Mon Sep 17 00:00:00 2001 From: Vladimir Pantelic Date: Fri, 16 Dec 2011 10:01:16 +0100 Subject: mpegts: replace some magic numbers with the existing define MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Martin Storsjö --- libavformat/mpegts.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/libavformat/mpegts.c b/libavformat/mpegts.c index c9b34abe1f..ca01003d80 100644 --- a/libavformat/mpegts.c +++ b/libavformat/mpegts.c @@ -635,7 +635,7 @@ static void new_pes_packet(PESContext *pes, AVPacket *pkt) pkt->size = pes->data_index; if(pes->total_size != MAX_PES_PAYLOAD && - pes->pes_header_size + pes->data_index != pes->total_size + 6) { + pes->pes_header_size + pes->data_index != pes->total_size + PES_START_SIZE) { av_log(pes->stream, AV_LOG_WARNING, "PES packet size mismatch\n"); pes->flags |= AV_PKT_FLAG_CORRUPT; } @@ -918,9 +918,9 @@ static int mpegts_push_data(MpegTSFilter *filter, * decreases demuxer delay for infrequent packets like subtitles from * a couple of seconds to milliseconds for properly muxed files. * total_size is the number of bytes following pes_packet_length - * in the pes header, i.e. not counting the first 6 bytes */ + * in the pes header, i.e. not counting the first PES_START_SIZE bytes */ if (!ts->stop_parse && pes->total_size < MAX_PES_PAYLOAD && - pes->pes_header_size + pes->data_index == pes->total_size + 6) { + pes->pes_header_size + pes->data_index == pes->total_size + PES_START_SIZE) { ts->stop_parse = 1; new_pes_packet(pes, ts->pkt); } -- cgit v1.2.3 From 11b1db27593a1f23a05e033f68b98a4342f1bd91 Mon Sep 17 00:00:00 2001 From: Mans Rullgard Date: Fri, 9 Dec 2011 21:21:26 +0000 Subject: rv40: NEON optimised weak loop filter Signed-off-by: Mans Rullgard --- libavcodec/arm/rv40dsp_init_neon.c | 9 +++ libavcodec/arm/rv40dsp_neon.S | 110 +++++++++++++++++++++++++++++++++++++ 2 files changed, 119 insertions(+) diff --git a/libavcodec/arm/rv40dsp_init_neon.c b/libavcodec/arm/rv40dsp_init_neon.c index 59dddb6605..898b841344 100644 --- a/libavcodec/arm/rv40dsp_init_neon.c +++ b/libavcodec/arm/rv40dsp_init_neon.c @@ -61,6 +61,13 @@ int ff_rv40_v_loop_filter_strength_neon(uint8_t *src, int stride, int beta, int beta2, int edge, int *p1, int *q1); +void ff_rv40_h_weak_loop_filter_neon(uint8_t *src, int stride, int filter_p1, + int filter_q1, int alpha, int beta, + int lim_p0q0, int lim_q1, int lim_p1); +void ff_rv40_v_weak_loop_filter_neon(uint8_t *src, int stride, int filter_p1, + int filter_q1, int alpha, int beta, + int lim_p0q0, int lim_q1, int lim_p1); + void ff_rv40dsp_init_neon(RV34DSPContext *c, DSPContext* dsp) { c->put_pixels_tab[0][ 1] = ff_put_rv40_qpel16_mc10_neon; @@ -126,4 +133,6 @@ void ff_rv40dsp_init_neon(RV34DSPContext *c, DSPContext* dsp) c->rv40_loop_filter_strength[0] = ff_rv40_h_loop_filter_strength_neon; c->rv40_loop_filter_strength[1] = ff_rv40_v_loop_filter_strength_neon; + c->rv40_weak_loop_filter[0] = ff_rv40_h_weak_loop_filter_neon; + c->rv40_weak_loop_filter[1] = ff_rv40_v_weak_loop_filter_neon; } diff --git a/libavcodec/arm/rv40dsp_neon.S b/libavcodec/arm/rv40dsp_neon.S index d9e1b7c959..f68f38234a 100644 --- a/libavcodec/arm/rv40dsp_neon.S +++ b/libavcodec/arm/rv40dsp_neon.S @@ -808,3 +808,113 @@ function ff_rv40_v_loop_filter_strength_neon, export=1 vmov.u16 r0, d0[0] bx lr endfunc + +.macro rv40_weak_loop_filter + vdup.16 d30, r2 @ filter_p1 + vdup.16 d31, r3 @ filter_q1 + ldrd r2, r3, [sp] + vdup.16 d28, r2 @ alpha + vdup.16 d29, r3 @ beta + ldr r12, [sp, #8] + vdup.16 d25, r12 @ lim_p0q0 + ldrd r2, r3, [sp, #12] + vsubl.u8 q9, d5, d4 @ x, t + vabdl.u8 q8, d5, d4 @ x, abs(t) + vneg.s16 q15, q15 + vceq.i16 d16, d19, #0 @ !t + vshl.s16 d19, d19, #2 @ t << 2 + vmul.u16 d18, d17, d28 @ alpha * abs(t) + vand d24, d30, d31 @ filter_p1 & filter_q1 + vsubl.u8 q1, d0, d4 @ p1p2, p1p0 + vsubl.u8 q3, d1, d5 @ q1q2, q1q0 + vmov.i16 d22, #3 + vshr.u16 d18, d18, #7 + vadd.i16 d22, d22, d24 @ 3 - (filter_p1 & filter_q1) + vsubl.u8 q10, d0, d1 @ src[-2] - src[1] + vcle.u16 d18, d18, d22 + vand d20, d20, d24 + vneg.s16 d23, d25 @ -lim_p0q0 + vadd.s16 d19, d19, d20 + vbic d16, d18, d16 @ t && u <= 3 - (fp1 & fq1) + vtrn.32 d4, d5 @ -3, 2, -1, 0 + vrshr.s16 d19, d19, #3 + vmov d28, d29 @ beta + vswp d3, d6 @ q1q2, p1p0 + vmin.s16 d19, d19, d25 + vand d30, d30, d16 + vand d31, d31, d16 + vadd.s16 q10, q1, q3 @ p1p2 + p1p0, q1q2 + q1q0 + vmax.s16 d19, d19, d23 @ diff + vabs.s16 q1, q1 @ abs(p1p2), abs(q1q2) + vand d18, d19, d16 @ diff + vcle.u16 q1, q1, q14 + vneg.s16 d19, d18 @ -diff + vdup.16 d26, r3 @ lim_p1 + vaddw.u8 q2, q9, d5 @ src[-1]+diff, src[0]-diff + vhsub.s16 q11, q10, q9 + vand q1, q1, q15 + vqmovun.s16 d4, q2 @ -1, 0 + vand q9, q11, q1 + vdup.16 d27, r2 @ lim_q1 + vneg.s16 q9, q9 + vneg.s16 q14, q13 + vmin.s16 q9, q9, q13 + vtrn.32 d0, d1 @ -2, 1, -2, 1 + vmax.s16 q9, q9, q14 + vaddw.u8 q3, q9, d0 + vqmovun.s16 d5, q3 @ -2, 1 +.endm + +function ff_rv40_h_weak_loop_filter_neon, export=1 + sub r0, r0, r1, lsl #1 + sub r0, r0, r1 + + vld1.32 {d4[]}, [r0,:32], r1 + vld1.32 {d0[]}, [r0,:32], r1 + vld1.32 {d4[1]}, [r0,:32], r1 + vld1.32 {d5[]}, [r0,:32], r1 + vld1.32 {d1[]}, [r0,:32], r1 + vld1.32 {d5[0]}, [r0,:32] + + sub r0, r0, r1, lsl #2 + + rv40_weak_loop_filter + + vst1.32 {d5[0]}, [r0,:32], r1 + vst1.32 {d4[0]}, [r0,:32], r1 + vst1.32 {d4[1]}, [r0,:32], r1 + vst1.32 {d5[1]}, [r0,:32], r1 + + bx lr +endfunc + +function ff_rv40_v_weak_loop_filter_neon, export=1 + sub r12, r0, #3 + sub r0, r0, #2 + + vld1.8 {d4}, [r12], r1 + vld1.8 {d5}, [r12], r1 + vld1.8 {d2}, [r12], r1 + vld1.8 {d3}, [r12], r1 + + vtrn.16 q2, q1 + vtrn.8 d4, d5 + vtrn.8 d2, d3 + + vrev64.32 d5, d5 + vtrn.32 q2, q1 + vdup.32 d0, d3[0] + vdup.32 d1, d2[0] + + rv40_weak_loop_filter + + vtrn.32 q2, q3 + vswp d4, d5 + + vst4.8 {d4[0],d5[0],d6[0],d7[0]}, [r0], r1 + vst4.8 {d4[1],d5[1],d6[1],d7[1]}, [r0], r1 + vst4.8 {d4[2],d5[2],d6[2],d7[2]}, [r0], r1 + vst4.8 {d4[3],d5[3],d6[3],d7[3]}, [r0], r1 + + bx lr +endfunc -- cgit v1.2.3 From 54e75be420e687867f9739b210d95015b31c3819 Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Mon, 12 Sep 2011 17:52:44 +0200 Subject: configure: refactor lists of tests and components into variables --- configure | 48 ++++++++++++++++++++---------------------------- 1 file changed, 20 insertions(+), 28 deletions(-) diff --git a/configure b/configure index b3af2e9c6b..974e75f91b 100755 --- a/configure +++ b/configure @@ -1748,6 +1748,20 @@ INDEV_LIST=$(find_things indev _IN libavdevice/alldevices.c) PROTOCOL_LIST=$(find_things protocol PROTOCOL libavformat/allformats.c) FILTER_LIST=$(find_things filter FILTER libavfilter/allfilters.c) +ALL_COMPONENTS=" + $BSF_LIST + $DECODER_LIST + $DEMUXER_LIST + $ENCODER_LIST + $FILTER_LIST + $HWACCEL_LIST + $INDEV_LIST + $MUXER_LIST + $OUTDEV_LIST + $PARSER_LIST + $PROTOCOL_LIST +" + find_tests(){ map "echo ${2}\${v}_test" $(ls "$source_path"/tests/ref/$1 | grep -v '[^-a-z0-9_]') } @@ -1758,6 +1772,8 @@ LAVF_TESTS=$(find_tests lavf) LAVFI_TESTS=$(find_tests lavfi) SEEK_TESTS=$(find_tests seek seek_) +ALL_TESTS="$ACODEC_TESTS $VCODEC_TESTS $LAVF_TESTS $LAVFI_TESTS $SEEK_TESTS" + pcm_test_deps=$(map 'echo ${v%_*}_decoder $v' $(filter pcm_* $ENCODER_LIST)) for n in $COMPONENT_LIST; do @@ -1766,7 +1782,7 @@ for n in $COMPONENT_LIST; do eval ${n}_if_any="\$$v" done -enable $ARCH_EXT_LIST $ACODEC_TESTS $VCODEC_TESTS $LAVF_TESTS $LAVFI_TESTS $SEEK_TESTS +enable $ARCH_EXT_LIST $ALL_TESTS die_unknown(){ echo "Unknown option \"$1\"." @@ -3119,22 +3135,8 @@ enabled_any $THREADS_LIST && enable threads check_deps $CONFIG_LIST \ $CONFIG_EXTRA \ $HAVE_LIST \ - $DECODER_LIST \ - $ENCODER_LIST \ - $HWACCEL_LIST \ - $PARSER_LIST \ - $BSF_LIST \ - $DEMUXER_LIST \ - $MUXER_LIST \ - $FILTER_LIST \ - $INDEV_LIST \ - $OUTDEV_LIST \ - $PROTOCOL_LIST \ - $ACODEC_TESTS \ - $VCODEC_TESTS \ - $LAVF_TESTS \ - $LAVFI_TESTS \ - $SEEK_TESTS \ + $ALL_COMPONENTS \ + $ALL_TESTS \ enabled asm || { arch=c; disable $ARCH_LIST $ARCH_EXT_LIST; } @@ -3382,17 +3384,7 @@ print_config ARCH_ "$config_files" $ARCH_LIST print_config HAVE_ "$config_files" $HAVE_LIST print_config CONFIG_ "$config_files" $CONFIG_LIST \ $CONFIG_EXTRA \ - $DECODER_LIST \ - $ENCODER_LIST \ - $HWACCEL_LIST \ - $PARSER_LIST \ - $BSF_LIST \ - $DEMUXER_LIST \ - $MUXER_LIST \ - $FILTER_LIST \ - $PROTOCOL_LIST \ - $INDEV_LIST \ - $OUTDEV_LIST \ + $ALL_COMPONENTS \ cat >>config.mak < Date: Fri, 16 Dec 2011 15:10:42 +0000 Subject: get_bits: remove useless pointer casts These pointers are already of the correct type. Signed-off-by: Mans Rullgard --- libavcodec/get_bits.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libavcodec/get_bits.h b/libavcodec/get_bits.h index 79802848d4..4c03e412ce 100644 --- a/libavcodec/get_bits.h +++ b/libavcodec/get_bits.h @@ -133,12 +133,12 @@ for examples see get_bits, show_bits, skip_bits, get_vlc # ifdef ALT_BITSTREAM_READER_LE # define UPDATE_CACHE(name, gb) \ - name##_cache = AV_RL32(((const uint8_t *)(gb)->buffer)+(name##_index>>3)) >> (name##_index&0x07) + name##_cache = AV_RL32((gb)->buffer+(name##_index>>3)) >> (name##_index&0x07) # define SKIP_CACHE(name, gb, num) name##_cache >>= (num) # else # define UPDATE_CACHE(name, gb) \ - name##_cache = AV_RB32(((const uint8_t *)(gb)->buffer)+(name##_index>>3)) << (name##_index&0x07) + name##_cache = AV_RB32((gb)->buffer+(name##_index>>3)) << (name##_index&0x07) # define SKIP_CACHE(name, gb, num) name##_cache <<= (num) # endif -- cgit v1.2.3 From 0b4c323213343bf514626ee89a7ad91bfd428322 Mon Sep 17 00:00:00 2001 From: "Ronald S. Bultje" Date: Mon, 12 Dec 2011 12:02:58 -0800 Subject: h264: don't drop B-frames after next keyframe on POC reset. The keyframe after a POC reset may not be the first to be returned to the user. Therefore, don't reset the expected next POC once we return a keyframe to the user, but once we know that the next frame in the return-queue is a keyframe. --- libavcodec/h264.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/libavcodec/h264.c b/libavcodec/h264.c index 109a109530..77acd7168f 100644 --- a/libavcodec/h264.c +++ b/libavcodec/h264.c @@ -1530,7 +1530,11 @@ static void decode_postinit(H264Context *h, int setup_finished){ h->next_outputed_poc = INT_MIN; } } else { - h->next_outputed_poc = out->poc; + if (out_idx == 0 && pics > 1 && h->delayed_pic[0]->f.key_frame) { + h->next_outputed_poc = INT_MIN; + } else { + h->next_outputed_poc = out->poc; + } } h->mmco_reset = 0; }else{ -- cgit v1.2.3 From 365e1ec26d7e89a951ebd7851214f59f4aefdec0 Mon Sep 17 00:00:00 2001 From: Derek Buitenhuis Date: Fri, 16 Dec 2011 13:31:28 -0500 Subject: wavpack: Clip samples after shifting It doesn't make much sense to clip pre-shift, nor is it correct for proper decoding. Signed-off-by: Derek Buitenhuis Signed-off-by: Anton Khirnov --- libavcodec/wavpack.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libavcodec/wavpack.c b/libavcodec/wavpack.c index 11e9904983..5358967704 100644 --- a/libavcodec/wavpack.c +++ b/libavcodec/wavpack.c @@ -405,12 +405,12 @@ static inline int wv_get_value_integer(WavpackFrameContext *s, uint32_t *crc, in } bit = (S & s->and) | s->or; - bit = (((S + bit) << s->shift) - bit); + bit = (((S + bit) << s->shift) - bit) << s->post_shift; if(s->hybrid) bit = av_clip(bit, -s->hybrid_maxclip, s->hybrid_maxclip - 1); - return bit << s->post_shift; + return bit; } static float wv_get_value_float(WavpackFrameContext *s, uint32_t *crc, int S) -- cgit v1.2.3 From bb9747c8eee134f2bf6058d368f8cbc799f4b7d3 Mon Sep 17 00:00:00 2001 From: Derek Buitenhuis Date: Fri, 16 Dec 2011 13:31:29 -0500 Subject: wavpack: Fix 32-bit clipping In the case that (frame_flags & 0x03) == 3, hybrid_maxclip may have had a signed integer overflow. Signed-off-by: Derek Buitenhuis Signed-off-by: Anton Khirnov --- libavcodec/wavpack.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libavcodec/wavpack.c b/libavcodec/wavpack.c index 5358967704..3cf5986103 100644 --- a/libavcodec/wavpack.c +++ b/libavcodec/wavpack.c @@ -408,7 +408,7 @@ static inline int wv_get_value_integer(WavpackFrameContext *s, uint32_t *crc, in bit = (((S + bit) << s->shift) - bit) << s->post_shift; if(s->hybrid) - bit = av_clip(bit, -s->hybrid_maxclip, s->hybrid_maxclip - 1); + bit = av_clip(bit, -s->hybrid_maxclip - 1, s->hybrid_maxclip); return bit; } @@ -798,7 +798,7 @@ static int wavpack_decode_block(AVCodecContext *avctx, int block_no, s->joint = s->frame_flags & WV_JOINT_STEREO; s->hybrid = s->frame_flags & WV_HYBRID_MODE; s->hybrid_bitrate = s->frame_flags & WV_HYBRID_BITRATE; - s->hybrid_maxclip = 1 << ((((s->frame_flags & 0x03) + 1) << 3) - 1); + s->hybrid_maxclip = (1LL << ((((s->frame_flags & 0x03) + 1) << 3) - 1)) - 1; s->post_shift = 8 * (bpp-1-(s->frame_flags&0x03)) + ((s->frame_flags >> 13) & 0x1f); s->CRC = AV_RL32(buf); buf += 4; if(wc->mkv_mode) -- cgit v1.2.3 From a7b5e841ffe4b0f8423288965b8d069bd2a7a792 Mon Sep 17 00:00:00 2001 From: Alexandra Khirnova Date: Tue, 13 Dec 2011 10:23:06 +0000 Subject: avconv: support stream specifiers in -metadata and -map_metadata Signed-off-by: Anton Khirnov --- avconv.c | 207 +++++++++++++++++++++++++------------------ doc/avconv.texi | 38 ++++++-- doc/avtools-common-opts.texi | 1 + 3 files changed, 150 insertions(+), 96 deletions(-) diff --git a/avconv.c b/avconv.c index 90ed00d935..ecbf5233c4 100644 --- a/avconv.c +++ b/avconv.c @@ -332,6 +332,8 @@ typedef struct OptionsContext { int nb_inter_matrices; SpecifierOpt *top_field_first; int nb_top_field_first; + SpecifierOpt *metadata_map; + int nb_metadata_map; SpecifierOpt *presets; int nb_presets; SpecifierOpt *copy_initial_nonkeyframes; @@ -2752,7 +2754,13 @@ static int opt_attach(OptionsContext *o, const char *opt, const char *arg) return 0; } -static void parse_meta_type(char *arg, char *type, int *index) +/** + * Parse a metadata specifier in arg. + * @param type metadata type is written here -- g(lobal)/s(tream)/c(hapter)/p(rogram) + * @param index for type c/p, chapter/program index is written here + * @param stream_spec for type s, the stream specifier is written here + */ +static void parse_meta_type(char *arg, char *type, int *index, const char **stream_spec) { if (*arg) { *type = *arg; @@ -2760,6 +2768,12 @@ static void parse_meta_type(char *arg, char *type, int *index) case 'g': break; case 's': + if (*(++arg) && *arg != ':') { + av_log(NULL, AV_LOG_FATAL, "Invalid metadata specifier %s.\n", arg); + exit_program(1); + } + *stream_spec = *arg == ':' ? arg + 1 : ""; + break; case 'c': case 'p': if (*(++arg) == ':') @@ -2773,31 +2787,76 @@ static void parse_meta_type(char *arg, char *type, int *index) *type = 'g'; } -static int opt_map_metadata(OptionsContext *o, const char *opt, const char *arg) +static int copy_metadata(char *outspec, char *inspec, AVFormatContext *oc, AVFormatContext *ic, OptionsContext *o) { - MetadataMap *m, *m1; - char *p; - - o->meta_data_maps = grow_array(o->meta_data_maps, sizeof(*o->meta_data_maps), - &o->nb_meta_data_maps, o->nb_meta_data_maps + 1); - - m = &o->meta_data_maps[o->nb_meta_data_maps - 1][1]; - m->file = strtol(arg, &p, 0); - parse_meta_type(*p ? p + 1 : p, &m->type, &m->index); + AVDictionary **meta_in = NULL; + AVDictionary **meta_out; + int i, ret = 0; + char type_in, type_out; + const char *istream_spec = NULL, *ostream_spec = NULL; + int idx_in = 0, idx_out = 0; - m1 = &o->meta_data_maps[o->nb_meta_data_maps - 1][0]; - if (p = strchr(opt, ':')) - parse_meta_type(p + 1, &m1->type, &m1->index); - else - m1->type = 'g'; + parse_meta_type(inspec, &type_in, &idx_in, &istream_spec); + parse_meta_type(outspec, &type_out, &idx_out, &ostream_spec); - if (m->type == 'g' || m1->type == 'g') + if (type_in == 'g' || type_out == 'g') o->metadata_global_manual = 1; - if (m->type == 's' || m1->type == 's') + if (type_in == 's' || type_out == 's') o->metadata_streams_manual = 1; - if (m->type == 'c' || m1->type == 'c') + if (type_in == 'c' || type_out == 'c') o->metadata_chapters_manual = 1; +#define METADATA_CHECK_INDEX(index, nb_elems, desc)\ + if ((index) < 0 || (index) >= (nb_elems)) {\ + av_log(NULL, AV_LOG_FATAL, "Invalid %s index %d while processing metadata maps.\n",\ + (desc), (index));\ + exit_program(1);\ + } + +#define SET_DICT(type, meta, context, index)\ + switch (type) {\ + case 'g':\ + meta = &context->metadata;\ + break;\ + case 'c':\ + METADATA_CHECK_INDEX(index, context->nb_chapters, "chapter")\ + meta = &context->chapters[index]->metadata;\ + break;\ + case 'p':\ + METADATA_CHECK_INDEX(index, context->nb_programs, "program")\ + meta = &context->programs[index]->metadata;\ + break;\ + }\ + + SET_DICT(type_in, meta_in, ic, idx_in); + SET_DICT(type_out, meta_out, oc, idx_out); + + /* for input streams choose first matching stream */ + if (type_in == 's') { + for (i = 0; i < ic->nb_streams; i++) { + if ((ret = check_stream_specifier(ic, ic->streams[i], istream_spec)) > 0) { + meta_in = &ic->streams[i]->metadata; + break; + } else if (ret < 0) + exit_program(1); + } + if (!meta_in) { + av_log(NULL, AV_LOG_FATAL, "Stream specifier %s does not match any streams.\n", istream_spec); + exit_program(1); + } + } + + if (type_out == 's') { + for (i = 0; i < oc->nb_streams; i++) { + if ((ret = check_stream_specifier(oc, oc->streams[i], ostream_spec)) > 0) { + meta_out = &oc->streams[i]->metadata; + av_dict_copy(meta_out, *meta_in, AV_DICT_DONT_OVERWRITE); + } else if (ret < 0) + exit_program(1); + } + } else + av_dict_copy(meta_out, *meta_in, AV_DICT_DONT_OVERWRITE); + return 0; } @@ -3702,6 +3761,20 @@ static void opt_output_file(void *optctx, const char *filename) oc->max_delay = (int)(o->mux_max_delay * AV_TIME_BASE); oc->flags |= AVFMT_FLAG_NONBLOCK; + /* copy metadata */ + for (i = 0; i < o->nb_metadata_map; i++) { + char *p; + int in_file_index = strtol(o->metadata_map[i].u.str, &p, 0); + + if (in_file_index < 0) + continue; + if (in_file_index >= nb_input_files) { + av_log(NULL, AV_LOG_FATAL, "Invalid input file index %d while processing metadata maps\n", in_file_index); + exit_program(1); + } + copy_metadata(o->metadata_map[i].specifier, *p ? p + 1 : p, oc, input_files[in_file_index].ctx, o); + } + /* copy chapters */ if (o->chapters_input_file >= nb_input_files) { if (o->chapters_input_file == INT_MAX) { @@ -3722,52 +3795,6 @@ static void opt_output_file(void *optctx, const char *filename) copy_chapters(&input_files[o->chapters_input_file], &output_files[nb_output_files - 1], !o->metadata_chapters_manual); - /* copy metadata */ - for (i = 0; i < o->nb_meta_data_maps; i++) { - AVFormatContext *files[2]; - AVDictionary **meta[2]; - int j; - -#define METADATA_CHECK_INDEX(index, nb_elems, desc)\ - if ((index) < 0 || (index) >= (nb_elems)) {\ - av_log(NULL, AV_LOG_FATAL, "Invalid %s index %d while processing metadata maps\n",\ - (desc), (index));\ - exit_program(1);\ - } - - int in_file_index = o->meta_data_maps[i][1].file; - if (in_file_index < 0) - continue; - METADATA_CHECK_INDEX(in_file_index, nb_input_files, "input file") - - files[0] = oc; - files[1] = input_files[in_file_index].ctx; - - for (j = 0; j < 2; j++) { - MetadataMap *map = &o->meta_data_maps[i][j]; - - switch (map->type) { - case 'g': - meta[j] = &files[j]->metadata; - break; - case 's': - METADATA_CHECK_INDEX(map->index, files[j]->nb_streams, "stream") - meta[j] = &files[j]->streams[map->index]->metadata; - break; - case 'c': - METADATA_CHECK_INDEX(map->index, files[j]->nb_chapters, "chapter") - meta[j] = &files[j]->chapters[map->index]->metadata; - break; - case 'p': - METADATA_CHECK_INDEX(map->index, files[j]->nb_programs, "program") - meta[j] = &files[j]->programs[map->index]->metadata; - break; - } - } - - av_dict_copy(meta[0], *meta[1], AV_DICT_DONT_OVERWRITE); - } - /* copy global metadata by default */ if (!o->metadata_global_manual && nb_input_files) av_dict_copy(&oc->metadata, input_files[0].ctx->metadata, @@ -3785,7 +3812,8 @@ static void opt_output_file(void *optctx, const char *filename) for (i = 0; i < o->nb_metadata; i++) { AVDictionary **m; char type, *val; - int index = 0; + const char *stream_spec; + int index = 0, j, ret; val = strchr(o->metadata[i].u.str, '='); if (!val) { @@ -3795,31 +3823,34 @@ static void opt_output_file(void *optctx, const char *filename) } *val++ = 0; - parse_meta_type(o->metadata[i].specifier, &type, &index); - switch (type) { - case 'g': - m = &oc->metadata; - break; - case 's': - if (index < 0 || index >= oc->nb_streams) { - av_log(NULL, AV_LOG_FATAL, "Invalid stream index %d in metadata specifier.\n", index); - exit_program(1); + parse_meta_type(o->metadata[i].specifier, &type, &index, &stream_spec); + if (type == 's') { + for (j = 0; j < oc->nb_streams; j++) { + if ((ret = check_stream_specifier(oc, oc->streams[j], stream_spec)) > 0) { + av_dict_set(&oc->streams[j]->metadata, o->metadata[i].u.str, *val ? val : NULL, 0); + } else if (ret < 0) + exit_program(1); } - m = &oc->streams[index]->metadata; - break; - case 'c': - if (index < 0 || index >= oc->nb_chapters) { - av_log(NULL, AV_LOG_FATAL, "Invalid chapter index %d in metadata specifier.\n", index); + printf("ret %d, stream_spec %s\n", ret, stream_spec); + } + else { + switch (type) { + case 'g': + m = &oc->metadata; + break; + case 'c': + if (index < 0 || index >= oc->nb_chapters) { + av_log(NULL, AV_LOG_FATAL, "Invalid chapter index %d in metadata specifier.\n", index); + exit_program(1); + } + m = &oc->chapters[index]->metadata; + break; + default: + av_log(NULL, AV_LOG_FATAL, "Invalid metadata specifier %s.\n", o->metadata[i].specifier); exit_program(1); } - m = &oc->chapters[index]->metadata; - break; - default: - av_log(NULL, AV_LOG_FATAL, "Invalid metadata specifier %s.\n", o->metadata[i].specifier); - exit_program(1); + av_dict_set(m, o->metadata[i].u.str, *val ? val : NULL, 0); } - - av_dict_set(m, o->metadata[i].u.str, *val ? val : NULL, 0); } reset_options(o); @@ -4114,7 +4145,7 @@ static const OptionDef options[] = { { "codec", HAS_ARG | OPT_STRING | OPT_SPEC, {.off = OFFSET(codec_names)}, "codec name", "codec" }, { "pre", HAS_ARG | OPT_STRING | OPT_SPEC, {.off = OFFSET(presets)}, "preset name", "preset" }, { "map", HAS_ARG | OPT_EXPERT | OPT_FUNC2, {(void*)opt_map}, "set input stream mapping", "[-]input_file_id[:stream_specifier][,sync_file_id[:stream_specifier]]" }, - { "map_metadata", HAS_ARG | OPT_EXPERT | OPT_FUNC2, {(void*)opt_map_metadata}, "set metadata information of outfile from infile", + { "map_metadata", HAS_ARG | OPT_STRING | OPT_SPEC, {.off = OFFSET(metadata_map)}, "set metadata information of outfile from infile", "outfile[,metadata]:infile[,metadata]" }, { "map_chapters", OPT_INT | HAS_ARG | OPT_EXPERT | OPT_OFFSET, {.off = OFFSET(chapters_input_file)}, "set chapters mapping", "input_file_index" }, { "t", HAS_ARG | OPT_TIME | OPT_OFFSET, {.off = OFFSET(recording_time)}, "record or transcode \"duration\" seconds of audio/video", "duration" }, diff --git a/doc/avconv.texi b/doc/avconv.texi index 84e0c1c4ef..157e233cc6 100644 --- a/doc/avconv.texi +++ b/doc/avconv.texi @@ -170,9 +170,9 @@ For example, for setting the title in the output file: avconv -i in.avi -metadata title="my title" out.flv @end example -To set the language of the second stream: +To set the language of the first audio stream: @example -avconv -i INPUT -metadata:s:1 language=eng OUTPUT +avconv -i INPUT -metadata:s:a:0 language=eng OUTPUT @end example @item -target @var{type} (@emph{output}) @@ -677,14 +677,28 @@ avconv -i INPUT -map 0 -map -0:a:1 OUTPUT Note that using this option disables the default mappings for this output file. -@item -map_metadata[:@var{metadata_type}][:@var{index}] @var{infile}[:@var{metadata_type}][:@var{index}] (@emph{output,per-metadata}) +@item -map_metadata[:@var{metadata_spec_out}] @var{infile}[:@var{metadata_spec_in}] (@emph{output,per-metadata}) Set metadata information of the next output file from @var{infile}. Note that those are file indices (zero-based), not filenames. -Optional @var{metadata_type} parameters specify, which metadata to copy - (g)lobal -(i.e. metadata that applies to the whole file), per-(s)tream, per-(c)hapter or -per-(p)rogram. All metadata specifiers other than global must be followed by the -stream/chapter/program index. If metadata specifier is omitted, it defaults to -global. +Optional @var{metadata_spec_in/out} parameters specify, which metadata to copy. +A metadata specifier can have the following forms: +@table @option +@item @var{g} +global metadata, i.e. metadata that applies to the whole file + +@item @var{s}[:@var{stream_spec}] +per-stream metadata. @var{stream_spec} is a stream specifier as described +in the @ref{Stream specifiers} chapter. In an input metadata specifier, the first +matching stream is copied from. In an output metadata specifier, all matching +streams are copied to. + +@item @var{c}:@var{chapter_index} +per-chapter metadata. @var{chapter_index} is the zero-based chapter index. + +@item @var{p}:@var{program_index} +per-program metadata. @var{program_index} is the zero-based program index. +@end table +If metadata specifier is omitted, it defaults to global. By default, global metadata is copied from the first input file, per-stream and per-chapter metadata is copied along with streams/chapters. These @@ -696,6 +710,14 @@ of the output file: @example avconv -i in.ogg -map_metadata 0:s:0 out.mp3 @end example + +To do the reverse, i.e. copy global metadata to all audio streams: +@example +avconv -i in.mkv -map_metadata:s:a 0:g out.mkv +@end example +Note that simple @code{0} would work as well in this example, since global +metadata is assumed by default. + @item -map_chapters @var{input_file_index} (@emph{output}) Copy chapters from input file with index @var{input_file_index} to the next output file. If no chapter mapping is specified, then chapters are copied from diff --git a/doc/avtools-common-opts.texi b/doc/avtools-common-opts.texi index 372a6f2dc1..18e7ba5cbe 100644 --- a/doc/avtools-common-opts.texi +++ b/doc/avtools-common-opts.texi @@ -11,6 +11,7 @@ corresponding value to true. They can be set to false by prefixing with "no" the option name, for example using "-nofoo" in the command line will set to false the boolean option with name "foo". +@anchor{Stream specifiers} @section Stream specifiers Some options are applied per-stream, e.g. bitrate or codec. Stream specifiers are used to precisely specify which stream(s) does a given option belong to. -- cgit v1.2.3 From a1e98f198e9db4e5ddfc2f777014179d3d7bc4d2 Mon Sep 17 00:00:00 2001 From: Mans Rullgard Date: Fri, 16 Dec 2011 21:19:50 +0000 Subject: get_bits: remove A32 variant The A32 bitstream reader variant is only used on ARMv5 and for Prores due to the larger bit cache this decoder requires. In benchmarks on ARMv5 (Marvell Sheeva) with gcc 4.6, the only statistically significant difference between ALT and A32 is a 4% advantage for ALT in FLAC decoding. There is thus no (longer) any reason to keep the A32 reader from this point of view. This patch adds an option to the ALT reader increasing the bit cache to 32 bits as required by the Prores decoder. Benchmarking shows no significant change in speed on Intel i7. Again, the A32 reader fails to justify its existence. Signed-off-by: Mans Rullgard --- libavcodec/dv.c | 2 +- libavcodec/get_bits.h | 111 +++++++------------------------------------------ libavcodec/imc.c | 1 - libavcodec/proresdec.c | 2 +- 4 files changed, 16 insertions(+), 100 deletions(-) diff --git a/libavcodec/dv.c b/libavcodec/dv.c index 6c50f77d3f..76825f51ee 100644 --- a/libavcodec/dv.c +++ b/libavcodec/dv.c @@ -37,7 +37,7 @@ * @file * DV codec. */ -#define ALT_BITSTREAM_READER + #include "libavutil/pixdesc.h" #include "avcodec.h" #include "dsputil.h" diff --git a/libavcodec/get_bits.h b/libavcodec/get_bits.h index 4c03e412ce..684cc992fe 100644 --- a/libavcodec/get_bits.h +++ b/libavcodec/get_bits.h @@ -35,31 +35,11 @@ #include "libavutil/log.h" #include "mathops.h" -#if defined(ALT_BITSTREAM_READER_LE) && !defined(ALT_BITSTREAM_READER) -# define ALT_BITSTREAM_READER -#endif - -#if !defined(A32_BITSTREAM_READER) && !defined(ALT_BITSTREAM_READER) -# if ARCH_ARM && !HAVE_FAST_UNALIGNED -# define A32_BITSTREAM_READER -# else -# define ALT_BITSTREAM_READER -//#define A32_BITSTREAM_READER -# endif -#endif - /* bit input */ /* buffer, buffer_end and size_in_bits must be present and used by every reader */ typedef struct GetBitContext { const uint8_t *buffer, *buffer_end; -#ifdef ALT_BITSTREAM_READER int index; -#elif defined A32_BITSTREAM_READER - uint32_t *buffer_ptr; - uint32_t cache0; - uint32_t cache1; - int bit_count; -#endif int size_in_bits; } GetBitContext; @@ -122,8 +102,11 @@ LAST_SKIP_BITS(name, gb, num) for examples see get_bits, show_bits, skip_bits, get_vlc */ -#ifdef ALT_BITSTREAM_READER +#ifdef LONG_BITSTREAM_READER +# define MIN_CACHE_BITS 32 +#else # define MIN_CACHE_BITS 25 +#endif # define OPEN_READER(name, gb) \ unsigned int name##_index = (gb)->index; \ @@ -132,13 +115,23 @@ for examples see get_bits, show_bits, skip_bits, get_vlc # define CLOSE_READER(name, gb) (gb)->index = name##_index # ifdef ALT_BITSTREAM_READER_LE +# ifdef LONG_BITSTREAM_READER +# define UPDATE_CACHE(name, gb) \ + name##_cache = AV_RL64((gb)->buffer+(name##_index>>3)) >> (name##_index&0x07) +# else # define UPDATE_CACHE(name, gb) \ name##_cache = AV_RL32((gb)->buffer+(name##_index>>3)) >> (name##_index&0x07) +# endif # define SKIP_CACHE(name, gb, num) name##_cache >>= (num) # else +# ifdef LONG_BITSTREAM_READER +# define UPDATE_CACHE(name, gb) \ + name##_cache = AV_RB64((gb)->buffer+(name##_index >> 3)) >> (32 - (name##_index & 0x07)) +# else # define UPDATE_CACHE(name, gb) \ name##_cache = AV_RB32((gb)->buffer+(name##_index>>3)) << (name##_index&0x07) +# endif # define SKIP_CACHE(name, gb, num) name##_cache <<= (num) # endif @@ -174,72 +167,6 @@ static inline void skip_bits_long(GetBitContext *s, int n){ s->index += n; } -#elif defined A32_BITSTREAM_READER - -# define MIN_CACHE_BITS 32 - -# define OPEN_READER(name, gb) \ - int name##_bit_count = (gb)->bit_count; \ - uint32_t name##_cache0 = (gb)->cache0; \ - uint32_t name##_cache1 = (gb)->cache1; \ - uint32_t *name##_buffer_ptr = (gb)->buffer_ptr - -# define CLOSE_READER(name, gb) do { \ - (gb)->bit_count = name##_bit_count; \ - (gb)->cache0 = name##_cache0; \ - (gb)->cache1 = name##_cache1; \ - (gb)->buffer_ptr = name##_buffer_ptr; \ - } while (0) - -# define UPDATE_CACHE(name, gb) do { \ - if(name##_bit_count > 0){ \ - const uint32_t next = av_be2ne32(*name##_buffer_ptr); \ - name##_cache0 |= NEG_USR32(next, name##_bit_count); \ - name##_cache1 |= next << name##_bit_count; \ - name##_buffer_ptr++; \ - name##_bit_count -= 32; \ - } \ - } while (0) - -# define SKIP_CACHE(name, gb, num) do { \ - name##_cache0 <<= (num); \ - name##_cache0 |= NEG_USR32(name##_cache1,num); \ - name##_cache1 <<= (num); \ - } while (0) - -# define SKIP_COUNTER(name, gb, num) name##_bit_count += (num) - -# define SKIP_BITS(name, gb, num) do { \ - SKIP_CACHE(name, gb, num); \ - SKIP_COUNTER(name, gb, num); \ - } while (0) - -# define LAST_SKIP_BITS(name, gb, num) SKIP_BITS(name, gb, num) -# define LAST_SKIP_CACHE(name, gb, num) SKIP_CACHE(name, gb, num) - -# define SHOW_UBITS(name, gb, num) NEG_USR32(name##_cache0, num) - -# define SHOW_SBITS(name, gb, num) NEG_SSR32(name##_cache0, num) - -# define GET_CACHE(name, gb) name##_cache0 - -static inline int get_bits_count(const GetBitContext *s) { - return ((uint8_t*)s->buffer_ptr - s->buffer)*8 - 32 + s->bit_count; -} - -static inline void skip_bits_long(GetBitContext *s, int n){ - OPEN_READER(re, s); - re_bit_count += n; - re_buffer_ptr += re_bit_count>>5; - re_bit_count &= 31; - re_cache0 = av_be2ne32(re_buffer_ptr[-1]) << re_bit_count; - re_cache1 = 0; - UPDATE_CACHE(re, s); - CLOSE_READER(re, s); -} - -#endif - /** * read mpeg1 dc style vlc (sign bit + mantisse with no MSB). * if MSB not set it is negative @@ -301,7 +228,6 @@ static inline void skip_bits(GetBitContext *s, int n){ } static inline unsigned int get_bits1(GetBitContext *s){ -#ifdef ALT_BITSTREAM_READER unsigned int index = s->index; uint8_t result = s->buffer[index>>3]; #ifdef ALT_BITSTREAM_READER_LE @@ -315,9 +241,6 @@ static inline unsigned int get_bits1(GetBitContext *s){ s->index = index; return result; -#else - return get_bits(s, 1); -#endif } static inline unsigned int show_bits1(GetBitContext *s){ @@ -392,13 +315,7 @@ static inline void init_get_bits(GetBitContext *s, s->buffer = buffer; s->size_in_bits = bit_size; s->buffer_end = buffer + buffer_size; -#ifdef ALT_BITSTREAM_READER s->index = 0; -#elif defined A32_BITSTREAM_READER - s->buffer_ptr = (uint32_t*)((intptr_t)buffer & ~3); - s->bit_count = 32 + 8*((intptr_t)buffer & 3); - skip_bits_long(s, 0); -#endif } static inline void align_get_bits(GetBitContext *s) diff --git a/libavcodec/imc.c b/libavcodec/imc.c index b55eee9b70..ff8e31e9e6 100644 --- a/libavcodec/imc.c +++ b/libavcodec/imc.c @@ -35,7 +35,6 @@ #include #include -#define ALT_BITSTREAM_READER #include "avcodec.h" #include "get_bits.h" #include "dsputil.h" diff --git a/libavcodec/proresdec.c b/libavcodec/proresdec.c index adadcf8b75..031760c3bb 100644 --- a/libavcodec/proresdec.c +++ b/libavcodec/proresdec.c @@ -28,7 +28,7 @@ * @see http://wiki.multimedia.cx/index.php?title=Apple_ProRes */ -#define A32_BITSTREAM_READER // some ProRes vlc codes require up to 28 bits to be read at once +#define LONG_BITSTREAM_READER // some ProRes vlc codes require up to 28 bits to be read at once #include -- cgit v1.2.3