[haiku-commits] r38851 - haiku/trunk/src/add-ons/media/plugins/ffmpeg

  • From: superstippi@xxxxxx
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Wed, 29 Sep 2010 17:17:35 +0200 (CEST)

Author: stippi
Date: 2010-09-29 17:17:35 +0200 (Wed, 29 Sep 2010)
New Revision: 38851
Changeset: http://dev.haiku-os.org/changeset/38851

Modified:
   haiku/trunk/src/add-ons/media/plugins/ffmpeg/AVFormatWriter.cpp
   haiku/trunk/src/add-ons/media/plugins/ffmpeg/AVFormatWriter.h
Log:
 * Do no manually allocate the buffer for the
   ByteIOContext. libavformat may reallocate it
   on demand, we need to use the matching allocation
   methods.
 * Init the ByteIOContext with the proper "write flag".
   This solves a busy loop when writing the trailer of
   MKV files, since the first buffer was initially skipped
   and the MKV muxer can not seek back in the stream
   where it wants.
 * Get rid of the fCalculatePTS member, and calculate
   PTS of audio packets as well. I don't remember why
   I prevented that, however VLC complains about audio
   packets having wrong PTS (with or without this change)
   Our own MediaPlayer plays videos generated by (a modified)
   Clockwerk at least once, but seeking subsequently fails.


Modified: haiku/trunk/src/add-ons/media/plugins/ffmpeg/AVFormatWriter.cpp
===================================================================
--- haiku/trunk/src/add-ons/media/plugins/ffmpeg/AVFormatWriter.cpp     
2010-09-29 15:11:28 UTC (rev 38850)
+++ haiku/trunk/src/add-ons/media/plugins/ffmpeg/AVFormatWriter.cpp     
2010-09-29 15:17:35 UTC (rev 38851)
@@ -75,7 +75,6 @@
                        AVFormatContext*        fContext;
                        AVStream*                       fStream;
                        AVPacket                        fPacket;
-                       bool                            fCalculatePTS;
                        // Since different threads may write to the target,
                        // we need to protect the file position and I/O by a 
lock.
                        BLocker*                        fStreamLock;
@@ -88,7 +87,6 @@
        :
        fContext(context),
        fStream(NULL),
-       fCalculatePTS(false),
        fStreamLock(streamLock)
 {
        av_init_packet(&fPacket);
@@ -160,8 +158,6 @@
                // Some formats want stream headers to be separate
                if ((fContext->oformat->flags & AVFMT_GLOBALHEADER) != 0)
                        fStream->codec->flags |= CODEC_FLAG_GLOBAL_HEADER;
-
-               fCalculatePTS = true;
        } else if (format->type == B_MEDIA_RAW_AUDIO) {
                fStream->codec->codec_type = CODEC_TYPE_AUDIO;
 #if GET_CONTEXT_DEFAULTS
@@ -170,11 +166,6 @@
 #endif
                // frame rate
                fStream->codec->sample_rate = 
(int)format->u.raw_audio.frame_rate;
-// NOTE: API example does not do this:
-//             fStream->codec->time_base.den = 
(int)format->u.raw_audio.frame_rate;
-//             fStream->codec->time_base.num = 1;
-//             fStream->time_base.den = (int)format->u.raw_audio.frame_rate;
-//             fStream->time_base.num = 1;
 
                // channels
                fStream->codec->channels = format->u.raw_audio.channel_count;
@@ -233,8 +224,6 @@
                        // The bits match 1:1 for media_multi_channels and 
FFmpeg defines.
                        fStream->codec->channel_layout = 
format->u.raw_audio.channel_mask;
                }
