Mercurial > audlegacy-plugins
comparison src/ffmpeg/libffwma/parser.c @ 806:74abcb9cafae trunk
[svn] - fork wma plugin
| author | nenolod |
|---|---|
| date | Mon, 12 Mar 2007 10:59:21 -0700 |
| parents | src/wma/libffwma/parser.c@3da1b8942b8b |
| children |
comparison
equal
deleted
inserted
replaced
| 805:1ba5f86aeac9 | 806:74abcb9cafae |
|---|---|
| 1 /* | |
| 2 * Audio and Video frame extraction | |
| 3 * Copyright (c) 2003 Fabrice Bellard. | |
| 4 * Copyright (c) 2003 Michael Niedermayer. | |
| 5 * | |
| 6 * This library is free software; you can redistribute it and/or | |
| 7 * modify it under the terms of the GNU Lesser General Public | |
| 8 * License as published by the Free Software Foundation; either | |
| 9 * version 2 of the License, or (at your option) any later version. | |
| 10 * | |
| 11 * This library is distributed in the hope that it will be useful, | |
| 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
| 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
| 14 * Lesser General Public License for more details. | |
| 15 * | |
| 16 * You should have received a copy of the GNU Lesser General Public | |
| 17 * License along with this library; if not, write to the Free Software | |
| 18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | |
| 19 */ | |
| 20 #include "avcodec.h" | |
| 21 #include "utils.h" | |
| 22 | |
| 23 AVCodecParser *av_first_parser = NULL; | |
| 24 | |
| 25 void av_register_codec_parser(AVCodecParser *parser) | |
| 26 { | |
| 27 parser->next = av_first_parser; | |
| 28 av_first_parser = parser; | |
| 29 } | |
| 30 | |
| 31 AVCodecParserContext *av_parser_init(int codec_id) | |
| 32 { | |
| 33 AVCodecParserContext *s; | |
| 34 AVCodecParser *parser; | |
| 35 int ret; | |
| 36 | |
| 37 for(parser = av_first_parser; parser != NULL; parser = parser->next) { | |
| 38 if (parser->codec_ids[0] == codec_id || | |
| 39 parser->codec_ids[1] == codec_id || | |
| 40 parser->codec_ids[2] == codec_id) | |
| 41 goto found; | |
| 42 } | |
| 43 return NULL; | |
| 44 found: | |
| 45 s = av_mallocz(sizeof(AVCodecParserContext)); | |
| 46 if (!s) | |
| 47 return NULL; | |
| 48 s->parser = parser; | |
| 49 s->priv_data = av_mallocz(parser->priv_data_size); | |
| 50 if (!s->priv_data) { | |
| 51 free(s); | |
| 52 return NULL; | |
| 53 } | |
| 54 if (parser->parser_init) { | |
| 55 ret = parser->parser_init(s); | |
| 56 if (ret != 0) { | |
| 57 free(s->priv_data); | |
| 58 free(s); | |
| 59 return NULL; | |
| 60 } | |
| 61 } | |
| 62 return s; | |
| 63 } | |
| 64 | |
| 65 /* NOTE: buf_size == 0 is used to signal EOF so that the last frame | |
| 66 can be returned if necessary */ | |
| 67 int av_parser_parse(AVCodecParserContext *s, | |
| 68 AVCodecContext *avctx, | |
| 69 uint8_t **poutbuf, int *poutbuf_size, | |
| 70 const uint8_t *buf, int buf_size, | |
| 71 int64_t pts, int64_t dts) | |
| 72 { | |
| 73 int index, i, k; | |
| 74 uint8_t dummy_buf[FF_INPUT_BUFFER_PADDING_SIZE]; | |
| 75 | |
| 76 if (buf_size == 0) { | |
| 77 /* padding is always necessary even if EOF, so we add it here */ | |
| 78 memset(dummy_buf, 0, sizeof(dummy_buf)); | |
| 79 buf = dummy_buf; | |
| 80 } else { | |
| 81 /* add a new packet descriptor */ | |
| 82 k = (s->cur_frame_start_index + 1) & (AV_PARSER_PTS_NB - 1); | |
| 83 s->cur_frame_start_index = k; | |
| 84 s->cur_frame_offset[k] = s->cur_offset; | |
| 85 s->cur_frame_pts[k] = pts; | |
| 86 s->cur_frame_dts[k] = dts; | |
| 87 | |
| 88 /* fill first PTS/DTS */ | |
| 89 if (s->cur_offset == 0) { | |
| 90 s->last_pts = pts; | |
| 91 s->last_dts = dts; | |
| 92 } | |
| 93 } | |
| 94 | |
| 95 /* WARNING: the returned index can be negative */ | |
| 96 index = s->parser->parser_parse(s, avctx, poutbuf, poutbuf_size, buf, buf_size); | |
| 97 /* update the file pointer */ | |
| 98 if (*poutbuf_size) { | |
| 99 /* fill the data for the current frame */ | |
| 100 s->frame_offset = s->last_frame_offset; | |
| 101 s->pts = s->last_pts; | |
| 102 s->dts = s->last_dts; | |
| 103 | |
| 104 /* offset of the next frame */ | |
| 105 s->last_frame_offset = s->cur_offset + index; | |
| 106 /* find the packet in which the new frame starts. It | |
| 107 is tricky because of MPEG video start codes | |
| 108 which can begin in one packet and finish in | |
| 109 another packet. In the worst case, an MPEG | |
| 110 video start code could be in 4 different | |
| 111 packets. */ | |
| 112 k = s->cur_frame_start_index; | |
| 113 for(i = 0; i < AV_PARSER_PTS_NB; i++) { | |
| 114 if (s->last_frame_offset >= s->cur_frame_offset[k]) | |
| 115 break; | |
| 116 k = (k - 1) & (AV_PARSER_PTS_NB - 1); | |
| 117 } | |
| 118 s->last_pts = s->cur_frame_pts[k]; | |
| 119 s->last_dts = s->cur_frame_dts[k]; | |
| 120 } | |
| 121 if (index < 0) | |
| 122 index = 0; | |
| 123 s->cur_offset += index; | |
| 124 return index; | |
| 125 } | |
| 126 | |
| 127 void av_parser_close(AVCodecParserContext *s) | |
| 128 { | |
| 129 if (s->parser->parser_close) | |
| 130 s->parser->parser_close(s); | |
| 131 | |
| 132 free(s->priv_data); | |
| 133 free(s); | |
| 134 } | |
| 135 |
