4

I have an IP Camera which gives H264 annexb Bitstream through SDK calls. I want to pack this video stream into FLV container. So far I've got to know the following :-

I have to convert H264 annexb to H264 AVCC : For this I'll have to replace NAL header byte (0x00000001) with Size of NALU (big endian format).

My question is, What do I do with SPS and PPS ? should I write (av_interleaved_write_frame) them as are after replacing the NAL header ? or do I not write these frames at all ?

I read about AVCC requiring extra data. How do I construct that ? where do I pass that ?

Muhammad Ali
  • 418
  • 6
  • 20

1 Answers1

4

First retrieve the SPS/PPS from the camera. Write the SPS/PPS to AVCC extradata format (see how to here: Possible Locations for Sequence/Picture Parameter Set(s) for H.264 Stream)

Set AVCodecContext.extradata

void *extradata = /**/;
int extradata_size = /**/;
codecCtx->extradata_size = extradata_size;
codecCtx->extradata = av_malloc ( codecCtx->extradata_size );
memcpy ( codecCtx->extradata, extradata, codecCtx->extradata_size);

Before calling avcodec_open2

Community
  • 1
  • 1
szatmary
  • 29,969
  • 8
  • 44
  • 57
  • I am not re-encoding the stream. I am just muxing it into FLV. So I don't have "avcodec_open2" in my code. ret = avcodec_copy_context(out_stream->codec, in_stream->codec); can I just assign extra data to outstream->codec->extradata ? after the copy context ? – Muhammad Ali Apr 21 '15 at 04:09
  • 1
    I understand. You don't need to call avcodec_encode_video(), but you should call open_codec2(). Its does final initialization of the AVCodecContext (parses the extradata and initializes internal variables such as resolution). – szatmary Apr 21 '15 at 04:12
  • ok I understand. One thing i've noticed is that I get SPS periodically. Does that mean i will be required to pass extra data to the CodecContext again n again ? i-e open_codec2 again and again whenever I get SPS ? – Muhammad Ali Apr 21 '15 at 05:12
  • 1
    No, you will not need to modify extradata or call open_codec2 a second time. Assuming its the same sps id as the first one (almost certainly) you can drop it. Personally I would just include it like any other NALU. Its very small and will have little effect on overall bitrate/file size. And then your covered if the encoder does change the id. – szatmary Apr 21 '15 at 05:18
  • Ok, Now I have extra data provided to the codec. I can print and verify the extra data to be correct. I am writing all NALU into the stream. the resultant video gets stuck on first frame but there are no errors in console (using ffplay). Duration is wrong and so is the bitrate. "Duration: 62:37:35.40, start: 0.000000, bitrate: 0 kb/s Stream #0:0, 41, 1/1000: Video: h264 (Main), yuvj420p(pc, bt709, left), 1280x720 [SAR 1:1 DAR 16:9], 1001/60000, 591 kb/s, 30.33 fps, 3.33 tbr, 1k tbn, 59.94 tbc Stream #0:1, 32, 1/1000: Audio: aac, 48000 Hz, mono, fltp, 45 kb/s " – Muhammad Ali Apr 21 '15 at 05:45
  • wrong duration and bad playback was due to bad pts and another bug in the code. Now I have a playable video. But the console shows "missing picture in access unit" errors followed by "no frame". although the video and audio play fine and are in proper sync. What else is there to be corrected to make them disappear ? Also advise what pts dts should be assigned to pps sps packets if i am writing them along in the stream. – Muhammad Ali Apr 21 '15 at 06:32
  • Make sure you read the link. SPS/PPS belong at the start of an access unit (i.e. frame). They should not be their own access unit. So one single AU should be SPS, PPS, Slice(s). If you can get your encoder to produces AUDs it will be a lot easier. – szatmary Apr 21 '15 at 09:50
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/75795/discussion-between-muhammad-ali-and-szatmary). – Muhammad Ali Apr 21 '15 at 10:52