[x264-devel] NAL slice support patch added?
Loren Merritt
lorenm at u.washington.edu
Tue Oct 23 06:53:49 CEST 2007
On Mon, 22 Oct 2007, Mojtaba Hosseini wrote:
> 2) The current patch does not do anything specific for rate control.
> Is this ok? That is, from the code, I do not see how this patch
> could affect rate control but please advise if otherwise.
Now that slices are divorced from threads, ratecontrol shouldn't care
about slices.
> 3) As per suggestion given on irc, number of NALs is allocated
> dynamically (because number of NALs in frame can potentially be
> very large). The default allocation is 20 and it grows by steps
> of 20, every time there is a need to grow. Is this a reasonable
> approach? Is 20 a good step size?
Does it even need to be >1 ? The arrays never shrink, so realloc is a O(1)
cost over the whole movie. Otoh, if you did expect arrays large enough for
copying to be nonnegligible, the usual way is to grow exponentially.
> 4) I have tested this patch with multiple threads and it worked.
> Is there a set of tests I should do to increase confidence in the
> patch?
How did you check for working? For patches that are supposed to change the
output (thus regression testing can't work):
#define DEBUG_DUMP_FRAME.
Encode something with x264.
Decode it with JM.
Compare x264's fdec.yuv to JM's output.
The options to pay most attention to in this case are:
threads, 8x8dct, and intra partitions.
> 5) As some of you may know, ffmpeg has an interface for its h263+ and
> mpeg4 encoders to specify number of bytes per 'slice' (started with
> a resync marker). The interface then allows a callback function provided
> by user to be called every time a 'slice' is made. The current
> implementation of x264 would allow us to have a similar interface except
> that user callback would be called at end of encoding process
> (after x264_encoder_encoder() and when calling individual
> x264_encode_NAL() functions). Is there opposition to adding
> a callback function so that user can be called when a NAL is ready to
> be encoded? Or is this too much change?
Ok if you can make it work. But with threading it can only reduce latency
by 1 frame, it can't output slices as soon as they're encoded.
If it takes more than a few lines of code, make it a separate patch.
> --- common.h (revision 680)
> +++ common.h (working copy)
> @@ -53,7 +53,7 @@
> #define X264_BFRAME_MAX 16
> #define X264_THREAD_MAX 128
> #define X264_SLICE_MAX 4
> -#define X264_NAL_MAX (4 + X264_SLICE_MAX)
> +#define X264_NAL_MAX (16 + X264_SLICE_MAX)
X264_NAL_MAX is no longer a maximum, and X264_SLICE_MAX should no longer
exist.
> --- x264.h (revision 680)
> +++ x264.h (working copy)
> @@ -275,6 +275,7 @@
> int b_aud; /* generate access unit delimiters */
> int b_repeat_headers; /* put SPS/PPS before each keyframe */
> int i_sps_id; /* SPS and PPS id number */
> + int i_slice_max; /* maximum slice size in bytes, split slices if larger than this many bytes (0 => unlimited) */
> } x264_param_t;
max_slice_size is a better name, especially if you plan to add
slice_count.
Also, it's not exactly a maximum, as a slicebreak occurs only after this
threshold is exceeded (by up to 385 bytes). This should be either fixed or
documented (I don't care which, but ffmpeg might).
> --- encoder.c (revision 680)
> +++ encoder.c (working copy)
> @@ -778,6 +779,18 @@
> x264_nal_t *nal = &h->out.nal[h->out.i_nal];
> nal->i_payload = &h->out.p_bitstream[bs_pos( &h->out.bs ) / 8] - nal->p_payload;
> h->out.i_nal++;
> + //if number of allocated nals is not enough, allocate a larger one (steps of X264_NAL_MAX)
> + //and copy previous to new, using a temporary buffer.
> + if(h->out.i_nal >= h->out.i_nals_allocated)
> + {
> + x264_nal_t *tmp = x264_malloc(sizeof ( x264_nal_t) * h->out.i_nals_allocated);
> + memcpy(tmp,h->out.nal,(sizeof ( x264_nal_t) * h->out.i_nals_allocated));
> + x264_free(h->out.nal);
> + h->out.nal = x264_malloc( sizeof ( x264_nal_t) * (h->out.i_nals_allocated + X264_NAL_MAX));
> + memcpy(h->out.nal,tmp,(sizeof ( x264_nal_t) * h->out.i_nals_allocated));
> + h->out.i_nals_allocated = h->out.i_nals_allocated + X264_NAL_MAX;
> + x264_free(tmp);
> + }
> }
Overly complicated (only 1 alloc/copy is needed), and anyway should be
in a x264_realloc().
--Loren Merritt
More information about the x264-devel
mailing list