# ER and EC fixes for field pictures

## Goals 

* have proper ER stats for field pictures, which is bogus due to ER context

* have some custom ECInfo stats SIDEDATA attached to pictures

## Multiple Contexts

```
H264Context
|-H264SliceContext[]
|-ERContext
|-H264Picture[]
| |-AVFrame *
| |-ThreadFrame
```

Each thread has its own context, and per thread *copies* of every other context.

## Thread safety

Conforming to the ffmpeg threading model, all data has either to be set up in the init of the thread, or propagated
using the dedicated calls:

- ff_h264_update_thread_context()
Copies/merges forwards previous H264Context structs towards next H264Context (of new thread) for next decoded slice

- ff_h264_update_thread_context_for_user()
Copies/merges data backwards to first/initial H264Context so it can be exposed through API to user.

Outside of this, everything has no thread safety.

## Thread safety and data sharing

Shared decoded data is AVFrame by refcounting, when building using multiple slices or different fields.
ER is also shared when frame has multiple slices.

## ER stats

ER for fields is bogus, either hitting same EC (single thread) or different EC.

(changed) we are now doing proper odd or even stats on the ER buffer, and use
only even or odd data for recovery.

Odd/even interleave is used as we can not use a flat half sized stats buffer 
for fields as error recovery would use wrong rows/slices.

## EC

Error recovery is not thread safe with fields, non coordinated motion vector reads.

(changed) It is disabled for field pictures

## Gathering EC stats between fields

When processing field picture, AVFrame is shared but different EC in multithread.

(changed) To fix this, the ER data ECInfo is shared in a refcounted buffer.

In a similar way, the error_count variable used to set frame flags does the same.

## Perfoming EC stats summary, including referenced errors 

Trying to share ECInfo, the proper way, in a custom shared by copy struct (Stats/POC array)
at ff_h264_update_thread_context time ended in a consistency failure.
In the case of fields, if both fields are decoded in a different thread,
the shared info becomes inconsistent as they both have a different next thread.

As a workaround corruption info synthesis is done at frame_output() time,
as this is the only guaranteed moment the references have also terminated their ER.

For that purpose, a mutex is shared on the refcounted ECInfo stats buffer and all referenced
H264Picture's own ECInfo is accessed, and then attached/forwarded as SIDEDATA.

### ER summary with MISSING references

When a full NAL is invalid, the reference is missing. In that case, the referring frame is assigned
some default reference frame, and the reference is *removed* from the list.

(changed) we tag the H264picture with a missing reference flag, which downgrades the score at export
time as corrupted.

As the decoding process is also not invoked on the missing references, there's no ER/EC code involved.

(changed) in that case we fill ECInfo as fully corrupted.

## Calls

```
- h264_decode_frame(AVCodecContext/H264Context)
|- h264_decode_nal_units(H264Context)
. |- ff_h264_queue_decode_slice
. . |- h264_field_start
. . . |- ff_thread_await_progress * ref concealment
. . . |- h264_frame_start
. . . . |- ff_er_frame_start
. |- ff_h264_execute_decode_slices(H264Context)
. . |- ff_h264_update_thread_context()
  [execs inthread]
. . |- decode_slice(AVCodecContext/H264Context)
. . . |- er_add_slice
. |- ff_er_frame_end()
. |- finalize_frame/output_frame()
. . |- ff_h264_field_end
. . . . |- ff_thread_report_progress
. |- ff_thread_report_progress
```

(changed)