Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | RSS feed

  1. /*
  2.  * Copyright (c) 2003 Fabrice Bellard
  3.  *
  4.  * Permission is hereby granted, free of charge, to any person obtaining a copy
  5.  * of this software and associated documentation files (the "Software"), to deal
  6.  * in the Software without restriction, including without limitation the rights
  7.  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  8.  * copies of the Software, and to permit persons to whom the Software is
  9.  * furnished to do so, subject to the following conditions:
  10.  *
  11.  * The above copyright notice and this permission notice shall be included in
  12.  * all copies or substantial portions of the Software.
  13.  *
  14.  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15.  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16.  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  17.  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  18.  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  19.  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  20.  * THE SOFTWARE.
  21.  */
  22.  
  23. /**
  24.  * @file
  25.  * libavformat API example.
  26.  *
  27.  * Output a media file in any supported libavformat format.
  28.  * The default codecs are used.
  29.  * @example doc/examples/muxing.c
  30.  */
  31.  
  32. #include <stdlib.h>
  33. #include <stdio.h>
  34. #include <string.h>
  35. #include <math.h>
  36.  
  37. #include <libavutil/opt.h>
  38. #include <libavutil/mathematics.h>
  39. #include <libavformat/avformat.h>
  40. #include <libswscale/swscale.h>
  41. #include <libswresample/swresample.h>
  42.  
  43. /* 5 seconds stream duration */
  44. #define STREAM_DURATION   200.0
  45. #define STREAM_FRAME_RATE 25 /* 25 images/s */
  46. #define STREAM_NB_FRAMES  ((int)(STREAM_DURATION * STREAM_FRAME_RATE))
  47. #define STREAM_PIX_FMT    AV_PIX_FMT_YUV420P /* default pix_fmt */
  48.  
  49. static int sws_flags = SWS_BICUBIC;
  50.  
  51. /* Add an output stream. */
  52. static AVStream *add_stream(AVFormatContext *oc, AVCodec **codec,
  53.                             enum AVCodecID codec_id)
  54. {
  55.     AVCodecContext *c;
  56.     AVStream *st;
  57.  
  58.     /* find the encoder */
  59.     *codec = avcodec_find_encoder(codec_id);
  60.     if (!(*codec)) {
  61.         fprintf(stderr, "Could not find encoder for '%s'\n",
  62.                 avcodec_get_name(codec_id));
  63.         exit(1);
  64.     }
  65.  
  66.     st = avformat_new_stream(oc, *codec);
  67.     if (!st) {
  68.         fprintf(stderr, "Could not allocate stream\n");
  69.         exit(1);
  70.     }
  71.     st->id = oc->nb_streams-1;
  72.     c = st->codec;
  73.  
  74.     switch ((*codec)->type) {
  75.     case AVMEDIA_TYPE_AUDIO:
  76.         c->sample_fmt  = AV_SAMPLE_FMT_FLTP;
  77.         c->bit_rate    = 64000;
  78.         c->sample_rate = 44100;
  79.         c->channels    = 2;
  80.         break;
  81.  
  82.     case AVMEDIA_TYPE_VIDEO:
  83.         c->codec_id = codec_id;
  84.  
  85.         c->bit_rate = 400000;
  86.         /* Resolution must be a multiple of two. */
  87.         c->width    = 352;
  88.         c->height   = 288;
  89.         /* timebase: This is the fundamental unit of time (in seconds) in terms
  90.          * of which frame timestamps are represented. For fixed-fps content,
  91.          * timebase should be 1/framerate and timestamp increments should be
  92.          * identical to 1. */
  93.         c->time_base.den = STREAM_FRAME_RATE;
  94.         c->time_base.num = 1;
  95.         c->gop_size      = 12; /* emit one intra frame every twelve frames at most */
  96.         c->pix_fmt       = STREAM_PIX_FMT;
  97.         if (c->codec_id == AV_CODEC_ID_MPEG2VIDEO) {
  98.             /* just for testing, we also add B frames */
  99.             c->max_b_frames = 2;
  100.         }
  101.         if (c->codec_id == AV_CODEC_ID_MPEG1VIDEO) {
  102.             /* Needed to avoid using macroblocks in which some coeffs overflow.
  103.              * This does not happen with normal video, it just happens here as
  104.              * the motion of the chroma plane does not match the luma plane. */
  105.             c->mb_decision = 2;
  106.         }
  107.     break;
  108.  
  109.     default:
  110.         break;
  111.     }
  112.  
  113.     /* Some formats want stream headers to be separate. */
  114.     if (oc->oformat->flags & AVFMT_GLOBALHEADER)
  115.         c->flags |= CODEC_FLAG_GLOBAL_HEADER;
  116.  
  117.     return st;
  118. }
  119.  
  120. /**************************************************************/
  121. /* audio output */
  122.  
  123. static float t, tincr, tincr2;
  124.  
  125. static uint8_t **src_samples_data;
  126. static int       src_samples_linesize;
  127. static int       src_nb_samples;
  128.  
  129. static int max_dst_nb_samples;
  130. uint8_t **dst_samples_data;
  131. int       dst_samples_linesize;
  132. int       dst_samples_size;
  133.  
  134. struct SwrContext *swr_ctx = NULL;
  135.  
  136. static void open_audio(AVFormatContext *oc, AVCodec *codec, AVStream *st)
  137. {
  138.     AVCodecContext *c;
  139.     int ret;
  140.  
  141.     c = st->codec;
  142.  
  143.     /* open it */
  144.     ret = avcodec_open2(c, codec, NULL);
  145.     if (ret < 0) {
  146.         fprintf(stderr, "Could not open audio codec: %s\n", av_err2str(ret));
  147.         exit(1);
  148.     }
  149.  
  150.     /* init signal generator */
  151.     t     = 0;
  152.     tincr = 2 * M_PI * 110.0 / c->sample_rate;
  153.     /* increment frequency by 110 Hz per second */
  154.     tincr2 = 2 * M_PI * 110.0 / c->sample_rate / c->sample_rate;
  155.  
  156.     src_nb_samples = c->codec->capabilities & CODEC_CAP_VARIABLE_FRAME_SIZE ?
  157.         10000 : c->frame_size;
  158.  
  159.     ret = av_samples_alloc_array_and_samples(&src_samples_data, &src_samples_linesize, c->channels,
  160.                                              src_nb_samples, c->sample_fmt, 0);
  161.     if (ret < 0) {
  162.         fprintf(stderr, "Could not allocate source samples\n");
  163.         exit(1);
  164.     }
  165.  
  166.     /* create resampler context */
  167.     if (c->sample_fmt != AV_SAMPLE_FMT_S16) {
  168.         swr_ctx = swr_alloc();
  169.         if (!swr_ctx) {
  170.             fprintf(stderr, "Could not allocate resampler context\n");
  171.             exit(1);
  172.         }
  173.  
  174.         /* set options */
  175.         av_opt_set_int       (swr_ctx, "in_channel_count",   c->channels,       0);
  176.         av_opt_set_int       (swr_ctx, "in_sample_rate",     c->sample_rate,    0);
  177.         av_opt_set_sample_fmt(swr_ctx, "in_sample_fmt",      AV_SAMPLE_FMT_S16, 0);
  178.         av_opt_set_int       (swr_ctx, "out_channel_count",  c->channels,       0);
  179.         av_opt_set_int       (swr_ctx, "out_sample_rate",    c->sample_rate,    0);
  180.         av_opt_set_sample_fmt(swr_ctx, "out_sample_fmt",     c->sample_fmt,     0);
  181.  
  182.         /* initialize the resampling context */
  183.         if ((ret = swr_init(swr_ctx)) < 0) {
  184.             fprintf(stderr, "Failed to initialize the resampling context\n");
  185.             exit(1);
  186.         }
  187.     }
  188.  
  189.     /* compute the number of converted samples: buffering is avoided
  190.      * ensuring that the output buffer will contain at least all the
  191.      * converted input samples */
  192.     max_dst_nb_samples = src_nb_samples;
  193.     ret = av_samples_alloc_array_and_samples(&dst_samples_data, &dst_samples_linesize, c->channels,
  194.                                              max_dst_nb_samples, c->sample_fmt, 0);
  195.     if (ret < 0) {
  196.         fprintf(stderr, "Could not allocate destination samples\n");
  197.         exit(1);
  198.     }
  199.     dst_samples_size = av_samples_get_buffer_size(NULL, c->channels, max_dst_nb_samples,
  200.                                                   c->sample_fmt, 0);
  201. }
  202.  
  203. /* Prepare a 16 bit dummy audio frame of 'frame_size' samples and
  204.  * 'nb_channels' channels. */
  205. static void get_audio_frame(int16_t *samples, int frame_size, int nb_channels)
  206. {
  207.     int j, i, v;
  208.     int16_t *q;
  209.  
  210.     q = samples;
  211.     for (j = 0; j < frame_size; j++) {
  212.         v = (int)(sin(t) * 10000);
  213.         for (i = 0; i < nb_channels; i++)
  214.             *q++ = v;
  215.         t     += tincr;
  216.         tincr += tincr2;
  217.     }
  218. }
  219.  
  220. static void write_audio_frame(AVFormatContext *oc, AVStream *st)
  221. {
  222.     AVCodecContext *c;
  223.     AVPacket pkt = { 0 }; // data and size must be 0;
  224.     AVFrame *frame = avcodec_alloc_frame();
  225.     int got_packet, ret, dst_nb_samples;
  226.  
  227.     av_init_packet(&pkt);
  228.     c = st->codec;
  229.  
  230.     get_audio_frame((int16_t *)src_samples_data[0], src_nb_samples, c->channels);
  231.  
  232.     /* convert samples from native format to destination codec format, using the resampler */
  233.     if (swr_ctx) {
  234.         /* compute destination number of samples */
  235.         dst_nb_samples = av_rescale_rnd(swr_get_delay(swr_ctx, c->sample_rate) + src_nb_samples,
  236.                                         c->sample_rate, c->sample_rate, AV_ROUND_UP);
  237.         if (dst_nb_samples > max_dst_nb_samples) {
  238.             av_free(dst_samples_data[0]);
  239.             ret = av_samples_alloc(dst_samples_data, &dst_samples_linesize, c->channels,
  240.                                    dst_nb_samples, c->sample_fmt, 0);
  241.             if (ret < 0)
  242.                 exit(1);
  243.             max_dst_nb_samples = dst_nb_samples;
  244.             dst_samples_size = av_samples_get_buffer_size(NULL, c->channels, dst_nb_samples,
  245.                                                           c->sample_fmt, 0);
  246.         }
  247.  
  248.         /* convert to destination format */
  249.         ret = swr_convert(swr_ctx,
  250.                           dst_samples_data, dst_nb_samples,
  251.                           (const uint8_t **)src_samples_data, src_nb_samples);
  252.         if (ret < 0) {
  253.             fprintf(stderr, "Error while converting\n");
  254.             exit(1);
  255.         }
  256.     } else {
  257.         dst_samples_data[0] = src_samples_data[0];
  258.         dst_nb_samples = src_nb_samples;
  259.     }
  260.  
  261.     frame->nb_samples = dst_nb_samples;
  262.     avcodec_fill_audio_frame(frame, c->channels, c->sample_fmt,
  263.                              dst_samples_data[0], dst_samples_size, 0);
  264.  
  265.     ret = avcodec_encode_audio2(c, &pkt, frame, &got_packet);
  266.     if (ret < 0) {
  267.         fprintf(stderr, "Error encoding audio frame: %s\n", av_err2str(ret));
  268.         exit(1);
  269.     }
  270.  
  271.     if (!got_packet)
  272.         return;
  273.  
  274.     pkt.stream_index = st->index;
  275.  
  276.     /* Write the compressed frame to the media file. */
  277.     ret = av_interleaved_write_frame(oc, &pkt);
  278.     if (ret != 0) {
  279.         fprintf(stderr, "Error while writing audio frame: %s\n",
  280.                 av_err2str(ret));
  281.         exit(1);
  282.     }
  283.     avcodec_free_frame(&frame);
  284. }
  285.  
  286. static void close_audio(AVFormatContext *oc, AVStream *st)
  287. {
  288.     avcodec_close(st->codec);
  289.     av_free(src_samples_data[0]);
  290.     av_free(dst_samples_data[0]);
  291. }
  292.  
  293. /**************************************************************/
  294. /* video output */
  295.  
  296. static AVFrame *frame;
  297. static AVPicture src_picture, dst_picture;
  298. static int frame_count;
  299.  
  300. static void open_video(AVFormatContext *oc, AVCodec *codec, AVStream *st)
  301. {
  302.     int ret;
  303.     AVCodecContext *c = st->codec;
  304.  
  305.     /* open the codec */
  306.     ret = avcodec_open2(c, codec, NULL);
  307.     if (ret < 0) {
  308.         fprintf(stderr, "Could not open video codec: %s\n", av_err2str(ret));
  309.         exit(1);
  310.     }
  311.  
  312.     /* allocate and init a re-usable frame */
  313.     frame = avcodec_alloc_frame();
  314.     if (!frame) {
  315.         fprintf(stderr, "Could not allocate video frame\n");
  316.         exit(1);
  317.     }
  318.  
  319.     /* Allocate the encoded raw picture. */
  320.     ret = avpicture_alloc(&dst_picture, c->pix_fmt, c->width, c->height);
  321.     if (ret < 0) {
  322.         fprintf(stderr, "Could not allocate picture: %s\n", av_err2str(ret));
  323.         exit(1);
  324.     }
  325.  
  326.     /* If the output format is not YUV420P, then a temporary YUV420P
  327.      * picture is needed too. It is then converted to the required
  328.      * output format. */
  329.     if (c->pix_fmt != AV_PIX_FMT_YUV420P) {
  330.         ret = avpicture_alloc(&src_picture, AV_PIX_FMT_YUV420P, c->width, c->height);
  331.         if (ret < 0) {
  332.             fprintf(stderr, "Could not allocate temporary picture: %s\n",
  333.                     av_err2str(ret));
  334.             exit(1);
  335.         }
  336.     }
  337.  
  338.     /* copy data and linesize picture pointers to frame */
  339.     *((AVPicture *)frame) = dst_picture;
  340. }
  341.  
  342. /* Prepare a dummy image. */
  343. static void fill_yuv_image(AVPicture *pict, int frame_index,
  344.                            int width, int height)
  345. {
  346.     int x, y, i;
  347.  
  348.     i = frame_index;
  349.  
  350.     /* Y */
  351.     for (y = 0; y < height; y++)
  352.         for (x = 0; x < width; x++)
  353.             pict->data[0][y * pict->linesize[0] + x] = x + y + i * 3;
  354.  
  355.     /* Cb and Cr */
  356.     for (y = 0; y < height / 2; y++) {
  357.         for (x = 0; x < width / 2; x++) {
  358.             pict->data[1][y * pict->linesize[1] + x] = 128 + y + i * 2;
  359.             pict->data[2][y * pict->linesize[2] + x] = 64 + x + i * 5;
  360.         }
  361.     }
  362. }
  363.  
  364. static void write_video_frame(AVFormatContext *oc, AVStream *st)
  365. {
  366.     int ret;
  367.     static struct SwsContext *sws_ctx;
  368.     AVCodecContext *c = st->codec;
  369.  
  370.     if (frame_count >= STREAM_NB_FRAMES) {
  371.         /* No more frames to compress. The codec has a latency of a few
  372.          * frames if using B-frames, so we get the last frames by
  373.          * passing the same picture again. */
  374.     } else {
  375.         if (c->pix_fmt != AV_PIX_FMT_YUV420P) {
  376.             /* as we only generate a YUV420P picture, we must convert it
  377.              * to the codec pixel format if needed */
  378.             if (!sws_ctx) {
  379.                 sws_ctx = sws_getContext(c->width, c->height, AV_PIX_FMT_YUV420P,
  380.                                          c->width, c->height, c->pix_fmt,
  381.                                          sws_flags, NULL, NULL, NULL);
  382.                 if (!sws_ctx) {
  383.                     fprintf(stderr,
  384.                             "Could not initialize the conversion context\n");
  385.                     exit(1);
  386.                 }
  387.             }
  388.             fill_yuv_image(&src_picture, frame_count, c->width, c->height);
  389.             sws_scale(sws_ctx,
  390.                       (const uint8_t * const *)src_picture.data, src_picture.linesize,
  391.                       0, c->height, dst_picture.data, dst_picture.linesize);
  392.         } else {
  393.             fill_yuv_image(&dst_picture, frame_count, c->width, c->height);
  394.         }
  395.     }
  396.  
  397.     if (oc->oformat->flags & AVFMT_RAWPICTURE) {
  398.         /* Raw video case - directly store the picture in the packet */
  399.         AVPacket pkt;
  400.         av_init_packet(&pkt);
  401.  
  402.         pkt.flags        |= AV_PKT_FLAG_KEY;
  403.         pkt.stream_index  = st->index;
  404.         pkt.data          = dst_picture.data[0];
  405.         pkt.size          = sizeof(AVPicture);
  406.  
  407.         ret = av_interleaved_write_frame(oc, &pkt);
  408.     } else {
  409.         AVPacket pkt = { 0 };
  410.         int got_packet;
  411.         av_init_packet(&pkt);
  412.  
  413.         /* encode the image */
  414.         ret = avcodec_encode_video2(c, &pkt, frame, &got_packet);
  415.         if (ret < 0) {
  416.             fprintf(stderr, "Error encoding video frame: %s\n", av_err2str(ret));
  417.             exit(1);
  418.         }
  419.         /* If size is zero, it means the image was buffered. */
  420.  
  421.         if (!ret && got_packet && pkt.size) {
  422.             pkt.stream_index = st->index;
  423.  
  424.             /* Write the compressed frame to the media file. */
  425.             ret = av_interleaved_write_frame(oc, &pkt);
  426.         } else {
  427.             ret = 0;
  428.         }
  429.     }
  430.     if (ret != 0) {
  431.         fprintf(stderr, "Error while writing video frame: %s\n", av_err2str(ret));
  432.         exit(1);
  433.     }
  434.     frame_count++;
  435. }
  436.  
  437. static void close_video(AVFormatContext *oc, AVStream *st)
  438. {
  439.     avcodec_close(st->codec);
  440.     av_free(src_picture.data[0]);
  441.     av_free(dst_picture.data[0]);
  442.     av_free(frame);
  443. }
  444.  
  445. /**************************************************************/
  446. /* media file output */
  447.  
  448. int main(int argc, char **argv)
  449. {
  450.     const char *filename;
  451.     AVOutputFormat *fmt;
  452.     AVFormatContext *oc;
  453.     AVStream *audio_st, *video_st;
  454.     AVCodec *audio_codec, *video_codec;
  455.     double audio_time, video_time;
  456.     int ret;
  457.  
  458.     /* Initialize libavcodec, and register all codecs and formats. */
  459.     av_register_all();
  460.  
  461.     if (argc != 2) {
  462.         printf("usage: %s output_file\n"
  463.                "API example program to output a media file with libavformat.\n"
  464.                "This program generates a synthetic audio and video stream, encodes and\n"
  465.                "muxes them into a file named output_file.\n"
  466.                "The output format is automatically guessed according to the file extension.\n"
  467.                "Raw images can also be output by using '%%d' in the filename.\n"
  468.                "\n", argv[0]);
  469.         return 1;
  470.     }
  471.  
  472.     filename = argv[1];
  473.  
  474.     /* allocate the output media context */
  475.     avformat_alloc_output_context2(&oc, NULL, NULL, filename);
  476.     if (!oc) {
  477.         printf("Could not deduce output format from file extension: using MPEG.\n");
  478.         avformat_alloc_output_context2(&oc, NULL, "mpeg", filename);
  479.     }
  480.     if (!oc) {
  481.         return 1;
  482.     }
  483.     fmt = oc->oformat;
  484.  
  485.     /* Add the audio and video streams using the default format codecs
  486.      * and initialize the codecs. */
  487.     video_st = NULL;
  488.     audio_st = NULL;
  489.  
  490.     if (fmt->video_codec != AV_CODEC_ID_NONE) {
  491.         video_st = add_stream(oc, &video_codec, fmt->video_codec);
  492.     }
  493.     if (fmt->audio_codec != AV_CODEC_ID_NONE) {
  494.         audio_st = add_stream(oc, &audio_codec, fmt->audio_codec);
  495.     }
  496.  
  497.     /* Now that all the parameters are set, we can open the audio and
  498.      * video codecs and allocate the necessary encode buffers. */
  499.     if (video_st)
  500.         open_video(oc, video_codec, video_st);
  501.     if (audio_st)
  502.         open_audio(oc, audio_codec, audio_st);
  503.  
  504.     av_dump_format(oc, 0, filename, 1);
  505.  
  506.     /* open the output file, if needed */
  507.     if (!(fmt->flags & AVFMT_NOFILE)) {
  508.         ret = avio_open(&oc->pb, filename, AVIO_FLAG_WRITE);
  509.         if (ret < 0) {
  510.             fprintf(stderr, "Could not open '%s': %s\n", filename,
  511.                     av_err2str(ret));
  512.             return 1;
  513.         }
  514.     }
  515.  
  516.     /* Write the stream header, if any. */
  517.     ret = avformat_write_header(oc, NULL);
  518.     if (ret < 0) {
  519.         fprintf(stderr, "Error occurred when opening output file: %s\n",
  520.                 av_err2str(ret));
  521.         return 1;
  522.     }
  523.  
  524.     if (frame)
  525.         frame->pts = 0;
  526.     for (;;) {
  527.         /* Compute current audio and video time. */
  528.         audio_time = audio_st ? audio_st->pts.val * av_q2d(audio_st->time_base) : 0.0;
  529.         video_time = video_st ? video_st->pts.val * av_q2d(video_st->time_base) : 0.0;
  530.  
  531.         if ((!audio_st || audio_time >= STREAM_DURATION) &&
  532.             (!video_st || video_time >= STREAM_DURATION))
  533.             break;
  534.  
  535.         /* write interleaved audio and video frames */
  536.         if (!video_st || (video_st && audio_st && audio_time < video_time)) {
  537.             write_audio_frame(oc, audio_st);
  538.         } else {
  539.             write_video_frame(oc, video_st);
  540.             frame->pts += av_rescale_q(1, video_st->codec->time_base, video_st->time_base);
  541.         }
  542.     }
  543.  
  544.     /* Write the trailer, if any. The trailer must be written before you
  545.      * close the CodecContexts open when you wrote the header; otherwise
  546.      * av_write_trailer() may try to use memory that was freed on
  547.      * av_codec_close(). */
  548.     av_write_trailer(oc);
  549.  
  550.     /* Close each codec. */
  551.     if (video_st)
  552.         close_video(oc, video_st);
  553.     if (audio_st)
  554.         close_audio(oc, audio_st);
  555.  
  556.     if (!(fmt->flags & AVFMT_NOFILE))
  557.         /* Close the output file. */
  558.         avio_close(oc->pb);
  559.  
  560.     /* free the stream */
  561.     avformat_free_context(oc);
  562.  
  563.     return 0;
  564. }
  565.