-
-               fCalculatePTS = false;
        }
 
        TRACE("  stream->time_base: (%d/%d), codec->time_base: (%d/%d))\n",
@@ -249,8 +238,9 @@
 AVFormatWriter::StreamCookie::WriteChunk(const void* chunkBuffer,
        size_t chunkSize, media_encode_info* encodeInfo)
 {
-       TRACE_PACKET("AVFormatWriter::StreamCookie::WriteChunk(%p, %ld, "
-               "start_time: %lld)\n", chunkBuffer, chunkSize, 
encodeInfo->start_time);
+       TRACE_PACKET("AVFormatWriter::StreamCookie[%d]::WriteChunk(%p, %ld, "
+               "start_time: %lld)\n", fStream->index, chunkBuffer, chunkSize,
+               encodeInfo->start_time);
 
        BAutolock _(fStreamLock);
 
@@ -260,14 +250,13 @@
        fPacket.data = const_cast<uint8_t*>((const uint8_t*)chunkBuffer);
        fPacket.size = chunkSize;
 
-       if (fCalculatePTS) {
-               fPacket.pts = (encodeInfo->start_time
-                       * fStream->time_base.den / fStream->time_base.num) / 
1000000;
-               TRACE_PACKET("  PTS: %lld  (stream->time_base: (%d/%d), "
-                       "codec->time_base: (%d/%d))\n", fPacket.pts,
-                       fStream->time_base.num, fStream->time_base.den,
-                       fStream->codec->time_base.num, 
fStream->codec->time_base.den);
-       }
+       fPacket.pts = int64_t((double)encodeInfo->start_time
+               * fStream->time_base.den / (1000000.0 * fStream->time_base.num)
+               + 0.5);
+       TRACE_PACKET("  PTS: %lld  (stream->time_base: (%d/%d), "
+               "codec->time_base: (%d/%d))\n", fPacket.pts,
+               fStream->time_base.num, fStream->time_base.den,
+               fStream->codec->time_base.num, fStream->codec->time_base.den);
 
 // From ffmpeg.c::do_audio_out():
 // TODO:
@@ -315,7 +304,6 @@
        :
        fContext(avformat_alloc_context()),
        fHeaderWritten(false),
-       fIOBuffer(NULL),
        fStreamLock("stream lock")
 {
        TRACE("AVFormatWriter::AVFormatWriter\n");
@@ -339,8 +327,7 @@
     }
 
        av_free(fContext);
-
-       delete[] fIOBuffer;
+       av_free(fIOContext.buffer);
 }
 
 
@@ -352,14 +339,13 @@
 {
        TRACE("AVFormatWriter::Init()\n");
 
-       delete[] fIOBuffer;
-       fIOBuffer = new(std::nothrow) uint8[kIOBufferSize];
-       if (fIOBuffer == NULL)
+       uint8* buffer = static_cast<uint8*>(av_malloc(kIOBufferSize));
+       if (buffer == NULL)
                return B_NO_MEMORY;
 
        // Init I/O context with buffer and hook functions, pass ourself as
        // cookie.
-       if (init_put_byte(&fIOContext, fIOBuffer, kIOBufferSize, 0, this,
+       if (init_put_byte(&fIOContext, buffer, kIOBufferSize, 1, this,
                        0, _Write, _Seek) != 0) {
                TRACE("  init_put_byte() failed!\n");
                return B_ERROR;
@@ -369,7 +355,7 @@
        fContext->pb = &fIOContext;
 
        // Set the AVOutputFormat according to fileFormat...
-       fContext->oformat = guess_format(fileFormat->short_name,
+       fContext->oformat = av_guess_format(fileFormat->short_name,
                fileFormat->file_extension, fileFormat->mime_type);
        if (fContext->oformat == NULL) {
                TRACE("  failed to find AVOuputFormat for %s\n",
@@ -430,10 +416,11 @@
        int result = av_write_header(fContext);
        if (result < 0)
                TRACE("  av_write_header(): %d\n", result);
-       else
-               fHeaderWritten = true;
 
-       #if TRACE_AVFORMAT_WRITER
+       // We need to close the codecs we opened, even in case of failure.
+       fHeaderWritten = true;
+
+       #ifdef TRACE_AVFORMAT_WRITER
        TRACE("  wrote header\n");
        for (unsigned i = 0; i < fContext->nb_streams; i++) {
                AVStream* stream = fContext->streams[i];

Modified: haiku/trunk/src/add-ons/media/plugins/ffmpeg/AVFormatWriter.h
===================================================================
--- haiku/trunk/src/add-ons/media/plugins/ffmpeg/AVFormatWriter.h       
2010-09-29 15:11:28 UTC (rev 38850)
+++ haiku/trunk/src/add-ons/media/plugins/ffmpeg/AVFormatWriter.h       
2010-09-29 15:17:35 UTC (rev 38851)
@@ -46,17 +46,15 @@
 private:
        static  int                                     _Write(void* cookie, 
uint8* buffer,
                                                                        int 
bufferSize);
-
        static  off_t                           _Seek(void* cookie, off_t 
offset, int whence);
 
 private:
-       class StreamCookie;
+                       class StreamCookie;
 
                        AVFormatContext*        fContext;
                        bool                            fHeaderWritten;
 
                        ByteIOContext           fIOContext;
-                       uint8*                          fIOBuffer;
 
                        StreamCookie**          fStreams;
                        BLocker                         fStreamLock;


Other related posts:

  • » [haiku-commits] r38851 - haiku/trunk/src/add-ons/media/plugins/ffmpeg - superstippi