]> git.sesse.net Git - ffmpeg/blobdiff - libavformat/smoothstreamingenc.c
vc1: Split bits used in libavformat into a separate header
[ffmpeg] / libavformat / smoothstreamingenc.c
index cc34f7eb4f02ffd311fbe815f4c8ce418759b2a2..457472dc83145d28f6d06906d38a7087f4706cc8 100644 (file)
@@ -51,7 +51,7 @@ typedef struct {
     char dirname[1024];
     uint8_t iobuf[32768];
     URLContext *out;  // Current output stream where all output is written
-    URLContext *out2; // Auxillary output stream where all output also is written
+    URLContext *out2; // Auxiliary output stream where all output is also written
     URLContext *tail_out; // The actual main output stream, if we're currently seeked back to write elsewhere
     int64_t tail_pos, cur_pos, cur_start_pos;
     int packets_written;
@@ -154,8 +154,11 @@ static void get_private_data(OutputStream *os)
     if (!ptr)
         return;
     os->private_str = av_mallocz(2*size + 1);
+    if (!os->private_str)
+        goto fail;
     for (i = 0; i < size; i++)
         snprintf(&os->private_str[2*i], 3, "%02x", ptr[i]);
+fail:
     if (ptr != codec->extradata)
         av_free(ptr);
 }
@@ -210,14 +213,17 @@ static int write_manifest(AVFormatContext *s, int final)
 {
     SmoothStreamingContext *c = s->priv_data;
     AVIOContext *out;
-    char filename[1024];
+    char filename[1024], temp_filename[1024];
     int ret, i, video_chunks = 0, audio_chunks = 0, video_streams = 0, audio_streams = 0;
     int64_t duration = 0;
 
     snprintf(filename, sizeof(filename), "%s/Manifest", s->filename);
-    ret = avio_open2(&out, filename, AVIO_FLAG_WRITE, &s->interrupt_callback, NULL);
-    if (ret < 0)
+    snprintf(temp_filename, sizeof(temp_filename), "%s/Manifest.tmp", s->filename);
+    ret = avio_open2(&out, temp_filename, AVIO_FLAG_WRITE, &s->interrupt_callback, NULL);
+    if (ret < 0) {
+        av_log(s, AV_LOG_ERROR, "Unable to open %s for writing\n", temp_filename);
         return ret;
+    }
     avio_printf(out, "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n");
     for (i = 0; i < s->nb_streams; i++) {
         OutputStream *os = &c->streams[i];
@@ -276,6 +282,7 @@ static int write_manifest(AVFormatContext *s, int final)
     avio_printf(out, "</SmoothStreamingMedia>\n");
     avio_flush(out);
     avio_close(out);
+    rename(temp_filename, filename);
     return 0;
 }
 
@@ -285,12 +292,7 @@ static int ism_write_header(AVFormatContext *s)
     int ret = 0, i;
     AVOutputFormat *oformat;
 
-    ret = mkdir(s->filename, 0777);
-    if (ret) {
-        av_log(s, AV_LOG_ERROR, "mkdir(%s): %s\n", s->filename, strerror(errno));
-        return AVERROR(errno);
-    }
-    ret = 0;
+    mkdir(s->filename, 0777);
 
     oformat = av_guess_format("ismv", NULL, NULL);
     if (!oformat) {
@@ -386,6 +388,7 @@ static int ism_write_header(AVFormatContext *s)
         av_log(s, AV_LOG_WARNING, "no video stream and no min frag duration set\n");
         ret = AVERROR(EINVAL);
     }
+    ret = write_manifest(s, 0);
 
 fail:
     if (ret)
@@ -445,12 +448,16 @@ fail:
 
 static int add_fragment(OutputStream *os, const char *file, const char *infofile, int64_t start_time, int64_t duration, int64_t start_pos, int64_t size)
 {
+    int err;
     Fragment *frag;
     if (os->nb_fragments >= os->fragments_size) {
         os->fragments_size = (os->fragments_size + 1) * 2;
-        os->fragments = av_realloc(os->fragments, sizeof(*os->fragments)*os->fragments_size);
-        if (!os->fragments)
-            return AVERROR(ENOMEM);
+        if ((err = av_reallocp(&os->fragments, sizeof(*os->fragments) *
+                               os->fragments_size)) < 0) {
+            os->fragments_size = 0;
+            os->nb_fragments = 0;
+            return err;
+        }
     }
     frag = av_mallocz(sizeof(*frag));
     if (!frag)
@@ -561,12 +568,15 @@ static int ism_write_packet(AVFormatContext *s, AVPacket *pkt)
     SmoothStreamingContext *c = s->priv_data;
     AVStream *st = s->streams[pkt->stream_index];
     OutputStream *os = &c->streams[pkt->stream_index];
-    int64_t end_pts = (c->nb_fragments + 1) * c->min_frag_duration;
+    int64_t end_dts = (c->nb_fragments + 1) * c->min_frag_duration;
     int ret;
 
+    if (st->first_dts == AV_NOPTS_VALUE)
+        st->first_dts = pkt->dts;
+
     if ((!c->has_video || st->codec->codec_type == AVMEDIA_TYPE_VIDEO) &&
-        av_compare_ts(pkt->pts, st->time_base,
-                      end_pts, AV_TIME_BASE_Q) >= 0 &&
+        av_compare_ts(pkt->dts - st->first_dts, st->time_base,
+                      end_dts, AV_TIME_BASE_Q) >= 0 &&
         pkt->flags & AV_PKT_FLAG_KEY && os->packets_written) {
 
         if ((ret = ism_flush(s, 0)) < 0)