aizvorski / h264bitstream Goto Github PK
View Code? Open in Web Editor NEWA complete set of functions to read and write H.264 video bitstreams, in particular to examine or modify headers.
License: GNU Lesser General Public License v2.1
A complete set of functions to read and write H.264 video bitstreams, in particular to examine or modify headers.
License: GNU Lesser General Public License v2.1
Sorry if this is the wrong place. I searched and this is all I found.
h264bitstream is a library, right?
Can you recommend an application that uses it to display to me the headers and values of AVC (H.264) videos?
How do I install h264bitstream? My attempt follows:
mark@mark-VirtualBox:~$ sudo apt-get install build-essential libtool autoconf ffmpeg
[sudo] password for mark:
Reading package lists... Done
Building dependency tree
Reading state information... Done
autoconf is already the newest version (2.69-11.1).
libtool is already the newest version (2.4.6-14).
The following additional packages will be installed:
g++ g++-9 libavresample4 libstdc++-9-dev
Suggested packages:
ffmpeg-doc g++-multilib g++-9-multilib gcc-9-doc libstdc++-9-doc
The following NEW packages will be installed:
build-essential ffmpeg g++ g++-9 libavresample4 libstdc++-9-dev
0 upgraded, 6 newly installed, 0 to remove and 0 not upgraded.
Need to get 11.7 MB of archives.
After this operation, 49.1 MB of additional disk space will be used.
Do you want to continue? [Y/n] y
Get:1 https://mirrors.gigenet.com/ubuntuarchive focal-updates/main amd64 libstdc++-9-dev amd64 9.4.0-1ubuntu1~20.04.2 [1,722 kB]
Get:2 https://mirrors.gigenet.com/ubuntuarchive focal-updates/main amd64 g++-9 amd64 9.4.0-1ubuntu1~20.04.2 [8,421 kB]
Get:3 https://mirrors.gigenet.com/ubuntuarchive focal/main amd64 g++ amd64 4:9.3.0-1ubuntu2 [1,604 B]
Get:4 https://mirrors.gigenet.com/ubuntuarchive focal-updates/main amd64 build-essential amd64 12.8ubuntu1.1 [4,664 B]
Get:5 https://mirrors.gigenet.com/ubuntuarchive focal-updates/universe amd64 libavresample4 amd64 7:4.2.7-0ubuntu0.1 [54.2 kB]
Get:6 https://mirrors.gigenet.com/ubuntuarchive focal-updates/universe amd64 ffmpeg amd64 7:4.2.7-0ubuntu0.1 [1,453 kB]
Fetched 11.7 MB in 4s (3,322 kB/s)
Selecting previously unselected package libstdc++-9-dev:amd64.
(Reading database ... 404185 files and directories currently installed.)
Preparing to unpack .../0-libstdc++-9-dev_9.4.0-1ubuntu1~20.04.2_amd64.deb ...
Unpacking libstdc++-9-dev:amd64 (9.4.0-1ubuntu1~20.04.2) ...
Selecting previously unselected package g++-9.
Preparing to unpack .../1-g++-9_9.4.0-1ubuntu1~20.04.2_amd64.deb ...
Unpacking g++-9 (9.4.0-1ubuntu1~20.04.2) ...
Selecting previously unselected package g++.
Preparing to unpack .../2-g++_4%3a9.3.0-1ubuntu2_amd64.deb ...
Unpacking g++ (4:9.3.0-1ubuntu2) ...
Selecting previously unselected package build-essential.
Preparing to unpack .../3-build-essential_12.8ubuntu1.1_amd64.deb ...
Unpacking build-essential (12.8ubuntu1.1) ...
Selecting previously unselected package libavresample4:amd64.
Preparing to unpack .../4-libavresample4_7%3a4.2.7-0ubuntu0.1_amd64.deb ...
Unpacking libavresample4:amd64 (7:4.2.7-0ubuntu0.1) ...
Selecting previously unselected package ffmpeg.
Preparing to unpack .../5-ffmpeg_7%3a4.2.7-0ubuntu0.1_amd64.deb ...
Unpacking ffmpeg (7:4.2.7-0ubuntu0.1) ...
Setting up libstdc++-9-dev:amd64 (9.4.0-1ubuntu1~20.04.2) ...
Setting up libavresample4:amd64 (7:4.2.7-0ubuntu0.1) ...
Setting up g++-9 (9.4.0-1ubuntu1~20.04.2) ...
Setting up g++ (4:9.3.0-1ubuntu2) ...
update-alternatives: using /usr/bin/g++ to provide /usr/bin/c++ (c++) in auto mode
Setting up build-essential (12.8ubuntu1.1) ...
Setting up ffmpeg (7:4.2.7-0ubuntu0.1) ...
Processing triggers for man-db (2.9.1-1) ...
Processing triggers for libc-bin (2.31-0ubuntu9.12) ...
mark@mark-VirtualBox:~$ autoreconf -i
autoreconf: 'configure.ac' or 'configure.in' is required
mark@mark-VirtualBox:~$
Thanks for the wonderful work. I'm wondering if you have any plan to support SVC. If no, I'd like to contribute to it. Please let me know your thought.
Hi there,
I'm looking for a very fast way to extract motion vectors from an h264 stream inside some container. I just need the x,y coordinates of the block and it's dx,dy movement. I'd like to cut out any CPU time not contributing to the motion vectors. The data is coming from ffmpeg (encoding as h264 in hardware) so I can set the container format to anything.
Is this repo what I'm after?
Please excuse my ignorance of h264 but I can't answer this question by looking at the code, nor would I know how to do it if you just said "yes", so some guidance would be very much appreciated.
I know this isn't really an "issue" but github seem to have disabled all other forms of messaging.
TIA, Adrian.
I'm using AFL++ to fuzz using the samples. So far there are a bunch of crashes. I'm making this note to let folks know I'm doing this and intend to update with collated results.
Does anyone know why h264_avcc* - files were excluded from makefile here?
https://github.com/aizvorski/h264bitstream/pull/17/files#diff-e09b9811ea67736fb60b6106ad1cb9bdL28
At line 51 in read_avcc()
, avcc->pps_table
is initialised using avcc->numOfSequenceParameterSets
where it should probably be using avcc->numOfPictureParameterSets
. Otherwise, there could be an out-of-bound situation if the number of PPS is greater than the number of SPS.
Line 51 in ae72f73
This line has compiler-dependent behavior
Line 203 in d8e53fd
Found by @LostInKadath #51 (comment)
(Probably gcc does what is intended here and clang on 64bit platforms is bugged)
<command-line>:0:0: note: this is the location of the previous definition
depbase=`echo h264_nal_for_app.o | sed 's|[^/]*$|.deps/&|;s|\.o$||'`;\
gcc -DPACKAGE_NAME=\"h264bitstream\" -DPACKAGE_TARNAME=\"h264bitstream\" -DPACKAGE_VERSION=\"0.2.0\" -DPACKAGE_STRING=\"h264bitstream\ 0.2.0\" -DPACKAGE_BUGREPORT=\"[email protected]\" -DPACKAGE_URL=\"\" -DPACKAGE=\"h264bitstream\" -DVERSION=\"0.2.0\" -DSTDC_HEADERS=1 -DHAVE_SYS_TYPES_H=1 -DHAVE_SYS_STAT_H=1 -DHAVE_STDLIB_H=1 -DHAVE_STRING_H=1 -DHAVE_MEMORY_H=1 -DHAVE_STRINGS_H=1 -DHAVE_INTTYPES_H=1 -DHAVE_STDINT_H=1 -DHAVE_UNISTD_H=1 -DHAVE_DLFCN_H=1 -DLT_OBJDIR=\".libs/\" -DHAVE_GETOPT_LONG=1 -DNDEBUG=/\*\*/ -I. -I. -Wall -std=c99 -std=c99 -Wno-error -g -O2 -MT h264_nal_for_app.o -MD -MP -MF $depbase.Tpo -c -o h264_nal_for_app.o h264_nal_for_app.c &&\
mv -f $depbase.Tpo $depbase.Po
/bin/sh ./libtool --tag=CC --mode=link gcc -I. -Wall -std=c99 -std=c99 -Wno-error -g -O2 -lm -o h264_analyze h264_analyze.o h264_nal_for_app.o libh264bitstream.la
libtool: link: gcc -I. -Wall -std=c99 -std=c99 -Wno-error -g -O2 -o .libs/h264_analyze h264_analyze.o h264_nal_for_app.o -lm ./.libs/libh264bitstream.so
./.libs/libh264bitstream.so: undefined reference to `debug_sps'
./.libs/libh264bitstream.so: undefined reference to `debug_pps'
collect2: error: ld returned 1 exit status
Makefile:510: recipe for target 'h264_analyze' failed
make: *** [h264_analyze] Error 1
[ERR]
14:24:24krieger@zver /usr/local/src/h264bitstream
$ grep debug_pps * -RnI
h264_avcc.c:140: debug_pps(avcc->pps_table[i]);
h264_stream.h:147: @see debug_pps
h264_stream.h:439:void debug_pps(pps_t* pps);
[OK]
14:24:36krieger@zver /usr/local/src/h264bitstream
$ grep debug_sps * -RnI
h264_avcc.c:131: debug_sps(avcc->sps_table[i]);
h264_stream.h:42: @see debug_sps
h264_stream.h:438:void debug_sps(sps_t* sps);
h264_slice_data.c file provides some functions for extracting slice and macroblock information but it is not implemented in h264_analyze. Is there going to be a patch for this anytime soon? Would it be straightforward to modify slice data functions or is there still a lot of work to do? It is regarded as a "large project" in the readme file, that's why I'm asking.
I am using the h264bitstream command to help me writing an h.264 decoder and i think the implementation of function more_rbsp_data() in h264bitstream_data is wrong. The parser is not detecting PPS with transform_8x8_mode_flag = 1 (nor the remaining PPS syntax elements) due to more_rbsp_data() interpreting that bit as the rsbp_stop_bit. Also, sei messages are not correctly parsed. This is a working implementation:
int more_rbsp_data(h264_stream_t* h, bs_t* bs) {
/* no more data */
if (bs_eof(bs)) return 0;
/* no rbsp_stop_bit yet */
if (bs_peek_u1(bs) == 0) return 1;
/* next bit is 1, is it the rsbp_stop_bit? only if the rest of bits are 0 */
bs_t aux;
bs_clone(&aux, bs);
bs_skip_u1(&aux);
while(!bs_eof(&aux)) {
/* A later bit was 1, it wasn't the rsbp_stop_bit */
if (bs_read_u1(&aux) == 1) return 1;
}
/* All following bits were 0, it was the rsbp_stop_bit */
return 0;
}
Hello,
I'd need to write a small tool that reads an h264 file, reads the NALs, modifies current data and eventually adds new units (more specifically, SEI data). I would like to start from a simple tool that copy-pastes an h264 bitstream from one file to another, with the output one being readable by players like mpv or derived tools like https://mradionov.github.io/h264-bitstream-viewer/.
This is what's being reported in the README:
'Reading and writing slice data is complex and may not be fully implemented soon (target: 1.0.0 version), although there is some work-in-progress code for it.'
Does this mean that it's possible to use this library to manipulate actual h264 data, obtaining playable results? If not, could you please guide me through the steps that would be needed to realize such a copy-paste tool? I have not been able to find any suitable example, although it should be one of the simplest usages of this library. Thanks in advance!
Hello. I caught a segmentation fault while working with an H264 video. This happens after calling the methods
find_nal_unit(...) and read_nal_unit(...) with the next set of bytes in hex:
"00000001419a246c437ffea7840000030000097800000001"
Application crashes in class h264_stream.c of method read_slice_layer_rbsp(...). Variable slice_data->rbsp_size is equal to negative value when we perform memcpy(...).
based on 7.4.2.11 RBSP trailing bits semantics
rbsp_stop_one_bit shall be equal to 1.
rbsp_alignment_zero_bit shall be equal to 0.
Code at h264_stream.in.c set it to 1.
//7.3.2.11 RBSP trailing bits syntax
void structure(rbsp_trailing_bits)(h264_stream_t* h, bs_t* b)
{
value( rbsp_stop_one_bit, f(1, 1) );
while( !bs_byte_aligned(b) )
{
value( rbsp_alignment_zero_bit, f(1, 0) );
}
}
when I execute autoreconf -i, it will return the following problem:
autoreconf: 'configure.ac' or 'configure.in' is required
how can i solve it ?
could we compile by mingw for ms windows? if not,could we support cmake?
in addition,compile on centos 6.7 with gcc 4.4.7(which have not full support for c99)will result in some error,that's this version of gcc doesn't supoort anonymous union,below is part of compile error:
h264_stream.h:199: warning: declaration does not declare anything
h264_stream.c: In function ‘read_subset_seq_parameter_set_rbsp’:
h264_stream.c:504: error: ‘sps_subset_t’ has no member named ‘sps_svc_ext’
h264_stream.c: In function ‘read_seq_parameter_set_svc_extension’:
h264_stream.c:529: error: ‘sps_subset_t’ has no member named ‘sps_svc_ext’
h264_stream.c: In function ‘read_pic_parameter_set_rbsp’:
h264_stream.c:771: warning: suggest parentheses around comparison in operand of ‘|’
h264_stream.c: In function ‘read_slice_header_in_scalable_extension’:
h264_stream.c:1334: error: ‘sps_subset_t’ has no member named ‘sps_svc_ext’
h264_stream.c:1371: error: ‘sps_subset_t’ has no member named ‘sps_svc_ext’
we can fix this issue by modify configure.ac
modify EXTRA_CFLAGS='-std=c99 -Wno-error' to EXTRA_CFLAGS='-std=gnu99 -Wno-error'
Hi @aizvorski
I try to read SPS with scaling list but I get error when I run the program.
Segmentation fault (core dumped)
I use live555 to get h264 stream
My camera send first
sprop-parameter-sets=Z2QAKK2ECSZuIzSQgSTNxGaSECSZuIzSQgSTNxGaSECSZuIzSQgSTNxGaSEFTS69fX5P6/J9eutVCCppdevr8n9fk+vXWqtAUBf8uAqkAAADAAQAAAMCWYEAD6AABGUb3vheEQjU,aO48sA==
I run base64Decode and the result I pass it through h264bitstream and I get the error.
With other SPS without scaling list work good.
Thank you so much.
Here's my installation sequence:
docker run -ti $PWD:/workdir ubuntu
apt update
apt-get install build-essential libtool autoreconf git
git clone https://github.com/aizvorski/h264bitstream && cd h264bitstream
autoreconf -i
./configure --prefix=/usr/local
make
make install
Then I run h264_analyze
and get
root@b64adfd865e3:/h264bitstream# h264_analyze
h264_analyze: error while loading shared libraries: libh264bitstream.so.0: cannot open shared object file: No such file or directory
I wanted to actually split the .264 bitstream into the base alyer and the enhancement layers. I figured our that I can use svc_split to do that, but needed help to actually recombine both and play it.
Any help would be great.
I cannot find the definition of debug_nal
. Is something wrong with my editor seacher of there simply isn't one anymore?
:-) this is a good job. hope it can support h.265 too.
With the latest master, when I run make install, the headers are placed in the root include directory (for example, /usr/include/ ). Also, bs.h is not installed, even though both the h264bitstream headers themselves and programs using h264bitstream need it.
So I suggest to install the headers in a h264bitstream/ subdirectory instead, and also install bs.h. Installing them in a subdirectory keeps the root include directory cleaner, and also prevents name collisions ("bs.h" sounds fairly generic).
Hi,
I'm getting the following error while compiling the h264_analyze.c code:
h264_analyze.c:(.text+0xb1): undefined reference to h264_new' h264_analyze.c:(.text+0xf8): undefined reference to
h264_dbgfile'
h264_analyze.c:(.text+0x118): undefined reference to h264_dbgfile' h264_analyze.c:(.text+0x1eb): undefined reference to
h264_dbgfile'
h264_analyze.c:(.text+0x1fe): undefined reference to h264_dbgfile' h264_analyze.c:(.text+0x2fe): undefined reference to
h264_dbgfile'
h264_analyze.c:(.text+0x33a): undefined reference to read_debug_nal_unit' h264_analyze.c:(.text+0x3d9): undefined reference to
h264_dbgfile'
h264_analyze.c:(.text+0x426): undefined reference to find_nal_unit' h264_analyze.c:(.text+0x4d1): undefined reference to
h264_free'
h264_analyze.c:(.text+0x4e4): undefined reference to `h264_dbgfile'
Can i get the right compile command with flags?
I installed the tool on Ubuntu 16.04 as per the instructions. When I try to run it, I get:
h264_analyze: error while loading shared libraries: libh264bitstream.so.0: cannot open shared object file: No such file or directory
I do have the libraries in /usr/local/lib
:
ll /usr/local/lib/libh*
-rw-r--r-- 1 root root 1418348 Jul 17 10:58 /usr/local/lib/libh264bitstream.a
-rwxr-xr-x 1 root root 996 Jul 17 10:58 /usr/local/lib/libh264bitstream.la
lrwxrwxrwx 1 root root 25 Jul 17 10:58 /usr/local/lib/libh264bitstream.so -> libh264bitstream.so.0.0.0
lrwxrwxrwx 1 root root 25 Jul 17 10:58 /usr/local/lib/libh264bitstream.so.0 -> libh264bitstream.so.0.0.0
-rwxr-xr-x 1 root root 906512 Jul 17 10:58 /usr/local/lib/libh264bitstream.so.0.0.0
And they are in the library path:
cat /etc/ld.so.conf.d/libc.conf
# libc default configuration
/usr/local/lib
The output from sudo make install
:
make[1]: Entering directory '/home/werner/Documents/Projects/h264bitstream'
/bin/mkdir -p '/usr/local/lib'
/bin/bash ./libtool --mode=install /usr/bin/install -c libh264bitstream.la '/usr/local/lib'
libtool: install: /usr/bin/install -c .libs/libh264bitstream.so.0.0.0 /usr/local/lib/libh264bitstream.so.0.0.0
libtool: install: (cd /usr/local/lib && { ln -s -f libh264bitstream.so.0.0.0 libh264bitstream.so.0 || { rm -f libh264bitstream.so.0 && ln -s libh264bitstream.so.0.0.0 libh264bitstream.so.0; }; })
libtool: install: (cd /usr/local/lib && { ln -s -f libh264bitstream.so.0.0.0 libh264bitstream.so || { rm -f libh264bitstream.so && ln -s libh264bitstream.so.0.0.0 libh264bitstream.so; }; })
libtool: install: /usr/bin/install -c .libs/libh264bitstream.lai /usr/local/lib/libh264bitstream.la
libtool: install: /usr/bin/install -c .libs/libh264bitstream.a /usr/local/lib/libh264bitstream.a
libtool: install: chmod 644 /usr/local/lib/libh264bitstream.a
libtool: install: ranlib /usr/local/lib/libh264bitstream.a
libtool: finish: PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/snap/bin:/sbin" ldconfig -n /usr/local/lib
----------------------------------------------------------------------
Libraries have been installed in:
/usr/local/lib
If you ever happen to want to link against installed libraries
in a given directory, LIBDIR, you must either use libtool, and
specify the full pathname of the library, or use the '-LLIBDIR'
flag during linking and do at least one of the following:
- add LIBDIR to the 'LD_LIBRARY_PATH' environment variable
during execution
- add LIBDIR to the 'LD_RUN_PATH' environment variable
during linking
- use the '-Wl,-rpath -Wl,LIBDIR' linker flag
- have your system administrator add LIBDIR to '/etc/ld.so.conf'
See any operating system documentation about shared libraries for
more information, such as the ld(1) and ld.so(8) manual pages.
----------------------------------------------------------------------
/bin/mkdir -p '/usr/local/bin'
/bin/bash ./libtool --mode=install /usr/bin/install -c h264_analyze svc_split '/usr/local/bin'
libtool: install: /usr/bin/install -c .libs/h264_analyze /usr/local/bin/h264_analyze
libtool: install: /usr/bin/install -c .libs/svc_split /usr/local/bin/svc_split
/bin/mkdir -p '/usr/local/include'
/usr/bin/install -c -m 644 h264_stream.h h264_sei.h h264_avcc.h '/usr/local/include'
/bin/mkdir -p '/usr/local/lib/pkgconfig'
/usr/bin/install -c -m 644 libh264bitstream.pc '/usr/local/lib/pkgconfig'
/bin/mkdir -p '/usr/local/include/h264bitstream'
/usr/bin/install -c -m 644 h264_stream.h h264_sei.h h264_avcc.h bs.h '/usr/local/include/h264bitstream'
make[1]: Leaving directory '/home/werner/Documents/Projects/h264bitstream'
When I first tried make install
without sudo
, I got:
make[1]: Entering directory '/home/werner/Documents/Projects/h264bitstream'
/bin/mkdir -p '/usr/local/lib'
/bin/bash ./libtool --mode=install /usr/bin/install -c libh264bitstream.la '/usr/local/lib'
libtool: install: /usr/bin/install -c .libs/libh264bitstream.so.0.0.0 /usr/local/lib/libh264bitstream.so.0.0.0
/usr/bin/install: cannot create regular file '/usr/local/lib/libh264bitstream.so.0.0.0': Permission denied
Makefile:433: recipe for target 'install-libLTLIBRARIES' failed
make[1]: *** [install-libLTLIBRARIES] Error 1
make[1]: Leaving directory '/home/werner/Documents/Projects/h264bitstream'
Makefile:872: recipe for target 'install-am' failed
make: *** [install-am] Error 2
Any idea as to what could be wrong?
The memcpy at the end of read_seq_parameter_set_rbsp() overwrites the struct it just filled with
a copy of what's in sps_table. Since h->sps == h->sps_table[0] it just filled that one, the memcpy in the id=0 case is (un?)luckily a no-op, while in all other cases the values just read are just all cleared to 0.
Swapping src/dst can't work properly as is either, since h->sps == h->sps_table[0]: when we notice that seq_parameter_set_id != 0 we have already overwritten h->sps_table[0].
if(0)-ing this memcpy as a workaround works much better...
I don't know if it will be helpful, but I made a bunch of changes to this library to fix some problems that I was seeing in my h264 stream. In particular, there were instances where some SPS/PPS golomb encoded values were not encoding correctly due to missing support for "big" values. H264 allows for values in some fields which are larger than what your bs_write_ue method allowed. The folks that work on the x264 library had to fix this some time back as well, so I formulated my solution based on their golomb encode/decode source. See the "big" variant that I added.
There are other various changes added as well, though mostly for my own purposes, so they may not be useful (or may be wrong in accordance with your intentions). Just thought I'd throw my work up here in case it was useful to anyone else:
Hello,
in line:
https://github.com/aizvorski/h264bitstream/blob/master/h264_stream.c#L1727, it is assumed the count of seq_scaling_list_present_flag
and ScalingListn*n
always sum up to 8.
As I saw from the reader code:
https://github.com/aizvorski/h264bitstream/blob/master/h264_stream.c#L398
it seems the count is dependent from chroma_format_idc
.
Should the write behave accordingly?
Thanks,
Fabio
$ cat ./build.sh
#!/bin/bash
gcc -I /usr/local/src/h264bitstream/ gen_stream.c /usr/local/src/h264bitstream/.libs/libh264bitstream.a -o gen_stream
[OK]
15:49:26krieger@zver ~/work/employers/bluecherry/h264_stream_gen
$ ./build.sh
[OK]
15:49:27krieger@zver ~/work/employers/bluecherry/h264_stream_gen
$ ./gen_stream
Stream start headers:
00 00 00 01 00 67 42 00 1e 92 44 05 a0 92 20 00 00 00 01 00 68 ce 08 48 80
Header before keyframe:
00 00 00 01 00 25 b8 04 00
Header before non-key frame 1:
00 00 00 01 00 21 e0 41
Header before non-key frame 2:
00 00 00 01 00 21 e0 82
Header before non-key frame 3:
00 00 00 01 00 21 e0 c3
[OK]
#include <h264_stream.h>
#define MIN(x, y) ({ \
typeof(x) _min1 = (x); \
typeof(y) _min2 = (y); \
(void) (&_min1 == &_min2); \
_min1 < _min2 ? _min1 : _min2; })
h264_stream_t* h = NULL;
uint8_t marker[] = {0x00, 0x00, 0x00, 0x01};
ssize_t write_stream_start(uint8_t *buf, size_t size)
{
ssize_t off = 0;
/* SPS */
if (size - off - 4 < 0)
return off; // TODO indicate error and not just "normal" premature return
memcpy(buf + off, marker, MIN(sizeof(marker), size - off));
off += 4;
h->nal->nal_ref_idc = 0x03;
h->nal->nal_unit_type = NAL_UNIT_TYPE_SPS;
h->sps->profile_idc = 0x42; /* == 66, baseline */
h->sps->level_idc = 30;
h->sps->log2_max_frame_num_minus4 = 3;
h->sps->log2_max_pic_order_cnt_lsb_minus4 = 3;
h->sps->num_ref_frames = 0x01;
h->sps->pic_width_in_mbs_minus1 = 0x2c; /* == 44 */
h->sps->pic_height_in_map_units_minus1 = 35; // 0x1d;
h->sps->frame_mbs_only_flag = 0x01;
off += write_nal_unit(h, buf + off, size - off);
/* PPS */
if (size - off - 4 < 0)
return off; // TODO indicate error and not just "normal" premature return
memcpy(buf + off, marker, MIN(sizeof(marker), size - off));
off += 4;
h->nal->nal_ref_idc = 0x03;
h->nal->nal_unit_type = NAL_UNIT_TYPE_PPS;
h->pps->pic_parameter_set_id = 0;
h->pps->seq_parameter_set_id = 0;
h->pps->entropy_coding_mode_flag = 0;
h->pps->pic_order_present_flag = 0;
h->pps->num_slice_groups_minus1 = 0;
h->pps->num_ref_idx_l0_active_minus1 = 0;
h->pps->num_ref_idx_l1_active_minus1 = 0;
h->pps->weighted_pred_flag = 0;
h->pps->weighted_bipred_idc = 0;
h->pps->pic_init_qp_minus26 = 2;
h->pps->pic_init_qs_minus26 = 2;
h->pps->chroma_qp_index_offset = 0;
h->pps->deblocking_filter_control_present_flag = 0;
h->pps->constrained_intra_pred_flag = 0;
h->pps->redundant_pic_cnt_present_flag = 0;
off += write_nal_unit(h, buf + off, size - off);
return off;
}
ssize_t write_stream_middle_idr(uint8_t *buf, size_t size)
{
ssize_t off = 0;
if (size - off - 4 < 0)
return off; // TODO indicate error and not just "normal" premature return
memcpy(buf + off, marker, MIN(sizeof(marker), size - off));
off += 4;
h->nal->nal_ref_idc = 1;
h->nal->nal_unit_type = NAL_UNIT_TYPE_CODED_SLICE_IDR;
h->sh->first_mb_in_slice = 0;
h->sh->slice_type = 2;
h->sh->pic_parameter_set_id = 0;
h->sh->frame_num = 0;
h->sh->idr_pic_id = 1;
h->sh->pic_order_cnt_lsb = 0;
h->sh->drpm.no_output_of_prior_pics_flag = 0;
h->sh->drpm.long_term_reference_flag = 0;
h->sh->slice_qp_delta = 0;
off += write_nal_unit(h, buf + off, size - off);
return off;
}
ssize_t write_stream_middle_non_idr(uint8_t *buf, size_t size, int frame_num_in_gop)
{
ssize_t off = 0;
if (size - off - 4 < 0)
return off; // TODO indicate error and not just "normal" premature return
memcpy(buf + off, marker, MIN(sizeof(marker), size - off));
off += 4;
h->nal->nal_ref_idc = 1;
h->nal->nal_unit_type = NAL_UNIT_TYPE_CODED_SLICE_NON_IDR;
h->sh->first_mb_in_slice = 0;
h->sh->slice_type = SH_SLICE_TYPE_P;
h->sh->pic_parameter_set_id = 0;
h->sh->frame_num = frame_num_in_gop;
h->sh->idr_pic_id = 1;
h->sh->pic_order_cnt_lsb = frame_num_in_gop * 2; /* for interlaced */
h->sh->drpm.no_output_of_prior_pics_flag = 0;
h->sh->drpm.long_term_reference_flag = 0;
h->sh->slice_qp_delta = 0;
off += write_nal_unit(h, buf + off, size - off);
return off;
}
void print_buf(uint8_t *buf, ssize_t size)
{
ssize_t i;
for (i = 0; i < size; i++) {
printf("%02x ", buf[i]);
}
printf("\n");
}
int main(int argc, uint8_t *argv[])
{
ssize_t stream_start_len = 0;
ssize_t stream_middle_len = 0;
uint8_t stream_start[64] = { 0, };
uint8_t stream_middle[64] = { 0, };
int i;
h = h264_new();
printf("Stream start headers:\n");
stream_start_len = write_stream_start(stream_start, sizeof(stream_start));
print_buf(stream_start, stream_start_len);
printf("Header before keyframe:\n");
stream_middle_len = write_stream_middle_idr(stream_middle, sizeof(stream_middle));
print_buf(stream_middle, stream_middle_len);
for (i = 1; i < 4; i++) {
printf("Header before non-key frame %d:\n", i);
stream_middle_len = write_stream_middle_non_idr(stream_middle, sizeof(stream_middle), i);
print_buf(stream_middle, stream_middle_len);
}
return 0;
}
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.