Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/FFmpeg/FFmpeg.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKarthick Jeyapal <kjeyapal@akamai.com>2018-05-04 08:15:58 +0300
committerKarthick Jeyapal <kjeyapal@akamai.com>2018-05-28 08:22:01 +0300
commit2efdbf7367989cf9d296c25fa3d2aff8d6e25fdd (patch)
tree0fd7614bf0fa46796f2b90e6287990cb45fc73f2 /libavformat
parente3275f937dc38e740c74539f2f6aad5bfdba2bf1 (diff)
avformat/dashenc: Added option for Segment file format
Right now segment file format is chosen to be either mp4 or webm based on the codec format. This patch makes that choice configurable by the user, instead of being decided by the muxer. Also with this change per-stream choice segment file format(based on codec type) is not possible. All the output audio and video streams should be in the same file format.
Diffstat (limited to 'libavformat')
-rw-r--r--libavformat/dashenc.c67
1 files changed, 39 insertions, 28 deletions
diff --git a/libavformat/dashenc.c b/libavformat/dashenc.c
index e27b61c096..56af916555 100644
--- a/libavformat/dashenc.c
+++ b/libavformat/dashenc.c
@@ -48,6 +48,12 @@
#include "vpcc.h"
#include "dash.h"
+typedef enum {
+ SEGMENT_TYPE_MP4 = 0,
+ SEGMENT_TYPE_WEBM,
+ SEGMENT_TYPE_NB
+} SegmentType;
+
typedef struct Segment {
char file[1024];
int64_t start_pos;
@@ -69,7 +75,6 @@ typedef struct OutputStream {
AVFormatContext *ctx;
int ctx_inited, as_idx;
AVIOContext *out;
- char format_name[8];
int packets_written;
char initfile[1024];
int64_t init_start_pos, pos;
@@ -126,6 +131,8 @@ typedef struct DASHContext {
int64_t timeout;
int index_correction;
char *format_options_str;
+ SegmentType segment_type;
+ const char *format_name;
} DASHContext;
static struct codec_string {
@@ -139,6 +146,15 @@ static struct codec_string {
{ 0, NULL }
};
+static struct format_string {
+ SegmentType segment_type;
+ const char *str;
+} formats[] = {
+ { SEGMENT_TYPE_MP4, "mp4" },
+ { SEGMENT_TYPE_WEBM, "webm" },
+ { 0, NULL }
+};
+
static int dashenc_io_open(AVFormatContext *s, AVIOContext **pb, char *filename,
AVDictionary **options) {
DASHContext *c = s->priv_data;
@@ -172,6 +188,14 @@ static void dashenc_io_close(AVFormatContext *s, AVIOContext **pb, char *filenam
}
}
+static const char *get_format_str(SegmentType segment_type) {
+ int i;
+ for (i = 0; i < SEGMENT_TYPE_NB; i++)
+ if (formats[i].segment_type == segment_type)
+ return formats[i].str;
+ return NULL;
+}
+
static void set_vp9_codec_str(AVFormatContext *s, AVCodecParameters *par,
AVRational *frame_rate, char *str, int size) {
VPCC vpcc;
@@ -582,13 +606,13 @@ static int write_adaptation_set(AVFormatContext *s, AVIOContext *out, int as_ind
if (as->media_type == AVMEDIA_TYPE_VIDEO) {
AVStream *st = s->streams[i];
avio_printf(out, "\t\t\t<Representation id=\"%d\" mimeType=\"video/%s\" codecs=\"%s\"%s width=\"%d\" height=\"%d\"",
- i, os->format_name, os->codec_str, bandwidth_str, s->streams[i]->codecpar->width, s->streams[i]->codecpar->height);
+ i, c->format_name, os->codec_str, bandwidth_str, s->streams[i]->codecpar->width, s->streams[i]->codecpar->height);
if (st->avg_frame_rate.num)
avio_printf(out, " frameRate=\"%d/%d\"", st->avg_frame_rate.num, st->avg_frame_rate.den);
avio_printf(out, ">\n");
} else {
avio_printf(out, "\t\t\t<Representation id=\"%d\" mimeType=\"audio/%s\" codecs=\"%s\"%s audioSamplingRate=\"%d\">\n",
- i, os->format_name, os->codec_str, bandwidth_str, s->streams[i]->codecpar->sample_rate);
+ i, c->format_name, os->codec_str, bandwidth_str, s->streams[i]->codecpar->sample_rate);
avio_printf(out, "\t\t\t\t<AudioChannelConfiguration schemeIdUri=\"urn:mpeg:dash:23003:3:audio_channel_configuration:2011\" value=\"%d\" />\n",
s->streams[i]->codecpar->channels);
}
@@ -960,27 +984,10 @@ static int dash_init(AVFormatContext *s)
if (!ctx)
return AVERROR(ENOMEM);
- // choose muxer based on codec: webm for VP8 and opus, mp4 otherwise
- // note: os->format_name is also used as part of the mimetype of the
- // representation, e.g. video/<format_name>
- if (s->streams[i]->codecpar->codec_id == AV_CODEC_ID_VP8 ||
- s->streams[i]->codecpar->codec_id == AV_CODEC_ID_OPUS ||
- s->streams[i]->codecpar->codec_id == AV_CODEC_ID_VORBIS) {
- snprintf(os->format_name, sizeof(os->format_name), "webm");
-
- if (s->strict_std_compliance > FF_COMPLIANCE_EXPERIMENTAL) {
- av_log(s, AV_LOG_ERROR,
- "WebM support in dashenc is experimental and has not "
- "been validated. For testing purposes, make sure "
- "to add -strict experimental and override "
- "-init_seg_name and -media_seg_name to end with "
- "the extension 'webm'.\n");
- return AVERROR(EINVAL);
- }
- } else {
- snprintf(os->format_name, sizeof(os->format_name), "mp4");
- }
- ctx->oformat = av_guess_format(os->format_name, NULL, NULL);
+ c->format_name = get_format_str(c->segment_type);
+ if (!c->format_name)
+ return AVERROR_MUXER_NOT_FOUND;
+ ctx->oformat = av_guess_format(c->format_name, NULL, NULL);
if (!ctx->oformat)
return AVERROR_MUXER_NOT_FOUND;
os->ctx = ctx;
@@ -1023,7 +1030,8 @@ static int dash_init(AVFormatContext *s)
if (ret < 0)
return ret;
}
- if (!strcmp(os->format_name, "mp4")) {
+
+ if (c->segment_type == SEGMENT_TYPE_MP4) {
if (c->streaming)
av_dict_set(&opts, "movflags", "frag_every_frame+dash+delay_moov", 0);
else
@@ -1088,7 +1096,7 @@ static int dash_write_header(AVFormatContext *s)
// Flush init segment
// Only for WebM segment, since for mp4 delay_moov is set and
// the init segment is thus flushed after the first packets.
- if (strcmp(os->format_name, "mp4") &&
+ if (c->segment_type == SEGMENT_TYPE_WEBM &&
(ret = flush_init_segment(s, os)) < 0)
return ret;
}
@@ -1259,7 +1267,7 @@ static int dash_flush(AVFormatContext *s, int final, int stream)
}
if (!c->single_file) {
- if (!strcmp(os->format_name, "mp4") && !os->written_len)
+ if (c->segment_type == SEGMENT_TYPE_MP4 && !os->written_len)
write_styp(os->ctx->pb);
} else {
snprintf(os->full_path, sizeof(os->full_path), "%s%s", c->dirname, os->initfile);
@@ -1449,7 +1457,7 @@ static int dash_write_packet(AVFormatContext *s, AVPacket *pkt)
}
//write out the data immediately in streaming mode
- if (c->streaming && !strcmp(os->format_name, "mp4")) {
+ if (c->streaming && c->segment_type == SEGMENT_TYPE_MP4) {
int len = 0;
uint8_t *buf = NULL;
if (!os->written_len)
@@ -1545,6 +1553,9 @@ static const AVOption options[] = {
{ "timeout", "set timeout for socket I/O operations", OFFSET(timeout), AV_OPT_TYPE_DURATION, { .i64 = -1 }, -1, INT_MAX, .flags = E },
{ "index_correction", "Enable/Disable segment index correction logic", OFFSET(index_correction), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, E },
{ "format_options","set list of options for the container format (mp4/webm) used for dash", OFFSET(format_options_str), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, E},
+ { "dash_segment_type", "set dash segment files type", OFFSET(segment_type), AV_OPT_TYPE_INT, {.i64 = SEGMENT_TYPE_MP4 }, 0, SEGMENT_TYPE_NB - 1, E, "segment_type"},
+ { "mp4", "make segment file in ISOBMFF format", 0, AV_OPT_TYPE_CONST, {.i64 = SEGMENT_TYPE_MP4 }, 0, UINT_MAX, E, "segment_type"},
+ { "webm", "make segment file in WebM format", 0, AV_OPT_TYPE_CONST, {.i64 = SEGMENT_TYPE_WEBM }, 0, UINT_MAX, E, "segment_type"},
{ NULL },
};