LCOV - code coverage report
Current view: top level - libavcodec - mpeg4video_parser.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 68 70 97.1 %
Date: 2018-05-20 11:54:08 Functions: 4 4 100.0 %

          Line data    Source code
       1             : /*
       2             :  * MPEG-4 video frame extraction
       3             :  * Copyright (c) 2003 Fabrice Bellard
       4             :  * Copyright (c) 2003 Michael Niedermayer
       5             :  *
       6             :  * This file is part of FFmpeg.
       7             :  *
       8             :  * FFmpeg is free software; you can redistribute it and/or
       9             :  * modify it under the terms of the GNU Lesser General Public
      10             :  * License as published by the Free Software Foundation; either
      11             :  * version 2.1 of the License, or (at your option) any later version.
      12             :  *
      13             :  * FFmpeg is distributed in the hope that it will be useful,
      14             :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      15             :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      16             :  * Lesser General Public License for more details.
      17             :  *
      18             :  * You should have received a copy of the GNU Lesser General Public
      19             :  * License along with FFmpeg; if not, write to the Free Software
      20             :  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
      21             :  */
      22             : 
      23             : #define UNCHECKED_BITSTREAM_READER 1
      24             : 
      25             : #include "internal.h"
      26             : #include "parser.h"
      27             : #include "mpegvideo.h"
      28             : #include "mpeg4video.h"
      29             : #include "mpeg4video_parser.h"
      30             : 
      31             : struct Mp4vParseContext {
      32             :     ParseContext pc;
      33             :     Mpeg4DecContext dec_ctx;
      34             :     int first_picture;
      35             : };
      36             : 
      37        8238 : int ff_mpeg4_find_frame_end(ParseContext *pc, const uint8_t *buf, int buf_size)
      38             : {
      39             :     int vop_found, i;
      40             :     uint32_t state;
      41             : 
      42        8238 :     vop_found = pc->frame_start_found;
      43        8238 :     state     = pc->state;
      44             : 
      45        8238 :     i = 0;
      46        8238 :     if (!vop_found) {
      47        8438 :         for (i = 0; i < buf_size; i++) {
      48        8436 :             state = (state << 8) | buf[i];
      49        8436 :             if (state == VOP_STARTCODE) {
      50        1085 :                 i++;
      51        1085 :                 vop_found = 1;
      52        1085 :                 break;
      53             :             }
      54             :         }
      55             :     }
      56             : 
      57        8238 :     if (vop_found) {
      58             :         /* EOF considered as end of frame */
      59        8236 :         if (buf_size == 0)
      60          24 :             return 0;
      61     8516208 :         for (; i < buf_size; i++) {
      62     8509069 :             state = (state << 8) | buf[i];
      63     8509069 :             if ((state & 0xFFFFFF00) == 0x100) {
      64        1073 :                 if (state == SLICE_STARTCODE || state == EXT_STARTCODE)
      65           0 :                     continue;
      66        1073 :                 pc->frame_start_found = 0;
      67        1073 :                 pc->state             = -1;
      68        1073 :                 return i - 3;
      69             :             }
      70             :         }
      71             :     }
      72        7141 :     pc->frame_start_found = vop_found;
      73        7141 :     pc->state             = state;
      74        7141 :     return END_NOT_FOUND;
      75             : }
      76             : 
      77             : /* XXX: make it use less memory */
      78        3549 : static int mpeg4_decode_header(AVCodecParserContext *s1, AVCodecContext *avctx,
      79             :                                const uint8_t *buf, int buf_size)
      80             : {
      81        3549 :     struct Mp4vParseContext *pc = s1->priv_data;
      82        3549 :     Mpeg4DecContext *dec_ctx = &pc->dec_ctx;
      83        3549 :     MpegEncContext *s = &dec_ctx->m;
      84        3549 :     GetBitContext gb1, *gb = &gb1;
      85             :     int ret;
      86             : 
      87        3549 :     s->avctx               = avctx;
      88        3549 :     s->current_picture_ptr = &s->current_picture;
      89             : 
      90        3549 :     if (avctx->extradata_size && pc->first_picture) {
      91         241 :         init_get_bits(gb, avctx->extradata, avctx->extradata_size * 8);
      92         241 :         ret = ff_mpeg4_decode_picture_header(dec_ctx, gb);
      93         241 :         if (ret < -1)
      94         241 :             av_log(avctx, AV_LOG_WARNING, "Failed to parse extradata\n");
      95             :     }
      96             : 
      97        3549 :     init_get_bits(gb, buf, 8 * buf_size);
      98        3549 :     ret = ff_mpeg4_decode_picture_header(dec_ctx, gb);
      99        7034 :     if (s->width && (!avctx->width || !avctx->height ||
     100        6970 :                      !avctx->coded_width || !avctx->coded_height)) {
     101          12 :         ret = ff_set_dimensions(avctx, s->width, s->height);
     102          12 :         if (ret < 0)
     103           0 :             return ret;
     104             :     }
     105        3549 :     if((s1->flags & PARSER_FLAG_USE_CODEC_TS) && s->avctx->time_base.den>0 && ret>=0){
     106             :         av_assert1(s1->pts == AV_NOPTS_VALUE);
     107             :         av_assert1(s1->dts == AV_NOPTS_VALUE);
     108             : 
     109         874 :         s1->pts = av_rescale_q(s->time, (AVRational){1, s->avctx->time_base.den}, (AVRational){1, 1200000});
     110             :     }
     111             : 
     112        3549 :     s1->pict_type     = s->pict_type;
     113        3549 :     pc->first_picture = 0;
     114        3549 :     return ret;
     115             : }
     116             : 
     117         328 : static av_cold int mpeg4video_parse_init(AVCodecParserContext *s)
     118             : {
     119         328 :     struct Mp4vParseContext *pc = s->priv_data;
     120             : 
     121         328 :     ff_mpeg4videodec_static_init();
     122             : 
     123         328 :     pc->first_picture           = 1;
     124         328 :     pc->dec_ctx.m.quant_precision     = 5;
     125         328 :     pc->dec_ctx.m.slice_context_count = 1;
     126         328 :     pc->dec_ctx.showed_packed_warning = 1;
     127         328 :     return 0;
     128             : }
     129             : 
     130       10690 : static int mpeg4video_parse(AVCodecParserContext *s,
     131             :                             AVCodecContext *avctx,
     132             :                             const uint8_t **poutbuf, int *poutbuf_size,
     133             :                             const uint8_t *buf, int buf_size)
     134             : {
     135       10690 :     ParseContext *pc = s->priv_data;
     136             :     int next;
     137             : 
     138       10690 :     if (s->flags & PARSER_FLAG_COMPLETE_FRAMES) {
     139        2452 :         next = buf_size;
     140             :     } else {
     141        8238 :         next = ff_mpeg4_find_frame_end(pc, buf, buf_size);
     142             : 
     143        8238 :         if (ff_combine_frame(pc, next, &buf, &buf_size) < 0) {
     144        7141 :             *poutbuf      = NULL;
     145        7141 :             *poutbuf_size = 0;
     146        7141 :             return buf_size;
     147             :         }
     148             :     }
     149        3549 :     mpeg4_decode_header(s, avctx, buf, buf_size);
     150             : 
     151        3549 :     *poutbuf      = buf;
     152        3549 :     *poutbuf_size = buf_size;
     153        3549 :     return next;
     154             : }
     155             : 
     156             : AVCodecParser ff_mpeg4video_parser = {
     157             :     .codec_ids      = { AV_CODEC_ID_MPEG4 },
     158             :     .priv_data_size = sizeof(struct Mp4vParseContext),
     159             :     .parser_init    = mpeg4video_parse_init,
     160             :     .parser_parse   = mpeg4video_parse,
     161             :     .parser_close   = ff_parse_close,
     162             :     .split          = ff_mpeg4video_split,
     163             : };

Generated by: LCOV version 1.13