[FFmpeg-devel] [PATCH v2 1/1] avformat/hlsenc: closed caption tags in the master playlist

刘歧 lq at chinaffmpeg.org
Tue Jan 9 11:06:24 EET 2018


> On 9 Jan 2018, at 16:45, vdixit at akamai.com wrote:
> 
> From: Vishwanath Dixit <vdixit at akamai.com>
> 
> ---
> doc/muxers.texi           |  37 +++++++++++
> libavformat/dashenc.c     |   2 +-
> libavformat/hlsenc.c      | 155 +++++++++++++++++++++++++++++++++++++++++++++-
> libavformat/hlsplaylist.c |   5 +-
> libavformat/hlsplaylist.h |   3 +-
> 5 files changed, 197 insertions(+), 5 deletions(-)
> 
> diff --git a/doc/muxers.texi b/doc/muxers.texi
> index b060c4f..d9a5cc0 100644
> --- a/doc/muxers.texi
> +++ b/doc/muxers.texi
> @@ -901,6 +901,43 @@ and they are mapped to the two video only variant streams with audio group names
> 
> By default, a single hls variant containing all the encoded streams is created.
> 
> + at item cc_stream_map
> +Map string which specifies different closed captions groups and their
> +attributes. The closed captions stream groups are separated by space.
> +Expected string format is like this
> +"ccgroup:<group name>,instreamid:<INSTREAM-ID>,language:<language code> ....".
> +'ccgroup' and 'instreamid' are mandatory attributes. 'language' is an optional
> +attribute.
> +The closed captions groups configured using this option are mapped to different
> +variant streams by providing the same 'ccgroup' name in the
> + at code{var_stream_map} string. If @code{var_stream_map} is not set, then the
> +first available ccgroup in @code{cc_stream_map} is mapped to the output variant
> +stream. The examples for these two use cases are given below.
> +
> + at example
> +ffmpeg -re -i in.ts -b:v 1000k -b:a 64k -a53cc 1 -f hls \
> +  -cc_stream_map "ccgroup:cc,instreamid:CC1,language:en" \
> +  -master_pl_name master.m3u8 \
> +  http://example.com/live/out.m3u8
> + at end example
> +This example adds @code{#EXT-X-MEDIA} tag with @code{TYPE=CLOSED-CAPTIONS} in
> +the master playlist with group name 'cc', langauge 'en' (english) and
> +INSTREAM-ID 'CC1'. Also, it adds @code{CLOSED-CAPTIONS} attribute with group
> +name 'cc' for the output variant stream.
> + at example
> +ffmpeg -re -i in.ts -b:v:0 1000k -b:v:1 256k -b:a:0 64k -b:a:1 32k \
> +  -a53cc:0 1 -a53cc:1 1\
> +  -map 0:v -map 0:a -map 0:v -map 0:a -f hls \
> +  -cc_stream_map "ccgroup:cc,instreamid:CC1,language:en ccgroup:cc,instreamid:CC2,language:sp" \
> +  -var_stream_map "v:0,a:0,ccgroup:cc v:1,a:1,ccgroup:cc" \
> +  -master_pl_name master.m3u8 \
> +  http://example.com/live/out_%v.m3u8
> + at end example
> +This example adds two @code{#EXT-X-MEDIA} tags with @code{TYPE=CLOSED-CAPTIONS} in
> +the master playlist for the INSTREAM-IDs 'CC1' and 'CC2'. Also, it adds
> + at code{CLOSED-CAPTIONS} attribute with group name 'cc' for the two output variant
> +streams.
> +
> @item master_pl_name
> Create HLS master playlist with the given name.
> 
> diff --git a/libavformat/dashenc.c b/libavformat/dashenc.c
> index 3345b89..39d0afe 100644
> --- a/libavformat/dashenc.c
> +++ b/libavformat/dashenc.c
> @@ -820,7 +820,7 @@ static int write_manifest(AVFormatContext *s, int final)
>                 stream_bitrate += max_audio_bitrate;
>             }
>             get_hls_playlist_name(playlist_file, sizeof(playlist_file), NULL, i);
> -            ff_hls_write_stream_info(st, out, stream_bitrate, playlist_file, agroup);
> +            ff_hls_write_stream_info(st, out, stream_bitrate, playlist_file, agroup, NULL);
>         }
>         avio_close(out);
>         if (use_rename)
> diff --git a/libavformat/hlsenc.c b/libavformat/hlsenc.c
> index e36120c..4e4b287 100644
> --- a/libavformat/hlsenc.c
> +++ b/libavformat/hlsenc.c
> @@ -145,9 +145,16 @@ typedef struct VariantStream {
>     unsigned int nb_streams;
>     int m3u8_created; /* status of media play-list creation */
>     char *agroup; /* audio group name */
> +    char *ccgroup; /* closed caption group name */
>     char *baseurl;
> } VariantStream;
> 
> +typedef struct ClosedCaptionsStream {
> +    char *ccgroup; /* closed caption group name */
> +    char *instreamid; /* closed captions INSTREAM-ID */
> +    char *language; /* closed captions langauge */
> +} ClosedCaptionsStream;
> +
> typedef struct HLSContext {
>     const AVClass *class;  // Class for private options.
>     int64_t start_sequence;
> @@ -196,11 +203,14 @@ typedef struct HLSContext {
> 
>     VariantStream *var_streams;
>     unsigned int nb_varstreams;
> +    ClosedCaptionsStream *cc_streams;
> +    unsigned int nb_ccstreams;
> 
>     int master_m3u8_created; /* status of master play-list creation */
>     char *master_m3u8_url; /* URL of the master m3u8 file */
>     int version; /* HLS version */
>     char *var_stream_map; /* user specified variant stream map string */
> +    char *cc_stream_map; /* user specified closed caption streams map string */
>     char *master_pl_name;
>     unsigned int master_publish_rate;
>     int http_persistent;
> @@ -1115,7 +1125,8 @@ static int create_master_playlist(AVFormatContext *s,
>     AVDictionary *options = NULL;
>     unsigned int i, j;
>     int m3u8_name_size, ret, bandwidth;
> -    char *m3u8_rel_name;
> +    char *m3u8_rel_name, *ccgroup;
> +    ClosedCaptionsStream *ccs;
> 
>     input_vs->m3u8_created = 1;
>     if (!hls->master_m3u8_created) {
> @@ -1142,6 +1153,16 @@ static int create_master_playlist(AVFormatContext *s,
> 
>     ff_hls_write_playlist_version(hls->m3u8_out, hls->version);
> 
> +    for (i = 0; i < hls->nb_ccstreams; i++) {
> +        ccs = &(hls->cc_streams[i]);
> +        avio_printf(hls->m3u8_out, "#EXT-X-MEDIA:TYPE=CLOSED-CAPTIONS");
> +        avio_printf(hls->m3u8_out, ",GROUP-ID=\"%s\"", ccs->ccgroup);
> +        avio_printf(hls->m3u8_out, ",NAME=\"%s\"", ccs->instreamid);
> +        if (ccs->language)
> +            avio_printf(hls->m3u8_out, ",LANGUAGE=\"%s\"", ccs->language);
> +        avio_printf(hls->m3u8_out, ",INSTREAM-ID=\"%s\"\n", ccs->instreamid);
> +    }
> +
>     /* For audio only variant streams add #EXT-X-MEDIA tag with attributes*/
>     for (i = 0; i < hls->nb_varstreams; i++) {
>         vs = &(hls->var_streams[i]);
> @@ -1226,8 +1247,23 @@ static int create_master_playlist(AVFormatContext *s,
>             bandwidth += aud_st->codecpar->bit_rate;
>         bandwidth += bandwidth / 10;
> 
> +        ccgroup = NULL;
> +        if (vid_st && vs->ccgroup) {
> +            /* check if this group name is available in the cc map string */
> +            for (j = 0; j < hls->nb_ccstreams; j++) {
> +                ccs = &(hls->cc_streams[j]);
> +                if (!av_strcasecmp(ccs->ccgroup, vs->ccgroup)) {
> +                    ccgroup = vs->ccgroup;
> +                    break;
> +                }
> +            }
> +            if (j == hls->nb_ccstreams)
> +                av_log(NULL, AV_LOG_WARNING, "mapping ccgroup %s not found\n",
> +                        vs->ccgroup);
> +        }
> +
>         ff_hls_write_stream_info(vid_st, hls->m3u8_out, bandwidth, m3u8_rel_name,
> -                aud_st ? vs->agroup : NULL);
> +                aud_st ? vs->agroup : NULL, ccgroup);
> 
>         av_freep(&m3u8_rel_name);
>     }
> @@ -1714,6 +1750,11 @@ static int parse_variant_stream_mapstring(AVFormatContext *s)
>                 if (!vs->agroup)
>                     return AVERROR(ENOMEM);
>                 continue;
> +            } else if (av_strstart(keyval, "ccgroup:", &val)) {
> +                vs->ccgroup = av_strdup(val);
> +                if (!vs->ccgroup)
> +                    return AVERROR(ENOMEM);
> +                continue;
>             } else if (av_strstart(keyval, "v:", &val)) {
>                 codec_type = AVMEDIA_TYPE_VIDEO;
>             } else if (av_strstart(keyval, "a:", &val)) {
> @@ -1744,9 +1785,94 @@ static int parse_variant_stream_mapstring(AVFormatContext *s)
>     return 0;
> }
> 
> +static int parse_cc_stream_mapstring(AVFormatContext *s)
> +{
> +    HLSContext *hls = s->priv_data;
> +    int nb_ccstreams;
> +    char *p, *q, *saveptr1, *saveptr2, *ccstr, *keyval;
> +    const char *val;
> +    ClosedCaptionsStream *ccs;
> +
> +    p = av_strdup(hls->cc_stream_map);
> +    q = p;
> +    while(av_strtok(q, " \t", &saveptr1)) {
> +        q = NULL;
> +        hls->nb_ccstreams++;
> +    }
> +    av_freep(&p);
> +
> +    hls->cc_streams = av_mallocz(sizeof(*hls->cc_streams) * hls->nb_ccstreams);
> +    if (!hls->cc_streams)
> +        return AVERROR(ENOMEM);
> +
> +    p = hls->cc_stream_map;
> +    nb_ccstreams = 0;
> +    while (ccstr = av_strtok(p, " \t", &saveptr1)) {
> +        p = NULL;
> +
> +        if (nb_ccstreams < hls->nb_ccstreams)
> +            ccs = &(hls->cc_streams[nb_ccstreams++]);
> +        else
> +            return AVERROR(EINVAL);
> +
> +        while (keyval = av_strtok(ccstr, ",", &saveptr2)) {
> +            ccstr = NULL;
> +
> +            if (av_strstart(keyval, "ccgroup:", &val)) {
> +                ccs->ccgroup = av_strdup(val);
> +                if (!ccs->ccgroup)
> +                    return AVERROR(ENOMEM);
> +            } else if (av_strstart(keyval, "instreamid:", &val)) {
> +                ccs->instreamid = av_strdup(val);
> +                if (!ccs->instreamid)
> +                    return AVERROR(ENOMEM);
> +            } else if (av_strstart(keyval, "language:", &val)) {
> +                ccs->language = av_strdup(val);
> +                if (!ccs->language)
> +                    return AVERROR(ENOMEM);
> +            } else {
> +                av_log(s, AV_LOG_ERROR, "Invalid keyval %s\n", keyval);
> +                return AVERROR(EINVAL);
> +            }
> +        }
> +
> +        if (!ccs->ccgroup || !ccs->instreamid) {
> +            av_log(s, AV_LOG_ERROR, "Insufficient parameters in cc stream map string\n");
> +            return AVERROR(EINVAL);
> +        }
> +
> +        if (av_strstart(ccs->instreamid, "CC", &val)) {
> +            if(atoi(val) < 1 || atoi(val) > 4) {
> +                av_log(s, AV_LOG_ERROR, "Invalid instream ID CC index %d in %s, range 1-4\n",
> +                       atoi(val), ccs->instreamid);
> +                return AVERROR(EINVAL);
> +            }
> +        } else if (av_strstart(ccs->instreamid, "SERVICE", &val)) {
> +            if(atoi(val) < 1 || atoi(val) > 63) {
> +                av_log(s, AV_LOG_ERROR, "Invalid instream ID SERVICE index %d in %s, range 1-63 \n",
> +                       atoi(val), ccs->instreamid);
> +                return AVERROR(EINVAL);
> +            }
> +        } else {
> +            av_log(s, AV_LOG_ERROR, "Invalid instream ID %s, supported are CCn or SERIVICEn\n",
> +                   ccs->instreamid);
> +            return AVERROR(EINVAL);
> +        }
> +    }
> +
> +    return 0;
> +}
> +
> static int update_variant_stream_info(AVFormatContext *s) {
>     HLSContext *hls = s->priv_data;
>     unsigned int i;
> +    int ret = 0;
> +
> +    if (hls->cc_stream_map) {
> +        ret = parse_cc_stream_mapstring(s);
> +        if (ret < 0)
> +            return ret;
> +    }
> 
>     if (hls->var_stream_map) {
>         return parse_variant_stream_mapstring(s);
> @@ -1764,6 +1890,13 @@ static int update_variant_stream_info(AVFormatContext *s) {
>         if (!hls->var_streams[0].streams)
>             return AVERROR(ENOMEM);
> 
> +        //by default, the first available ccgroup is mapped to the variant stream
> +        if (hls->nb_ccstreams) {
> +            hls->var_streams[0].ccgroup = av_strdup(hls->cc_streams[0].ccgroup);
> +            if (!hls->var_streams[0].ccgroup)
> +                return AVERROR(ENOMEM);
> +        }
> +
>         for (i = 0; i < s->nb_streams; i++)
>             hls->var_streams[0].streams[i] = s->streams[i];
>     }
> @@ -2127,13 +2260,22 @@ failed:
>     av_freep(&vs->m3u8_name);
>     av_freep(&vs->streams);
>     av_freep(&vs->agroup);
> +    av_freep(&vs->ccgroup);
>     av_freep(&vs->baseurl);
>     }
> 
> +    for (i = 0; i < hls->nb_ccstreams; i++) {
> +        ClosedCaptionsStream *ccs = &hls->cc_streams[i];
> +        av_freep(&ccs->ccgroup);
> +        av_freep(&ccs->instreamid);
> +        av_freep(&ccs->language);
> +    }
> +
>     ff_format_io_close(s, &hls->m3u8_out);
>     ff_format_io_close(s, &hls->sub_m3u8_out);
>     av_freep(&hls->key_basename);
>     av_freep(&hls->var_streams);
> +    av_freep(&hls->cc_streams);
>     av_freep(&hls->master_m3u8_url);
>     return 0;
> }
> @@ -2470,13 +2612,21 @@ fail:
>             av_freep(&vs->vtt_m3u8_name);
>             av_freep(&vs->streams);
>             av_freep(&vs->agroup);
> +            av_freep(&vs->ccgroup);
>             av_freep(&vs->baseurl);
>             if (vs->avf)
>                 avformat_free_context(vs->avf);
>             if (vs->vtt_avf)
>                 avformat_free_context(vs->vtt_avf);
>         }
> +        for (i = 0; i < hls->nb_ccstreams; i++) {
> +            ClosedCaptionsStream *ccs = &hls->cc_streams[i];
> +            av_freep(&ccs->ccgroup);
> +            av_freep(&ccs->instreamid);
> +            av_freep(&ccs->language);
> +        }
>         av_freep(&hls->var_streams);
> +        av_freep(&hls->cc_streams);
>         av_freep(&hls->master_m3u8_url);
>     }
> 
> @@ -2536,6 +2686,7 @@ static const AVOption options[] = {
>     {"datetime", "current datetime as YYYYMMDDhhmmss", 0, AV_OPT_TYPE_CONST, {.i64 = HLS_START_SEQUENCE_AS_FORMATTED_DATETIME }, INT_MIN, INT_MAX, E, "start_sequence_source_type" },
>     {"http_user_agent", "override User-Agent field in HTTP header", OFFSET(user_agent), AV_OPT_TYPE_STRING, {.str = NULL},  0, 0,    E},
>     {"var_stream_map", "Variant stream map string", OFFSET(var_stream_map), AV_OPT_TYPE_STRING, {.str = NULL},  0, 0,    E},
> +    {"cc_stream_map", "Closed captions stream map string", OFFSET(cc_stream_map), AV_OPT_TYPE_STRING, {.str = NULL},  0, 0,    E},
>     {"master_pl_name", "Create HLS master playlist with this name", OFFSET(master_pl_name), AV_OPT_TYPE_STRING, {.str = NULL},  0, 0,    E},
>     {"master_pl_publish_rate", "Publish master play list every after this many segment intervals", OFFSET(master_publish_rate), AV_OPT_TYPE_INT, {.i64 = 0}, 0, UINT_MAX, E},
>     {"http_persistent", "Use persistent HTTP connections", OFFSET(http_persistent), AV_OPT_TYPE_BOOL, {.i64 = 0 }, 0, 1, E },
> diff --git a/libavformat/hlsplaylist.c b/libavformat/hlsplaylist.c
> index 098dc89..e797f14 100644
> --- a/libavformat/hlsplaylist.c
> +++ b/libavformat/hlsplaylist.c
> @@ -46,7 +46,8 @@ void ff_hls_write_audio_rendition(AVIOContext *out, char *agroup,
> }
> 
> void ff_hls_write_stream_info(AVStream *st, AVIOContext *out,
> -                              int bandwidth, char *filename, char *agroup) {
> +                              int bandwidth, char *filename, char *agroup,
> +                              char *ccgroup) {
>     if (!out || !filename)
>         return;
> 
> @@ -62,6 +63,8 @@ void ff_hls_write_stream_info(AVStream *st, AVIOContext *out,
>                 st->codecpar->height);
>     if (agroup && strlen(agroup) > 0)
>         avio_printf(out, ",AUDIO=\"group_%s\"", agroup);
> +    if (ccgroup && strlen(ccgroup) > 0)
> +        avio_printf(out, ",CLOSED-CAPTIONS=\"%s\"", ccgroup);
>     avio_printf(out, "\n%s\n\n", filename);
> }
> 
> diff --git a/libavformat/hlsplaylist.h b/libavformat/hlsplaylist.h
> index 9969315..29c5123 100644
> --- a/libavformat/hlsplaylist.h
> +++ b/libavformat/hlsplaylist.h
> @@ -40,7 +40,8 @@ void ff_hls_write_playlist_version(AVIOContext *out, int version);
> void ff_hls_write_audio_rendition(AVIOContext *out, char *agroup,
>                                   char *filename, int name_id, int is_default);
> void ff_hls_write_stream_info(AVStream *st, AVIOContext *out,
> -                              int bandwidth, char *filename, char *agroup);
> +                              int bandwidth, char *filename, char *agroup,
> +                              char *ccgroup);
> void ff_hls_write_playlist_header(AVIOContext *out, int version, int allowcache,
>                                   int target_duration, int64_t sequence,
>                                   uint32_t playlist_type);
> -- 
> 1.9.1
> 

If only copy command of the document, it’s ok,
If input string by myself, It’s have problem, cannot be used.


liuqideMacBook-Pro:xxx liuqi$ ./ffmpeg -re -f lavfi -i color=red  -g 25  -b:v 1000k -b:a 64k -a53cc 1 -f hls  -cc_stream_map "ccgroup:cc,instreamid:CC1,language:en"   -master_pl_name master.m3u8  live/out.m3u8
ffmpeg version N-89757-g42a5fe340f Copyright (c) 2000-2018 the FFmpeg developers
  built with Apple LLVM version 9.0.0 (clang-900.0.39.2)
  configuration: --enable-fontconfig --enable-gpl --enable-libass --enable-libbluray --enable-libfreetype --enable-libmp3lame --enable-libspeex --enable-libx264 --enable-libx265 --enable-libfdk-aac --enable-version3 --cc='ccache gcc' --enable-nonfree --enable-videotoolbox
  libavutil      56.  7.100 / 56.  7.100
  libavcodec     58.  9.100 / 58.  9.100
  libavformat    58.  3.100 / 58.  3.100
  libavdevice    58.  0.100 / 58.  0.100
  libavfilter     7. 11.101 /  7. 11.101
  libswscale      5.  0.101 /  5.  0.101
  libswresample   3.  0.101 /  3.  0.101
  libpostproc    55.  0.100 / 55.  0.100
Input #0, lavfi, from 'color=red':
  Duration: N/A, start: 0.000000, bitrate: N/A
    Stream #0:0: Video: rawvideo (I420 / 0x30323449), yuv420p, 320x240 [SAR 1:1 DAR 4:3], 25 tbr, 25 tbn, 25 tbc
Stream mapping:
  Stream #0:0 -> #0:0 (rawvideo (native) -> h264 (libx264))
Press [q] to stop, [?] for help
[libx264 @ 0x7fadae801600] using SAR=1/1
[libx264 @ 0x7fadae801600] using cpu capabilities: MMX2 SSE2Fast SSSE3 SSE4.2 AVX
[libx264 @ 0x7fadae801600] profile High, level 2.0
[libx264 @ 0x7fadae801600] 264 - core 148 r2694 3b70645 - H.264/MPEG-4 AVC codec - Copyleft 2003-2016 - http://www.videolan.org/x264.html - options: cabac=1 ref=3 deblock=1:0:0 analyse=0x3:0x113 me=hex subme=7 psy=1 psy_rd=1.00:0.00 mixed_ref=1 me_range=16 chroma_me=1 trellis=1 8x8dct=1 cqm=0 deadzone=21,11 fast_pskip=1 chroma_qp_offset=-2 threads=6 lookahead_threads=1 sliced_threads=0 nr=0 decimate=1 interlaced=0 bluray_compat=0 constrained_intra=0 bframes=3 b_pyramid=2 b_adapt=1 b_bias=0 direct=1 weightb=1 open_gop=0 weightp=2 keyint=25 keyint_min=2 scenecut=40 intra_refresh=0 rc_lookahead=25 rc=abr mbtree=1 bitrate=1000 ratetol=1.0 qcomp=0.60 qpmin=0 qpmax=69 qpstep=4 ip_ratio=1.40 aq=1:1.00
[hls @ 0x7fadae81ec00] Opening 'live/out0.ts' for writing
Output #0, hls, to 'live/out.m3u8':
  Metadata:
    encoder         : Lavf58.3.100
    Stream #0:0: Video: h264 (libx264), yuv420p, 320x240 [SAR 1:1 DAR 4:3], q=-1--1, 1000 kb/s, 25 fps, 90k tbn, 25 tbc
    Metadata:
      encoder         : Lavc58.9.100 libx264
    Side data:
      cpb: bitrate max/min/avg: 0/0/1000000 buffer size: 0 vbv_delay: -1
[hls @ 0x7fadae81ec00] Opening 'live/out1.ts' for writingte=N/A speed=0.514x
[hls @ 0x7fadae81ec00] Opening 'live/out.m3u8.tmp' for writing
[hls @ 0x7fadae81ec00] Opening 'live/master.m3u8' for writing
[hls @ 0x7fadae81ec00] Opening 'live/out2.ts' for writingte=N/A speed=0.71x
[hls @ 0x7fadae81ec00] Opening 'live/out.m3u8.tmp' for writing
[hls @ 0x7fadae81ec00] Opening 'live/out3.ts' for writingte=N/A speed=0.794x
[hls @ 0x7fadae81ec00] Opening 'live/out.m3u8.tmp' for writing
[hls @ 0x7fadae81ec00] Opening 'live/out4.ts' for writingte=N/A speed=0.809x
[hls @ 0x7fadae81ec00] Opening 'live/out.m3u8.tmp' for writing
[hls @ 0x7fadae81ec00] Opening 'live/out.m3u8.tmp' for writing
frame=  202 fps= 25 q=-1.0 Lsize=N/A time=00:00:08.00 bitrate=N/A speed=0.99x
video:5kB audio:0kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: unknown
[libx264 @ 0x7fadae801600] frame I:9     Avg QP: 0.44  size:    72
[libx264 @ 0x7fadae801600] frame P:49    Avg QP: 0.14  size:    22
[libx264 @ 0x7fadae801600] frame B:144   Avg QP: 0.36  size:    16
[libx264 @ 0x7fadae801600] consecutive B-frames:  5.0%  0.0%  0.0% 95.0%
[libx264 @ 0x7fadae801600] mb I  I16..4: 100.0%  0.0%  0.0%
[libx264 @ 0x7fadae801600] mb P  I16..4:  0.0%  0.0%  0.0%  P16..4:  0.0%  0.0%  0.0%  0.0%  0.0%    skip:100.0%
[libx264 @ 0x7fadae801600] mb B  I16..4:  0.0%  0.0%  0.0%  B16..8:  0.0%  0.0%  0.0%  direct: 0.0%  skip:100.0%
[libx264 @ 0x7fadae801600] final ratefactor: -27.54
[libx264 @ 0x7fadae801600] 8x8 transform intra:0.0%
[libx264 @ 0x7fadae801600] coded y,uvDC,uvAC intra: 0.0% 0.3% 0.0% inter: 0.0% 0.0% 0.0%
[libx264 @ 0x7fadae801600] i16 v,h,dc,p: 93%  0%  7%  0%
[libx264 @ 0x7fadae801600] i8c dc,h,v,p: 100%  0%  0%  0%
[libx264 @ 0x7fadae801600] Weighted P-Frames: Y:0.0% UV:0.0%
[libx264 @ 0x7fadae801600] kb/s:4.05



liuqideMacBook-Pro:xxx liuqi$ ./ffmpeg -re -f lavfi -i color=red  -g 25  -b:v 1000k -b:a 64k -a53cc 1 -f hls  -cc_stream_map "closecgroup:cc,instreamid:CC1,language:en"   -master_pl_name master.m3u8  live/out.m3u8
ffmpeg version N-89757-g42a5fe340f Copyright (c) 2000-2018 the FFmpeg developers
  built with Apple LLVM version 9.0.0 (clang-900.0.39.2)
  configuration: --enable-fontconfig --enable-gpl --enable-libass --enable-libbluray --enable-libfreetype --enable-libmp3lame --enable-libspeex --enable-libx264 --enable-libx265 --enable-libfdk-aac --enable-version3 --cc='ccache gcc' --enable-nonfree --enable-videotoolbox
  libavutil      56.  7.100 / 56.  7.100
  libavcodec     58.  9.100 / 58.  9.100
  libavformat    58.  3.100 / 58.  3.100
  libavdevice    58.  0.100 / 58.  0.100
  libavfilter     7. 11.101 /  7. 11.101
  libswscale      5.  0.101 /  5.  0.101
  libswresample   3.  0.101 /  3.  0.101
  libpostproc    55.  0.100 / 55.  0.100
Input #0, lavfi, from 'color=red':
  Duration: N/A, start: 0.000000, bitrate: N/A
    Stream #0:0: Video: rawvideo (I420 / 0x30323449), yuv420p, 320x240 [SAR 1:1 DAR 4:3], 25 tbr, 25 tbn, 25 tbc
Stream mapping:
  Stream #0:0 -> #0:0 (rawvideo (native) -> h264 (libx264))
Press [q] to stop, [?] for help
[libx264 @ 0x7fb463005800] using SAR=1/1
[libx264 @ 0x7fb463005800] using cpu capabilities: MMX2 SSE2Fast SSSE3 SSE4.2 AVX
[libx264 @ 0x7fb463005800] profile High, level 2.0
[libx264 @ 0x7fb463005800] 264 - core 148 r2694 3b70645 - H.264/MPEG-4 AVC codec - Copyleft 2003-2016 - http://www.videolan.org/x264.html - options: cabac=1 ref=3 deblock=1:0:0 analyse=0x3:0x113 me=hex subme=7 psy=1 psy_rd=1.00:0.00 mixed_ref=1 me_range=16 chroma_me=1 trellis=1 8x8dct=1 cqm=0 deadzone=21,11 fast_pskip=1 chroma_qp_offset=-2 threads=6 lookahead_threads=1 sliced_threads=0 nr=0 decimate=1 interlaced=0 bluray_compat=0 constrained_intra=0 bframes=3 b_pyramid=2 b_adapt=1 b_bias=0 direct=1 weightb=1 open_gop=0 weightp=2 keyint=25 keyint_min=2 scenecut=40 intra_refresh=0 rc_lookahead=25 rc=abr mbtree=1 bitrate=1000 ratetol=1.0 qcomp=0.60 qpmin=0 qpmax=69 qpstep=4 ip_ratio=1.40 aq=1:1.00
[hls @ 0x7fb46383bc00] Invalid keyval closecgroup:cc
[hls @ 0x7fb46383bc00] Variant stream info update failed with status ffffffea
Could not write header for output file #0 (incorrect codec parameters ?): Invalid argument
Error initializing output stream 0:0 --
[libx264 @ 0x7fb463005800] final ratefactor: 17.61
Conversion failed!
liuqideMacBook-Pro:xxx liuqi$




Thanks

Steven





More information about the ffmpeg-devel mailing list