I'm a beginner to H.264 data compression standard, and i need to know where the slice header flag (slc_hdr) of the H.264 bitstream is located ? Is it for example existed in the slice header? cause i need to extract it and set it to 1.
Summarized answer from Comments:
In order to understand a received packet, to see whether it is a slice, you need to get the NAL Header from the packet. Then, parse the NAL header and check nal_unit_type. If nal_unit_type matches to one of the values {1, 2, 3, 4 ,5}, set the slc_hdr flag. This slc_hdr flag has nothing to do with H.264 standard, it's just implementation specific.
What you pointed in your screen-shot may be to deal with VC-1 codec.
Related
there are a h264 rtp stream passing through server, I catch every rtp packets and extract every nalu by getting rid of rtp header, and then write every nalu to file record.h264 with adding a h264 prefix start code 0x00000001, but file record.h264 cannot be played by ffplay and cannot be parsed by ffprobe, where is wrong?
here is my record file:https://github.com/sshsu/record_h264_file
You might be skipping the decoding of the NAL header within the RtpPacket to it's full format from the aggregated form.
I have an implementation in C# here:
https://github.com/juliusfriedman/net7mma_core/blob/master/RtspServer/MediaTypes/RFC6184Media.cs if it helps you.
According to the description, it places global headers in extradata instead of every keyframe.
But what's the actual purpose? Is it useful e.g. for streaming?
I guess that the resulting video file will be marginally shorter, but more prone to corruption (no redundancy = file unplayable if main header corrupted or only partially downloaded)?
Or maybe it somehow improves decoding a little bit? As headers are truly global and cannot change from keyframe to keyframe?
Thanks!
By extradata FFmpeg means out-of-band, as opposed to in-band. The behavior of the flag is format specific. This is useful for headers that are not expected to change because it reduces the overhead.
Example: for H.264 in MP4 the SPS and PPS are stored in the avcC atom. For the same H.264 stream in let's say MPEG-TS the sequences are repeated in the bitstream.
I'm trying to write a decoder for a webrtc app in C. I receive a RTP stream, I parse every packet, reorder them, and put the payload in a AVPacket, as described here (FFmpeg decode raw buffer with avcodec_decode_video2).
The reordering part is not described in this link but I'm pretty sure this part is OK.
The question is, I dont know how to give the decoder information about resolution, pix_fmt etc. Do I need to create an AVstream* and fill it with all information I took from rtp header?
Do someone have a piece of running code that decode a VP8 packet depacketized without the use of rtp_dec etc.?
In this link, no more information seems to be sent to the decoder, is it able to decode without knowing resolution and without any header?
You don't need to feed "resolution, pix_fmt etc." information to decoder, as those get derived by decoder from the input AVPackets.
Encoders need such information like resolution, pix_fmt etc. to generate the compressed byte/bit-stream. And, encoders embed this (resolution, pix_fmt etc.) information in generated bit-stream. Once decoder receives bit-stream in right order, it derives the resolution, pix_fmt info before proceeding to de-compressing it.
Probably, the packet order that you are feeding to decoder is the cause in your case.
I'm going through the HEVC decoder integrated in FFMPEG. I'm actually trying to understand its flow and working.
By flow, i mean the part in code where it is reading various parameters of the input .bin file. Like where is it reading the resolution, where is it deciding the fps that it needs to play, the output display format that is yuv420p etc.
Initially What i suspected is the demuxer of hevc situated at /libavformat/hevcdec.c In this file does the input file reading work. There is a probe function which is used to detect which decoder to select while decoding the input bin stream. Further we have a FF_DEF_RAWVIDEO_DEMUXER. Is it in this function that the resolution and other parameters read from the input file?
Secondly what i suspect is the hevc parser situated at: /libavcodec/hevc_parser.c but here i think it is just parsing the frame data, that is finding end of frame. So, is this assumption of mine right?
Any suggestions or any predictions will be really helpful to me. Please provide your valuable suggestions. Thanks in advance.
To understand more specifically what is going on in decoder, it's better to start your study with HEVC/H.265 standard (http://www.itu.int/rec/T-REC-H.265). It contains all the information you need to know to find the location of resolution, fps, etc.
If you want to get more details from FFMPEG, here are some hints:
/libavcodec/hevc_parser.c contains H.265 Annex B parser, which converts byte stream into series of NAL units. Each NAL unit has its own format and should be parsed depending on its NAL unit type.
If you are looking for basic properties of video sequence, you may be interested in SPS (Sequence Parameter Set) parsing. Its format is described in section 7.3.2.2.1 of the standard and there is a function ff_hevc_decode_nal_sps located in /libavcodec/hevc_ps.c which extracts SPS parameters from the bitstream.
Note: I was talking about FFMPEG version 2.5.3. Code structure can be different for other versions.
I tried to decode a series of nal units with ffmpeg (libavcodec) but I get a "no frame" error. I produced the nal units with the guideline at How does one encode a series of images into H264 using the x264 C API?. I tried the following strategy for decoding:
avcodec_init();
avcodec_register_all();
AVCodec* pCodec;
pCodec=lpavcodec_find_decoder(CODEC_ID_H264);
AVCodecContext* pCodecContext;
pCodecContext=lpavcodec_alloc_context();
avcodec_open(pCodecContext,pCodec);
AVFrame *pFrame;
pFrame=avcodec_alloc_frame();
//for every nal unit:
int frameFinished=0;
//nalData2 is nalData without the first 4 bytes
avcodec_decode_video(pCodecContext,pFrame,&frameFinished,(uint8_t*) nalData2,nalLength);
I passed all units I got to this code but frameFinished stays 0. I guess there must be something wrong with the pCodecContext setup. Can someone send me a working example?
Thank you
Check out this tutorial. It should be able to decode any video type including H.264:
http://dranger.com/ffmpeg/
I don't know exactly what is causing the problem, but I suspect it has something to do with the fact that you are not using the av_read_frame from libavformat to parse out a frames worth of data at a time. H.264 has the ability to split a frame into multiple slices and therefore multiple NAL units.
I am pretty sure the x264 encoder does not do this by default and produces one NAL unit per frame. However, there are NAL units with other stream information that need to be fed to the decoder. I have experimented with this in the past and when av_read_frame parses out a frames worth of data, it sometimes contains multiple NAL units. I would suggest following the tutorial closely and seeing if that works.
Another thing is that I think you do need to pass the first 4 bytes of the NAL unit into avcodec_decode_video if that is the start code you are talking about (0x00000001). Having investigated the output from av_read_frame, the start codes are still in the data when passed to the decoder.
Try this after the codec context instantiation code:
if(pCodec->capabilities & CODEC_CAP_TRUNCATED)
pCodecContext->flags |= CODEC_FLAG_TRUNCATED; /* We may send incomplete frames */
if(pCodec->capabilities & CODEC_FLAG2_CHUNKS)
pCodecContext->flags2 |= CODEC_FLAG2_CHUNKS;