[FFmpeg-devel] [PATCH] avformat/hlsenc: creation of hls variant streams with master playlist in a single hlsenc instance
刘歧
lq at chinaffmpeg.org
Thu Nov 16 08:38:45 EET 2017
> 在 2017年11月15日,21:48,Dixit, Vishwanath <vdixit at akamai.com> 写道:
>
>
>> On 11/15/17, 9:56 AM, "刘歧" <lq at chinaffmpeg.org> wrote:
>> all test info bellow:
>>
>> 1st, look at the ffmpeg.exe banner
>> 2nd, test with fate-filter-hls-append
>> 3nd, test with filter-hls-vs-with-master
>>
>>
>> /home/liuqi/ffmpeg/tests/fate-run.sh: 1: eval: ffmpeg.exe: not found
>> make: *** [fate-filter-hls-vs-with-master] Error 1
>> liuqi at localhost:~/ffmpeg/windows$
>
> I have fixed the issue. Please find the updated patches in the attachment. The following updates are made,
> 1. An additional FATE ‘run’ command was needed in the test to resolve ‘ffmpeg.exe: not found’ issue.
> 2. Line splitter ‘\’ in make file was creating some sort of un-certainty in test results between linux and windows. I have removed line splitter and have made it a single line command.
> 3. There are minor updates to resolve the compile time warnings.
>
> <0001-avformat-hlsenc-creation-of-hls-variant-streams-in-a.patch><0002-avformat-hlsenc-creation-of-hls-master-playlist-file.patch><0003-tests-fate-addition-of-test-case-for-hls-variant-str.patch>_______________________________________________
> ffmpeg-devel mailing list
> ffmpeg-devel at ffmpeg.org
> http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
FATE test passed: Ubuntu, OS X, qemu+MIPS Linux, wine MingW, qemu+ARM Linux, Thanks.
> 0001-avformat-hlsenc-creation-of-hls-variant-streams-in-a.patch:
+static int format_name(char *name, int name_buf_len, int i)
+{
+ char *p;
+ char extension[10] = {'\0'};
+
+ p = strrchr(name, '.');
+ if (p) {
+ strcpy(extension, p);
What about use av_strlcpy ?
+ *p = '\0';
+ }
+
+ snprintf(name + strlen(name), name_buf_len - strlen(name), POSTFIX_PATTERN, i);
+
+ if (strlen(extension))
+ av_strlcat(name, extension, name_buf_len);
+
+ return 0;
+}
+
+static int get_nth_codec_stream_index(AVFormatContext *s,
+ enum AVMediaType codec_type,
+ int stream_id)
+{
+ unsigned int stream_index, cnt;
+ if (stream_id < 0 || stream_id > s->nb_streams - 1)
+ return -1;
+ cnt = 0;
+ for (stream_index = 0; stream_index < s->nb_streams; stream_index++) {
+ if (s->streams[stream_index]->codecpar->codec_type != codec_type)
+ continue;
+ if (cnt == stream_id)
+ return stream_index;
+ cnt++;
+ }
+ return -1;
+}
+
+static int parse_variant_stream_mapstring(AVFormatContext *s)
+{
+ HLSContext *hls = s->priv_data;
+ VariantStream *vs;
+ int stream_index;
+ enum AVMediaType codec_type;
+ int nb_varstreams, nb_streams;
+ char *p, *q, *saveptr1, *saveptr2, *varstr, *keyval;
+ const char *val;
+
+ /**
+ * Expected format for var_stream_map string is as below:
+ * "a:0,v:0 a:1,v:1"
+ * This string specifies how to group the audio, video and subtitle streams
+ * into different variant streams. The variant stream groups are separated
+ * by space.
+ *
+ * a:, v:, s: are keys to specify audio, video and subtitle streams
+ * respectively. Allowed values are 0 to 9 digits (limited just based on
+ * practical usage)
+ *
+ */
+ p = av_strdup(hls->var_stream_map);
+ q = p;
+ while(av_strtok(q, " \t", &saveptr1)) {
+ q = NULL;
+ hls->nb_varstreams++;
+ }
+ av_freep(&p);
+
+ hls->var_streams = av_mallocz(sizeof(*hls->var_streams) * hls->nb_varstreams);
+ if (!hls->var_streams)
+ return AVERROR(ENOMEM);
+
+ p = hls->var_stream_map;
+ nb_varstreams = 0;
+ while (varstr = av_strtok(p, " \t", &saveptr1)) {
+ p = NULL;
+
+ if (nb_varstreams < hls->nb_varstreams)
+ vs = &(hls->var_streams[nb_varstreams++]);
+ else
+ return -1;
+
+ q = varstr;
+ while (q < varstr + strlen(varstr)) {
+ if (!strncmp(q, "a:", 2) || !strncmp(q, "v:", 2) ||
+ !strncmp(q, "s:", 2))
What about use av_strcasecmp ?
+ vs->nb_streams++;
+ q++;
+ }
+ vs->streams = av_mallocz(sizeof(AVStream *) * vs->nb_streams);
+ if (!vs->streams)
+ return AVERROR(ENOMEM);
+
+ nb_streams = 0;
+ while (keyval = av_strtok(varstr, ",", &saveptr2)) {
+ varstr = NULL;
+
+ if (av_strstart(keyval, "v:", &val)) {
+ codec_type = AVMEDIA_TYPE_VIDEO;
+ } else if (av_strstart(keyval, "a:", &val)) {
+ codec_type = AVMEDIA_TYPE_AUDIO;
+ } else if (av_strstart(keyval, "s:", &val)) {
+ codec_type = AVMEDIA_TYPE_SUBTITLE;
+ } else {
+ av_log(s, AV_LOG_ERROR, "Invalid keyval %s\n", keyval);
+ return -1;
What about use return AVERROR(EINVAL)?
+ }
+
+ stream_index = -1;
+ if (av_isdigit(*val))
+ stream_index = get_nth_codec_stream_index (s, codec_type,
+ atoi(val));
+
+ if (stream_index >= 0 && nb_streams < vs->nb_streams) {
+ vs->streams[nb_streams++] = s->streams[stream_index];
+ } else {
+ av_log(s, AV_LOG_ERROR, "Unable to map stream at %s\n", keyval);
+ return -1;
same as above.
+ }
+ }
+ }
+ av_log(s, AV_LOG_DEBUG, "Number of variant streams %d\n",
+ hls->nb_varstreams);
+
+ return 0;
+}
+
+static int update_variant_stream_info(AVFormatContext *s) {
+ HLSContext *hls = s->priv_data;
+ unsigned int i;
+
+ if (hls->var_stream_map) {
+ return parse_variant_stream_mapstring(s);
+ } else {
+ //By default, a single variant stream with all the codec streams is created
+ hls->nb_varstreams = 1;
+ hls->var_streams = av_mallocz(sizeof(*hls->var_streams) *
+ hls->nb_varstreams);
+ if (!hls->var_streams)
+ return AVERROR(ENOMEM);
+
+ hls->var_streams[0].nb_streams = s->nb_streams;
+ hls->var_streams[0].streams = av_mallocz(sizeof(AVStream *) *
+ hls->var_streams[0].nb_streams);
+ if (!hls->var_streams[0].streams)
+ return AVERROR(ENOMEM);
+
+ for (i = 0; i < s->nb_streams; i++)
+ hls->var_streams[0].streams[i] = s->streams[i];
+ }
+ return 0;
+}
+
> 0002-avformat-hlsenc-creation-of-hls-master-playlist-file.patch:
+static int get_relative_url(const char *master_url, const char *media_url,
+ char *rel_url, int rel_url_buf_size)
+{
+ char *p = NULL;
+ int base_len = -1;
+ p = strrchr(master_url, '/') ? strrchr(master_url, '/') :\
+ strrchr(master_url, '\\');
+ if (p) {
+ base_len = abs(p - master_url);
use FFABS
+ if (strncmp(master_url, media_url, base_len)) {
use av_strcasecmp
+ av_log(NULL, AV_LOG_WARNING, "Unable to find relative url\n");
+ return -1;
+ }
+ }
+ av_strlcpy(rel_url, &(media_url[base_len + 1]), rel_url_buf_size);
+ return 0;
+}
More information about the ffmpeg-devel
mailing list