[haiku-commits] r39035 - in haiku/trunk: headers/os/media headers/private/media src/add-ons/media/plugins/ffmpeg src/kits/media

  • From: superstippi@xxxxxx
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Wed, 20 Oct 2010 23:36:23 +0200 (CEST)

Author: stippi
Date: 2010-10-20 23:36:23 +0200 (Wed, 20 Oct 2010)
New Revision: 39035
Changeset: http://dev.haiku-os.org/changeset/39035

Modified:
   haiku/trunk/headers/os/media/MediaTrack.h
   haiku/trunk/headers/private/media/MediaWriter.h
   haiku/trunk/headers/private/media/WriterPlugin.h
   haiku/trunk/src/add-ons/media/plugins/ffmpeg/AVFormatWriter.cpp
   haiku/trunk/src/add-ons/media/plugins/ffmpeg/AVFormatWriter.h
   haiku/trunk/src/kits/media/MediaTrack.cpp
   haiku/trunk/src/kits/media/MediaWriter.cpp
Log:
 * Change the signature of the Writer plugins setup methods such
   that they can modify the media_format passed in. For example they
   can store information in the user_data section. I don't actually
   use this anymore, but it may come in handy again.

AVFormatWriter:
 * Adjust the AVCodecContext flags not only for video, but also
   for audio streams (as the API example does). This mechanism
   may not yet work, since the AVCodecEncoder actually uses a
   different AVCodecContext instance.
 * Use the encodeInfo->flags and specify the key frame flag
   for the AVPacket. This finally makes videos encoded on Haiku
   seekable.


Modified: haiku/trunk/headers/os/media/MediaTrack.h
===================================================================
--- haiku/trunk/headers/os/media/MediaTrack.h   2010-10-20 21:29:16 UTC (rev 
39034)
+++ haiku/trunk/headers/os/media/MediaTrack.h   2010-10-20 21:36:23 UTC (rev 
39035)
@@ -227,8 +227,7 @@
        // For write-only access to a BMediaTrack
                                                                BMediaTrack(
                                                                        
BPrivate::media::MediaWriter* writer,
-                                                                       int32 
streamIndex,
-                                                                       const 
media_format* format,
+                                                                       int32 
streamIndex, media_format* format,
                                                                        const 
media_codec_info* codecInfo);
 
                        void                            SetupWorkaround();

Modified: haiku/trunk/headers/private/media/MediaWriter.h
===================================================================
--- haiku/trunk/headers/private/media/MediaWriter.h     2010-10-20 21:29:16 UTC 
(rev 39034)
+++ haiku/trunk/headers/private/media/MediaWriter.h     2010-10-20 21:36:23 UTC 
(rev 39035)
@@ -1,6 +1,6 @@
 /*
- * Copyright 2009, Stephan Aßmus <superstippi@xxxxxx>. All rights reserved.
- * Distributed under the terms of the MIT License.
+ * Copyright 2009-2010, Stephan Aßmus <superstippi@xxxxxx>.
+ * All rights reserved. Distributed under the terms of the MIT License.
  */
 #ifndef _MEDIA_WRITER_H
 #define _MEDIA_WRITER_H
@@ -27,8 +27,7 @@
 
                        status_t                        CreateEncoder(Encoder** 
_encoder,
                                                                        const 
media_codec_info* codecInfo,
-                                                                       const 
media_format* format,
-                                                                       uint32 
flags = 0);
+                                                                       
media_format* format, uint32 flags = 0);
 
                        status_t                        SetCopyright(int32 
streamIndex,
                                                                        const 
char* copyright);

Modified: haiku/trunk/headers/private/media/WriterPlugin.h
===================================================================
--- haiku/trunk/headers/private/media/WriterPlugin.h    2010-10-20 21:29:16 UTC 
(rev 39034)
+++ haiku/trunk/headers/private/media/WriterPlugin.h    2010-10-20 21:36:23 UTC 
(rev 39035)
@@ -21,7 +21,7 @@
        virtual status_t                        Close() = 0;
 
        virtual status_t                        AllocateCookie(void** cookie,
-                                                                       const 
media_format* format,
+                                                                       
media_format* format,
                                                                        const 
media_codec_info* codecInfo) = 0;
        virtual status_t                        FreeCookie(void* cookie) = 0;
 

Modified: haiku/trunk/src/add-ons/media/plugins/ffmpeg/AVFormatWriter.cpp
===================================================================
--- haiku/trunk/src/add-ons/media/plugins/ffmpeg/AVFormatWriter.cpp     
2010-10-20 21:29:16 UTC (rev 39034)
+++ haiku/trunk/src/add-ons/media/plugins/ffmpeg/AVFormatWriter.cpp     
2010-10-20 21:36:23 UTC (rev 39035)
@@ -61,7 +61,7 @@
                                                                        
BLocker* streamLock);
        virtual                                         ~StreamCookie();
 
