Libav 0.7.1
|
00001 /* 00002 * Chinese AVS video (AVS1-P2, JiZhun profile) parser. 00003 * Copyright (c) 2006 Stefan Gehrer <stefan.gehrer@gmx.de> 00004 * 00005 * This file is part of Libav. 00006 * 00007 * Libav is free software; you can redistribute it and/or 00008 * modify it under the terms of the GNU Lesser General Public 00009 * License as published by the Free Software Foundation; either 00010 * version 2.1 of the License, or (at your option) any later version. 00011 * 00012 * Libav is distributed in the hope that it will be useful, 00013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00015 * Lesser General Public License for more details. 00016 * 00017 * You should have received a copy of the GNU Lesser General Public 00018 * License along with Libav; if not, write to the Free Software 00019 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 00020 */ 00021 00028 #include "parser.h" 00029 #include "cavs.h" 00030 00031 00036 static int cavs_find_frame_end(ParseContext *pc, const uint8_t *buf, 00037 int buf_size) { 00038 int pic_found, i; 00039 uint32_t state; 00040 00041 pic_found= pc->frame_start_found; 00042 state= pc->state; 00043 00044 i=0; 00045 if(!pic_found){ 00046 for(i=0; i<buf_size; i++){ 00047 state= (state<<8) | buf[i]; 00048 if(state == PIC_I_START_CODE || state == PIC_PB_START_CODE){ 00049 i++; 00050 pic_found=1; 00051 break; 00052 } 00053 } 00054 } 00055 00056 if(pic_found){ 00057 /* EOF considered as end of frame */ 00058 if (buf_size == 0) 00059 return 0; 00060 for(; i<buf_size; i++){ 00061 state= (state<<8) | buf[i]; 00062 if((state&0xFFFFFF00) == 0x100){ 00063 if(state > SLICE_MAX_START_CODE){ 00064 pc->frame_start_found=0; 00065 pc->state=-1; 00066 return i-3; 00067 } 00068 } 00069 } 00070 } 00071 pc->frame_start_found= pic_found; 00072 pc->state= state; 00073 return END_NOT_FOUND; 00074 } 00075 00076 static int cavsvideo_parse(AVCodecParserContext *s, 00077 AVCodecContext *avctx, 00078 const uint8_t **poutbuf, int *poutbuf_size, 00079 const uint8_t *buf, int buf_size) 00080 { 00081 ParseContext *pc = s->priv_data; 00082 int next; 00083 00084 if(s->flags & PARSER_FLAG_COMPLETE_FRAMES){ 00085 next= buf_size; 00086 }else{ 00087 next= cavs_find_frame_end(pc, buf, buf_size); 00088 00089 if (ff_combine_frame(pc, next, &buf, &buf_size) < 0) { 00090 *poutbuf = NULL; 00091 *poutbuf_size = 0; 00092 return buf_size; 00093 } 00094 } 00095 *poutbuf = buf; 00096 *poutbuf_size = buf_size; 00097 return next; 00098 } 00099 00100 AVCodecParser ff_cavsvideo_parser = { 00101 { CODEC_ID_CAVS }, 00102 sizeof(ParseContext1), 00103 NULL, 00104 cavsvideo_parse, 00105 ff_parse1_close, 00106 ff_mpeg4video_split, 00107 };