Advertisement
Guest User

AVI MP3 muxing creates short audio (200 frames short)

a guest
Apr 8th, 2014
265
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 23.15 KB | None | 0 0
  1.  
  2.  
  3. #define __STDC_FORMAT_MACROS
  4. #define __STDC_LIMIT_MACROS
  5. #include <inttypes.h>
  6.  
  7. #include <cstdio>
  8.  
  9. #ifdef _WIN32
  10. #define snprintf _snprintf
  11. #endif
  12.  
  13. extern "C" {
  14. #include <libavutil/audioconvert.h>
  15. #include <libavutil/mathematics.h>
  16. #include <libavutil/timestamp.h>
  17. #include <libavutil/pixdesc.h>
  18. #include <libavutil/time.h>
  19. #include <libavutil/opt.h>
  20. #include <libswresample/swresample.h>
  21. }
  22.  
  23. #include "core/aviImage.h"
  24. #include "gui/mrvIO.h"
  25. #include "core/mrvFrameFunctors.h"
  26. #include "core/mrvColorSpaces.h"
  27.  
  28. #define mrv_err2str(buf, errnum) \
  29.     av_make_error_string(buf, AV_ERROR_MAX_STRING_SIZE, errnum)
  30.  
  31. namespace {
  32. const char* kModule = "save";
  33. }
  34.  
  35. #define IMG_ERROR(x) LOG_ERROR( name() << " - " << x )
  36. #define IMG_WARNING(x) LOG_WARNING( name() << " - " << x )
  37. #define LOG(x) std::cerr << x << std::endl;
  38.  
  39. namespace mrv {
  40.  
  41.  
  42. int video_is_eof = 0;
  43. int audio_is_eof = 0;
  44. static AVFrame *picture = NULL;
  45. static AVPicture src_picture, dst_picture;
  46. static int frame_count = 0, video_outbuf_size;
  47.  
  48. static void log_packet(const AVFormatContext *fmt_ctx, const AVPacket *pkt)
  49. {
  50.     AVRational *time_base = &fmt_ctx->streams[pkt->stream_index]->time_base;
  51.  
  52.     char buf[AV_TS_MAX_STRING_SIZE];
  53.     char buf2[AV_TS_MAX_STRING_SIZE];
  54.  
  55.     printf("pts:%s pts_time:%s ",
  56.            av_ts_make_string(buf, pkt->pts),
  57.            av_ts_make_time_string(buf2, pkt->pts, time_base) );
  58.  
  59.     printf( "dts:%s dts_time:%s ",
  60.             av_ts_make_string(buf, pkt->dts),
  61.             av_ts_make_time_string(buf2, pkt->dts, time_base) );
  62.  
  63.     printf( "duration:%s duration_time:%s stream_index:%d\n",
  64.             av_ts_make_string(buf, pkt->duration),
  65.             av_ts_make_time_string(buf2, pkt->duration, time_base),
  66.             pkt->stream_index);
  67. }
  68.  
  69. static int write_frame(AVFormatContext *fmt_ctx, const AVRational *time_base, AVStream *st, AVPacket *pkt)
  70. {
  71.     /* rescale output packet timestamp values from codec to stream timebase */
  72.    pkt->pts = av_rescale_q_rnd(pkt->pts, *time_base, st->time_base,
  73.                                AVRounding( AV_ROUND_NEAR_INF|AV_ROUND_PASS_MINMAX ) );
  74.    pkt->dts = av_rescale_q_rnd(pkt->dts, *time_base, st->time_base,
  75.                                AVRounding( AV_ROUND_NEAR_INF|AV_ROUND_PASS_MINMAX ) );
  76.    pkt->duration = av_rescale_q(pkt->duration, *time_base, st->time_base);
  77.    pkt->stream_index = st->index;
  78.    
  79.    /* Write the compressed frame to the media file. */
  80.    log_packet(fmt_ctx, pkt);
  81.    return av_interleaved_write_frame(fmt_ctx, pkt);
  82. }
  83.  
  84. /* Add an output stream. */
  85. static AVStream *add_stream(AVFormatContext *oc, AVCodec **codec,
  86.                             enum AVCodecID codec_id, const CMedia* const img )
  87. {
  88.     AVCodecContext *c;
  89.     AVStream *st;
  90.  
  91.     /* find the encoder */
  92.     *codec = avcodec_find_encoder(codec_id);
  93.     if (!(*codec)) {
  94.        LOG_ERROR( "Could not find encoder for '" <<
  95.                   avcodec_get_name(codec_id) << "'" );
  96.        return NULL;
  97.     }
  98.  
  99.  
  100.     LOG_INFO( "Open encoder " << avcodec_get_name(codec_id) );
  101.  
  102.     st = avformat_new_stream(oc, *codec);
  103.     if (!st) {
  104.         fprintf(stderr, "Could not allocate stream\n");
  105.         return NULL;
  106.     }
  107.     st->id = oc->nb_streams-1;
  108.     c = st->codec;
  109.     c->codec_id = codec_id;
  110.  
  111.     switch ((*codec)->type) {
  112.        case AVMEDIA_TYPE_AUDIO:
  113.           c->strict_std_compliance = FF_COMPLIANCE_EXPERIMENTAL;
  114.           c->sample_fmt  = (*codec)->sample_fmts ?
  115.                            (*codec)->sample_fmts[0] : AV_SAMPLE_FMT_FLTP;
  116.           c->bit_rate    = 64000;
  117.           c->sample_rate = img->audio_frequency();
  118.           c->channels    = img->audio_channels();
  119.           c->time_base.num = 1;
  120.           c->time_base.den = c->sample_rate;
  121.           if (( codec_id == AV_CODEC_ID_MP3 ) || (codec_id == AV_CODEC_ID_AC3))
  122.              c->block_align = 0;
  123.           break;
  124.  
  125.        case AVMEDIA_TYPE_VIDEO:
  126.  
  127.           c->bit_rate = img->width() * img->height() * 3;
  128.           /* Resolution must be a multiple of two. */
  129.           c->width    = ( img->width() + 1 ) / 2 * 2;
  130.           c->height   = ( img->height() + 1 ) / 2 * 2;
  131.           /* timebase: This is the fundamental unit of time (in seconds) in terms
  132.            * of which frame timestamps are represented. For fixed-fps content,
  133.            * timebase should be 1/framerate and timestamp increments should be
  134.            * identical to 1. */
  135.           //c->time_base.den = img->fps();
  136.           //c->time_base.num = 1;
  137.           c->time_base.den = 1000 * (double) img->fps();
  138.           c->time_base.num = 1000;
  139.           c->gop_size      = 12; /* emit one intra frame every twelve frames at most */
  140.           c->pix_fmt       = AV_PIX_FMT_YUV420P;
  141.           if (c->codec_id == AV_CODEC_ID_MPEG2VIDEO) {
  142.              /* just for testing, we also add B frames */
  143.              c->max_b_frames = 2;
  144.           }
  145.           if (c->codec_id == AV_CODEC_ID_MPEG1VIDEO) {
  146.              /* Needed to avoid using macroblocks in which some coeffs overflow.
  147.               * This does not happen with normal video, it just happens here as
  148.               * the motion of the chroma plane does not match the luma plane. */
  149.              c->mb_decision = 2;
  150.           }
  151.           break;
  152.          
  153.     default:
  154.         break;
  155.     }
  156.  
  157.     /* Some formats want stream headers to be separate. */
  158.     if (oc->oformat->flags & AVFMT_GLOBALHEADER)
  159.         c->flags |= CODEC_FLAG_GLOBAL_HEADER;
  160.  
  161.     return st;
  162. }
  163.  
  164. /**************************************************************/
  165. /* audio output */
  166.  
  167. AVSampleFormat aformat;
  168. AVFrame* audio_frame;
  169. static uint8_t **src_samples_data = NULL;
  170. static int       src_samples_linesize;
  171. static int       src_nb_samples;
  172. static unsigned  src_samples_size;
  173.  
  174. static int max_dst_nb_samples;
  175. uint8_t **dst_samples_data = NULL;
  176. int       dst_samples_linesize;
  177. int       dst_samples_size;
  178. int       samples_count;
  179.  
  180. struct SwrContext *swr_ctx = NULL;
  181.  
  182. static bool open_audio_static(AVFormatContext *oc, AVCodec* codec,
  183.                   AVStream* st, const CMedia* img )
  184.  
  185. {
  186.     AVCodecContext* c = st->codec;
  187.  
  188.     /* allocate and init a re-usable frame */
  189.     audio_frame = av_frame_alloc();
  190.     if (!audio_frame) {
  191.         LOG_ERROR( "Could not allocate audio frame");
  192.         return false;
  193.     }
  194.  
  195.  
  196.    /* open it */
  197.     if (avcodec_open2(c, codec, NULL) < 0) {
  198.        LOG_ERROR( _("Could not open audio codec" ) );
  199.        return false;
  200.     }
  201.    
  202.     if (c->codec->capabilities & CODEC_CAP_VARIABLE_FRAME_SIZE)
  203.     {
  204.        src_nb_samples = 10000;
  205.     }
  206.     else
  207.     {
  208.         src_nb_samples = c->frame_size;
  209.     }
  210.  
  211.  
  212.     aformat = AudioEngine::ffmpeg_format( img->audio_format() );
  213.  
  214.     if ( aformat != c->sample_fmt )
  215.     {
  216.  
  217.         /* set options */
  218.        swr_ctx  = swr_alloc();
  219.        if ( swr_ctx == NULL )
  220.        {
  221.       LOG_ERROR( "Could not alloc swr_ctx" );
  222.       return false;
  223.        }
  224.  
  225.        ;
  226.  
  227.         av_opt_set_int       (swr_ctx, "in_channel_layout",
  228.                               av_get_default_channel_layout(c->channels), 0);
  229.         av_opt_set_int       (swr_ctx, "in_channel_count",   c->channels, 0);
  230.         av_opt_set_int       (swr_ctx, "in_sample_rate",     c->sample_rate, 0);
  231.         av_opt_set_sample_fmt(swr_ctx, "in_sample_fmt",      aformat, 0);
  232.         av_opt_set_int       (swr_ctx, "out_channel_layout",
  233.                               av_get_default_channel_layout(c->channels), 0);
  234.         av_opt_set_int       (swr_ctx, "out_channel_count",  c->channels,   0);
  235.         av_opt_set_int       (swr_ctx, "out_sample_rate",    c->sample_rate, 0);
  236.         av_opt_set_sample_fmt(swr_ctx, "out_sample_fmt",     c->sample_fmt, 0);
  237.    
  238.  
  239.     LOG_INFO( "Audio conversion of channels " << c->channels << ", freq "
  240.           << c->sample_rate << " " << av_get_sample_fmt_name( aformat )
  241.           << " to " << std::endl
  242.           << "              channels " << c->channels
  243.           << " freq " << c->sample_rate << " "
  244.           << av_get_sample_fmt_name( c->sample_fmt ) << "." );
  245.            
  246.    
  247.         // assert( src_samples_data[0] != NULL );
  248.         // assert( src_samples_linesize > 0 );
  249.  
  250.         max_dst_nb_samples = src_nb_samples;
  251.  
  252.         assert( src_nb_samples > 0 );
  253.  
  254.         int ret = av_samples_alloc_array_and_samples(&dst_samples_data,
  255.                                                      &dst_samples_linesize,
  256.                                                      c->channels,
  257.                                                      max_dst_nb_samples,
  258.                                                      c->sample_fmt, 0);
  259.         if ( ret < 0 )
  260.         {
  261.            LOG_ERROR( _("Could not allocate destination samples") );
  262.            return false;
  263.         }
  264.    
  265.         /* initialize the resampling context */
  266.         if ((swr_init(swr_ctx)) < 0) {
  267.            LOG_ERROR( _("Failed to initialize the resampling context") );
  268.        return false;
  269.         }
  270.  
  271.     }
  272.     else
  273.     {
  274.        dst_samples_data = src_samples_data;
  275.        max_dst_nb_samples = src_nb_samples;
  276.     }
  277.  
  278.     assert( dst_samples_data[0] != NULL );
  279.     assert( dst_samples_linesize != 0 );
  280.     assert( max_dst_nb_samples > 0 );
  281.     dst_samples_size = av_samples_get_buffer_size(NULL, c->channels,
  282.                           max_dst_nb_samples,
  283.                                                   c->sample_fmt, 1);
  284.                                                   // c->sample_fmt, 0);
  285.     assert( dst_samples_size > 0 );
  286.     assert( max_dst_nb_samples > 0 );
  287.  
  288.     return true;
  289. }
  290.  
  291.  
  292. static void write_audio_frame(AVFormatContext *oc, AVStream *st,
  293.                   const CMedia* img)
  294. {
  295.    AVPacket pkt = {0};
  296.    int got_packet, ret, dst_nb_samples;
  297.    
  298.    char buf[AV_ERROR_MAX_STRING_SIZE];
  299.    
  300.    {
  301.       av_init_packet(&pkt);
  302.       pkt.size = 0;
  303.       pkt.data = NULL;
  304.  
  305.  
  306.       int size = 0;
  307.        
  308.       AVCodecContext* c = st->codec;
  309.       int bytes_per_sample = av_get_bytes_per_sample(c->sample_fmt);
  310.  
  311.       assert( src_samples_data[0] != NULL );
  312.  
  313.       const audio_type_ptr& audio = img->get_audio_frame();
  314.       if ( !audio || audio->size() == 0 ) {
  315.          LOG_ERROR( _("Could not get audio frame for encoding") );
  316.          return;
  317.          // memset( src_samples_data[0], 0, src_nb_samples
  318.          //      * c->channels * bytes_per_sample);
  319.       }
  320.  
  321.       if (swr_ctx) {
  322.          /* compute destination number of samples */
  323.          dst_nb_samples = av_rescale_rnd(swr_get_delay(swr_ctx, c->sample_rate) + src_nb_samples,
  324.                                          c->sample_rate, c->sample_rate, AV_ROUND_UP);
  325.          if (dst_nb_samples > max_dst_nb_samples) {
  326.             av_free(dst_samples_data[0]);
  327.             ret = av_samples_alloc(dst_samples_data, &dst_samples_linesize, c->channels,
  328.                                    dst_nb_samples, c->sample_fmt, 0);
  329.             if (ret < 0)
  330.             {
  331.                LOG_ERROR( "Cannot allocate dst samples" );
  332.                return;
  333.             }
  334.  
  335.             max_dst_nb_samples = dst_nb_samples;
  336.             dst_samples_size = av_samples_get_buffer_size(NULL,
  337.                                                           c->channels,
  338.                                                           dst_nb_samples,
  339.                                                           c->sample_fmt,
  340.                                                           0);
  341.          }
  342.  
  343.            
  344.          /* convert to destination format */
  345.          const uint8_t* data = audio->data();
  346.          src_samples_data = (uint8_t**)&data;
  347.          ret = swr_convert(swr_ctx,
  348.                            dst_samples_data, dst_nb_samples,
  349.                            (const uint8_t **)src_samples_data,
  350.                            src_nb_samples);
  351.          if (ret < 0) {
  352.             LOG_ERROR( _("Error while converting audio: ")
  353.                        << mrv_err2str(buf, ret) );
  354.             return;
  355.          }
  356.            
  357.       } else {
  358.          dst_nb_samples = src_nb_samples;
  359.       }
  360.          
  361.       audio_frame->nb_samples = dst_nb_samples;
  362.       AVRational ratio = { 1, c->sample_rate };
  363.       audio_frame->pts = av_rescale_q( samples_count, ratio,
  364.                                        c->time_base );
  365.       c->frame_size = dst_nb_samples;
  366.  
  367.       assert( dst_samples_data[0] != NULL );
  368.       assert( dst_samples_size != 0 );
  369.       assert( dst_samples_size >= dst_nb_samples );
  370.       assert( dst_nb_samples > 0 );
  371.       assert( c->channels > 0 );
  372.       assert( c->sample_fmt != 0 );
  373.  
  374.       ret = avcodec_fill_audio_frame(audio_frame, c->channels,
  375.                                      c->sample_fmt,
  376.                                      dst_samples_data[0],
  377.                                      dst_samples_size, 0 );
  378.       samples_count += dst_nb_samples;
  379.  
  380.       if (ret < 0)
  381.       {
  382.      LOG_ERROR( _("Could not fill audio frame. Error: ") <<
  383.              mrv_err2str(buf, ret) );
  384.      return;
  385.       }
  386.  
  387.       ret = avcodec_encode_audio2(c, &pkt, audio_frame, &got_packet);
  388.       if (ret < 0)
  389.       {
  390.          LOG_ERROR( _("Could not encode audio frame: ") <<
  391.                      mrv_err2str(buf, ret) );
  392.      return;
  393.       }
  394.  
  395.       if (!got_packet) {
  396.          LOG_ERROR( "Did not get audio packet" );
  397.          return;
  398.       }
  399.      
  400.       ret = write_frame(oc, &c->time_base, st, &pkt);
  401.       if (ret < 0) {
  402.          LOG_ERROR( "Error while writing audio frame: " <<
  403.                     mrv_err2str(buf, ret) );
  404.          return;
  405.       }
  406.      
  407.    }
  408.    
  409. }
  410.  
  411.  
  412.  
  413.  
  414. static void close_audio_static(AVFormatContext *oc, AVStream *st)
  415. {
  416.    avcodec_close(st->codec);
  417.     if (dst_samples_data != src_samples_data) {
  418.         av_free(dst_samples_data[0]);
  419.         av_free(dst_samples_data);
  420.     }
  421.     av_frame_free(&audio_frame);
  422. }
  423.  
  424. static AVFrame *alloc_picture(enum PixelFormat pix_fmt, int width, int height)
  425. {
  426.     uint8_t *frame_buf;
  427.     int size, ret;
  428.  
  429.     picture = av_frame_alloc();
  430.     if (!picture)
  431.         return NULL;
  432.  
  433.     picture->width = width;
  434.     picture->height = height;
  435.  
  436.     /* Allocate the encoded raw picture. */
  437.     ret = avpicture_alloc(&dst_picture, pix_fmt, width, height);
  438.     if (ret < 0) {
  439.        LOG_ERROR( "Could not allocate picture: " << ret );
  440.        exit(1);
  441.     }
  442.  
  443.     /* copy data and linesize picture pointers to frame */
  444.     *((AVPicture *)picture) = dst_picture;
  445.  
  446.     return picture;
  447. }
  448.  
  449. static bool open_video(AVFormatContext *oc, AVCodec* codec, AVStream *st,
  450.                const CMedia* img )
  451. {
  452.     AVCodecContext* c = st->codec;
  453.  
  454.     /* open the codec */
  455.     if (avcodec_open2(c, codec, NULL) < 0) {
  456.        LOG_ERROR( _("Could not open video codec") );
  457.        return false;
  458.     }
  459.  
  460.    
  461.     /* Allocate the encoded raw frame. */
  462.     picture = alloc_picture(c->pix_fmt, img->width(), img->height());
  463.     if (!picture) {
  464.        LOG_ERROR( _("Could not allocate picture") );
  465.        return false;
  466.     }
  467.  
  468.     return true;
  469. }
  470.  
  471. static void close_video(AVFormatContext *oc, AVStream *st)
  472. {
  473.     avcodec_close(st->codec);
  474.     av_free(src_picture.data[0]);
  475.     av_free(dst_picture.data[0]);
  476.     av_frame_free(&picture);
  477. }
  478.  
  479. /* prepare a yuv image */
  480. static void fill_yuv_image(AVFrame *pict, const CMedia* img )
  481. {
  482.  
  483.    CMedia* m = (CMedia*) img;
  484.  
  485.    image_type_ptr hires = img->hires();
  486.  
  487.    unsigned w = img->width();
  488.    unsigned h = img->height();
  489.  
  490.    for ( unsigned y = 0; y < h; ++y )
  491.    {
  492.       for ( unsigned x = 0; x < w; ++x )
  493.       {
  494.      ImagePixel p = hires->pixel( x, y );
  495.  
  496.      float gamma = 1.0f/img->gamma();
  497.      if ( gamma != 1.0f )
  498.      {
  499.         p.r = powf( p.r, gamma );
  500.         p.g = powf( p.g, gamma );
  501.         p.b = powf( p.b, gamma );
  502.  
  503.         if (p.r < 0.0f) p.r = 0.0f;
  504.         if (p.g < 0.0f) p.g = 0.0f;
  505.         if (p.b < 0.0f) p.b = 0.0f;
  506.         if (p.r > 1.0f) p.r = 1.0f;
  507.         if (p.g > 1.0f) p.g = 1.0f;
  508.         if (p.b > 1.0f) p.b = 1.0f;
  509.      }
  510.  
  511.      ImagePixel yuv = color::rgb::to_ITU601( p );
  512.  
  513.      pict->data[0][y * pict->linesize[0]   + x   ] = uint8_t(yuv.r);
  514.  
  515.      unsigned x2 = x / 2;
  516.      unsigned y2 = y / 2;
  517.  
  518.      pict->data[1][y2 * pict->linesize[1] + x2 ] = uint8_t(yuv.g);
  519.      pict->data[2][y2 * pict->linesize[2] + x2 ] = uint8_t(yuv.b);
  520.       }
  521.    }
  522.  
  523.    pict->extended_data = pict->data;
  524.  
  525. }
  526.  
  527. static bool write_video_frame(AVFormatContext* oc, AVStream* st,
  528.                   const CMedia* img )
  529. {
  530.    int ret;
  531.    AVCodecContext* c = st->codec;
  532.  
  533.    
  534. #if 1
  535.    if (frame_count >= img->duration() ) {
  536.       /* No more frames to compress. The codec has a latency of a few
  537.        * frames if using B-frames, so we get the last frames by
  538.        * passing the same frame again. */
  539.    }
  540.    else
  541. #endif
  542.    {
  543.       fill_yuv_image( picture, img );
  544.    }
  545.  
  546.    if (oc->oformat->flags & AVFMT_RAWPICTURE ) {
  547.       /* Raw video case - directly store the frame in the packet */
  548.       AVPacket pkt;
  549.       av_init_packet(&pkt);
  550.  
  551.       pkt.flags        |= AV_PKT_FLAG_KEY;
  552.       pkt.stream_index  = st->index;
  553.         pkt.data          = dst_picture.data[0];
  554.         pkt.size          = sizeof(AVPicture);
  555.  
  556.       ret = av_interleaved_write_frame(oc, &pkt);
  557.    } else {
  558.  
  559.       AVPacket pkt = { 0 };
  560.       av_init_packet(&pkt);
  561.  
  562.       int got_packet = 0;
  563.  
  564.       /* encode the image */
  565.       picture->pts = frame_count;
  566.       ret = avcodec_encode_video2(c, &pkt, picture, &got_packet);
  567.       if (ret < 0) {
  568.          LOG_ERROR( _("Error while encoding video frame: ") << ret );
  569.          return false;
  570.       }
  571.        
  572.       /* If size is zero, it means the image was buffered. */
  573.       if ( got_packet )
  574.       {
  575.          ret = write_frame( oc, &c->time_base, st, &pkt );
  576.       }
  577.       else
  578.       {
  579.          ret = 0;
  580.       }
  581.  
  582.       if (ret < 0) {
  583.          LOG_ERROR( _("Error while writing video frame: ") << ret );
  584.          return false;
  585.       }
  586.  
  587.       frame_count++;
  588.    }
  589.    
  590.  
  591.    return true;
  592. }
  593.  
  594.  
  595. static AVFormatContext *oc = NULL;
  596. static AVOutputFormat* fmt = NULL;
  597. static AVStream* audio_st = NULL, *video_st = NULL;
  598.  
  599. AVCodec* audio_cdc, *video_codec;
  600.  
  601.  
  602.  
  603. /* check that a given sample format is supported by the encoder */
  604. static int check_sample_fmt(AVCodec *codec, enum AVSampleFormat sample_fmt)
  605. {
  606.     const enum AVSampleFormat *p = codec->sample_fmts;
  607.  
  608.     while (*p != AV_SAMPLE_FMT_NONE) {
  609.         if (*p == sample_fmt)
  610.             return 1;
  611.         p++;
  612.     }
  613.     return 0;
  614. }
  615.  
  616. static inline
  617. int64_t get_valid_channel_layout(int64_t channel_layout, int channels)
  618. {
  619.     if (channel_layout && av_get_channel_layout_nb_channels(channel_layout) == channels)
  620.         return channel_layout;
  621.     else
  622.         return 0;
  623. }
  624.  
  625.  
  626.  
  627. /* prepare a 16 bit dummy audio frame of 'frame_size' samples and
  628.    'nb_channels' channels */
  629. audio_type_ptr CMedia::get_audio_frame() const
  630. {
  631.     audio_cache_t::const_iterator end = _audio.end();
  632.     audio_cache_t::const_iterator i = std::lower_bound( _audio.begin(), end,
  633.                             _frame,
  634.                             LessThanFunctor() );
  635.     if ( i == end ) {
  636.        IMG_ERROR( _("Could not get audio frame ") << _frame );
  637.        src_nb_samples = 0;
  638.        return *i;
  639.     }
  640.  
  641.     src_nb_samples = (*i)->size();
  642.     src_nb_samples /= audio_channels();
  643.     src_nb_samples /= av_get_bytes_per_sample( aformat );
  644.  
  645.     return *i;
  646. }
  647.  
  648.  
  649.  
  650. bool aviImage::open_movie( const char* filename, const CMedia* img )
  651. {
  652.  
  653.    samples_count = 0;
  654.    frame_count = 0;
  655.  
  656.    avcodec_register_all();
  657.    av_register_all();
  658.  
  659.    if ( oc != NULL ) return false;
  660.  
  661.    std::string ext = "avi";
  662.    std::string file = filename;
  663.    size_t pos = file.rfind( '.' );
  664.    if ( pos != std::string::npos )
  665.    {
  666.       ext = file.substr( pos, file.size() );
  667.    }
  668.  
  669.    // Avoutputformat* outformat = av_guess_format(NULL, filename, NULL);
  670.    // if ( outformat == NULL )
  671.    // {
  672.    //    LOG_ERROR("Could not guess output format from filenmae" );
  673.    // }
  674.  
  675.  
  676.    int err = avformat_alloc_output_context2(&oc, NULL, NULL, filename);
  677.    if (!oc || err < 0) {
  678.       LOG_INFO( _("Could not deduce output format from file extension: using MPEG.") );
  679.  
  680.       err = avformat_alloc_output_context2(&oc, NULL, "mpeg", filename);
  681.       if ( err < 0 )
  682.       {
  683.      LOG_ERROR( _("Could not open mpeg movie") );
  684.      return false;
  685.       }
  686.    }
  687.  
  688.    fmt = oc->oformat;
  689.    // fmt->audio_codec = AV_CODEC_ID_PCM_S16LE;
  690.  
  691.    video_st = NULL;
  692.    audio_st = NULL;
  693.    if (img->has_picture() && fmt->video_codec != CODEC_ID_NONE) {
  694.       video_st = add_stream(oc, &video_codec, fmt->video_codec, img);
  695.    }
  696.  
  697.    if (img->has_audio() && fmt->audio_codec != CODEC_ID_NONE) {
  698.       audio_st = add_stream(oc, &audio_cdc, fmt->audio_codec,
  699.                             img );
  700.    }
  701.  
  702.  
  703.    /* Now that all the parameters are set, we can open the audio and
  704.     * video codecs and allocate the necessary encode buffers. */
  705.    if (video_st)
  706.       if ( ! open_video(oc, video_codec, video_st, img) )
  707.      return false;
  708.    
  709.    if (audio_st)
  710.       if ( ! open_audio_static(oc, audio_cdc, audio_st, img) )
  711.       {
  712.      audio_st = NULL;
  713.      if ( !video_st ) return false;
  714.       }
  715.    
  716.  
  717.    if (!(fmt->flags & AVFMT_NOFILE)) {
  718.       if (avio_open(&oc->pb, filename, AVIO_FLAG_WRITE) < 0) {
  719.      LOG_ERROR( _("Could not open '") << filename << "'" );
  720.      return false;
  721.       }
  722.    }
  723.    
  724.    /* Write the stream header, if any. */
  725.    err = avformat_write_header(oc, NULL);
  726.    if ( err < 0 )
  727.    {
  728.       LOG_ERROR( _("Error occurred when opening output file: ") << err );
  729.       return false;
  730.    }
  731.  
  732.    return true;
  733.  
  734. }
  735.  
  736.  
  737. bool aviImage::save_movie_frame( const CMedia* img )
  738. {
  739.  
  740.    double audio_time, video_time;
  741.    
  742.    
  743.    audio_time = audio_st ? audio_st->pts.val * av_q2d(audio_st->time_base) : 0.0;
  744.    video_time = video_st ? video_st->pts.val * av_q2d(video_st->time_base) : 0.0;
  745.  
  746.    if (!audio_st && !video_st)
  747.       return false;
  748.  
  749.    // double STREAM_DURATION = (double) img->duration() / (double) img->fps();
  750.  
  751.     /* Compute current audio and video time. */
  752.     audio_time = audio_st ? audio_st->pts.val * av_q2d(audio_st->time_base) : INFINITY;
  753.     video_time = video_st ? video_st->pts.val * av_q2d(video_st->time_base) : INFINITY;
  754.  
  755.  
  756.     // if (!flush &&
  757.     //     (!audio_st || audio_time >= STREAM_DURATION) &&
  758.     //     (!video_st || video_time >= STREAM_DURATION)) {
  759.     //    LOG_WARNING( ">>>>>>>>>>>>  FLUSH = ! " );
  760.     //    flush = 1;
  761.     // }
  762.    
  763.     /* write interleaved audio and video frames */
  764.     if ( audio_st )
  765.     {
  766.        while( audio_time <= video_time) {
  767.           write_audio_frame(oc, audio_st, img);
  768.           audio_time = audio_st->pts.val * av_q2d(audio_st->time_base);
  769.        }
  770.     }
  771.    
  772.     if ( video_st ) {
  773.        write_video_frame(oc, video_st, img);
  774.  
  775.        picture->pts += av_rescale_q(1, video_st->codec->time_base,
  776.                                     video_st->time_base);
  777.     }
  778.  
  779.  
  780.    return true;
  781. }
  782.  
  783.  
  784. bool aviImage::close_movie()
  785. {
  786.    /* Write the trailer, if any. The trailer must be written before you
  787.     * close the CodecContexts open when you wrote the header; otherwise
  788.     * av_write_trailer() may try to use memory that was freed on
  789.     * av_codec_close(). */
  790.    av_write_trailer(oc);
  791.    
  792.     /* Close each codec. */
  793.     if (video_st)
  794.         close_video(oc, video_st);
  795.     if (audio_st)
  796.        close_audio_static(oc, audio_st);
  797.  
  798.     if (!(fmt->flags & AVFMT_NOFILE))
  799.        /* Close the output file. */
  800.        avio_close(oc->pb);
  801.  
  802.     /* free the stream */
  803.     avformat_free_context(oc);
  804.  
  805.     return true;
  806. }
  807.  
  808. } // namespace mrv
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement