00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "libavutil/md5.h"
00023 #include "avformat.h"
00024 #include "internal.h"
00025
00026 struct MD5Context {
00027 struct AVMD5 *md5;
00028 };
00029
00030 static void md5_finish(struct AVFormatContext *s, char *buf)
00031 {
00032 struct MD5Context *c = s->priv_data;
00033 uint8_t md5[16];
00034 int i, offset = strlen(buf);
00035 av_md5_final(c->md5, md5);
00036 for (i = 0; i < sizeof(md5); i++) {
00037 snprintf(buf + offset, 3, "%02"PRIx8, md5[i]);
00038 offset += 2;
00039 }
00040 buf[offset] = '\n';
00041 buf[offset+1] = 0;
00042
00043 avio_write(s->pb, buf, strlen(buf));
00044 avio_flush(s->pb);
00045 }
00046
00047 #if CONFIG_MD5_MUXER
00048 static int write_header(struct AVFormatContext *s)
00049 {
00050 struct MD5Context *c = s->priv_data;
00051 c->md5 = av_md5_alloc();
00052 if (!c->md5)
00053 return AVERROR(ENOMEM);
00054 av_md5_init(c->md5);
00055 return 0;
00056 }
00057
00058 static int write_packet(struct AVFormatContext *s, AVPacket *pkt)
00059 {
00060 struct MD5Context *c = s->priv_data;
00061 av_md5_update(c->md5, pkt->data, pkt->size);
00062 return 0;
00063 }
00064
00065 static int write_trailer(struct AVFormatContext *s)
00066 {
00067 struct MD5Context *c = s->priv_data;
00068 char buf[64] = "MD5=";
00069
00070 md5_finish(s, buf);
00071
00072 av_freep(&c->md5);
00073 return 0;
00074 }
00075
00076 AVOutputFormat ff_md5_muxer = {
00077 .name = "md5",
00078 .long_name = NULL_IF_CONFIG_SMALL("MD5 testing"),
00079 .priv_data_size = sizeof(struct MD5Context),
00080 .audio_codec = AV_CODEC_ID_PCM_S16LE,
00081 .video_codec = AV_CODEC_ID_RAWVIDEO,
00082 .write_header = write_header,
00083 .write_packet = write_packet,
00084 .write_trailer = write_trailer,
00085 .flags = AVFMT_NOTIMESTAMPS,
00086 };
00087 #endif
00088
00089 #if CONFIG_FRAMEMD5_MUXER
00090 static int framemd5_write_header(struct AVFormatContext *s)
00091 {
00092 struct MD5Context *c = s->priv_data;
00093 c->md5 = av_md5_alloc();
00094 if (!c->md5)
00095 return AVERROR(ENOMEM);
00096 return ff_framehash_write_header(s);
00097 }
00098
00099 static int framemd5_write_packet(struct AVFormatContext *s, AVPacket *pkt)
00100 {
00101 struct MD5Context *c = s->priv_data;
00102 char buf[256];
00103 av_md5_init(c->md5);
00104 av_md5_update(c->md5, pkt->data, pkt->size);
00105
00106 snprintf(buf, sizeof(buf) - 64, "%d, %10"PRId64", %10"PRId64", %8d, %8d, ",
00107 pkt->stream_index, pkt->dts, pkt->pts, pkt->duration, pkt->size);
00108 md5_finish(s, buf);
00109 return 0;
00110 }
00111
00112 static int framemd5_write_trailer(struct AVFormatContext *s)
00113 {
00114 struct MD5Context *c = s->priv_data;
00115 av_freep(&c->md5);
00116 return 0;
00117 }
00118
00119 AVOutputFormat ff_framemd5_muxer = {
00120 .name = "framemd5",
00121 .long_name = NULL_IF_CONFIG_SMALL("Per-frame MD5 testing"),
00122 .priv_data_size = sizeof(struct MD5Context),
00123 .audio_codec = AV_CODEC_ID_PCM_S16LE,
00124 .video_codec = AV_CODEC_ID_RAWVIDEO,
00125 .write_header = framemd5_write_header,
00126 .write_packet = framemd5_write_packet,
00127 .write_trailer = framemd5_write_trailer,
00128 .flags = AVFMT_VARIABLE_FPS | AVFMT_TS_NONSTRICT,
00129 };
00130 #endif