[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Gnash-commit] /srv/bzr/gnash/trunk r10004: Add support for FLVs with em
From: |
Bastiaan Jacques |
Subject: |
[Gnash-commit] /srv/bzr/gnash/trunk r10004: Add support for FLVs with embedded H.264 video: |
Date: |
Sun, 19 Oct 2008 21:05:30 +0200 |
User-agent: |
Bazaar (1.5) |
------------------------------------------------------------
revno: 10004
committer: Bastiaan Jacques <address@hidden>
branch nick: trunk
timestamp: Sun 2008-10-19 21:05:30 +0200
message:
Add support for FLVs with embedded H.264 video:
libmedia/FLVParser.cpp: For h264, skip four extra bytes per FLV spec.
Stop attempting to parse width and height for h.263, since it's not
necessary (and our values for other video codecs were bogus).
libmedia/FLVParser.h: Add FLV-specific extradata (for h264).
libmedia/MediaParser.h: Add h264 to codec type enum.
libmedia/ffmpeg/VideoDecoderFfmpeg.cpp: Add FLVParser's extradata.
libmedia/gst: Update interfaces to include FLVParser's extradata.
modified:
libmedia/FLVParser.cpp
libmedia/FLVParser.h
libmedia/MediaParser.h
libmedia/ffmpeg/VideoDecoderFfmpeg.cpp
libmedia/gst/MediaHandlerGst.cpp
libmedia/gst/VideoDecoderGst.cpp
libmedia/gst/VideoDecoderGst.h
=== modified file 'libmedia/FLVParser.cpp'
--- a/libmedia/FLVParser.cpp 2008-09-30 22:44:56 +0000
+++ b/libmedia/FLVParser.cpp 2008-10-19 19:05:30 +0000
@@ -370,11 +370,26 @@
boost::uint16_t codec = (tag[11] & 0x0f) >> 0;
- if (codec == VIDEO_CODEC_VP6 || codec == VIDEO_CODEC_VP6A)
- {
- _stream->read_byte();
- --bodyLength;
- }
+ if (codec == VIDEO_CODEC_VP6 || codec == VIDEO_CODEC_VP6A)
+ {
+ _stream->read_byte();
+ --bodyLength;
+ }
+
+ bool header = false;
+
+ if (codec == VIDEO_CODEC_H264) {
+ boost::uint8_t packettype = _stream->read_byte();
+ IF_VERBOSE_PARSE( log_debug(_("AVC packet type: %d"),
(unsigned)packettype) );
+
+ header = (packettype == 0);
+
+ // 24-bits value for composition time offset ignored
for now.
+ boost::uint8_t tmp[3];
+ _stream->read(tmp, 3);
+
+ bodyLength -= 4;
+ }
if ( doIndex )
{
@@ -399,74 +414,18 @@
// video format has been noted, so we do that now
if ( ! _videoInfo.get() )
{
- // Set standard guessed size...
- boost::uint16_t width = 320;
- boost::uint16_t height = 240;
-
- // Extract the video size from the videodata header
- if (codec == VIDEO_CODEC_H263) {
-
- // We're going to re-read some data here
- // (can likely avoid with a better cleanup)
-
- size_t bkpos = _stream->tell();
- if ( _stream->seek(dataPosition) ) {
- log_error(" Couldn't seek to VideoTag
data position -- should never happen, as we just read that!");
- _parsingComplete=true;
- _indexingCompleted=true;
- return false;
- }
- boost::uint8_t videohead[12];
-
- int actuallyRead = _stream->read(videohead, 12);
- _stream->seek(bkpos); // rewind
-
- if ( actuallyRead < 12 )
- {
- log_error("FLVParser::parseNextTag: can't read H263 video
header (needed 12 bytes, only got %d)", actuallyRead);
- _parsingComplete=true;
- _indexingCompleted=true;
- return false;
- }
-
- bool sizebit1 = (videohead[3] & 0x02);
- bool sizebit2 = (videohead[3] & 0x01);
- bool sizebit3 = (videohead[4] & 0x80);
-
- // First some predefined sizes
- if (!sizebit1 && sizebit2 && !sizebit3 ) {
- width = 352;
- height = 288;
- } else if (!sizebit1 && sizebit2 && sizebit3 ) {
- width = 176;
- height = 144;
- } else if (sizebit1 && !sizebit2 && !sizebit3 )
{
- width = 128;
- height = 96;
- } else if (sizebit1 && !sizebit2 && sizebit3 ) {
- width = 320;
- height = 240;
- } else if (sizebit1 && sizebit2 && !sizebit3 ) {
- width = 160;
- height = 120;
-
- // Then the custom sizes (1 byte - untested and
ugly)
- } else if (!sizebit1 && !sizebit2 && !sizebit3
) {
- width = (videohead[4] & 0x40) |
(videohead[4] & 0x20) | (videohead[4] & 0x20) | (videohead[4] & 0x08) |
(videohead[4] & 0x04) | (videohead[4] & 0x02) | (videohead[4] & 0x01) |
(videohead[5] & 0x80);
-
- height = (videohead[5] & 0x40) |
(videohead[5] & 0x20) | (videohead[5] & 0x20) | (videohead[5] & 0x08) |
(videohead[5] & 0x04) | (videohead[5] & 0x02) | (videohead[5] & 0x01) |
(videohead[6] & 0x80);
-
- // Then the custom sizes (2 byte - untested and
ugly)
- } else if (!sizebit1 && !sizebit2 && sizebit3 )
{
- width = (videohead[4] & 0x40) |
(videohead[4] & 0x20) | (videohead[4] & 0x20) | (videohead[4] & 0x08) |
(videohead[4] & 0x04) | (videohead[4] & 0x02) | (videohead[4] & 0x01) |
(videohead[5] & 0x80) | (videohead[5] & 0x40) | (videohead[5] & 0x20) |
(videohead[5] & 0x20) | (videohead[5] & 0x08) | (videohead[5] & 0x04) |
(videohead[5] & 0x02) | (videohead[5] & 0x01) | (videohead[6] & 0x80);
-
- height = (videohead[6] & 0x40) |
(videohead[6] & 0x20) | (videohead[6] & 0x20) | (videohead[6] & 0x08) |
(videohead[6] & 0x04) | (videohead[6] & 0x02) | (videohead[6] & 0x01) |
(videohead[7] & 0x80) | (videohead[7] & 0x40) | (videohead[7] & 0x20) |
(videohead[7] & 0x20) | (videohead[7] & 0x08) | (videohead[7] & 0x04) |
(videohead[7] & 0x02) | (videohead[7] & 0x01) | (videohead[8] & 0x80);
- }
-
+ _videoInfo.reset( new VideoInfo(codec, 0 /* width */, 0
/* height */, 0 /*frameRate*/, 0 /*duration*/, FLASH /*codec type*/) );
+
+ if (header) {
+ boost::uint8_t* newbuf = new
boost::uint8_t[frame->dataSize()];
+ memcpy(newbuf, frame->data(),
frame->dataSize());
+
+ _videoInfo->extra.reset(
+ new ExtraVideoInfoFlv(newbuf,
frame->dataSize())
+ );
}
// Create the videoinfo
- _videoInfo.reset( new VideoInfo(codec, width, height, 0
/*frameRate*/, 0 /*duration*/, FLASH /*codec type*/) );
}
// Release the stream lock
@@ -627,6 +586,7 @@
// We won't need frameNum, so will set to zero...
// TODO: fix this ?
// NOTE: ownership of 'data' is transferred here
+
frame.reset( new EncodedVideoFrame(data, dataSize, 0, timestamp) );
return frame;
}
=== modified file 'libmedia/FLVParser.h'
--- a/libmedia/FLVParser.h 2008-09-02 23:15:48 +0000
+++ b/libmedia/FLVParser.h 2008-10-19 19:05:30 +0000
@@ -42,6 +42,21 @@
namespace gnash {
namespace media {
+
+
+class ExtraVideoInfoFlv : public VideoInfo::ExtraInfo
+{
+public:
+ ExtraVideoInfoFlv(boost::uint8_t* extradata, size_t datasize)
+ :
+ data(extradata),
+ size(datasize)
+ {
+ }
+ boost::scoped_array<boost::uint8_t> data;
+ size_t size;
+};
+
/// The FLVParser class parses FLV streams
class DSOEXPORT FLVParser : public MediaParser
{
=== modified file 'libmedia/MediaParser.h'
--- a/libmedia/MediaParser.h 2008-10-05 00:08:38 +0000
+++ b/libmedia/MediaParser.h 2008-10-19 19:05:30 +0000
@@ -89,7 +89,9 @@
VIDEO_CODEC_VP6A = 5,
/// Screenvideo2 codec
- VIDEO_CODEC_SCREENVIDEO2 = 6
+ VIDEO_CODEC_SCREENVIDEO2 = 6,
+
+ VIDEO_CODEC_H264 = 7
};
std::ostream& operator<< (std::ostream& os, const videoCodecType& t);
=== modified file 'libmedia/ffmpeg/VideoDecoderFfmpeg.cpp'
--- a/libmedia/ffmpeg/VideoDecoderFfmpeg.cpp 2008-10-01 15:15:40 +0000
+++ b/libmedia/ffmpeg/VideoDecoderFfmpeg.cpp 2008-10-19 19:05:30 +0000
@@ -40,6 +40,8 @@
#include <boost/format.hpp>
#include <algorithm>
+#include "FLVParser.h"
+
namespace gnash {
namespace media {
@@ -129,10 +131,15 @@
int extradataSize=0;
if ( info.extra.get() )
{
- assert(dynamic_cast<ExtraVideoInfoFfmpeg*>(info.extra.get()));
- const ExtraVideoInfoFfmpeg& ei =
static_cast<ExtraVideoInfoFfmpeg&>(*info.extra);
- extradata = ei.data;
- extradataSize = ei.dataSize;
+ if (dynamic_cast<ExtraVideoInfoFfmpeg*>(info.extra.get())) {
+ const ExtraVideoInfoFfmpeg& ei =
static_cast<ExtraVideoInfoFfmpeg&>(*info.extra);
+ extradata = ei.data;
+ extradataSize = ei.dataSize;
+ } else if (dynamic_cast<ExtraVideoInfoFlv*>(info.extra.get())) {
+ const ExtraVideoInfoFlv& ei =
static_cast<ExtraVideoInfoFlv&>(*info.extra);
+ extradata = ei.data.get();
+ extradataSize = ei.size;
+ } else assert(0);
}
init(codec_id, info.width, info.height, extradata, extradataSize);
}
@@ -170,14 +177,9 @@
throw MediaException(msg.str());
}
- ctx->width = width;
- ctx->height = height;
-
log_debug(_("VideoDecoder: initialized FFMPEG codec %s (%d)"),
_videoCodec->name, (int)codecId);
- assert(ctx->width > 0);
- assert(ctx->height > 0);
}
VideoDecoderFfmpeg::~VideoDecoderFfmpeg()
@@ -279,7 +281,6 @@
std::auto_ptr<image::ImageBase>
VideoDecoderFfmpeg::decode(const boost::uint8_t* input, boost::uint32_t
input_size)
{
-
// This object shouldn't exist if there's no codec, as it can'
// do anything anyway.
assert(_videoCodecCtx.get());
@@ -343,6 +344,8 @@
{
// Find the decoder and init the parser
switch(format) {
+ case VIDEO_CODEC_H264:
+ return CODEC_ID_H264;
case VIDEO_CODEC_H263:
// CODEC_ID_H263I didn't work with Lavc51.50.0
// and NetStream-SquareTest.swf
=== modified file 'libmedia/gst/MediaHandlerGst.cpp'
--- a/libmedia/gst/MediaHandlerGst.cpp 2008-10-05 00:08:38 +0000
+++ b/libmedia/gst/MediaHandlerGst.cpp 2008-10-19 19:05:30 +0000
@@ -75,7 +75,16 @@
int width = info.width;
int height = info.height;
- std::auto_ptr<VideoDecoder> ret( new VideoDecoderGst(format, width,
height) );
+ boost::uint8_t* extradata = 0;
+ size_t datasize = 0;
+
+ ExtraVideoInfoFlv* extrainfo =
dynamic_cast<ExtraVideoInfoFlv*>(info.extra.get());
+ if (extrainfo) {
+ extradata = extrainfo->data.get();
+ datasize = extrainfo->size;
+ }
+
+ std::auto_ptr<VideoDecoder> ret( new VideoDecoderGst(format, width,
height, extradata, datasize) );
return ret;
}
=== modified file 'libmedia/gst/VideoDecoderGst.cpp'
--- a/libmedia/gst/VideoDecoderGst.cpp 2008-10-07 19:32:41 +0000
+++ b/libmedia/gst/VideoDecoderGst.cpp 2008-10-19 19:05:30 +0000
@@ -39,13 +39,27 @@
}
-VideoDecoderGst::VideoDecoderGst(videoCodecType codec_type, int width, int
height)
+VideoDecoderGst::VideoDecoderGst(videoCodecType codec_type, int width, int
height,
+ const boost::uint8_t* extradata, size_t
extradatasize)
{
// init GStreamer. TODO: what about doing this in MediaHandlerGst ctor?
gst_init (NULL, NULL);
GstCaps* caps;
switch (codec_type) {
+ case VIDEO_CODEC_H264:
+ {
+ caps = gst_caps_new_simple ("video/x-h264",
+ NULL);
+
+ if (extradata && extradatasize) {
+
+ GstBuffer* buf = gst_buffer_new_and_alloc(extradatasize);
+ memcpy(GST_BUFFER_DATA(buf), extradata, extradatasize);
+ gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, buf, NULL);
+ }
+ break;
+ }
case VIDEO_CODEC_H263:
caps = gst_caps_new_simple ("video/x-flash-video",
NULL);
=== modified file 'libmedia/gst/VideoDecoderGst.h'
--- a/libmedia/gst/VideoDecoderGst.h 2008-10-13 09:43:19 +0000
+++ b/libmedia/gst/VideoDecoderGst.h 2008-10-19 19:05:30 +0000
@@ -76,7 +76,8 @@
class DSOEXPORT VideoDecoderGst : public VideoDecoder
{
public:
- VideoDecoderGst(videoCodecType codec_type, int width, int height);
+ VideoDecoderGst(videoCodecType codec_type, int width, int height,
+ const boost::uint8_t* extradata, size_t extradatasize);
VideoDecoderGst(GstCaps* caps);
~VideoDecoderGst();
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Gnash-commit] /srv/bzr/gnash/trunk r10004: Add support for FLVs with embedded H.264 video:,
Bastiaan Jacques <=