---
libavcodec/h264.c | 46 +++++++++++++++++++++++++++-------------------
1 files changed, 27 insertions(+), 19 deletions(-)
diff --git a/libavcodec/h264.c b/libavcodec/h264.c
index 95a5aed..e0ab15d 100644
--- a/libavcodec/h264.c
+++ b/libavcodec/h264.c
@@ -1640,29 +1640,17 @@ static inline int quantize_c(DCTELEM *block, uint8_t *scantable, int qscale, int
static inline int mc_dir_part_y(H264Context *h, Picture *pic, int n, int height,
int y_offset, int list){
- MpegEncContext * const s = &h->s;
int my= h->mv_cache[list][ scan8[n] ][1] + 4*y_offset;
int filter_height= 6;
int extra_height= h->emu_edge_height;
const int full_my= my>>2;
if(!pic->data[0]) return -1;
- if((pic->reference&3) != PICT_FRAME) return 16*s->mb_height-1;
if(full_my < (extra_height + filter_height)){
my = abs(my) + extra_height*4;
}
- /*
- if(!ENABLE_GRAY && !(s->flags&CODEC_FLAG_GRAY)){
- if(MB_FIELD){
- const int pic_height = 16*s->mb_height >> MB_FIELD;
- // chroma offset when predicting from a field of opposite parity
- my += 2 * ((s->mb_y & 1) - (pic->reference - 1));
- emu |= (my>>3) < 0 || (my>>3) + 8 >= (pic_height>>1);
- }
- }*/
-
return (my + height * 4 + filter_height * 4 + 1) >> 2;
}
@@ -1671,12 +1659,17 @@ static inline void mc_part_y(H264Context *h, int refs[2][48], int n, int height,
MpegEncContext * const s = &h->s;
int my;
- y_offset += 16*(s->mb_y >> MB_FIELD);
+ y_offset += 16*(s->mb_y >> FIELD_PICTURE);
if(list0){
int ref_n = h->ref_cache[0][ scan8[n] ], my;
Picture *ref= &h->ref_list[0][ref_n];
- if(ref->thread_opaque != s->current_picture_ptr->thread_opaque){
+
+ // Error resilience puts the current picture in the ref list.
+ // Don't try to wait on these as it will cause a deadlock.
+ // Fields can wait on each other, though.
+ if(ref->thread_opaque != s->current_picture.thread_opaque ||
+ (ref->reference&3) != s->picture_structure) {
my = mc_dir_part_y(h, ref, n, height, y_offset, 0);
refs[0][ref_n] = FFMAX(refs[0][ref_n], my);
}
@@ -1685,7 +1678,9 @@ static inline void mc_part_y(H264Context *h, int refs[2][48], int n, int height,
if(list1){
int ref_n = h->ref_cache[1][ scan8[n] ];
Picture *ref= &h->ref_list[1][ref_n];
- if(ref->thread_opaque != s->current_picture_ptr->thread_opaque){
+
+ if(ref->thread_opaque != s->current_picture.thread_opaque ||
+ (ref->reference&3) != s->picture_structure) {
my = mc_dir_part_y(h, ref, n, height, y_offset, 1);
refs[1][ref_n] = FFMAX(refs[1][ref_n], my);
}
@@ -1703,7 +1698,6 @@ static void avail_motion(H264Context *h){
const int mb_type= s->current_picture.mb_type[mb_xy];
int refs[2][48];
int ref, list;
- int pic_height = 16*s->mb_height;
memset(refs, -1, sizeof(refs));
@@ -1755,11 +1749,25 @@ static void avail_motion(H264Context *h){
}
}
- //L1 refs are closer than L0, so wait for them first
for(list=1; list>=0; list--){
for(ref=0; ref<48; ref++){
- if(refs[list][ref] >= 0)
- ff_await_frame_progress((AVFrame*)&h->ref_list[list][ref], FFMIN(refs[list][ref], pic_height-1));
+ int row = refs[list][ref];
+ if(row >= 0){
+ Picture *ref_pic = &h->ref_list[list][ref];
+ int pic_height = 16*s->mb_height >> ref_pic->field_picture;
+ int ref_field = ref_pic->reference - 1;
+
+ if(!FIELD_PICTURE && ref_pic->field_picture){ // frame referencing two fields
+ ff_await_field_progress((AVFrame*)ref_pic, FFMIN((row >> 1) - !(row&1), pic_height-1), 1);
+ ff_await_field_progress((AVFrame*)ref_pic, FFMIN((row >> 1) , pic_height-1), 0);
+ }else if(FIELD_PICTURE && !ref_pic->field_picture){ // field referencing one field of a frame
+ ff_await_field_progress((AVFrame*)ref_pic, FFMIN(row*2 + ref_field , pic_height-1), 0);
+ }else if(FIELD_PICTURE){
+ ff_await_field_progress((AVFrame*)ref_pic, FFMIN(row, pic_height-1), ref_field);
+ }else{
+ ff_await_field_progress((AVFrame*)ref_pic, FFMIN(row, pic_height-1), 0);
+ }
+ }
}
}
}
_______________________________________________
FFmpeg-soc mailing list
[email protected]
https://lists.mplayerhq.hu/mailman/listinfo/ffmpeg-soc