Browse Source

优化了一些bug

worker
unknown 7 years ago
parent
commit
f7ede79df1
  1. 45
      H5LiveClient.cpp
  2. 1
      H5LiveClient.js
  3. 2
      MemoryStream.h
  4. 54
      ffmpeg.h
  5. 4
      h5lc.py
  6. 30
      js/FlvClient.js
  7. 6
      js/flv.html
  8. 32
      public/H5LiveClient.js
  9. 31
      public/index.html

45
H5LiveClient.cpp

@ -54,8 +54,7 @@ struct H5LCBase
{
val::global("clearTimeout")(videoTimeoutId);
emscripten_log(0, "FlvDecoder release!\n");
if (videoDecoder)
delete videoDecoder;
if (audioDecoder)
delete audioDecoder;
}
@ -108,14 +107,15 @@ struct H5LCBase
unsigned int timestamp = buffer.readUInt24B();
u8 ext = buffer.readu8();
buffer.readUInt24B();
MemoryStream ms(buffer.readString(length));
MemoryStream ms;
ms << buffer.readString(length);
switch (type)
{
case 0x08:
decodeAudio(timestamp, ms);
decodeAudio(timestamp, move(ms));
break;
case 0x09:
decodeVideo(timestamp, ms);
decodeVideo(timestamp, move(ms));
break;
}
length = buffer.readUInt32B();
@ -130,13 +130,13 @@ struct H5LCBase
case 1:
{
MemoryStream ms(data.substr(1));
decodeAudio(ms.readUInt32B(), ms);
decodeAudio(ms.readUInt32B(), move(ms));
}
break;
case 2:
{
MemoryStream ms(data.substr(1));
decodeVideo(ms.readUInt32B(), ms);
decodeVideo(ms.readUInt32B(), move(ms));
}
break;
default:
@ -145,7 +145,7 @@ struct H5LCBase
}
}
}
void decodeAudio(clock_t timestamp, MemoryStream &ms)
void decodeAudio(clock_t timestamp, MemoryStream &&ms)
{
unsigned char flag = 0;
ms.readB<1>(flag);
@ -191,10 +191,8 @@ struct H5LCBase
audioDecoder = new AudioDecoder(frameCount * channels * 2);
call<void>("initAudio", frameCount, samplerate, channels, (int)audioDecoder->outputBuffer >> 1);
}
void decodeVideo(clock_t _timestamp, MemoryStream &data)
void decodeVideo(clock_t _timestamp, MemoryStream &&data)
{
if (videoDecoder == nullptr)
return;
if (waitFirstVideo)
{
u8 frame_type = data[0];
@ -224,15 +222,19 @@ struct H5LCBase
else
{
data >>= 5;
if (videoBuffer && checkTimeout(_timestamp))
if (videoBuffer && (bufferIsPlaying || checkTimeout(_timestamp)))
{
videoBuffers.emplace(_timestamp, move(data));
videoBuffers.emplace(_timestamp, forward<MemoryStream>(data));
// emscripten_log(0, "push timestamp:%d", _timestamp);
// auto &&info = val::object();
// info.set("code", "NetStream.Play.Start");
// call<void>("onNetStatus", info);
}
else
{
// emscripten_log(0, "play timestamp:%d", _timestamp);
videoDecoder->decode(data);
}
}
}
void decodeVideoBuffer()
@ -243,6 +245,7 @@ struct H5LCBase
auto &v = videoBuffers.front();
if (check && checkTimeout(v.timestamp))
return;
// emscripten_log(0, "play timestamp:%d", v.timestamp);
videoDecoder->decode(v.data);
videoBuffers.pop();
check = true;
@ -253,7 +256,7 @@ struct H5LCBase
{
auto timeout = getTimespan(timestamp);
bool isTimeout = timeout > 0;
if (isTimeout && !bufferIsPlaying)
if (isTimeout)
{
bufferIsPlaying = true;
videoTimeoutId = call<int>("playVideoBuffer", timeout);
@ -262,17 +265,17 @@ struct H5LCBase
}
clock_t getTimespan(clock_t t)
{
return call<clock_t>("timespan",t) + videoBuffer * 1000;
return call<clock_t>("timespan", t) + videoBuffer * 1000;
}
void $close()
{
val::global("clearTimeout")(videoTimeoutId);
while (!videoBuffers.empty())
{
videoBuffers.pop();
}
if (videoDecoder)
videoDecoder->clear();
videoBuffers = queue<VideoPacket>();
// while (!videoBuffers.empty())
// {
// videoBuffers.pop();
// }
videoDecoder->clear();
if (audioDecoder)
audioDecoder->clear();
videoTimeoutId = 0;

1
H5LiveClient.js

@ -314,6 +314,7 @@ mergeInto(LibraryManager.library, {
_this.decodeVideoBuffer();
}
this.playVideoBuffer = function(t) {
// console.log("setTimeout:", t);
return setTimeout(playVideo, t, this)
}
},

2
MemoryStream.h

@ -49,7 +49,7 @@ class MemoryStream
}
return *this;
}
MemoryStream(string &&right) : data(move(right)), offset(0)
MemoryStream(string &&right) : data(forward<string>(right)), offset(0)
{
}
MemoryStream(string &right) : data(move(right)), offset(0)

54
ffmpeg.h

@ -1,5 +1,6 @@
#pragma once
extern "C" {
extern "C"
{
#include <libavcodec/avcodec.h>
}
@ -11,7 +12,6 @@ class FFmpeg : public VideoDecoder
AVCodecContext *dec_ctx = NULL;
AVFrame *frame;
AVPacket *pkt;
MemoryStream extradata;
FFmpeg() : pkt(av_packet_alloc()), frame(av_frame_alloc())
{
emscripten_log(0, "FFMpeg init");
@ -19,48 +19,32 @@ class FFmpeg : public VideoDecoder
~FFmpeg()
{
emscripten_log(0, "FFMpeg destory");
av_parser_close(parser);
avcodec_free_context(&dec_ctx);
clear();
av_frame_free(&frame);
av_packet_free(&pkt);
}
void clear() override{
void clear() override
{
VideoDecoder::clear();
extradata.clear();
av_parser_close(parser);
avcodec_free_context(&dec_ctx);
av_parser_close(parser);
free(dec_ctx->extradata);
avcodec_free_context(&dec_ctx);
}
void decodeHeader(MemoryStream &data, int codec_id) override
{
codec = avcodec_find_decoder(codec_id == 7 ? AV_CODEC_ID_H264 : AV_CODEC_ID_H265);
emscripten_log(0, "codec = %d,ptr = %d", codec_id,codec);
emscripten_log(0, "codec = %d,ptr = %d", codec_id, codec);
parser = av_parser_init(codec->id);
dec_ctx = avcodec_alloc_context3(codec);
if (codec_id == 7)
{
u8 lengthSizeMinusOne = data[9];
lengthSizeMinusOne &= 0x03;
NAL_unit_length = lengthSizeMinusOne;
data >>= 5;
extradata << data;
extradata.consoleHex();
extradata.offset = data.offset;
dec_ctx->extradata = (u8 *)(const u8 *)extradata;
dec_ctx->extradata_size = extradata.length();
//dec_ctx->extradata = (u8 *)(const u8 *)data;
dec_ctx->extradata_size = data.length();
dec_ctx->extradata = (u8 *)malloc(dec_ctx->extradata_size);
memcpy( dec_ctx->extradata,(const u8 *)data,dec_ctx->extradata_size);
auto ret = avcodec_open2(dec_ctx, codec, NULL);
emscripten_log(0, "avcodec_open2:%d",ret);
// int spsLen = 0;
// int ppsLen = 0;
// data.read2B(spsLen);
// if (spsLen > 0) {
// _decode((const char*)data,spsLen);
// data >>= spsLen;
// }
// data >>= 1;
// data.read2B(ppsLen);
// if (ppsLen > 0) {
// _decode((const char*)data,ppsLen);
// }
emscripten_log(0, "avcodec_open2:%d", ret);
}
else
{
@ -86,7 +70,7 @@ class FFmpeg : public VideoDecoder
_decode((const char *)data, data.length());
}
void _decode(const char *data, int len) override
{
{ //emscripten_log(0, "len:%d", len);
int ret = av_parser_parse2(parser, dec_ctx, &pkt->data, &pkt->size,
(const u8 *)(data), len, AV_NOPTS_VALUE, AV_NOPTS_VALUE, 0);
if (ret >= 0 && pkt->size)
@ -100,12 +84,14 @@ class FFmpeg : public VideoDecoder
p_yuv[0] = (u32)frame->data[0];
p_yuv[1] = (u32)frame->data[1];
p_yuv[2] = (u32)frame->data[2];
if (videoWidth != frame->width || videoHeight!= frame->height)
if (videoWidth != frame->width || videoHeight != frame->height)
decodeVideoSize(frame->width, frame->height);
decodeYUV420();
}
}else{
emscripten_log(0,"ffmpeg decode ret:%d",ret);
}
else
{
emscripten_log(0, "ffmpeg decode ret:%d", ret);
}
}
};

4
h5lc.py

@ -36,9 +36,9 @@ emcc_args = [
'-IBroadway', '-I.',
#'-I../libid3tag',
'-Iffmpeg/include',
# '-DUSE_MP3',
'-DUSE_MP3',
#'-DUSE_LIBDE265',
'-DUSE_AAC',
# '-DUSE_AAC',
'-DUSE_FFMPEG',
'--js-library', 'H5LiveClient.js'
]

30
js/FlvClient.js
File diff suppressed because it is too large
View File

6
js/flv.html

@ -31,8 +31,8 @@
function test() {
//mc.connect("182.16.68.70:81", "live", "")
fc.play("ws://localhost:8080/live/user1", webGLCanvas)
// fc.play("ws://test.qihaipi.com/gnddragon/test1.flv",webGLCanvas)
// fc.play("ws://localhost:8080/live/user1", webGLCanvas)
fc.play("ws://test.qihaipi.com/gnddragon/h2642.flv", webGLCanvas)
//fc.play("ws://192.168.2.205:8088/live/user1.flv", document.getElementById("canvas"));
//fc.play("ws://182.16.68.41:8088/live/test.flv", webGLCanvas);
//mc.connect("113.10.201.210:81", "live", "")
@ -91,7 +91,7 @@
postRun: function() {
webGLCanvas = new WebGLCanvas(document.getElementById("canvas"), Module["noWebGL"], {});
fc = new FlvClient();
fc.videoBuffer = 0;
fc.videoBuffer = 1;
fc.audioBuffer = 12;
fc.onNetStatus = function(info) {
console.log(info.code);

32
public/H5LiveClient.js
File diff suppressed because it is too large
View File

31
public/index.html

@ -3,7 +3,7 @@
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>FlvClient 1.0</title>
<title>H5LiveClient 1.0</title>
<meta charset="utf-8" />
</head>
@ -17,9 +17,33 @@
onerror = handleErr;
var txt = "";
var h5lc = null;
var canvas = document.getElementById("canvas");
disabledMouseWheel(canvas)
function test() {
h5lc.play("ws://localhost:8080/live/user1", document.getElementById("canvas"))
// h5lc.play("ws://localhost:8080/live/user1", document.getElementById("canvas"))
h5lc.play("ws://test.qihaipi.com/gnddragon/h2642.flv", canvas)
}
function disabledMouseWheel(ele) {
if (ele.addEventListener) {
ele.addEventListener('DOMMouseScroll', scrollFunc, false);
} //W3C
ele.onmousewheel = scrollFunc; //IE/Opera/Chrome
}
function scrollFunc(evt) {
evt = evt || window.event;
if (evt.preventDefault) {
// Firefox
evt.preventDefault();
evt.stopPropagation();
} else {
// IE
evt.cancelBubble = true;
evt.returnValue = false;
}
return false;
}
function handleErr(msg, url, l) {
@ -31,7 +55,6 @@
return true;
}
var Module = {
noWebGL: false,
print: (function() {
return function(text) {
if (arguments.length > 1) text = Array.prototype.slice.call(arguments).join(' ');
@ -55,7 +78,7 @@
},
postRun: function() {
h5lc = new H5LiveClient();
h5lc.videoBuffer = 0;
h5lc.videoBuffer = 1;
}
};
</script>

Loading…
Cancel
Save