About h.264 sps, pps
SPS = 00 00 01 67 . 81 00 PPS = 00 00 01 68 . 80 00 right? I know SPS, PPS have 3 or 4 byte pattern. SPS is obviously 3 bytes, But what is bytes of PPS? 00 00 00 01 68? or 00 00 01 68 ?
asked Jun 19, 2018 at 1:28
375 2 2 silver badges 13 13 bronze badges
1 Answer 1
00 00 00 01 68 ? or 00 00 01 68 ?
Both are correct. Any NALU (sps, pps, aud, sei, idr, whatever) can have a 3 OR 4 byte start code.
answered Jun 19, 2018 at 3:10
30.1k 8 8 gold badges 44 44 silver badges 57 57 bronze badges
-
The Overflow Blog
Related
Hot Network Questions
Subscribe to RSS
Question feed
To subscribe to this RSS feed, copy and paste this URL into your RSS reader.
Site design / logo © 2023 Stack Exchange Inc; user contributions licensed under CC BY-SA . rev 2023.10.27.43697
By clicking “Accept all cookies”, you agree Stack Exchange can store cookies on your device and disclose information in accordance with our Cookie Policy.
Что заставляет кодировщик часто генерировать SPS\PPS?
Хочу записывать mp4 из webrtc стрима. Проблема в том, что кодировщик chrome почему то слишком часто (с каждым IDR) посылает ещё и SPS\PPS пакеты. Парсил и сравнивал эти SPS\PPS, они все одинаковые (за исключением битов выравнивания в конце rbsp_alignment_zero_bit). Разрешение в потоке идет постоянное, не изменяется
Смотрел другие видео, везде SPS посылается один, в начале видео. В моем же случае они сыпятся с каждым IDR
Вот примерный порядок NAL (вырезал nal_unit_type=1, т.к. их слишком много)
nal_unit_type 00111 = 7 (SPS) nal_unit_type 01000 = 8 (PPS) nal_unit_type 00111 = 7 nal_unit_type 01000 = 8 nal_unit_type 00101 = 5 (IDR) nal_unit_type 00111 = 7 nal_unit_type 01000 = 8 nal_unit_type 00101 = 5 nal_unit_type 00111 = 7 nal_unit_type 01000 = 8 nal_unit_type 00101 = 5 nal_unit_type 00111 = 7 nal_unit_type 01000 = 8 nal_unit_type 00101 = 5 nal_unit_type 00111 = 7 nal_unit_type 01000 = 8 nal_unit_type 00101 = 5 nal_unit_type 00111 = 7 nal_unit_type 01000 = 8 nal_unit_type 00101 = 5 nal_unit_type 00111 = 7 nal_unit_type 01000 = 8 nal_unit_type 00101 = 5 nal_unit_type 00111 = 7 nal_unit_type 01000 = 8 nal_unit_type 00101 = 5 nal_unit_type 00111 = 7 nal_unit_type 01000 = 8 nal_unit_type 00101 = 5 nal_unit_type 00111 = 7 nal_unit_type 01000 = 8 nal_unit_type 00101 = 5 nal_unit_type 00111 = 7 nal_unit_type 01000 = 8 nal_unit_type 00101 = 5 nal_unit_type 00111 = 7 nal_unit_type 01000 = 8 nal_unit_type 00101 = 5 nal_unit_type 00111 = 7 nal_unit_type 01000 = 8 nal_unit_type 00101 = 5 nal_unit_type 00111 = 7
Последовательность такая SPS PPS IDR, SPS PPS IDR, SPS PPS IDR. Ничего не понимаю, зачем слать каждый раз SPS, если он не меняется. Что ещё может меняться в стриме, что заставляет кодировщик слать эти SPS?
Не охота пока дебажить хром, может кто подскажет куда копать )
Трансляция h264 видео без перекодирования и задержки
А почему не передавать записанные SPS и PPS перед каждым IDR NAL? Я пишу SPS + PPS и передаю преред каждым IDR. Кроме того, отдельно храню IDR и при первом подключении клиента сыплю сохраненный IDR+SPS+PPS (можно хранить и сыпать все налы между IDR), с минимальным интервалом между датаграммами, что позволяет получить картинку сразу после подключения.
Всего голосов 1: ↑1 и ↓0 +1
Ответить Добавить в закладки Ещё
Показать предыдущий комментарий
С SPS и PPS кадрами в нашем случае проблем не было: наша камера шлет их регулярно, с каждым кадром (см. парсинг потока камеры ELP). Что касается сохранения старых IDR кадрой, то в таком случае в начале трансляции будет показан старый IDR кадр, но последующие Non-IDR кадры буду накладываться на старый IDR, что будет давать плохую картинку. Нас такая ситуация не устраивала, к тому же небольшая задержка старта видео (менее секунды) нас не беспокоила.
Всего голосов 1: ↑1 и ↓0 +1
Ответить Добавить в закладки Ещё
Показать предыдущий комментарий
ничего накладываться не будет. При подключении посылаете записанные IDR+NIDRы, только не с интервалом 20-30мс, как при трансляции, а 3-4мс. Получаете готовый кадр и приемник готов к приему след. нонидров. Можно послать идр и игнорить все налы до след. идра, тогда вы получите статическую картинку на пару секунд. Все это верно и при трансляции записанного AnnexB файла, когда, как правило SPS/PPS передаются только раз.
Всего голосов 1: ↑1 и ↓0 +1
Ответить Добавить в закладки Ещё
Показать предыдущий комментарий
В условиях ограниченной пропускной способности сети и ограниченной производительности планшета мы не можем сильно поднять скорость передачи кадров (максимум на 20-50 процентов). Таким образом мы будем ждать пока видео синхронизируется с реальным временем где-то секунду. При текущем подходе мы ждем примерно столько же.
Всего голосов 1: ↑1 и ↓0 +1
Ответить Добавить в закладки Ещё
(ошибся веткой)
Комментарий пока не оценивали 0
Ответить Добавить в закладки Ещё
Есть еще GStreamer с кучей плагинов и вроде с плагином от интела в том числе (GStreamer Media SDK plugins) В первом комменте в статье про mjpg-streamer его тоже вспоминают. Его не пробовали?
Всего голосов 6: ↑6 и ↓0 +6
Ответить Добавить в закладки Ещё
Показать предыдущий комментарий
Пробовали, практически в самом начале разработки. Чем-то он нам сразу не подошел, уже точно не помню чем. По-моему, не удалось передавать видео без перекодирования.
Всего голосов 1: ↑1 и ↓0 +1
Ответить Добавить в закладки Ещё
Показать предыдущий комментарий
Значит просто не разобрались в gstreamer.
Обычно то, что нерешает vlc и ffmpeg можно небольшими шаманствами с плагинами решить gstreamer’ом. Притом что в gstreamer’е можно спокойно использовать ffmpeg
Всего голосов 1: ↑1 и ↓0 +1
Ответить Добавить в закладки Ещё
Показать предыдущий комментарий
Может и так. GStreamer конечно мощная и лаконичная штука. Если подскажете, как передать с помощью gstreamer’а видео без перекодирования, будем благодарны.
Комментарий пока не оценивали 0
Ответить Добавить в закладки Ещё
Показать предыдущий комментарий
Если у вас камера выдает картинку в mjpg или в raw, а вы хотите h264, то перекодировать придется.
Если же камера сама умеет выдавать h264, то это будет что-то вроде:
gst-launch v4lsrc ! video/x-h264,width=640,height=480 ! rtph264pay ! udpsink host=127.0.0.1 port=5555
Писал по памяти, скорее всего нагнал, пишите в личку, если не взлетит.
Всего голосов 1: ↑1 и ↓0 +1
Ответить Добавить в закладки Ещё
Показать предыдущий комментарий
Спасибо, завтра попробую
Комментарий пока не оценивали 0
Ответить Добавить в закладки Ещё
Показать предыдущий комментарий
в данном конкретном случае capsfilter (тот элемент пайплайна который «video/x-h264,width=640,height=480») даже не нужен наверно, так как rtph264pay по своей природе на вход просит следующее:
video/x-h264, stream-format=(string)avc, alignment=(string)au
video/x-h264, stream-format=(string)byte-stream, alignment=(string)
а вот если паковать в какой-то мультиформатный контейнер (у меня для стриминга в свое время очень хорошо mpegtsmux себя показал) то конечно стоит прописать капсфильтр чтобы исключить перекодирование.
Кроме того, если передача будет вестись по не самому надежному каналу (а тут у нас именно такой, БПЛА же) возникает проблема потерь udp пакетов (возникнет как только выйдете из лаборатории) соответственно я бы все же советовал tcp использовать, иначе рискуете вообще никакой картинки не получить. MJPEG кстати в этом отношении лучше, так как нет межкадрового, что получил то и отобразил, в худшем случае теряя фреймрейт.
Так вот, если использовать tcp то помимо той задержки которую вы видите на старте появляется назойливая «накапливающаяся» задержка.
Выглядит это следующим образом: связь устанавливается, картинка отображается, задержка небольшая. вдруг откуда ни возьмись возникают проблемы в канале связи, картинка фризится, стример/приемник начинает увеличивать буферы чтобы давать плавную картинку. В итоге через пару таких фризов имеем вместо стартовой задержки в 200 мс аж 2-3 секунды задержки. что конечно неприемлемо.
Всех путей решения данной проблемы я если честно и не вспомню уже сейчас, года 3-4 назад занимался. один из вариантов добавить leaky queue который будет дропать слишком старые, все равно никого не интересующие данные если есть более новые.
Кстати. vlc имеет настроечку network-caching позволяющую настроить политику кеширования. если его в качестве клиента использовать — отлично работает
The H.264 Sequence Parameter Set
This is a follow-up to my World’s Smallest H.264 Encoder post. I’ve received several emails asking about precise details of things in two entities in the H.264 bitstream: the Sequence Parameter Set (SPS) and the Picture Parameter Set (PPS). Both entities contain information that an H.264 decoder needs to decode the video data, for example, the resolution and frame rate of the video.
Recall that an H.264 bitstream contains a sequence of Network Abstraction Layer (NAL) units. The SPS and PPS are both types of NAL units. The SPS NAL unit contains parameters that apply to a series of consecutive coded video pictures, referred to as a “coded video sequence” in the H.264 standard. The PPS NAL unit contains parameters that apply to the decoding of one or more individual pictures inside a coded video sequence.
Using the SPS & PPS for Data Stream
In the case of my simple encoder, we emitted a single SPS and PPS at the start of the video data stream, but in the case of a more complex encoder, it would not be uncommon to see them inserted periodically in the data for two reasons — first, often a decoder will need to start decoding midstream, and second, because the encoder may wish to vary parameters for different parts of the stream in order to achieve better compression or quality goals.
In my trivial encoder, the h.264 SPS and PPS were hardcoded in hex as:
/* h.264 bitstreams */
const uint8_t sps[] =
const uint8_t pps[] =
Let’s decode this into something readable from the spec. The first thing I did was to look at section 7 of the H.264 specification. I saw that at a minimum I had to choose how to fill in the SPS parameters in the table below. In the table, as in the standard, the type u(n) indicates an unsigned integer of n bits, and ue(v) indicates an unsigned exponential-Golomb-coded value of a variable number of bits. The spec doesn’t seem to define the maximum number of bits anywhere, but the reference encoder software uses 32. (People wishing to explore the security of decoder software may find it interesting to violate this assumption!)
Parameter Name | Type | Value | Comments |
forbidden_zero_bit | u(1) | 0 | Despite being forbidden, it must be set to 0! |
nal_ref_idc | u(2) | 3 | 3 means it is “important” (this is an SPS). |
nal_unit_type | u(5) | 7 | Indicates this is a sequence parameter set. |
profile_idc | u(8) | 66 | Baseline profile. |
constraint_set0_flag | u(1) | 0 | We’re not going to honor constraints. |
constraint_set1_flag | u(1) | 0 | We’re not going to honor constraints. |
constraint_set2_flag | u(1) | 0 | We’re not going to honor constraints. |
constraint_set3_flag | u(1) | 0 | We’re not going to honor constraints. |
reserved_zero_4bits | u(4) | 0 | Better set them to zero. |
level_idc | u(8) | 10 | Level 1, sec A.3.1. |
seq_parameter_set_id | ue(v) | 0 | We’ll just use id 0. |
log2_max_frame_num_minus4 | ue(v) | 0 | Let’s have as few frame numbers as possible. |
pic_order_cnt_type | ue(v) | 0 | Keep things simple. |
log2_max_pic_order_cnt_lsb_minus4 | ue(v) | 0 | Fewer is better. |
num_ref_frames | ue(v) | 0 | We will only send I slices. |
gaps_in_frame_num_value_allowed_flag | u(1) | 0 | We will have no gaps. |
pic_width_in_mbs_minus_1 | ue(v) | 7 | SQCIF is 8 macroblocks wide. |
pic_height_in_map_units_minus_1 | ue(v) | 5 | SQCIF is 6 macroblocks high. |
frame_mbs_only_flag | u(1) | 1 | We will not to field/frame encoding. |
direct_8x8_inference_flag | u(1) | 0 | Used for B slices. We will not send B slices. |
frame_cropping_flag | u(1) | 0 | We will not do frame cropping. |
vui_prameters_present_flag | u(1) | 0 | We will not send VUI data. |
rbsp_stop_one_bit | u(1) | 1 | Stop bit. I missed this at first and it caused me much trouble. |
Some key things here are the profile ( profile_idc ) and level ( level_idc ) that I chose, and the picture width and height. If you encode the above table in hex, you will get the values in the SPS array declared above.
SPS, PPS Parameters
A question I got a couple of times in email was about the width and height parameters — specifically, what to do if the picture width or height is not an integer multiple of macroblock size. Recall that, for the 4:2:0 sampling scheme in my encoder, a macroblock consists of 16×16 luma samples. In this case, you would set the frame_cropping_flag to 1, and reduce the number of pixels in the horizontal and vertical direction with the frame_crop_left_offset , frame_crop_right_offset , frame_crop_top_offset , and frame_crop_bottom_offset parameters, which are conditionally present in the bitstream only if the frame_cropping_flag is set to one.
One interesting problem that we see fairly often with H.264 is when the container format (MP4, MOV, etc.) contains different values for some of these parameters than the SPS and PPS. In this case, we find different video players handle the streams differently.
Decoding H.264 Bitstreams Using the H264Bitstream Tool & SPS, PPS
A handy tool for decoding H.264 bitstreams, including the SPS, is the h264bitstream tool. It comes with a command-line program that decodes a bitstream to the parameter names defined in the h.264 specification. Let’s look at its output for a sample mp4 file I downloaded from youtube. First, I extract the H.264 NAL units from the file using ffmpeg:
ffmpeg.exe -i Old Faithful.mp4?-vcodec copy -vbsf h264_mp4toannexb -an of.h264
The NAL units now reside in the file of.h264 . I then run the h264_analyze command from the h264bitstream package to produce the following output:
h264_analyze of.h264
!! Found NAL at offset 4 (0x0004), size 25 (0x0019)
forbidden_zero_bit : 0
nal_ref_idc : 3
nal_unit_type : 7 ( Sequence parameter set )
profile_idc : 100
constraint_set0_flag : 0
constraint_set1_flag : 0
constraint_set2_flag : 0
constraint_set3_flag : 0
reserved_zero_4bits : 0
level_idc : 31
seq_parameter_set_id : 0
chroma_format_idc : 1
residual_colour_transform_flag : 0
bit_depth_luma_minus8 : 0
bit_depth_chroma_minus8 : 0
qpprime_y_zero_transform_bypass_flag : 0
seq_scaling_matrix_present_flag : 0
log2_max_frame_num_minus4 : 3
pic_order_cnt_type : 0
log2_max_pic_order_cnt_lsb_minus4 : 3
delta_pic_order_always_zero_flag : 0
offset_for_non_ref_pic : 0
offset_for_top_to_bottom_field : 0
num_ref_frames_in_pic_order_cnt_cycle : 0
num_ref_frames : 1
gaps_in_frame_num_value_allowed_flag : 0
pic_width_in_mbs_minus1 : 79
pic_height_in_map_units_minus1 : 44
frame_mbs_only_flag : 1
mb_adaptive_frame_field_flag : 0
direct_8x8_inference_flag : 1
frame_cropping_flag : 0
frame_crop_left_offset : 0
frame_crop_right_offset : 0
frame_crop_top_offset : 0
frame_crop_bottom_offset : 0
vui_parameters_present_flag : 1
aspect_ratio_info_present_flag : 1
aspect_ratio_idc : 1
sar_width : 0
sar_height : 0
overscan_info_present_flag : 0
overscan_appropriate_flag : 0
video_signal_type_present_flag : 0
video_signal_type_present_flag : 0
video_format : 0
video_full_range_flag : 0
colour_description_present_flag : 0
colour_primaries : 0
transfer_characteristics : 0
matrix_coefficients : 0
chroma_loc_info_present_flag : 0
chroma_sample_loc_type_top_field : 0
chroma_sample_loc_type_bottom_field : 0
timing_info_present_flag : 1
num_units_in_tick : 100
time_scale : 5994
fixed_frame_rate_flag : 1
nal_hrd_parameters_present_flag : 0
vcl_hrd_parameters_present_flag : 0
low_delay_hrd_flag : 0
pic_struct_present_flag : 0
bitstream_restriction_flag : 1
motion_vectors_over_pic_boundaries_flag : 1
max_bytes_per_pic_denom : 0
max_bits_per_mb_denom : 0
log2_max_mv_length_horizontal : 11
log2_max_mv_length_vertical : 11
num_reorder_frames : 0
max_dec_frame_buffering : 1
cpb_cnt_minus1 : 0
bit_rate_scale : 0
cpb_size_scale : 0
initial_cpb_removal_delay_length_minus1 : 0
cpb_removal_delay_length_minus1 : 0
dpb_output_delay_length_minus1 : 0
time_offset_length : 0
The only additional thing I’d like to point out here is that this particular SPS also contains information about the frame rate of the video (see timing_info_present_flag ). These parameters must be closely checked when you generate bitstreams to ensure they agree with the container format that the H.264 will eventually be muxed into. Even a small error, such as 29.97 fps in one place and 30 fps in another, can result in severe audio/video synchronization problems.
Next time, I will write about the H.264 Picture Parameter Set (PPS).
If you enjoyed this blog, subscribe to our quarterly newsletter below!