]> git.sesse.net Git - ffmpeg/blobdiff - libavformat/output-example.c
aiffdec: use av_get_audio_frame_duration() to set block_duration for AIFF-C
[ffmpeg] / libavformat / output-example.c
index 06207eddfcd53240bf7b41014c6e4f5614575bef..86324b48420d860229e22585e8951bbe244ecba9 100644 (file)
@@ -1,7 +1,4 @@
 /*
- * Libavformat API example: Output a media file in any supported
- * libavformat format. The default codecs are used.
- *
  * Copyright (c) 2003 Fabrice Bellard
  *
  * Permission is hereby granted, free of charge, to any person obtaining a copy
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  * THE SOFTWARE.
  */
+
+/**
+ * @file
+ * libavformat API example.
+ *
+ * @example libavformat/output-example.c
+ * Output a media file in any supported libavformat format.
+ * The default codecs are used.
+ */
+
 #include <stdlib.h>
 #include <stdio.h>
 #include <string.h>
 #include <math.h>
 
+#include "libavutil/mathematics.h"
 #include "libavformat/avformat.h"
 #include "libswscale/swscale.h"
 
@@ -43,11 +51,9 @@ static int sws_flags = SWS_BICUBIC;
 /**************************************************************/
 /* audio output */
 
-float t, tincr, tincr2;
-int16_t *samples;
-uint8_t *audio_outbuf;
-int audio_outbuf_size;
-int audio_input_frame_size;
+static float t, tincr, tincr2;
+static int16_t *samples;
+static int audio_input_frame_size;
 
 /*
  * add an audio output stream
@@ -56,16 +62,22 @@ static AVStream *add_audio_stream(AVFormatContext *oc, enum CodecID codec_id)
 {
     AVCodecContext *c;
     AVStream *st;
+    AVCodec *codec;
+
+    /* find the audio encoder */
+    codec = avcodec_find_encoder(codec_id);
+    if (!codec) {
+        fprintf(stderr, "codec not found\n");
+        exit(1);
+    }
 
-    st = av_new_stream(oc, 1);
+    st = avformat_new_stream(oc, codec);
     if (!st) {
         fprintf(stderr, "Could not alloc stream\n");
         exit(1);
     }
 
     c = st->codec;
-    c->codec_id = codec_id;
-    c->codec_type = AVMEDIA_TYPE_AUDIO;
 
     /* put sample parameters */
     c->sample_fmt = AV_SAMPLE_FMT_S16;
