FFmpeg technical

From MultimediaWiki
Jump to navigation Jump to search

Demuxer stuff

How to use demuxer with raw data

Write a parser. There are two main function - parse and split. parse is used to reconstruct precisely one frame from raw packets, split is used for extracting extradata from the same stream.

Parser declarations will look like this:

 typedef struct MyParseContext{
    ParseContext pc; /* always include this first */
    another data
 };
 AVParser some_parser = {
    { CODEC_ID_1 [CODEC_ID_2, ...] },
   sizeof (MyParseContext),
   NULL, /* usually there is no need in parser_open */
   my_parse,
   ff_parse_close, /* again, use standard close function */
   my_split,
 };

And here is the code for some parser which splits frame by some markers:

 static int xxx_find_frame_end(XXXParseContext *pc1, const uint8_t *buf,
                              int buf_size) {
   int start_found, i;
   uint32_t state;
   ParseContext *pc = &pc1->pc;
   start_found= pc->frame_start_found;
   state= pc->state;
   i=0;
   if(!start_found){
       for(i=0; i<buf_size; i++){
           state= (state<<8) | buf[i];
           if(state == MARKER){
               start_found=1;
               break;
           }
       }
   }
   if(start_found){
       for(; i<buf_size; i++){
           state= (state<<8) | buf[i];
           if(state == MARKER){
               pc->frame_start_found= 0;
               pc->state= -1;
               return i-3;
           }
       }
   }
   pc->frame_start_found= start_found;
   pc->state= state;
   return END_NOT_FOUND;
 }
 static int xxx_parse(AVCodecParserContext *s,
                          AVCodecContext *avctx,
                          uint8_t **poutbuf, int *poutbuf_size,
                          const uint8_t *buf, int buf_size)
 {
   XXXParseContext *pc1 = s->priv_data;
   ParseContext *pc = &pc1->pc;
   int next;
   if(s->flags & PARSER_FLAG_COMPLETE_FRAMES){
       next= buf_size;
   }else{
       next= xxx_find_frame_end(pc1, buf, buf_size);
       if (ff_combine_frame(pc, next, (uint8_t **)&buf, &buf_size) < 0) {
           *poutbuf = NULL;
           *poutbuf_size = 0;
           return buf_size;
       }
   }
   *poutbuf = (uint8_t *)buf;
   *poutbuf_size = buf_size;
   return next;
}

Decoder stuff