int segment_idx_wrap; ///< number after which the index wraps
int segment_idx_wrap_nb; ///< number of time the index has wraped
int segment_count; ///< number of segment files already written
- ff_const59 AVOutputFormat *oformat;
+ const AVOutputFormat *oformat;
AVFormatContext *avf;
char *format; ///< format to use for output segment files
AVDictionary *format_options;
int list_flags; ///< flags affecting list generation
int list_size; ///< number of entries for the segment list file
+ int is_nullctx; ///< whether avf->pb is a nullctx
int use_clocktime; ///< flag to cut segments at regular clock time
int64_t clocktime_offset; //< clock offset for cutting the segments at regular clock time
int64_t clocktime_wrap_duration; //< wrapping duration considered for starting a new segment
if (!(st = avformat_new_stream(oc, NULL)))
return AVERROR(ENOMEM);
+ ret = ff_stream_encode_params_copy(st, ist);
+ if (ret < 0)
+ return ret;
opar = st->codecpar;
- avcodec_parameters_copy(opar, ipar);
if (!oc->oformat->codec_tag ||
av_codec_get_id (oc->oformat->codec_tag, ipar->codec_tag) == opar->codec_id ||
av_codec_get_tag(oc->oformat->codec_tag, ipar->codec_id) <= 0) {
} else {
opar->codec_tag = 0;
}
- st->sample_aspect_ratio = ist->sample_aspect_ratio;
- st->time_base = ist->time_base;
- st->avg_frame_rate = ist->avg_frame_rate;
- st->disposition = ist->disposition;
-#if FF_API_LAVF_AVCTX
-FF_DISABLE_DEPRECATION_WARNINGS
- if (ipar->codec_tag == MKTAG('t','m','c','d'))
- st->codec->time_base = ist->codec->time_base;
-FF_ENABLE_DEPRECATION_WARNINGS
-#endif
- av_dict_copy(&st->metadata, ist->metadata, 0);
}
return 0;
/* check on monotonicity */
if (i && (*times)[i-1] > (*times)[i]) {
av_log(log_ctx, AV_LOG_ERROR,
- "Specified time %f is greater than the following time %f\n",
+ "Specified time %f is smaller than the last time %f\n",
(float)((*times)[i])/1000000, (float)((*times)[i-1])/1000000);
FAIL(AVERROR(EINVAL));
}
static int parse_frames(void *log_ctx, int **frames, int *nb_frames,
const char *frames_str)
{
- char *p;
- int i, ret = 0;
- char *frames_str1 = av_strdup(frames_str);
- char *saveptr = NULL;
-
- if (!frames_str1)
- return AVERROR(ENOMEM);
-
-#define FAIL(err) ret = err; goto end
+ const char *p;
+ int i;
*nb_frames = 1;
- for (p = frames_str1; *p; p++)
+ for (p = frames_str; *p; p++)
if (*p == ',')
(*nb_frames)++;
*frames = av_malloc_array(*nb_frames, sizeof(**frames));
if (!*frames) {
av_log(log_ctx, AV_LOG_ERROR, "Could not allocate forced frames array\n");
- FAIL(AVERROR(ENOMEM));
+ return AVERROR(ENOMEM);
}
- p = frames_str1;
+ p = frames_str;
for (i = 0; i < *nb_frames; i++) {
long int f;
char *tailptr;
- char *fstr = av_strtok(p, ",", &saveptr);
- p = NULL;
- if (!fstr) {
+ if (*p == '\0' || *p == ',') {
av_log(log_ctx, AV_LOG_ERROR, "Empty frame specification in frame list %s\n",
frames_str);
- FAIL(AVERROR(EINVAL));
+ return AVERROR(EINVAL);
}
- f = strtol(fstr, &tailptr, 10);
- if (*tailptr || f <= 0 || f >= INT_MAX) {
+ f = strtol(p, &tailptr, 10);
+ if (*tailptr != '\0' && *tailptr != ',' || f <= 0 || f >= INT_MAX) {
av_log(log_ctx, AV_LOG_ERROR,
- "Invalid argument '%s', must be a positive integer <= INT64_MAX\n",
- fstr);
- FAIL(AVERROR(EINVAL));
+ "Invalid argument '%s', must be a positive integer < INT_MAX\n",
+ p);
+ return AVERROR(EINVAL);
}
+ if (*tailptr == ',')
+ tailptr++;
+ p = tailptr;
(*frames)[i] = f;
/* check on monotonicity */
if (i && (*frames)[i-1] > (*frames)[i]) {
av_log(log_ctx, AV_LOG_ERROR,
- "Specified frame %d is greater than the following frame %d\n",
+ "Specified frame %d is smaller than the last frame %d\n",
(*frames)[i], (*frames)[i-1]);
- FAIL(AVERROR(EINVAL));
+ return AVERROR(EINVAL);
}
}
-end:
- av_free(frames_str1);
- return ret;
+ return 0;
}
static int open_null_ctx(AVIOContext **ctx)
static void seg_free(AVFormatContext *s)
{
SegmentContext *seg = s->priv_data;
+ SegmentListEntry *cur;
+
ff_format_io_close(s, &seg->list_pb);
- avformat_free_context(seg->avf);
- seg->avf = NULL;
+ if (seg->avf) {
+ if (seg->is_nullctx)
+ close_null_ctxp(&seg->avf->pb);
+ else
+ ff_format_io_close(s, &seg->avf->pb);
+ avformat_free_context(seg->avf);
+ seg->avf = NULL;
+ }
av_freep(&seg->times);
av_freep(&seg->frames);
av_freep(&seg->cur_entry.filename);
+
+ cur = seg->segment_list_entries;
+ while (cur) {
+ SegmentListEntry *next = cur->next;
+ av_freep(&cur->filename);
+ av_free(cur);
+ cur = next;
+ }
}
static int seg_init(AVFormatContext *s)
} else {
if ((ret = open_null_ctx(&oc->pb)) < 0)
return ret;
+ seg->is_nullctx = 1;
}
av_dict_copy(&options, seg->format_options, 0);
av_dict_free(&options);
if (ret < 0) {
- ff_format_io_close(oc, &oc->pb);
return ret;
}
seg->segment_frame_count = 0;
ff_format_io_close(oc, &oc->pb);
} else {
close_null_ctxp(&oc->pb);
+ seg->is_nullctx = 0;
}
if ((ret = oc->io_open(oc, &oc->pb, oc->url, AVIO_FLAG_WRITE, NULL)) < 0)
return ret;
return AVERROR(EINVAL);
if (!st->codecpar->extradata_size) {
- int pkt_extradata_size;
+ size_t pkt_extradata_size;
uint8_t *pkt_extradata = av_packet_get_side_data(pkt, AV_PKT_DATA_NEW_EXTRADATA, &pkt_extradata_size);
if (pkt_extradata && pkt_extradata_size > 0) {
ret = ff_alloc_extradata(st->codecpar, pkt_extradata_size);
{
SegmentContext *seg = s->priv_data;
AVFormatContext *oc = seg->avf;
- SegmentListEntry *cur, *next;
- int ret = 0;
+ int ret;
if (!oc)
- goto fail;
+ return 0;
if (!seg->write_header_trailer) {
if ((ret = segment_end(s, 0, 1)) < 0)
- goto fail;
+ return ret;
if ((ret = open_null_ctx(&oc->pb)) < 0)
- goto fail;
+ return ret;
+ seg->is_nullctx = 1;
ret = av_write_trailer(oc);
- close_null_ctxp(&oc->pb);
} else {
ret = segment_end(s, 1, 1);
}
-fail:
- if (seg->list)
- ff_format_io_close(s, &seg->list_pb);
-
- av_opt_free(seg);
-
- cur = seg->segment_list_entries;
- while (cur) {
- next = cur->next;
- av_freep(&cur->filename);
- av_free(cur);
- cur = next;
- }
-
- avformat_free_context(oc);
- seg->avf = NULL;
return ret;
}