[FFmpeg-devel] [RFC] Seeking in PVA files

Michael Niedermayer michaelni
Sat Jan 5 21:20:45 CET 2008


On Sat, Jan 05, 2008 at 08:23:25PM +0100, Ivo wrote:
> On Saturday 05 January 2008 18:44, Michael Niedermayer wrote:
> > av_seek_frame_binary() uses the index
> > av_index_search_timestamp() is not correct unless you have indexed the
> > whole file or at least a single continous area
> >
> > if you read the first 10% then seek to the end end agaib read 10% then
> > av_index_search_timestamp() will not fail if you seek between these 2 but
> > it will neither give you a reasonable result
> 
> I see. Basically read_seek if mostly for containers that have their own 
> index. I RTFS'd a bit more, which resulted in the attached patch. It also 
> includes the refactoring of mpeg.c so the pes ts code can be reused.
> 

[...]

>      st->codec->codec_type = CODEC_TYPE_AUDIO;
> -    st->codec->codec_id   = CODEC_ID_MP3;
> +    st->codec->codec_id   = CODEC_ID_MP2;
>      st->need_parsing      = AVSTREAM_PARSE_HEADERS;

seperate patch/commit!


[...]
> +static inline void read_pva_header(ByteIOContext *pb, int *syncword,
> +                    int *streamid, int *reserved, int *flags, int *length) {
> +    *syncword = get_be16(pb);
> +    *streamid = get_byte(pb);
> +    get_byte(pb);               /* counter not used */
> +    *reserved = get_byte(pb);
> +    *flags    = get_byte(pb);
> +    *length   = get_be16(pb);
> +}
> +
> +static inline void get_pes_header(ByteIOContext *pb, int *pes_signal,
> +        int *pes_packet_length, int *pes_flags, int *pes_header_data_length,
> +        int8_t *pes_header_data) {
> +    *pes_signal             = get_be24(pb);
> +    get_byte(pb);
> +    *pes_packet_length      = get_be16(pb);
> +    *pes_flags              = get_be16(pb);
> +    *pes_header_data_length = get_byte(pb);
> +    get_buffer(pb, pes_header_data, *pes_header_data_length);
> +}
> +
>  static int pva_read_packet(AVFormatContext *s, AVPacket *pkt) {
>      ByteIOContext *pb = s->pb;
>      PVAContext *pvactx = s->priv_data;
>      int ret, syncword, streamid, reserved, flags, length, pts_flag;
> -    long long pva_pts = 0;
> +    int64_t pva_pts = AV_NOPTS_VALUE, startpos = url_ftell(pb);
>  
> -    syncword = get_be16(pb);
> -    streamid = get_byte(pb);
> -    get_byte(pb);               /* counter not used */
> -    reserved = get_byte(pb);
> -    flags    = get_byte(pb);
> -    length   = get_be16(pb);

seperate patch/commit!
and there is no check for streamid being valid 


[...]
> -            unsigned char pes_header_data[256];
> +            uint8_t pes_header_data[256];

cosmetic -> ok but seperate commit please


[...]
> +static int64_t pva_read_timestamp(struct AVFormatContext *s, int stream_index,
> +                                  int64_t *pos, int64_t pos_limit) {
> +    ByteIOContext *pb = s->pb;
> +    PVAContext *pvactx = s->priv_data;
> +    int64_t res = AV_NOPTS_VALUE;
> +

> +    if (pos_limit - *pos > PVA_MAX_PAYLOAD_LENGTH * 16)
> +        pos_limit = *pos + PVA_MAX_PAYLOAD_LENGTH * 16;

FFMIN()


> +
> +    while (*pos < pos_limit) {
> +        int syncword, streamid, reserved, flags, length;
> +
> +        if (url_fseek(pb, *pos, SEEK_SET) < 0) return AV_NOPTS_VALUE;
> +

> +        read_pva_header(pb, &syncword, &streamid, &reserved, &flags, &length);
> +
> +        if (syncword != PVA_MAGIC || reserved != 0x55 || !streamid ||
> +            streamid >PVA_AUDIO_PAYLOAD || length > PVA_MAX_PAYLOAD_LENGTH) {
> +            (*pos)++;
> +            continue;
> +        }

shouldnt these checks be in read_pva_header() ? 


> +
> +        if (streamid - 1 == stream_index) {
> +            if (streamid == PVA_VIDEO_PAYLOAD && flags & 0x10) {
> +                res = get_be32(pb);
> +                break;
> +            } else if (streamid == PVA_AUDIO_PAYLOAD) {
> +                int pes_signal, pes_header_data_length, pes_packet_length,
> +                    pes_flags;
> +                uint8_t pes_header_data[256];
> +
> +                get_pes_header(pb, &pes_signal, &pes_packet_length, &pes_flags,
> +                               &pes_header_data_length, pes_header_data);
> +
> +                if (pes_signal == 1) {
> +                    if (pes_flags & 0x80 && (pes_header_data[0] & 0xf0)== 0x20)
> +                        res = ff_parse_pes_pts(pes_header_data);
> +                    if (res != AV_NOPTS_VALUE) break;
> +                }
> +            }
> +        }

you should parse all streams and use av_add_index_entry() even if the
specific stream hasnt been requested

also cant more code be factored with pva_read_packet() ?
this looks somewhat similar
if so you might even avoid the need for some of the new functions

[...]


> Index: libavformat/mpeg.c

needs mans approval

[...]
-- 
Michael     GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB

I count him braver who overcomes his desires than him who conquers his
enemies for the hardest victory is over self. -- Aristotle
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: Digital signature
URL: <http://lists.mplayerhq.hu/pipermail/ffmpeg-devel/attachments/20080105/87b4b9cf/attachment.pgp>



More information about the ffmpeg-devel mailing list