@@ -83,19 +95,11 @@ static AVStream *add_audio_stream(AVFormatContext *oc, enum CodecID codec_id)
 static void open_audio(AVFormatContext *oc, AVStream *st)
 {
     AVCodecContext *c;
-    AVCodec *codec;
 
     c = st->codec;
 
-    /* find the audio encoder */
-    codec = avcodec_find_encoder(c->codec_id);
-    if (!codec) {
-        fprintf(stderr, "codec not found\n");
-        exit(1);
-    }
-
     /* open it */
-    if (avcodec_open(c, codec) < 0) {
+    if (avcodec_open2(c, NULL, NULL) < 0) {
         fprintf(stderr, "could not open codec\n");
         exit(1);
     }
@@ -106,27 +110,12 @@ static void open_audio(AVFormatContext *oc, AVStream *st)
     /* increment frequency by 110 Hz per second */
     tincr2 = 2 * M_PI * 110.0 / c->sample_rate / c->sample_rate;
 
-    audio_outbuf_size = 10000;
-    audio_outbuf = av_malloc(audio_outbuf_size);
-
-    /* ugly hack for PCM codecs (will be removed ASAP with new PCM
-       support to compute the input frame size in samples */
-    if (c->frame_size <= 1) {
-        audio_input_frame_size = audio_outbuf_size / c->channels;
-        switch(st->codec->codec_id) {
-        case CODEC_ID_PCM_S16LE:
-        case CODEC_ID_PCM_S16BE:
-        case CODEC_ID_PCM_U16LE:
-        case CODEC_ID_PCM_U16BE:
-            audio_input_frame_size >>= 1;
-            break;
-        default:
-            break;
-        }
-    } else {
+    if (c->codec->capabilities & CODEC_CAP_VARIABLE_FRAME_SIZE)
+        audio_input_frame_size = 10000;
+    else
         audio_input_frame_size = c->frame_size;
-    }
-    samples = av_malloc(audio_input_frame_size * 2 * c->channels);
+    samples = av_malloc(audio_input_frame_size * av_get_bytes_per_sample(c->sample_fmt)
+                        * c->channels);
 }
 
 /* prepare a 16 bit dummy audio frame of 'frame_size' samples and
@@ -150,19 +139,23 @@ static void write_audio_frame(AVFormatContext *oc, AVStream *st)
 {
     AVCodecContext *c;
     AVPacket pkt;
-    av_init_packet(&pkt);
+    AVFrame *frame = avcodec_alloc_frame();
+    int got_packet;
 
+    av_init_packet(&pkt);
     c = st->codec;
 
     get_audio_frame(samples, audio_input_frame_size, c->channels);
+    frame->nb_samples = audio_input_frame_size;
+    avcodec_fill_audio_frame(frame, c->channels, c->sample_fmt, (uint8_t *)samples,
+                             audio_input_frame_size * av_get_bytes_per_sample(c->sample_fmt)
+                             * c->channels, 1);
 
-    pkt.size= avcodec_encode_audio(c, audio_outbuf, audio_outbuf_size, samples);
+    avcodec_encode_audio2(c, &pkt, frame, &got_packet);
+    if (!got_packet)
+        return;
 
-    if (c->coded_frame && c->coded_frame->pts != AV_NOPTS_VALUE)
-        pkt.pts= av_rescale_q(c->coded_frame->pts, c->time_base, st->time_base);
-    pkt.flags |= AV_PKT_FLAG_KEY;
     pkt.stream_index= st->index;
-    pkt.data= audio_outbuf;
 
     /* write the compressed frame in the media file */
     if (av_interleaved_write_frame(oc, &pkt) != 0) {
@@ -176,31 +169,36 @@ static void close_audio(AVFormatContext *oc, AVStream *st)
     avcodec_close(st->codec);
 
     av_free(samples);
-    av_free(audio_outbuf);
 }
 
 /**************************************************************/
 /* video output */
 
-AVFrame *picture, *tmp_picture;
-uint8_t *video_outbuf;
-int frame_count, video_outbuf_size;
+static AVFrame *picture, *tmp_picture;
+static uint8_t *video_outbuf;
+static int frame_count, video_outbuf_size;
 
 /* add a video output stream */
 static AVStream *add_video_stream(AVFormatContext *oc, enum CodecID codec_id)
 {
     AVCodecContext *c;
     AVStream *st;
+    AVCodec *codec;
+
+    /* find the video encoder */
+    codec = avcodec_find_encoder(codec_id);
+    if (!codec) {
+        fprintf(stderr, "codec not found\n");
+        exit(1);
+    }
 
-    st = av_new_stream(oc, 0);
+    st = avformat_new_stream(oc, codec);
     if (!st) {
         fprintf(stderr, "Could not alloc stream\n");
         exit(1);
     }
 
     c = st->codec;
-    c->codec_id = codec_id;
-    c->codec_type = AVMEDIA_TYPE_VIDEO;
 
     /* put sample parameters */
     c->bit_rate = 400000;
@@ -254,20 +252,12 @@ static AVFrame *alloc_picture(enum PixelFormat pix_fmt, int width, int height)
 
 static void open_video(AVFormatContext *oc, AVStream *st)
 {
-    AVCodec *codec;
     AVCodecContext *c;
 
     c = st->codec;
 
-    /* find the video encoder */
-    codec = avcodec_find_encoder(c->codec_id);
-    if (!codec) {
-        fprintf(stderr, "codec not found\n");
-        exit(1);
-    }
-
     /* open the codec */
-    if (avcodec_open(c, codec) < 0) {
+    if (avcodec_open2(c, NULL, NULL) < 0) {
         fprintf(stderr, "could not open codec\n");
         exit(1);
     }
@@ -437,7 +427,7 @@ int main(int argc, char **argv)
                "The output format is automatically guessed according to the file extension.\n"
                "Raw images can also be output by using '%%d' in the filename\n"
                "\n", argv[0]);
-        exit(1);
+        return 1;
     }
 
     filename = argv[1];
@@ -451,14 +441,14 @@ int main(int argc, char **argv)
     }
     if (!fmt) {
         fprintf(stderr, "Could not find suitable output format\n");
-        exit(1);
+        return 1;
     }
 
     /* allocate the output media context */
     oc = avformat_alloc_context();
     if (!oc) {
         fprintf(stderr, "Memory error\n");
-        exit(1);
+        return 1;
     }
     oc->oformat = fmt;
     snprintf(oc->filename, sizeof(oc->filename), "%s", filename);
@@ -474,14 +464,7 @@ int main(int argc, char **argv)
         audio_st = add_audio_stream(oc, fmt->audio_codec);
     }
 
-    /* set the output parameters (must be done even if no
-       parameters). */
-    if (av_set_parameters(oc, NULL) < 0) {
-        fprintf(stderr, "Invalid output format parameters\n");
-        exit(1);
-    }
-
-    dump_format(oc, 0, filename, 1);
+    av_dump_format(oc, 0, filename, 1);
 
     /* now that all the parameters are set, we can open the audio and
        video codecs and allocate the necessary encode buffers */
@@ -492,14 +475,14 @@ int main(int argc, char **argv)
 
     /* open the output file, if needed */
     if (!(fmt->flags & AVFMT_NOFILE)) {
-        if (url_fopen(&oc->pb, filename, URL_WRONLY) < 0) {
+        if (avio_open(&oc->pb, filename, AVIO_FLAG_WRITE) < 0) {
             fprintf(stderr, "Could not open '%s'\n", filename);
-            exit(1);
+            return 1;
         }
     }
 
     /* write the stream header, if any */
-    av_write_header(oc);
+    avformat_write_header(oc, NULL);
 
     for(;;) {
         /* compute current audio and video time */
@@ -545,7 +528,7 @@ int main(int argc, char **argv)
 
     if (!(fmt->flags & AVFMT_NOFILE)) {
         /* close the output file */
-        url_fclose(oc->pb);
+        avio_close(oc->pb);
     }
 
     /* free the stream */