mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2025-03-17 20:17:55 +02:00
Merge commit 'eb447d515956b3ce182d9750083131735f00324c'
* commit 'eb447d515956b3ce182d9750083131735f00324c': segment: Free and reinit the muxer before calling avformat_write_header Conflicts: libavformat/segment.c Merged-by: Michael Niedermayer <michaelni@gmx.at>
This commit is contained in:
commit
008d36ba1d
@ -54,6 +54,7 @@ typedef struct {
|
|||||||
int segment_idx; ///< index of the segment file to write, starting from 0
|
int segment_idx; ///< index of the segment file to write, starting from 0
|
||||||
int segment_idx_wrap; ///< number after which the index wraps
|
int segment_idx_wrap; ///< number after which the index wraps
|
||||||
int segment_count; ///< number of segment files already written
|
int segment_count; ///< number of segment files already written
|
||||||
|
AVOutputFormat *oformat;
|
||||||
AVFormatContext *avf;
|
AVFormatContext *avf;
|
||||||
char *format; ///< format to use for output segment files
|
char *format; ///< format to use for output segment files
|
||||||
char *list; ///< filename for the segment list file
|
char *list; ///< filename for the segment list file
|
||||||
@ -90,21 +91,52 @@ static void print_csv_escaped_str(AVIOContext *ctx, const char *str)
|
|||||||
avio_w8(ctx, '"');
|
avio_w8(ctx, '"');
|
||||||
}
|
}
|
||||||
|
|
||||||
static int segment_start(AVFormatContext *s)
|
static int segment_mux_init(AVFormatContext *s)
|
||||||
{
|
{
|
||||||
SegmentContext *seg = s->priv_data;
|
SegmentContext *seg = s->priv_data;
|
||||||
AVFormatContext *oc = seg->avf;
|
AVFormatContext *oc;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
seg->avf = oc = avformat_alloc_context();
|
||||||
|
if (!oc)
|
||||||
|
return AVERROR(ENOMEM);
|
||||||
|
|
||||||
|
oc->oformat = seg->oformat;
|
||||||
|
oc->interrupt_callback = s->interrupt_callback;
|
||||||
|
|
||||||
|
for (i = 0; i < s->nb_streams; i++) {
|
||||||
|
AVStream *st;
|
||||||
|
if (!(st = avformat_new_stream(oc, NULL)))
|
||||||
|
return AVERROR(ENOMEM);
|
||||||
|
avcodec_copy_context(st->codec, s->streams[i]->codec);
|
||||||
|
st->sample_aspect_ratio = s->streams[i]->sample_aspect_ratio;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int segment_start(AVFormatContext *s)
|
||||||
|
{
|
||||||
|
SegmentContext *c = s->priv_data;
|
||||||
|
AVFormatContext *oc = c->avf;
|
||||||
int err = 0;
|
int err = 0;
|
||||||
|
|
||||||
if (seg->segment_idx_wrap)
|
avformat_free_context(oc);
|
||||||
seg->segment_idx %= seg->segment_idx_wrap;
|
c->avf = NULL;
|
||||||
|
if ((err = segment_mux_init(s)) < 0)
|
||||||
|
return err;
|
||||||
|
oc = c->avf;
|
||||||
|
|
||||||
|
if (c->segment_idx_wrap)
|
||||||
|
c->segment_idx %= c->segment_idx_wrap;
|
||||||
|
|
||||||
if (av_get_frame_filename(oc->filename, sizeof(oc->filename),
|
if (av_get_frame_filename(oc->filename, sizeof(oc->filename),
|
||||||
s->filename, seg->segment_idx++) < 0) {
|
s->filename, c->segment_idx++) < 0) {
|
||||||
av_log(oc, AV_LOG_ERROR, "Invalid segment filename template '%s'\n", s->filename);
|
av_log(oc, AV_LOG_ERROR, "Invalid segment filename template '%s'\n", s->filename);
|
||||||
return AVERROR(EINVAL);
|
return AVERROR(EINVAL);
|
||||||
}
|
}
|
||||||
seg->segment_count++;
|
c->segment_count++;
|
||||||
|
|
||||||
if ((err = avio_open2(&oc->pb, oc->filename, AVIO_FLAG_WRITE,
|
if ((err = avio_open2(&oc->pb, oc->filename, AVIO_FLAG_WRITE,
|
||||||
&s->interrupt_callback, NULL)) < 0)
|
&s->interrupt_callback, NULL)) < 0)
|
||||||
@ -250,7 +282,7 @@ end:
|
|||||||
static int seg_write_header(AVFormatContext *s)
|
static int seg_write_header(AVFormatContext *s)
|
||||||
{
|
{
|
||||||
SegmentContext *seg = s->priv_data;
|
SegmentContext *seg = s->priv_data;
|
||||||
AVFormatContext *oc;
|
AVFormatContext *oc = NULL;
|
||||||
int ret, i;
|
int ret, i;
|
||||||
|
|
||||||
seg->segment_count = 0;
|
seg->segment_count = 0;
|
||||||
@ -292,11 +324,6 @@ static int seg_write_header(AVFormatContext *s)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
oc = avformat_alloc_context();
|
|
||||||
|
|
||||||
if (!oc)
|
|
||||||
return AVERROR(ENOMEM);
|
|
||||||
|
|
||||||
if (seg->list) {
|
if (seg->list) {
|
||||||
if (seg->list_type == LIST_TYPE_UNDEFINED) {
|
if (seg->list_type == LIST_TYPE_UNDEFINED) {
|
||||||
if (av_match_ext(seg->list, "csv" )) seg->list_type = LIST_TYPE_CSV;
|
if (av_match_ext(seg->list, "csv" )) seg->list_type = LIST_TYPE_CSV;
|
||||||
@ -319,31 +346,22 @@ static int seg_write_header(AVFormatContext *s)
|
|||||||
"More than a single video stream present, "
|
"More than a single video stream present, "
|
||||||
"expect issues decoding it.\n");
|
"expect issues decoding it.\n");
|
||||||
|
|
||||||
oc->oformat = av_guess_format(seg->format, s->filename, NULL);
|
seg->oformat = av_guess_format(seg->format, s->filename, NULL);
|
||||||
|
|
||||||
if (!oc->oformat) {
|
if (!seg->oformat) {
|
||||||
ret = AVERROR_MUXER_NOT_FOUND;
|
ret = AVERROR_MUXER_NOT_FOUND;
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
if (oc->oformat->flags & AVFMT_NOFILE) {
|
if (seg->oformat->flags & AVFMT_NOFILE) {
|
||||||
av_log(s, AV_LOG_ERROR, "format %s not supported.\n",
|
av_log(s, AV_LOG_ERROR, "format %s not supported.\n",
|
||||||
oc->oformat->name);
|
oc->oformat->name);
|
||||||
ret = AVERROR(EINVAL);
|
ret = AVERROR(EINVAL);
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
oc->interrupt_callback = s->interrupt_callback;
|
if ((ret = segment_mux_init(s)) < 0)
|
||||||
seg->avf = oc;
|
|
||||||
|
|
||||||
for (i = 0; i < s->nb_streams; i++) {
|
|
||||||
AVStream *st;
|
|
||||||
if (!(st = avformat_new_stream(oc, NULL))) {
|
|
||||||
ret = AVERROR(ENOMEM);
|
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
oc = seg->avf;
|
||||||
avcodec_copy_context(st->codec, s->streams[i]->codec);
|
|
||||||
st->sample_aspect_ratio = s->streams[i]->sample_aspect_ratio;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (av_get_frame_filename(oc->filename, sizeof(oc->filename),
|
if (av_get_frame_filename(oc->filename, sizeof(oc->filename),
|
||||||
s->filename, seg->segment_idx++) < 0) {
|
s->filename, seg->segment_idx++) < 0) {
|
||||||
@ -363,9 +381,10 @@ static int seg_write_header(AVFormatContext *s)
|
|||||||
|
|
||||||
fail:
|
fail:
|
||||||
if (ret) {
|
if (ret) {
|
||||||
avformat_free_context(oc);
|
|
||||||
if (seg->list)
|
if (seg->list)
|
||||||
segment_list_close(s);
|
segment_list_close(s);
|
||||||
|
if (seg->avf)
|
||||||
|
avformat_free_context(seg->avf);
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@ -396,6 +415,9 @@ static int seg_write_packet(AVFormatContext *s, AVPacket *pkt)
|
|||||||
|
|
||||||
if ((ret = segment_end(s)) < 0 || (ret = segment_start(s)) < 0)
|
if ((ret = segment_end(s)) < 0 || (ret = segment_start(s)) < 0)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
|
oc = seg->avf;
|
||||||
|
|
||||||
seg->start_time = (double)pkt->pts * av_q2d(st->time_base);
|
seg->start_time = (double)pkt->pts * av_q2d(st->time_base);
|
||||||
} else if (pkt->pts != AV_NOPTS_VALUE) {
|
} else if (pkt->pts != AV_NOPTS_VALUE) {
|
||||||
seg->end_time = FFMAX(seg->end_time,
|
seg->end_time = FFMAX(seg->end_time,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user