On Wed, 11 Sep 2013 23:26:21 +0200, Vladimir Pantelic <[email protected]> 
wrote:
> ASF markers only have a start time, so we lose the chapter end times,
> but that is ASF for you
> 
> Signed-off-by: Vladimir Pantelic <[email protected]>
> ---
>  Changelog            |  1 +
>  libavformat/asfenc.c | 63 
> +++++++++++++++++++++++++++++++++++++++++++++++++++-
>  2 files changed, 63 insertions(+), 1 deletion(-)
> 
> diff --git a/Changelog b/Changelog
> index 7e210a7..79cc3e6 100644
> --- a/Changelog
> +++ b/Changelog
> @@ -33,6 +33,7 @@ version 10:
>  - avconv -t option can now be used for inputs, to limit the duration of
>    data read from an input file
>  - incomplete Voxware MetaSound decoder
> +- mux chapters in ASF files
>  
>  
>  version 9:
> diff --git a/libavformat/asfenc.c b/libavformat/asfenc.c
> index 7e1594b..0ba2729 100644
> --- a/libavformat/asfenc.c
> +++ b/libavformat/asfenc.c
> @@ -20,6 +20,7 @@
>   */
>  
>  #include "libavutil/dict.h"
> +#include "libavutil/mathematics.h"
>  #include "avformat.h"
>  #include "avio_internal.h"
>  #include "internal.h"
> @@ -287,6 +288,61 @@ static int64_t unix_to_file_time(int ti)
>      return t;
>  }
>  
> +static int32_t get_send_time(ASFContext *asf, int64_t pres_time, uint64_t 
> *offset)
> +{
> +    int i;
> +    int32_t send_time = 0;
> +    *offset = asf->data_offset + DATA_HEADER_SIZE;
> +    for (i = 0; i < asf->nb_index_count; i++) {
> +        if (pres_time <= asf->index_ptr[i].send_time)
> +            break;
> +        send_time = asf->index_ptr[i].send_time;
> +        *offset   = asf->index_ptr[i].offset;
> +    }
> +
> +    return send_time / 10000;
> +}
> +
> +static int asf_write_markers(AVFormatContext *s)
> +{
> +    ASFContext *asf = s->priv_data;
> +    AVIOContext *pb = s->pb;
> +    int i;
> +    AVRational scale = {1, 10000000};
> +    int64_t hpos = put_header(pb, &ff_asf_marker_header);
> +
> +    put_guid(pb, &ff_asf_reserved_4);  // ASF spec mandates this reserved 
> value
> +    avio_wl32(pb, s->nb_chapters);     // markers count
> +    avio_wl16(pb, 0);                  // ASF spec mandates 0 for this
> +    avio_wl16(pb, 0);                  // name length 0, no name given
> +
> +    for (i = 0; i < s->nb_chapters; i++) {
> +        AVChapter *c = s->chapters[i];
> +        AVDictionaryEntry *t = av_dict_get(c->metadata, "title", NULL, 0);
> +        int64_t pres_time = av_rescale_q(c->start, c->time_base, scale);
> +        uint64_t offset;
> +        int32_t send_time = get_send_time(asf, pres_time, &offset);
> +        int len;
> +        uint8_t *buf;
> +        AVIOContext *dyn_buf;
> +        if (avio_open_dyn_buf(&dyn_buf) < 0)
> +            return AVERROR(ENOMEM);
> +        avio_put_str16le(dyn_buf, t->value);

t may be NULL, a chapter doesn't necessarily have a title

Otherwise looks very nice.
Finally proper ASF support.

-- 
Anton Khirnov
_______________________________________________
libav-devel mailing list
[email protected]
https://lists.libav.org/mailman/listinfo/libav-devel

Reply via email to