Advertisement
Guest User

Untitled

a guest
Jun 25th, 2015
295
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 9.20 KB | None | 0 0
  1. .vp6 files may contain two video streams: one for the primary video
  2. stream and another for the alpha mask. The file format uses identical
  3. data structures for both streams.
  4.  
  5. Signed-off-by: Peter Ross <pross@xvid.org>
  6. ---
  7. libavformat/electronicarts.c | 136 +++++++++++++++++++++++++------------------
  8. 1 file changed, 80 insertions(+), 56 deletions(-)
  9.  
  10. diff --git a/libavformat/electronicarts.c b/libavformat/electronicarts.c
  11. index d999a0b..1c35e2d 100644
  12. --- a/libavformat/electronicarts.c
  13. +++ b/libavformat/electronicarts.c
  14. @@ -59,18 +59,25 @@
  15. #define MVhd_TAG MKTAG('M', 'V', 'h', 'd')
  16. #define MV0K_TAG MKTAG('M', 'V', '0', 'K')
  17. #define MV0F_TAG MKTAG('M', 'V', '0', 'F')
  18. +#define AVhd_TAG MKTAG('A', 'V', 'h', 'd')
  19. +#define AV0K_TAG MKTAG('A', 'V', '0', 'K')
  20. +#define AV0F_TAG MKTAG('A', 'V', '0', 'F')
  21. #define MVIh_TAG MKTAG('M', 'V', 'I', 'h') /* CMV header */
  22. #define MVIf_TAG MKTAG('M', 'V', 'I', 'f') /* CMV I-frame */
  23. #define AVP6_TAG MKTAG('A', 'V', 'P', '6')
  24.  
  25. -typedef struct EaDemuxContext {
  26. - int big_endian;
  27. -
  28. - enum AVCodecID video_codec;
  29. +typedef struct VideoProperties {
  30. + enum AVCodecID codec;
  31. AVRational time_base;
  32. int width, height;
  33. int nb_frames;
  34. - int video_stream_index;
  35. + int stream_index;
  36. +} VideoProperties;
  37. +
  38. +typedef struct EaDemuxContext {
  39. + int big_endian;
  40. +
  41. + VideoProperties video, alpha;
  42.  
  43. enum AVCodecID audio_codec;
  44. int audio_stream_index;
  45. @@ -302,46 +309,43 @@ static void process_audio_header_sead(AVFormatContext *s)
  46. ea->audio_codec = AV_CODEC_ID_ADPCM_IMA_EA_SEAD;
  47. }
  48.  
  49. -static void process_video_header_mdec(AVFormatContext *s)
  50. +static void process_video_header_mdec(AVFormatContext *s, VideoProperties *video)
  51. {
  52. - EaDemuxContext *ea = s->priv_data;
  53. AVIOContext *pb = s->pb;
  54. avio_skip(pb, 4);
  55. - ea->width = avio_rl16(pb);
  56. - ea->height = avio_rl16(pb);
  57. - ea->time_base = (AVRational) { 1, 15 };
  58. - ea->video_codec = AV_CODEC_ID_MDEC;
  59. + video->width = avio_rl16(pb);
  60. + video->height = avio_rl16(pb);
  61. + video->time_base = (AVRational) { 1, 15 };
  62. + video->codec = AV_CODEC_ID_MDEC;
  63. }
  64.  
  65. -static int process_video_header_vp6(AVFormatContext *s)
  66. +static int process_video_header_vp6(AVFormatContext *s, VideoProperties *video)
  67. {
  68. - EaDemuxContext *ea = s->priv_data;
  69. - AVIOContext *pb = s->pb;
  70. + AVIOContext *pb = s->pb;
  71.  
  72. avio_skip(pb, 8);
  73. - ea->nb_frames = avio_rl32(pb);
  74. + video->nb_frames = avio_rl32(pb);
  75. avio_skip(pb, 4);
  76. - ea->time_base.den = avio_rl32(pb);
  77. - ea->time_base.num = avio_rl32(pb);
  78. - if (ea->time_base.den <= 0 || ea->time_base.num <= 0) {
  79. + video->time_base.den = avio_rl32(pb);
  80. + video->time_base.num = avio_rl32(pb);
  81. + if (video->time_base.den <= 0 || video->time_base.num <= 0) {
  82. av_log(s, AV_LOG_ERROR, "Timebase is invalid\n");
  83. return AVERROR_INVALIDDATA;
  84. }
  85. - ea->video_codec = AV_CODEC_ID_VP6;
  86. + video->codec = AV_CODEC_ID_VP6;
  87.  
  88. return 1;
  89. }
  90.  
  91. -static void process_video_header_cmv(AVFormatContext *s)
  92. +static void process_video_header_cmv(AVFormatContext *s, VideoProperties *video)
  93. {
  94. - EaDemuxContext *ea = s->priv_data;
  95. int fps;
  96.  
  97. avio_skip(s->pb, 10);
  98. fps = avio_rl16(s->pb);
  99. if (fps)
  100. - ea->time_base = (AVRational) { 1, fps };
  101. - ea->video_codec = AV_CODEC_ID_CMV;
  102. + video->time_base = (AVRational) { 1, fps };
  103. + video->codec = AV_CODEC_ID_CMV;
  104. }
  105.  
  106. /* Process EA file header.
  107. @@ -353,7 +357,7 @@ static int process_ea_header(AVFormatContext *s)
  108. AVIOContext *pb = s->pb;
  109. int i;
  110.  
  111. - for (i = 0; i < 5 && (!ea->audio_codec || !ea->video_codec); i++) {
  112. + for (i = 0; i < 5 && (!ea->audio_codec || !ea->video.codec); i++) {
  113. uint64_t startpos = avio_tell(pb);
  114. int err = 0;
  115.  
  116. @@ -395,40 +399,44 @@ static int process_ea_header(AVFormatContext *s)
  117. break;
  118.  
  119. case MVIh_TAG:
  120. - process_video_header_cmv(s);
  121. + process_video_header_cmv(s, &ea->video);
  122. break;
  123.  
  124. case kVGT_TAG:
  125. - ea->video_codec = AV_CODEC_ID_TGV;
  126. + ea->video.codec = AV_CODEC_ID_TGV;
  127. break;
  128.  
  129. case mTCD_TAG:
  130. - process_video_header_mdec(s);
  131. + process_video_header_mdec(s, &ea->video);
  132. break;
  133.  
  134. case MPCh_TAG:
  135. - ea->video_codec = AV_CODEC_ID_MPEG2VIDEO;
  136. + ea->video.codec = AV_CODEC_ID_MPEG2VIDEO;
  137. break;
  138.  
  139. case pQGT_TAG:
  140. case TGQs_TAG:
  141. - ea->video_codec = AV_CODEC_ID_TGQ;
  142. - ea->time_base = (AVRational) { 1, 15 };
  143. + ea->video.codec = AV_CODEC_ID_TGQ;
  144. + ea->video.time_base = (AVRational) { 1, 15 };
  145. break;
  146.  
  147. case pIQT_TAG:
  148. - ea->video_codec = AV_CODEC_ID_TQI;
  149. - ea->time_base = (AVRational) { 1, 15 };
  150. + ea->video.codec = AV_CODEC_ID_TQI;
  151. + ea->video.time_base = (AVRational) { 1, 15 };
  152. break;
  153.  
  154. case MADk_TAG:
  155. - ea->video_codec = AV_CODEC_ID_MAD;
  156. + ea->video.codec = AV_CODEC_ID_MAD;
  157. avio_skip(pb, 6);
  158. - ea->time_base = (AVRational) { avio_rl16(pb), 1000 };
  159. + ea->video.time_base = (AVRational) { avio_rl16(pb), 1000 };
  160. break;
  161.  
  162. case MVhd_TAG:
  163. - err = process_video_header_vp6(s);
  164. + err = process_video_header_vp6(s, &ea->video);
  165. + break;
  166. +
  167. + case AVhd_TAG:
  168. + err = process_video_header_vp6(s, &ea->alpha);
  169. break;
  170. }
  171.  
  172. @@ -458,6 +466,7 @@ static int ea_probe(AVProbeData *p)
  173. case MADk_TAG:
  174. case MPCh_TAG:
  175. case MVhd_TAG:
  176. + case AVhd_TAG:
  177. case MVIh_TAG:
  178. case AVP6_TAG:
  179. break;
  180. @@ -474,6 +483,34 @@ static int ea_probe(AVProbeData *p)
  181. return AVPROBE_SCORE_MAX;
  182. }
  183.  
  184. +static int init_video_stream(AVFormatContext *s, VideoProperties *video)
  185. +{
  186. + AVStream *st;
  187. +
  188. + if (!video->codec)
  189. + return 0;
  190. +
  191. + /* initialize the video decoder stream */
  192. + st = avformat_new_stream(s, NULL);
  193. + if (!st)
  194. + return AVERROR(ENOMEM);
  195. + video->stream_index = st->index;
  196. + st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
  197. + st->codec->codec_id = video->codec;
  198. + // parsing is necessary to make FFmpeg generate correct timestamps
  199. + if (st->codec->codec_id == AV_CODEC_ID_MPEG2VIDEO)
  200. + st->need_parsing = AVSTREAM_PARSE_HEADERS;
  201. + st->codec->codec_tag = 0; /* no fourcc */
  202. + st->codec->width = video->width;
  203. + st->codec->height = video->height;
  204. + st->duration = st->nb_frames = video->nb_frames;
  205. + if (video->time_base.num)
  206. + avpriv_set_pts_info(st, 64, video->time_base.num, video->time_base.den);
  207. + st->r_frame_rate =
  208. + st->avg_frame_rate = av_inv_q(video->time_base);
  209. + return 0;
  210. +}
  211. +
  212. static int ea_read_header(AVFormatContext *s)
  213. {
  214. EaDemuxContext *ea = s->priv_data;
  215. @@ -482,26 +519,8 @@ static int ea_read_header(AVFormatContext *s)
  216. if (process_ea_header(s)<=0)
  217. return AVERROR(EIO);
  218.  
  219. - if (ea->video_codec) {
  220. - /* initialize the video decoder stream */
  221. - st = avformat_new_stream(s, NULL);
  222. - if (!st)
  223. - return AVERROR(ENOMEM);
  224. - ea->video_stream_index = st->index;
  225. - st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
  226. - st->codec->codec_id = ea->video_codec;
  227. - // parsing is necessary to make FFmpeg generate correct timestamps
  228. - if (st->codec->codec_id == AV_CODEC_ID_MPEG2VIDEO)
  229. - st->need_parsing = AVSTREAM_PARSE_HEADERS;
  230. - st->codec->codec_tag = 0; /* no fourcc */
  231. - st->codec->width = ea->width;
  232. - st->codec->height = ea->height;
  233. - st->duration = st->nb_frames = ea->nb_frames;
  234. - if (ea->time_base.num)
  235. - avpriv_set_pts_info(st, 64, ea->time_base.num, ea->time_base.den);
  236. - st->r_frame_rate =
  237. - st->avg_frame_rate = av_inv_q(ea->time_base);
  238. - }
  239. + if (init_video_stream(s, &ea->video) || init_video_stream(s, &ea->alpha))
  240. + return AVERROR(ENOMEM);
  241.  
  242. if (ea->audio_codec) {
  243. if (ea->num_channels <= 0 || ea->num_channels > 2) {
  244. @@ -661,10 +680,12 @@ static int ea_read_packet(AVFormatContext *s, AVPacket *pkt)
  245. goto get_video_packet;
  246.  
  247. case MV0K_TAG:
  248. + case AV0K_TAG:
  249. case MPCh_TAG:
  250. case pIQT_TAG:
  251. key = AV_PKT_FLAG_KEY;
  252. case MV0F_TAG:
  253. + case AV0F_TAG:
  254. get_video_packet:
  255. if (!chunk_size)
  256. continue;
  257. @@ -678,7 +699,10 @@ get_video_packet:
  258. break;
  259. }
  260. partial_packet = chunk_type == MVIh_TAG;
  261. - pkt->stream_index = ea->video_stream_index;
  262. + if (chunk_type == AV0K_TAG || chunk_type == AV0F_TAG)
  263. + pkt->stream_index = ea->alpha.stream_index;
  264. + else
  265. + pkt->stream_index = ea->video.stream_index;
  266. pkt->flags |= key;
  267. packet_read = 1;
  268. break;
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement