00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00027 #include "parser.h"
00028 #include "libavutil/intreadwrite.h"
00029
00030 typedef struct {
00031 ParseContext pc;
00032 int64_t key_dts;
00033 int key_pts;
00034 } RV34ParseContext;
00035
00036 static const int rv_to_av_frame_type[4] = {
00037 AV_PICTURE_TYPE_I, AV_PICTURE_TYPE_I, AV_PICTURE_TYPE_P, AV_PICTURE_TYPE_B,
00038 };
00039
00040 static int rv34_parse(AVCodecParserContext *s,
00041 AVCodecContext *avctx,
00042 const uint8_t **poutbuf, int *poutbuf_size,
00043 const uint8_t *buf, int buf_size)
00044 {
00045 RV34ParseContext *pc = s->priv_data;
00046 int type, pts, hdr;
00047
00048 if (buf_size < 13 + *buf * 8) {
00049 *poutbuf = buf;
00050 *poutbuf_size = buf_size;
00051 return buf_size;
00052 }
00053
00054 hdr = AV_RB32(buf + 9 + *buf * 8);
00055 if (avctx->codec_id == CODEC_ID_RV30) {
00056 type = (hdr >> 27) & 3;
00057 pts = (hdr >> 7) & 0x1FFF;
00058 } else {
00059 type = (hdr >> 29) & 3;
00060 pts = (hdr >> 6) & 0x1FFF;
00061 }
00062
00063 if (type != 3 && s->pts != AV_NOPTS_VALUE) {
00064 pc->key_dts = s->pts;
00065 pc->key_pts = pts;
00066 } else {
00067 if (type != 3)
00068 s->pts = pc->key_dts + ((pts - pc->key_pts) & 0x1FFF);
00069 else
00070 s->pts = pc->key_dts - ((pc->key_pts - pts) & 0x1FFF);
00071 }
00072 s->pict_type = rv_to_av_frame_type[type];
00073
00074 *poutbuf = buf;
00075 *poutbuf_size = buf_size;
00076 return buf_size;
00077 }
00078
00079 #if CONFIG_RV30_PARSER
00080 AVCodecParser ff_rv30_parser = {
00081 .codec_ids = { CODEC_ID_RV30 },
00082 .priv_data_size = sizeof(RV34ParseContext),
00083 .parser_parse = rv34_parse,
00084 };
00085 #endif
00086
00087 #if CONFIG_RV40_PARSER
00088 AVCodecParser ff_rv40_parser = {
00089 .codec_ids = { CODEC_ID_RV40 },
00090 .priv_data_size = sizeof(RV34ParseContext),
00091 .parser_parse = rv34_parse,
00092 };
00093 #endif