-                       status_t                        Init(const 
media_format* format,
+                       status_t                        Init(media_format* 
format,
                                                                        const 
media_codec_info* codecInfo);
 
                        status_t                        WriteChunk(const void* 
chunkBuffer,
@@ -99,7 +99,7 @@
 
 
 status_t
-AVFormatWriter::StreamCookie::Init(const media_format* format,
+AVFormatWriter::StreamCookie::Init(media_format* format,
        const media_codec_info* codecInfo)
 {
        TRACE("AVFormatWriter::StreamCookie::Init()\n");
@@ -123,7 +123,7 @@
 
        // Setup the stream according to the media format...
        if (format->type == B_MEDIA_RAW_VIDEO) {
-               fStream->codec->codec_type = CODEC_TYPE_VIDEO;
+               fStream->codec->codec_type = AVMEDIA_TYPE_VIDEO;
 #if GET_CONTEXT_DEFAULTS
 // NOTE: API example does not do this:
                avcodec_get_context_defaults(fStream->codec);
@@ -131,11 +131,6 @@
                // frame rate
                fStream->codec->time_base.den = 
(int)format->u.raw_video.field_rate;
                fStream->codec->time_base.num = 1;
-// NOTE: API example does not do this:
-//             fStream->r_frame_rate.den = (int)format->u.raw_video.field_rate;
-//             fStream->r_frame_rate.num = 1;
-//             fStream->time_base.den = (int)format->u.raw_video.field_rate;
-//             fStream->time_base.num = 1;
                // video size
                fStream->codec->width = format->u.raw_video.display.line_width;
                fStream->codec->height = format->u.raw_video.display.line_count;
@@ -151,15 +146,19 @@
                                fStream->codec->height, 255);
                }
 
+               fStream->codec->gop_size = 12;
+
                fStream->codec->sample_aspect_ratio = 
fStream->sample_aspect_ratio;
-               // TODO: Don't hard code this...
-               fStream->codec->pix_fmt = PIX_FMT_YUV420P;
 
-               // Some formats want stream headers to be separate
-               if ((fContext->oformat->flags & AVFMT_GLOBALHEADER) != 0)
-                       fStream->codec->flags |= CODEC_FLAG_GLOBAL_HEADER;
+               // Use the last supported pixel format of the AVCodec, which we 
hope
+               // is the one with the best quality (true for all currently 
supported
+               // encoders).
+               AVCodec* codec = fStream->codec->codec;
+               for (int i = 0; codec->pix_fmts[i] != PIX_FMT_NONE; i++)
+                       fStream->codec->pix_fmt = codec->pix_fmts[i];
+
        } else if (format->type == B_MEDIA_RAW_AUDIO) {
-               fStream->codec->codec_type = CODEC_TYPE_AUDIO;
+               fStream->codec->codec_type = AVMEDIA_TYPE_AUDIO;
 #if GET_CONTEXT_DEFAULTS
 // NOTE: API example does not do this:
                avcodec_get_context_defaults(fStream->codec);
@@ -226,6 +225,10 @@
                }
        }
 
+       // Some formats want stream headers to be separate
+       if ((fContext->oformat->flags & AVFMT_GLOBALHEADER) != 0)
+               fStream->codec->flags |= CODEC_FLAG_GLOBAL_HEADER;
+
        TRACE("  stream->time_base: (%d/%d), codec->time_base: (%d/%d))\n",
                fStream->time_base.num, fStream->time_base.den,
                fStream->codec->time_base.num, fStream->codec->time_base.den);
@@ -244,27 +247,22 @@
 
        BAutolock _(fStreamLock);
 
-       // TODO: Probably the AVCodecEncoder needs to pass packet data
-       // in encodeInfo...
-
        fPacket.data = const_cast<uint8_t*>((const uint8_t*)chunkBuffer);
        fPacket.size = chunkSize;
 
        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), "
+
+       fPacket.flags = 0;
+       if ((encodeInfo->flags & B_MEDIA_KEY_FRAME) != 0)
+               fPacket.flags |= AV_PKT_FLAG_KEY;
+
+       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:
-//     if (enc->coded_frame && enc->coded_frame->pts != AV_NOPTS_VALUE)
-//             fPacket.pts = av_rescale_q(enc->coded_frame->pts,
-//             enc->time_base, ost->st->time_base);
-
-
 #if 0
        // TODO: Eventually, we need to write interleaved packets, but
        // maybe we are only supposed to use this if we have actually
@@ -396,9 +394,9 @@
        if (av_set_parameters(fContext, NULL) < 0)
                return B_ERROR;
 
+#if OPEN_CODEC_CONTEXT
        for (unsigned i = 0; i < fContext->nb_streams; i++) {
                AVStream* stream = fContext->streams[i];
-#if OPEN_CODEC_CONTEXT
                // NOTE: Experimental, this should not be needed. Especially, 
since
                // we have no idea (in the future) what CodecID some encoder 
uses,
                // it may be an encoder from a different plugin.
@@ -407,11 +405,11 @@
                if (codec == NULL || avcodec_open(codecContext, codec) < 0) {
                        TRACE("  stream[%u] - failed to open AVCodecContext\n", 
i);
                }
-#endif
                TRACE("  stream[%u] time_base: (%d/%d), codec->time_base: 
(%d/%d)\n",
                        i, stream->time_base.num, stream->time_base.den,
                        stream->codec->time_base.num, 
stream->codec->time_base.den);
        }
