RReverser / mpegts

Javascript HTTP Live Streaming realtime converter and player
http://rreverser.github.io/mpegts/
MIT License
839 stars 155 forks source link

"Unknown type: dependentField" when trying to write PES packet #23

Open MaMazav opened 9 years ago

MaMazav commented 9 years ago

I'm trying to write a PES packet using jBinary and PES.js implemented in this repo. Something like:

    var PES = require('./mpegts/mpegts_to_mp4/pes.js');
    var jBinary = require('jbinary');
    var streamId;
    var data;
    // ...
    var pesHeaderLength = 11;
    lastCameraModelPesPacketToSerialize = {
        streamId: streamId,
        length: data.length,
        scramblingControl: 0,
        priority: 0,
        dataAlignmentIndicator: 0,
        hasCopyright: 0,
        isOriginal: 1,
        //_hasPTS: 0,
        //_hasDTS: 0,
        //_hasESCR: 0,
        //_hasESRate: 0,
        dsmTrickMode: 0,
        //_hasAdditionalCopyInfo: 0,
        //_hasPESCRC: 0,
        //_hasExtension: 0,
        dataLength: 5,
        data: data
    };
    var pesWriter = new jBinary(data.length + pesHeaderLength, PES);
    pesWriter.write('PESPacket', pesPacket);

I get the following exception: if (!(type in this.typeSet)) throw new ReferenceError("Unknown typ ^ ReferenceError: Unknown type: dependentField at jBinary.proto._getType (\node_modules\jbinary\dist\node\jbinary.js:198:48)

I guess that it's a simple bug in the PES definition which arises when trying to WRITE PES packet (which is not the common scenario in this repo), or that I've done something stupid. But due to lack of internal knowledge in jBinary implementation I found it hard to debug the problem.

Any help is appreciated.

EDIT: The same error appears also when trying to write an mpegts packet using mpegts.js. (It does not necessary mean that the problem is in jBinary, because the implementation of FlagDependent and Flag types is duplicated and identical between MPEGTS and PES).

RReverser commented 9 years ago

This shouldn't happen. Please install stack-displayname to your project as dev dependency for better logs and also you can use lines from https://github.com/RReverser/mpegts/blob/gh-pages/node.js#L3-L24 for even more clear output.

Then, you should see error stack trace being built from type names, field names and binary offsets instead of anonymous internal functions - hopefully that will help to track the issue more precisely.

MaMazav commented 9 years ago

Thanks for reply. I've done it now but the error is still the same. Anyway my problem is not about understanding where the problem is. I've debugged jBinary and understood that the problem is that it tries to parse 'dependentField' parameter of 'Flag' as a type instead of as a parameter name. It happens on the hasPTS field of PESPacket. I just don't know why it happens because I don't know jBinary internals.

RReverser commented 9 years ago

I've done it now but the error is still the same. Anyway my problem is not about understanding where the problem is.

That's exactly why I suggested steps above. They don't fix anything, just help to see error in better format to understand where and why it occurs.

This has nothing to do with jBinary internals, most likely problem with some definition, but I can't say anything for sure without prepared stacktrace.

RReverser commented 9 years ago

Could you please show me your stacktrace prepared in this way?

MaMazav commented 9 years ago

Oh sorry, I was unclear. By saying "I've done it now but the error is still the same" I meant that I could not make it work and the error and stacktrace is shown in the same way as before. I copied the code to the beginning of my node script and installed stack-displayname, but the result is the same as before.

Anyway I debugged it and found that it fails within the following "stack": PESPacket -> hasPTS -> Flag -> getType('dependentField').

I ended up by workaround, so the issue is irrelevant for me, but I can try provide more information if you still want to solve the bug.

Thanks anyway

RReverser commented 9 years ago

I copied the code to the beginning of my node script and installed stack-displayname, but the result is the same as before.

I hope you did notice that given block depends on process.env.NODE_ENV === 'development' condition that needs to be either satisfied by setting NODE_ENV="development" in environment variables or just removed so that the import happens unconditionally?

RReverser commented 9 years ago

PESPacket -> hasPTS -> Flag -> getType('dependentField').

This is pretty weird since Flag shouldn't perform getType (and if it would, online demo would also break). Not sure what's happening there.

MaMazav commented 9 years ago

I tried to comment out the condition, but the stack trace is still unclear.

As an alternative, I created a small piece of code which reproduces the problem. Just npm install mpegts and jbinary in the folder and execute the following code:

// Enable advanced stack in dev mode.
//if (process.env.NODE_ENV === 'development') {
    require('stack-displayname');

    Error.stackTraceLimit = Infinity;
    var prevPrepareStackTrace = Error.prepareStackTrace;
    Error.prepareStackTrace = function(error, frames) {
        var firstNamedIndex = 0, firstNonNamedIndex = 0;
        var filteredFrames = frames.filter(function(frame, index) {
            if ('displayName' in frame.getFunction()) {
                if (!firstNamedIndex) {
                    firstNamedIndex = index;
                }
                firstNonNamedIndex = index + 1;
                return true;
            } else {
                return false;
            }
        });
        return prevPrepareStackTrace(error, frames.slice(0, firstNamedIndex).concat(filteredFrames).concat(frames.slice(firstNonNamedIndex)));
    };
//}

var PES = require('./node_modules/mpegts_to_mp4/mpegts_to_mp4/PES.js');
var jBinary = require('jbinary');

var payload = [0xC0, 0xC0, 0xA0, 0xC0, 0xFF, 0xEE];

var pesHeaderLength = 11;
var packetToSerialize = {
    streamId: 0xC0,
    length: payload.length,
    scramblingControl: 0,
    priority: 0,
    dataAlignmentIndicator: 0,
    hasCopyright: 0,
    isOriginal: 1,
    //_hasPTS: 0,
    //_hasDTS: 0,
    //_hasESCR: 0,
    //_hasESRate: 0,
    dsmTrickMode: 0,
    //_hasAdditionalCopyInfo: 0,
    //_hasPESCRC: 0,
    //_hasExtension: 0,
    dataLength: 5,
    data: payload
};

var pesWriter = new jBinary(payload.length + pesHeaderLength, PES);
pesWriter.write('PESPacket', packetToSerialize);