PDA

View Full Version : Can P frames only reference I frame in X264?


nwumengfei
23rd May 2008, 05:33
Dear all:

I change the x264_reference_update() function to surpport only reference I frames as follow,is it right?
/////////////////////////////////////////////////////////
#define ONLY_REFERENCE_I_SLICE 1 // I define it

static inline void x264_reference_update( x264_t *h )
{
int i;

if( h->fdec->i_frame >= 0 )
h->i_frame++;

if( !h->fdec->b_kept_as_ref )
{
if( h->param.i_threads > 1 )
{
x264_frame_push_unused( h, h->fdec );
h->fdec = x264_frame_pop_unused( h );
}
return;
}

/* move lowres copy of the image to the ref frame */
for( i = 0; i < 4; i++)
{
XCHG( uint8_t*, h->fdec->lowres[i], h->fenc->lowres[i] );
XCHG( uint8_t*, h->fdec->buffer_lowres[i], h->fenc->buffer_lowres[i] );
}

/* adaptive B decision needs a pointer, since it can't use the ref lists */
if( h->sh.i_type != SLICE_TYPE_B )
h->frames.last_nonb = h->fdec;

// now I try to only push the I frame
if ( ONLY_REFERENCE_I_SLICE
&& IS_X264_TYPE_I( h->fdec->i_type ) )
{
x264_frame_push( h->frames.reference, h->fdec );
}
// end

/* move frame in the buffer */
// x264_frame_push( h->frames.reference, h->fdec );
if( h->frames.reference[h->frames.i_max_dpb] )
x264_frame_push_unused( h, x264_frame_shift( h->frames.reference ) );
h->fdec = x264_frame_pop_unused( h );
}
/////////////////////////////////////////////////////////

GOP size is 20, but the encoded video quality is quite poor, can someone give me some advices? Thankyou!

Dark Shikari
23rd May 2008, 15:21
GOP size is 20, but the encoded video quality is quite poor, can someone give me some advices? Thankyou!You set P-frames to only reference I-frames and you wonder why the result sucks? :p

nwumengfei
26th May 2008, 03:25
I'm sorry,I think I have not make myself clear!
I want to know: By change the function x264_reference_update can I make P frames only reference I frame?

Dark Shikari
26th May 2008, 03:32
I'm sorry,I think I have not make myself clear!
I want to know: By change the function x264_reference_update can I make P frames only reference I frame?This would be problematic, because in order to ensure that the decoder always keeps the prior I-frame in memory, you'd have to implement MMCO.

Sergey A. Sablin
26th May 2008, 13:52
This would be problematic, because in order to ensure that the decoder always keeps the prior I-frame in memory, you'd have to implement MMCO.

that's pretty easy - use nal_ref_idc = 0 for all P-frames. (and I really believe that before trying to help someone you need to be sure you know what you're talking about)

Dark Shikari
26th May 2008, 18:27
that's pretty easy - use nal_ref_idc = 0 for all P-frames. (and I really believe that before trying to help someone you need to be sure you know what you're talking about)I do know what I'm talking about, I just didn't see such an obvious method of doing things :p

So yes, Sablin is right, you can simply turn off referencing on each P-frame rather than using reflist reordering/MMCO. An ugly hack, yes, but it works (now whether its a good idea I would doubt...)

Sergey A. Sablin
26th May 2008, 21:17
I do know what I'm talking about, I just didn't see such an obvious method of doing things :p

So yes, Sablin is right, you can simply turn off referencing on each P-frame rather than using reflist reordering/MMCO. An ugly hack, yes, but it works (now whether its a good idea I would doubt...)

what exactly is ugly hack here? it's absolutely standard way to mark references.
the ugly hack would be to write nal_ref_idc!=0 and then write MMCO which would remove just added to DPB picture from it.

akupenguin
26th May 2008, 21:31
The ugly hack is asking for I-frames to be the only referenced pictures. No matter how you implement it.

nwumengfei
27th May 2008, 06:25
Thankyou, everyone!
I have make the nal_ref_idc = 0 for the P frames, it works fine!
I want to know,at decoder side,is P frames only ref the I frame?

nwumengfei
27th May 2008, 07:34
I use ffmpeg for playback and I found that the P frames ref the frame before but not the I frame.
Here I make the P frames only ref I frame bacause I think that P frames in one GOP can be decoded even if the P frames before it lost in network.

akupenguin
27th May 2008, 09:00
Here I make the P frames only ref I frame bacause I think that P frames in one GOP can be decoded even if the P frames before it lost in network.
And you would be wrong. The fact that you had to change x264 to make it work your way, combined with the fact that you lost a ton of compression efficiency in the process, should be your first hints.

Sergey A. Sablin
27th May 2008, 15:06
I use ffmpeg for playback and I found that the P frames ref the frame before but not the I frame.
how do you found this? is stream broken or just bad quality?
if the stream is broken then you didn't change x264 properly - run it in debug mode and see what's happening in it's DPB; if it is just bad quality, then no wonder - using only I-frames as references will work more or less good on static scenes, such as teleconferencing, where backgorund isn't changed at all, while foreground have very small changes.

nwumengfei
30th May 2008, 13:29
how do you found this? is stream broken or just bad quality?


I'm sorry for such a long time delay.
I'm wrong!
I just extracted the H.264 decoder in ffmpeg and check it in debug mode and found that the P frames only ref I frames,so thankyou everyone!

nwumengfei
31st May 2008, 06:00
I want ask a question more.
Does x264 surpport I_PCM mode, and can this make the P frames a better quality?

Dark Shikari
31st May 2008, 06:03
I want ask a question more.
Does x264 surpport I_PCM mode, and can this make the P frames a better quality?PCM is supported but hasn't been really tested; I tried it a while back for kicks and it seemed to work.

PCM mode means that it codes the macroblock directly to the bitstream without compression, resulting in roughly 3072 bits written to the bitstream, an order of magnitude more than any normal macroblock. This is generally only at all useful in lossless mode for extremely uncompressible blocks or at extremely high bitrates in non-lossless mode with highly complex sources (example: 8-bit video game footage with tons of sharp lines), and even then PCM would be very rarely used.

Technically the standard requires PCM for any block greater than 384 bytes (to avoid compressed blocks larger than an uncompressed block), but I don't know if anyone bothers with that requirement...

nwumengfei
31st May 2008, 08:23
I compared x264 and MPEG4(a commercial static lib), and I found that the PSNR of the I frame of H.264 is always lower than MPEG4.Here is a group of test info:
x264 (QP = 26): PSNR: [Y: 37.66] [U: 41.14] [V: 40.07]
MPEG4(I don't know the QP): PSNR: [Y: 40.43] [U: 41.81] [V: 41.35]
I want to know how to get a better key frame in x264?

Dark Shikari
31st May 2008, 08:35
I compared x264 and MPEG4(a commercial static lib), and I found that the PSNR of the I frame of H.264 is always lower than MPEG4.Here is a group of test info:
x264 (QP = 26): PSNR: [Y: 37.66] [U: 41.14] [V: 40.07]
MPEG4(I don't know the QP): PSNR: [Y: 40.43] [U: 41.81] [V: 41.35]
I want to know how to get a better key frame in x264?Raise --ipratio.

Note if you're optimizing for PSNR you'll want to disable psyopts, such as AQ...