+#endif
 
        int result = av_write_header(fContext);
        if (result < 0)
@@ -463,7 +461,7 @@
 
 
 status_t
-AVFormatWriter::AllocateCookie(void** _cookie, const media_format* format,
+AVFormatWriter::AllocateCookie(void** _cookie, media_format* format,
        const media_codec_info* codecInfo)
 {
        TRACE("AVFormatWriter::AllocateCookie()\n");

Modified: haiku/trunk/src/add-ons/media/plugins/ffmpeg/AVFormatWriter.h
===================================================================
--- haiku/trunk/src/add-ons/media/plugins/ffmpeg/AVFormatWriter.h       
2010-10-20 21:29:16 UTC (rev 39034)
+++ haiku/trunk/src/add-ons/media/plugins/ffmpeg/AVFormatWriter.h       
2010-10-20 21:36:23 UTC (rev 39035)
@@ -28,7 +28,7 @@
        virtual status_t                        Close();
 
        virtual status_t                        AllocateCookie(void** cookie,
-                                                                       const 
media_format* format,
+                                                                       
media_format* format,
                                                                        const 
media_codec_info* codecInfo);
        virtual status_t                        FreeCookie(void* cookie);
 

Modified: haiku/trunk/src/kits/media/MediaTrack.cpp
===================================================================
--- haiku/trunk/src/kits/media/MediaTrack.cpp   2010-10-20 21:29:16 UTC (rev 
39034)
+++ haiku/trunk/src/kits/media/MediaTrack.cpp   2010-10-20 21:36:23 UTC (rev 
39035)
@@ -331,6 +331,14 @@
                bigtime_t framesDuration = (bigtime_t)(*_frameCount * 1000000
                        / _FrameRate());
                fCurrentTime = _header->start_time + framesDuration;
+// This debug output shows drift between calculated fCurrentFrame and 
time-based
+// current frame, if there is any.
+//if (fFormat.type == B_MEDIA_RAW_AUDIO) {
+//printf("current frame: %lld / calculated: %lld (%.2f/%.2f)\r", fCurrentFrame,
+//int64(fCurrentTime * _FrameRate() / 1000000.0 + 0.5), fCurrentTime / 
1000000.0,
+//(float)fCurrentFrame / _FrameRate());
+//fflush(stdout);
+//}
        } else {
                ERROR("BMediaTrack::ReadFrames: decoder returned error 0x%08lx 
(%s)\n",
                        result, strerror(result));
@@ -782,7 +790,7 @@
 
 
 BMediaTrack::BMediaTrack(BPrivate::media::MediaWriter* writer,
-       int32 streamIndex, const media_format* format,
+       int32 streamIndex, media_format* format,
        const media_codec_info* codecInfo)
 {
        CALLED();
@@ -792,7 +800,6 @@
        fEncoderID = -1;
                // TODO: Not yet sure what this was needed for...
        fWriter = writer;
-       fFormat = *format;
        fStream = streamIndex;
        fInitStatus = B_OK;
 
@@ -803,14 +810,17 @@
                if (ret != B_OK) {
                        TRACE("BMediaTrack::BMediaTrack: Error: creating 
decoder failed: "
                                "%s\n", strerror(ret));
-                       // We do not set fInitStatus here, because WriteChunk 
should still work.
+                       // We do not set fInitStatus here, because WriteChunk 
should still
+                       // work.
                        fEncoder = NULL;
                } else {
                        fCodecInfo = *codecInfo;
-                       fInitStatus = fEncoder->SetUp(&fFormat);
+                       fInitStatus = fEncoder->SetUp(format);
                }
        }
 
+       fFormat = *format;
+
        // not used:
        fCurrentFrame = 0;
        fCurrentTime = 0;

Modified: haiku/trunk/src/kits/media/MediaWriter.cpp
===================================================================
--- haiku/trunk/src/kits/media/MediaWriter.cpp  2010-10-20 21:29:16 UTC (rev 
39034)
+++ haiku/trunk/src/kits/media/MediaWriter.cpp  2010-10-20 21:36:23 UTC (rev 
39035)
@@ -1,6 +1,6 @@
 /*
- * Copyright 2009, Stephan Aßmus <superstippi@xxxxxx>. All rights reserved.
- * Distributed under the terms of the MIT license.
+ * Copyright 2009-2010, Stephan Aßmus <superstippi@xxxxxx>.
+ * All rights reserved. Distributed under the terms of the MIT license.
  */
 
 
@@ -96,8 +96,7 @@
 
 status_t
 MediaWriter::CreateEncoder(Encoder** _encoder,
-       const media_codec_info* codecInfo, const media_format* format,
-       uint32 flags)
+       const media_codec_info* codecInfo, media_format* format, uint32 flags)
 {
        CALLED();
 


Other related posts:

  • » [haiku-commits] r39035 - in haiku/trunk: headers/os/media headers/private/media src/add-ons/media/plugins/ffmpeg src/kits/media - superstippi