00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00027 #include "avformat.h"
00028 #include "bswap.h"
00029
00030 #define MTV_ASUBCHUNK_DATA_SIZE 500
00031 #define MTV_HEADER_SIZE 512
00032 #define MTV_AUDIO_PADDING_SIZE 12
00033 #define AUDIO_SAMPLING_RATE 44100
00034 #define VIDEO_SID 0
00035 #define AUDIO_SID 1
00036
00037 typedef struct MTVDemuxContext {
00038
00039 unsigned int file_size;
00040 unsigned int segments;
00041 unsigned int audio_identifier;
00042 unsigned int audio_br;
00043 unsigned int img_colorfmt;
00044 unsigned int img_bpp;
00045 unsigned int img_width;
00046 unsigned int img_height;
00047 unsigned int img_segment_size;
00048 unsigned int video_fps;
00049 unsigned int audio_subsegments;
00050
00051 uint8_t audio_packet_count;
00052
00053 } MTVDemuxContext;
00054
00055 static int mtv_probe(AVProbeData *p)
00056 {
00057
00058
00059 if(*(p->buf) != 'A' || *(p->buf+1) != 'M' || *(p->buf+2) != 'V')
00060 return 0;
00061
00062 return AVPROBE_SCORE_MAX;
00063 }
00064
00065 static int mtv_read_header(AVFormatContext *s, AVFormatParameters *ap)
00066 {
00067 MTVDemuxContext *mtv = s->priv_data;
00068 ByteIOContext *pb = s->pb;
00069 AVStream *st;
00070
00071
00072 url_fskip(pb, 3);
00073 mtv->file_size = get_le32(pb);
00074 mtv->segments = get_le32(pb);
00075 url_fskip(pb, 32);
00076 mtv->audio_identifier = get_le24(pb);
00077 mtv->audio_br = get_le16(pb);
00078 mtv->img_colorfmt = get_le24(pb);
00079 mtv->img_bpp = get_byte(pb);
00080 mtv->img_width = get_le16(pb);
00081 mtv->img_height = get_le16(pb);
00082 mtv->img_segment_size = get_le16(pb);
00083 url_fskip(pb, 4);
00084 mtv->audio_subsegments = get_le16(pb);
00085 mtv->video_fps = (mtv->audio_br / 4) / mtv->audio_subsegments;
00086
00087
00088
00089
00090
00091 mtv->audio_packet_count = 1;
00092
00093
00094
00095
00096
00097 st = av_new_stream(s, VIDEO_SID);
00098 if(!st)
00099 return AVERROR(ENOMEM);
00100
00101 av_set_pts_info(st, 64, 1, mtv->video_fps);
00102 st->codec->codec_type = CODEC_TYPE_VIDEO;
00103 st->codec->codec_id = CODEC_ID_RAWVIDEO;
00104 st->codec->codec_tag = MKTAG('R', 'G', 'B', mtv->img_bpp);
00105 st->codec->width = mtv->img_width;
00106 st->codec->height = mtv->img_height;
00107 st->codec->bits_per_sample = mtv->img_bpp;
00108 st->codec->sample_rate = mtv->video_fps;
00109
00110
00111
00112 st = av_new_stream(s, AUDIO_SID);
00113 if(!st)
00114 return AVERROR(ENOMEM);
00115
00116 av_set_pts_info(st, 64, 1, AUDIO_SAMPLING_RATE);
00117 st->codec->codec_type = CODEC_TYPE_AUDIO;
00118 st->codec->codec_id = CODEC_ID_MP3;
00119 st->codec->bit_rate = mtv->audio_br;
00120 st->need_parsing = AVSTREAM_PARSE_FULL;
00121
00122
00123
00124 if(url_fseek(pb, MTV_HEADER_SIZE, SEEK_SET) != MTV_HEADER_SIZE)
00125 return AVERROR(EIO);
00126
00127 return(0);
00128
00129 }
00130
00131 static int mtv_read_packet(AVFormatContext *s, AVPacket *pkt)
00132 {
00133 MTVDemuxContext *mtv = s->priv_data;
00134 ByteIOContext *pb = s->pb;
00135 int ret;
00136 #ifndef WORDS_BIGENDIAN
00137 int i;
00138 #endif
00139
00140 ret = 0;
00141
00142 if(mtv->audio_subsegments >= mtv->audio_packet_count)
00143 {
00144 url_fskip(pb, MTV_AUDIO_PADDING_SIZE);
00145
00146 ret = av_get_packet(pb, pkt, MTV_ASUBCHUNK_DATA_SIZE);
00147 if(ret != MTV_ASUBCHUNK_DATA_SIZE)
00148 return AVERROR(EIO);
00149
00150 mtv->audio_packet_count++;
00151 pkt->stream_index = AUDIO_SID;
00152
00153 }else
00154 {
00155 ret = av_get_packet(pb, pkt, mtv->img_segment_size);
00156 if(ret != mtv->img_segment_size)
00157 return AVERROR(EIO);
00158
00159 #ifndef WORDS_BIGENDIAN
00160
00161
00162
00163
00164
00165
00166
00167 for(i=0;i<mtv->img_segment_size/2;i++)
00168 *((uint16_t *)pkt->data+i) = bswap_16(*((uint16_t *)pkt->data+i));
00169 #endif
00170 mtv->audio_packet_count = 1;
00171 pkt->stream_index = VIDEO_SID;
00172 }
00173
00174 return(ret);
00175 }
00176
00177 AVInputFormat mtv_demuxer = {
00178 "MTV",
00179 "MTV format",
00180 sizeof(MTVDemuxContext),
00181 mtv_probe,
00182 mtv_read_header,
00183 mtv_read_packet,
00184 };