[Live-devel] H264VideoFramer truncating frames
Robert Smith
smith at cognitec.com
Wed Mar 11 05:54:42 PDT 2015
I've got this working now, I think my problem was conceptually treating
the byte stream as a series of frames instead of as a continuous stream.
Having looked at the ByteStreamMemoryBufferSource class it makes a lot
more sense now.
On 03/11/2015 10:10 AM, Robert Smith wrote:
> Firstly apologies for the multiple posts.
>
> The platform is a TI DaVinci DM8148 using TI's HDVICP2 video encoder
> hardware. As far as I can tell the encoder is capable of outputting
> discrete NALU's but we are only able to use the encoder via an OpenMAX
> API which doesn't expose this behaviour.. it's frustrating!.
>
> The encoder provides discrete 'frames' which consist of a buffer of
> concatenated NALU's prepended with the start codes.
>
> Now that I think about it, If the H264VideoFramer is expecting to read
> X bytes from a continuous stream, I should be able to give it only
> part of the 'frame' that I receive from the encoder? I'll try this and
> see how it works.
>
> Btw, On our other systems we use the Intel IPP H264 encoder and the
> Intel Media SDK encoder, I'm not as familiar with them but I
> understand that they also don't output discrete NALU's so I thought
> this was common amongst encoders.
>
>
> Regarding slices, I can configure the encoder to encode a frame as
> multiple slices based either on a maximum slice size or number of MB's
> per slice but we're using GStreamer as one of our clients and I get a
> lot of image corruption with multiple slices enabled.
>
> I haven't had time to look into the problem deeper but using a single
> slice was a quick and easy solution.
>
> Thanks,
>
> Robert Smith.
>
> On 03/10/2015 01:49 AM, Ross Finlayson wrote:
>>> The encoder unfortunately only supplies frames in Annex B byte
>>> stream format requiring the frames to be parsed.
>>
>> Are you sure about this? (Often, hardware encoders have firmware
>> upgrades available.)
>>
>>
>>> Previously I was using my own class to identify the NAL unit's in
>>> conjunction with the H264VideoDiscreteFramer which worked fine but
>>> it's heavy on the CPU. So I've been trying to use the
>>> H264VideoFramer and just pass the full frames in which works ok and
>>> is faster than my solution except that I'm seeing a lot of truncated
>>> frames.
>>>
>>> Having looked into the code it appears to be caused by the behaviour
>>> of the StreamParser class; specifically the ensureValidBytes1()
>>> method which calls getNextFrame() on my source with maxSize =
>>> BANK_SIZE - fTotNumValidBytes. The method switches banks to ensure
>>> that the larger of numBytesNeeded or the input sources
>>> maxFrameSize() will fit.
>>>
>>> I can 'fix' the problem by increasing BANK_SIZE and implementing
>>> maxFrameSize() on my source but I'm not totally happy with this
>>> solution because I would prefer not to modify the library source and
>>> I'm just guessing for the maxFrameSize() value.
>>>
>>> I was wondering whether it's possible to return a partial frame from
>>> my video source?
>>
>> Yes, but not in the way that you might think :-) A H.264 encoder
>> actually delivers "NAL units". "NAL units" are what actually get
>> parsed by our code, and packed into RTP packets.
>>
>> Often, a "NAL unit" is a complete frame. It is possible, however,
>> for a 'key frame' to be split up - by your encoder - into multiple
>> 'slice' NAL units. For datagram streaming (e.g., over RTP), it is
>> *much* better to have your key frames broken up into multiple 'slice'
>> NAL units, than to have the key frame be a single, large NAL unit -
>> which is what you have now. This is especially true if your key
>> frames are exceptionally large: ~150000 bytes or larger, which
>> appears to be the case for you, because you are hitting the BANK_SIZE
>> limit (which was deliberately set to be larger than realistically
>> needed).
>>
>> Note that a 150000 byte key frame NAL unit will get transmitted as
>> more than 1000 RTP packets (datagrams). (Our code automatically
>> handles the required fragmentation.) If *any* of these 1000 packets
>> gets lost in transit, then the entire key frame will be undeliverable.
>>
>> If, instead, your encoder delivers each key frame as multiple 'slice'
>> NAL units, then your streaming will be much more resilient to network
>> packet loss.
>>
>> So, your first task should be to check whether your encoder:
>> 1/ can be reconfigured to deliver discrete frames, rather than a
>> stream with each NAL unit prepended by a 0x00 0x00 0x00 0x01 'start
>> code', and
>> 2/ can be reconfigured to deliver key frames as multiple 'slice' NAL
>> units, rather than as a single (ridiculously large) NAL unit.
>>
>>
>> Ross Finlayson
>> Live Networks, Inc.
>> http://www.live555.com/
>>
>>
>>
>> _______________________________________________
>> live-devel mailing list
>> live-devel at lists.live555.com
>> http://lists.live555.com/mailman/listinfo/live-devel
>
>
>
> _______________________________________________
> live-devel mailing list
> live-devel at lists.live555.com
> http://lists.live555.com/mailman/listinfo/live-devel
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.live555.com/pipermail/live-devel/attachments/20150311/a723a9dc/attachment.html>
More information about the live-devel
mailing list