Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. /*
  2. * Copyright (c) 2013 Nicolas George
  3. *
  4. * This file is part of FFmpeg.
  5. *
  6. * FFmpeg is free software; you can redistribute it and/or
  7. * modify it under the terms of the GNU Lesser General Public License
  8. * as published by the Free Software Foundation; either
  9. * version 2.1 of the License, or (at your option) any later version.
  10. *
  11. * FFmpeg 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
  14. * GNU Lesser General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU Lesser General Public License
  17. * along with FFmpeg; if not, write to the Free Software Foundation, Inc.,
  18. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  19. */
  20.  
  21. #include "libavutil/adler32.h"
  22. #include "libavutil/avassert.h"
  23. #include "libavutil/bprint.h"
  24. #include "libavutil/imgutils.h"
  25. #include "libavutil/pixdesc.h"
  26. #include "avformat.h"
  27. #include "internal.h"
  28.  
  29. /* Identical to Adler32 when the type is uint8_t. */
  30. #define DEFINE_CKSUM_LINE(name, type, conv) \
  31. static void cksum_line_ ## name(unsigned *cksum, void *data, unsigned size) \
  32. { \
  33.     type *p = data; \
  34.     unsigned a = *cksum & 0xFFFF, b = *cksum >> 16; \
  35.     for (; size > 0; size--, p++) { \
  36.         a = (a + (unsigned)(conv)) % 65521; \
  37.         b = (b + a) % 65521; \
  38.     } \
  39.     *cksum = a | (b << 16); \
  40. }
  41.  
  42. DEFINE_CKSUM_LINE(u8,  uint8_t, *p)
  43. DEFINE_CKSUM_LINE(s16, int16_t, *p + 0x8000)
  44. DEFINE_CKSUM_LINE(s32, int32_t, *p + 0x80000000)
  45. DEFINE_CKSUM_LINE(flt, float,   *p * 0x80000000 + 0x80000000)
  46. DEFINE_CKSUM_LINE(dbl, double,  *p * 0x80000000 + 0x80000000)
  47.  
  48. static void video_frame_cksum(AVBPrint *bp, AVFrame *frame)
  49. {
  50.     const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(frame->format);
  51.     int i, y;
  52.     uint8_t *data;
  53.     int linesize[5] = { 0 };
  54.  
  55.     av_bprintf(bp, ", %d x %d", frame->width, frame->height);
  56.     if (!desc) {
  57.         av_bprintf(bp, ", unknown");
  58.         return;
  59.     }
  60.     if (av_image_fill_linesizes(linesize, frame->format, frame->width) < 0)
  61.         return;
  62.     av_bprintf(bp, ", %s", desc->name);
  63.     for (i = 0; linesize[i]; i++) {
  64.         unsigned cksum = 0;
  65.         int h = frame->height;
  66.         if ((i == 1 || i == 2) && desc->nb_components >= 3)
  67.             h = -((-h) >> desc->log2_chroma_h);
  68.         data = frame->data[i];
  69.         for (y = 0; y < h; y++) {
  70.             cksum = av_adler32_update(cksum, data, linesize[i]);
  71.             data += frame->linesize[i];
  72.         }
  73.         av_bprintf(bp, ", 0x%08x", cksum);
  74.     }
  75. }
  76.  
  77. static void audio_frame_cksum(AVBPrint *bp, AVFrame *frame)
  78. {
  79.     int nb_planes, nb_samples, p;
  80.     const char *name;
  81.  
  82.     nb_planes  = av_frame_get_channels(frame);
  83.     nb_samples = frame->nb_samples;
  84.     if (!av_sample_fmt_is_planar(frame->format)) {
  85.         nb_samples *= nb_planes;
  86.         nb_planes = 1;
  87.     }
  88.     name = av_get_sample_fmt_name(frame->format);
  89.     av_bprintf(bp, ", %d samples", frame->nb_samples);
  90.     av_bprintf(bp, ", %s", name ? name : "unknown");
  91.     for (p = 0; p < nb_planes; p++) {
  92.         uint32_t cksum = 0;
  93.         void *d = frame->extended_data[p];
  94.         switch (frame->format) {
  95.         case AV_SAMPLE_FMT_U8:
  96.         case AV_SAMPLE_FMT_U8P:
  97.             cksum_line_u8(&cksum, d, nb_samples);
  98.             break;
  99.         case AV_SAMPLE_FMT_S16:
  100.         case AV_SAMPLE_FMT_S16P:
  101.             cksum_line_s16(&cksum, d, nb_samples);
  102.             break;
  103.         case AV_SAMPLE_FMT_S32:
  104.         case AV_SAMPLE_FMT_S32P:
  105.             cksum_line_s32(&cksum, d, nb_samples);
  106.             break;
  107.         case AV_SAMPLE_FMT_FLT:
  108.         case AV_SAMPLE_FMT_FLTP:
  109.             cksum_line_flt(&cksum, d, nb_samples);
  110.             break;
  111.         case AV_SAMPLE_FMT_DBL:
  112.         case AV_SAMPLE_FMT_DBLP:
  113.             cksum_line_dbl(&cksum, d, nb_samples);
  114.             break;
  115.         default:
  116.             av_assert0(!"reached");
  117.         }
  118.         av_bprintf(bp, ", 0x%08x", cksum);
  119.     }
  120. }
  121.  
  122. static int write_frame(struct AVFormatContext *s, int stream_index,
  123.                        AVFrame **frame, unsigned flags)
  124. {
  125.     AVBPrint bp;
  126.     int ret = 0;
  127.     enum AVMediaType type;
  128.     const char *type_name;
  129.  
  130.     if ((flags & AV_WRITE_UNCODED_FRAME_QUERY))
  131.         return 0;
  132.  
  133.     av_bprint_init(&bp, 0, AV_BPRINT_SIZE_UNLIMITED);
  134.     av_bprintf(&bp, "%d, %10"PRId64"",
  135.                stream_index, (*frame)->pts);
  136.     type = s->streams[stream_index]->codec->codec_type;
  137.     type_name = av_get_media_type_string(type);
  138.     av_bprintf(&bp, ", %s", type_name ? type_name : "unknown");
  139.     switch (type) {
  140.         case AVMEDIA_TYPE_VIDEO:
  141.             video_frame_cksum(&bp, *frame);
  142.             break;
  143.         case AVMEDIA_TYPE_AUDIO:
  144.             audio_frame_cksum(&bp, *frame);
  145.             break;
  146.     }
  147.  
  148.     av_bprint_chars(&bp, '\n', 1);
  149.     if (av_bprint_is_complete(&bp))
  150.         avio_write(s->pb, bp.str, bp.len);
  151.     else
  152.         ret = AVERROR(ENOMEM);
  153.     av_bprint_finalize(&bp, NULL);
  154.     return ret;
  155. }
  156.  
  157. static int write_packet(struct AVFormatContext *s, AVPacket *pkt)
  158. {
  159.     return AVERROR(ENOSYS);
  160. }
  161.  
  162. AVOutputFormat ff_uncodedframecrc_muxer = {
  163.     .name              = "uncodedframecrc",
  164.     .long_name         = NULL_IF_CONFIG_SMALL("uncoded framecrc testing"),
  165.     .audio_codec       = AV_CODEC_ID_PCM_S16LE,
  166.     .video_codec       = AV_CODEC_ID_RAWVIDEO,
  167.     .write_header      = ff_framehash_write_header,
  168.     .write_packet      = write_packet,
  169.     .write_uncoded_frame = write_frame,
  170.     .flags             = AVFMT_VARIABLE_FPS | AVFMT_TS_NONSTRICT |
  171.                          AVFMT_TS_NEGATIVE,
  172. };
  173.