The Big Picture
===============

- Lots of documentation
- Uniform time representation
- Restore audio encoding


Encoding
========

- Make everything mutable. Later, we can introduce a PseudoMutable base class
  for everything that has a .assert_mutable() method and public is_read_only


Time
====

- What are the various rates and scales?

  see: http://ffmpeg.org/pipermail/libav-user/2011-December/001041.html
  see: http://stackoverflow.com/questions/12234949/ffmpeg-time-unit-explanation-and-av-seek-frame-method/16739755#16739755

  - Stream.guessed_rate or AVStream.r_frame_rate:
    FFmpeg's guess as to the frame rate. Often 24/1.

  - Stream.average_rate or AVStream.avg_frame_rate:
    Average frame rate that has been inspected in the file. This is what VLC
    reports in the media information. Often near 24/1.

    It may calculate this from 20 frames; see: http://ffmpeg.org/doxygen/trunk/libavformat_2utils_8c_source.html#l02768

  - Stream.time_base or AVStream.time_base:
    Duration of one time unit for AVStream times.

  - Stream.rate or CodecContext.time_base:
      The length of a single frame as reported by the file. Sometimes 1/24,
      sometimes really really wrong.

  possibilities for discrepencies:
    - .mov supports a fixed frame rate
    - .mp4 does not support a fixed frame rate?
    - see: http://ffmpeg.org/doxygen/trunk/libavformat_2utils_8c_source.html#l02647


Unsorted
========

- Protocol for streams to pull packets from iterators. Then secondary streams
  get easier: container.add_stream('audio_codec', source=av.open('music.aiff').iter_packets(only_primary=True))

- Container.demux(video=True)
- Container.decode(video=True) -> straight to frames

- Flush AudioResampler.


- Container.add_stream(template=stream)

- atexit.register something to clean up FFmpeg threads

- Create Codec Descriptor

- Make av.utils.SmartPointer to wrap around a pointer?

runtime_library_dirs

- Look at how stream alloc works; can we manually do this and register the
  stream on a format context later?

- Context use a StringIO or similar to write into/from?
    - Create wrapper around AVIOContext for arbitrary Python object with read/write
      methods.

- libavdevice? Pull from video input?

- Various AudioLayout/AudioFormat/VideoFormat attributes should be writable.
    - is_mutable flags on various objects (including formats, layouts, contexts,
      streams, etc.) could guard the __set__ methods of properties.

- Should methods be: to_bytes, as_bytes, tobytes, asbytes??

- Plane.array_format could be a format string for array.array
- Plane.update_from_array(array.array)
    - If it were HD RGB then it would be 1920 * 1080 * 3 long.
- Plane.update_from_ndarray(numpy.ndarray)
    - If it were HD RGB then it would have shape (1080, 1920, 3)
- Plane.update(input_)
    And then it tries if it is a buffer, memoryview, bytes, etc..

- Stream.encode(...) -> list of packets, automatically checking buffer)
- Context.mux(...) -> take a single packet, or an iterator of them:
        context.mux(stream.encode(frame))

- Context.add_stream(codec_name, frame_rate) -> Context.streams.append(Stream(codec_name, frame_rate))?

- SwsContext -> av.video.rescaler.Rescaler

- TestCase.rms_diff(one, two) -> Root-mean-square diff
- try to wrap API of testsrc filters

---

- FFmpeg tutorial: http://dranger.com/ffmpeg/
	- also has function reference: http://dranger.com/ffmpeg/functions.html
	- updated tutorial code: https://github.com/chelyaev/ffmpeg-tutorial

- Even out more of the differences:
    - See README of https://github.com/chelyaev/ffmpeg-tutorial

- Replicate av_frame_get_best_effort_timestamp

    http://ffmpeg.org/pipermail/ffmpeg-devel/2011-February/104327.html
    http://pastebin.com/Aq8eDZw3/
    http://web.archiveorange.com/archive/v/yR2T4bybpYnYCUXmzAI5


