Changeset cc9e7a06 in git


Ignore:
Timestamp:
17/06/11 05:31:40 (8 years ago)
Author:
Olly Betts <olly@…>
Branches:
add-show-splays, line_contents, master, stereo, svn/github/master, svn/origin/master, svn/tags/1.2.0, svn/tags/1.2.1, svn/tags/1.2.2, svn/tags/1.2.3, svn/tags/1.2.4, svn/tags/1.2.5, svn/trunk, travis-osx
Children:
75d4a2b
Parents:
90a2e0f
Message:

configure.in,src/moviemaker.cc,src/moviemaker.h: Mostly update movie
making code to work with current FFmpeg. Still TODO: convert call
to img_convert() to use sws_scale() - currently you just get an all
green movie!

git-svn-id: file:///home/survex-svn/survex/trunk@3615 4b37db11-9a0c-4f06-9ece-9ab7cdaee568

Files:
4 edited

Legend:

Unmodified
Added
Removed
  • ChangeLog

    r90a2e0f rcc9e7a06  
     1Fri Jun 17 04:30:12 GMT 2011  Olly Betts <olly@survex.com>
     2
     3        * configure.in,src/moviemaker.cc,src/moviemaker.h: Mostly update movie
     4          making code to work with current FFmpeg.  Still TODO: convert call
     5          to img_convert() to use sws_scale() - currently you just get an all
     6          green movie!
     7
    18Mon May 30 07:40:12 GMT 2011  Olly Betts <olly@survex.com>
    29
  • configure.in

    r90a2e0f rcc9e7a06  
    203203AC_CHECK_LIB(avcodec, avcodec_init,
    204204  [AC_CHECK_LIB(avformat, av_register_all,
    205     [AC_CHECK_HEADERS([avformat.h],
     205    [AC_CHECK_HEADERS([libavformat/avformat.h],
    206206      [MOVIE_LIBS="-lavformat -lavcodec"])], [], [-lavcodec $WX_LIBS])])
    207207AC_SUBST(MOVIE_LIBS)
  • src/moviemaker.cc

    r90a2e0f rcc9e7a06  
    2121//
    2222
     23/* Based on output-example.c:
     24 *
     25 * Libavformat API example: Output a media file in any supported
     26 * libavformat format. The default codecs are used.
     27 *
     28 * Copyright (c) 2003 Fabrice Bellard
     29 *
     30 * Permission is hereby granted, free of charge, to any person obtaining a copy
     31 * of this software and associated documentation files (the "Software"), to deal
     32 * in the Software without restriction, including without limitation the rights
     33 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
     34 * copies of the Software, and to permit persons to whom the Software is
     35 * furnished to do so, subject to the following conditions:
     36 *
     37 * The above copyright notice and this permission notice shall be included in
     38 * all copies or substantial portions of the Software.
     39 *
     40 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     41 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     42 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
     43 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
     44 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
     45 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
     46 * THE SOFTWARE.
     47 */
     48
    2349#ifdef HAVE_CONFIG_H
    2450#include <config.h>
    2551#endif
     52
     53#define __STDC_CONSTANT_MACROS
    2654
    2755#include <assert.h>
     
    3159#include "moviemaker.h"
    3260
    33 #ifdef HAVE_AVFORMAT_H
    34 #include "avformat.h"
     61#ifdef HAVE_LIBAVFORMAT_AVFORMAT_H
     62extern "C" {
     63#include "libavformat/avformat.h"
     64}
     65#ifndef AV_PKT_FLAG_KEY
     66# define AV_PKT_FLAG_KEY PKT_FLAG_KEY
     67#endif
    3568#endif
    3669
     
    4477    : oc(0), st(0), frame(0), outbuf(0), in(0), out(0), pixels(0)
    4578{
    46 #ifdef HAVE_AVFORMAT_H
     79#ifdef HAVE_LIBAVFORMAT_AVFORMAT_H
    4780    static bool initialised_ffmpeg = false;
    4881    if (initialised_ffmpeg) return;
     
    5790bool MovieMaker::Open(const char *fnm, int width, int height)
    5891{
    59 #ifdef HAVE_AVFORMAT_H
     92#ifdef HAVE_LIBAVFORMAT_AVFORMAT_H
    6093    AVOutputFormat * fmt = guess_format(NULL, fnm, NULL);
    6194    if (!fmt) {
     
    95128
    96129    // Initialise the code.
    97     AVCodecContext *c = &st->codec;
     130    AVCodecContext *c = st->codec;
    98131    c->codec_id = fmt->video_codec;
    99132    c->codec_type = CODEC_TYPE_VIDEO;
     
    103136    c->width = width;
    104137    c->height = height;
    105     c->frame_rate = 25; // FPS
    106     c->frame_rate_base = 1;
     138    c->time_base.num = 1;
     139    c->time_base.den = 25; // Frames per second.
    107140    c->gop_size = 12; // One intra frame every twelve frames.
    108141    c->pix_fmt = PIX_FMT_YUV420P;
     
    111144    // c->max_b_frames = 2;
    112145
     146    if (oc->oformat->flags & AVFMT_GLOBALHEADER)
     147        c->flags |= CODEC_FLAG_GLOBAL_HEADER;
     148
    113149    // Set the output parameters (must be done even if no parameters).
    114150    if (av_set_parameters(oc, NULL) < 0) {
     
    133169    }
    134170
    135     outbuf = (unsigned char *)malloc(OUTBUF_SIZE);
    136     if (!outbuf) {
     171    if ((oc->oformat->flags & AVFMT_RAWPICTURE)) {
     172        outbuf = NULL;
     173    } else {
     174        outbuf = (unsigned char *)malloc(OUTBUF_SIZE);
     175        if (!outbuf) {
     176            // FIXME : out of memory
     177            return false;
     178        }
     179    }
     180
     181    frame = avcodec_alloc_frame();
     182    if (!frame) {
    137183        // FIXME : out of memory
    138184        return false;
    139185    }
    140 
    141     frame = avcodec_alloc_frame();
    142     in = (AVPicture *)malloc(sizeof(AVPicture));
    143     out = (AVPicture *)malloc(sizeof(AVPicture));
    144     if (!frame || !in || !out) {
     186    int size = avpicture_get_size(c->pix_fmt, width, height);
     187    in = (unsigned char*)av_malloc(size);
     188    if (!in) {
     189        av_free(frame);
    145190        // FIXME : out of memory
    146191        return false;
    147192    }
    148 
    149     int size = width * height;
    150     out->data[0] = (unsigned char *)malloc(size * 3 / 2);
    151     if (!out->data[0]) {
    152         // FIXME : out of memory
    153         return false;
    154     }
    155     avpicture_fill((AVPicture *)frame, out->data[0], c->pix_fmt, width, height);
    156     out->data[1] = frame->data[1];
    157     out->data[2] = frame->data[2];
    158     out->linesize[0] = frame->linesize[0];
    159     out->linesize[1] = frame->linesize[1];
    160     out->linesize[2] = frame->linesize[2];
     193    avpicture_fill((AVPicture *)frame, in, c->pix_fmt, width, height);
     194
     195    out = NULL;
     196    if (c->pix_fmt != PIX_FMT_YUV420P) {
     197        // FIXME need to allocate another frame for this case if we stop
     198        // hardcoding PIX_FMT_YUV420P.
     199        abort();
     200    }
    161201
    162202    pixels = (unsigned char *)malloc(width * height * 6);
     
    165205        return false;
    166206    }
    167     in->data[0] = pixels + height * width * 3;
    168     in->linesize[0] = width * 3;
    169 
    170     out_size = 0;
    171207
    172208    if (url_fopen(&oc->pb, fnm, URL_WRONLY) < 0) {
     
    192228int MovieMaker::GetWidth() const {
    193229    assert(st);
    194 #ifdef HAVE_AVFORMAT_H
    195     AVCodecContext *c = &st->codec;
     230#ifdef HAVE_LIBAVFORMAT_AVFORMAT_H
     231    AVCodecContext *c = st->codec;
    196232    return c->width;
    197233#else
     
    202238int MovieMaker::GetHeight() const {
    203239    assert(st);
    204 #ifdef HAVE_AVFORMAT_H
    205     AVCodecContext *c = &st->codec;
     240#ifdef HAVE_LIBAVFORMAT_AVFORMAT_H
     241    AVCodecContext *c = st->codec;
    206242    return c->height;
    207243#else
     
    212248void MovieMaker::AddFrame()
    213249{
    214 #ifdef HAVE_AVFORMAT_H
    215     AVCodecContext * c = &st->codec;
     250#ifdef HAVE_LIBAVFORMAT_AVFORMAT_H
     251    AVCodecContext * c = st->codec;
     252
     253    if (c->pix_fmt != PIX_FMT_YUV420P) {
     254        // FIXME convert...
     255        abort();
     256    }
    216257
    217258    const int len = 3 * c->width;
     
    222263    }
    223264
    224     img_convert(out, PIX_FMT_YUV420P, in, PIX_FMT_RGB24, c->width, c->height);
     265    // FIXME: Need to convert this to use sws_scale() instead of img_convert().
     266    //img_convert(out, PIX_FMT_YUV420P, in, PIX_FMT_RGB24, c->width, c->height);
     267    if (oc->oformat->flags & AVFMT_RAWPICTURE) {
     268        abort();
     269    }
    225270
    226271    // Encode this frame.
     
    228273    // outsize == 0 means that this frame has been buffered, so there's nothing
    229274    // to write yet.
    230     if (out_size != 0) {
     275    if (out_size) {
    231276        // Write the compressed frame to the media file.
    232         if (av_write_frame(oc, st->index, outbuf, out_size) != 0) {
    233             fprintf(stderr, "Error while writing video frame\n");
    234             exit(1);
     277        AVPacket pkt;
     278        av_init_packet(&pkt);
     279
     280        if (c->coded_frame->pts != AV_NOPTS_VALUE)
     281            pkt.pts = av_rescale_q(c->coded_frame->pts, c->time_base, st->time_base);
     282        if (c->coded_frame->key_frame)
     283            pkt.flags |= AV_PKT_FLAG_KEY;
     284        pkt.stream_index = st->index;
     285        pkt.data = outbuf;
     286        pkt.size = out_size;
     287
     288        /* write the compressed frame in the media file */
     289        if (av_interleaved_write_frame(oc, &pkt) != 0) {
     290            abort();
    235291        }
    236292    }
     
    240296MovieMaker::~MovieMaker()
    241297{
    242 #ifdef HAVE_AVFORMAT_H
     298#ifdef HAVE_LIBAVFORMAT_AVFORMAT_H
    243299    if (st) {
    244300        // No more frames to compress.  The codec may have a few frames
    245301        // buffered if we're using B frames, so write those too.
    246         AVCodecContext * c = &st->codec;
     302        AVCodecContext * c = st->codec;
    247303
    248304        while (out_size) {
    249305            out_size = avcodec_encode_video(c, outbuf, OUTBUF_SIZE, NULL);
    250306            if (out_size) {
    251                 if (av_write_frame(oc, st->index, outbuf, out_size) != 0) {
    252                     fprintf(stderr, "Error while writing video frame\n");
    253                     exit(1);
     307                // Write the compressed frame to the media file.
     308                AVPacket pkt;
     309                av_init_packet(&pkt);
     310
     311                if (c->coded_frame->pts != AV_NOPTS_VALUE)
     312                    pkt.pts = av_rescale_q(c->coded_frame->pts, c->time_base, st->time_base);
     313                if (c->coded_frame->key_frame)
     314                    pkt.flags |= AV_PKT_FLAG_KEY;
     315                pkt.stream_index = st->index;
     316                pkt.data = outbuf;
     317                pkt.size = out_size;
     318
     319                /* write the compressed frame in the media file */
     320                if (av_interleaved_write_frame(oc, &pkt) != 0) {
     321                    abort();
    254322                }
    255323            }
    256324        }
    257325
     326        av_write_trailer(oc);
     327
    258328        // Close codec.
    259329        avcodec_close(c);
    260330    }
    261331
    262     free(frame);
    263     if (out) free(out->data[0]);
     332    if (frame) {
     333        free(frame->data[0]);
     334        free(frame);
     335    }
    264336    free(outbuf);
    265337    free(pixels);
     
    268340
    269341    if (oc) {
    270         // Write the trailer, if any.
    271         av_write_trailer(oc);
    272 
    273342        // Free the streams.
    274         for(int i = 0; i < oc->nb_streams; ++i) {
     343        for (size_t i = 0; i < oc->nb_streams; ++i) {
     344            av_freep(&oc->streams[i]->codec);
    275345            av_freep(&oc->streams[i]);
    276346        }
    277347
    278         // Close the output file.
    279         url_fclose(&oc->pb);
     348        if (!(oc->oformat->flags & AVFMT_NOFILE)) {
     349            // Close the output file.
     350            url_fclose(oc->pb);
     351        }
    280352
    281353        // Free the stream.
  • src/moviemaker.h

    r90a2e0f rcc9e7a06  
    3232    AVFrame *frame;
    3333    unsigned char *outbuf;
    34     AVPicture *in;
     34    unsigned char *in;
    3535    AVPicture *out;
    3636    unsigned char *pixels;
Note: See TracChangeset for help on using the changeset viewer.