framecrcenc.c 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191
  1. /*
  2. * frame CRC encoder (for codec/format testing)
  3. * Copyright (c) 2002 Fabrice Bellard
  4. *
  5. * This file is part of FFmpeg.
  6. *
  7. * FFmpeg is free software; you can redistribute it and/or
  8. * modify it under the terms of the GNU Lesser General Public
  9. * License as published by the Free Software Foundation; either
  10. * version 2.1 of the License, or (at your option) any later version.
  11. *
  12. * FFmpeg is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  15. * Lesser General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU Lesser General Public
  18. * License along with FFmpeg; if not, write to the Free Software
  19. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  20. */
  21. #include <inttypes.h>
  22. #include "config.h"
  23. #include "libavutil/adler32.h"
  24. #include "libavutil/avstring.h"
  25. #include "libavutil/hdr_dynamic_metadata.h"
  26. #include "libavutil/intreadwrite.h"
  27. #include "libavcodec/codec_id.h"
  28. #include "libavcodec/codec_par.h"
  29. #include "libavcodec/packet.h"
  30. #include "avformat.h"
  31. #include "internal.h"
  32. #include "mux.h"
  33. static int framecrc_write_header(struct AVFormatContext *s)
  34. {
  35. int i;
  36. for (i = 0; i < s->nb_streams; i++) {
  37. AVStream *st = s->streams[i];
  38. AVCodecParameters *par = st->codecpar;
  39. if (par->extradata) {
  40. uint32_t crc = av_adler32_update(0, par->extradata, par->extradata_size);
  41. avio_printf(s->pb, "#extradata %d: %8d, 0x%08"PRIx32"\n",
  42. i, par->extradata_size, crc);
  43. }
  44. }
  45. return ff_framehash_write_header(s);
  46. }
  47. av_unused static void inline bswap(char *buf, int offset, int size)
  48. {
  49. if (size == 8) {
  50. uint64_t val = AV_RN64(buf + offset);
  51. AV_WN64(buf + offset, av_bswap64(val));
  52. } else if (size == 4) {
  53. uint32_t val = AV_RN32(buf + offset);
  54. AV_WN32(buf + offset, av_bswap32(val));
  55. } else if (size == 2) {
  56. uint16_t val = AV_RN16(buf + offset);
  57. AV_WN16(buf + offset, av_bswap16(val));
  58. }
  59. }
  60. static int framecrc_write_packet(struct AVFormatContext *s, AVPacket *pkt)
  61. {
  62. uint32_t crc = av_adler32_update(0, pkt->data, pkt->size);
  63. char buf[256];
  64. snprintf(buf, sizeof(buf), "%d, %10"PRId64", %10"PRId64", %8"PRId64", %8d, 0x%08"PRIx32,
  65. pkt->stream_index, pkt->dts, pkt->pts, pkt->duration, pkt->size, crc);
  66. if (pkt->flags != AV_PKT_FLAG_KEY)
  67. av_strlcatf(buf, sizeof(buf), ", F=0x%0X", pkt->flags);
  68. if (pkt->side_data_elems) {
  69. av_strlcatf(buf, sizeof(buf), ", S=%d", pkt->side_data_elems);
  70. for (int i = 0; i < pkt->side_data_elems; i++) {
  71. const AVPacketSideData *const sd = &pkt->side_data[i];
  72. const uint8_t *data = sd->data;
  73. uint32_t side_data_crc = 0;
  74. switch (sd->type) {
  75. #if HAVE_BIGENDIAN
  76. uint8_t bswap_buf[FFMAX3(sizeof(AVCPBProperties),
  77. sizeof(AVProducerReferenceTime),
  78. sizeof(AVDynamicHDRPlus))];
  79. case AV_PKT_DATA_PALETTE:
  80. case AV_PKT_DATA_REPLAYGAIN:
  81. case AV_PKT_DATA_DISPLAYMATRIX:
  82. case AV_PKT_DATA_STEREO3D:
  83. case AV_PKT_DATA_AUDIO_SERVICE_TYPE:
  84. case AV_PKT_DATA_FALLBACK_TRACK:
  85. case AV_PKT_DATA_MASTERING_DISPLAY_METADATA:
  86. case AV_PKT_DATA_SPHERICAL:
  87. case AV_PKT_DATA_CONTENT_LIGHT_LEVEL:
  88. case AV_PKT_DATA_S12M_TIMECODE:
  89. for (size_t j = 0; j < sd->size / 4; j++) {
  90. uint8_t buf[4];
  91. AV_WL32(buf, AV_RB32(sd->data + 4 * j));
  92. side_data_crc = av_adler32_update(side_data_crc, buf, 4);
  93. }
  94. break;
  95. case AV_PKT_DATA_CPB_PROPERTIES:
  96. #define BSWAP(struct, field) bswap(bswap_buf, offsetof(struct, field), sizeof(((struct){0}).field))
  97. #define BSWAP_RAT(struct, field) do {BSWAP(struct, field.num); BSWAP(struct, field.den);} while(0)
  98. if (sd->size == sizeof(AVCPBProperties)) {
  99. memcpy(bswap_buf, sd->data, sizeof(AVCPBProperties));
  100. data = bswap_buf;
  101. BSWAP(AVCPBProperties, max_bitrate);
  102. BSWAP(AVCPBProperties, min_bitrate);
  103. BSWAP(AVCPBProperties, avg_bitrate);
  104. BSWAP(AVCPBProperties, buffer_size);
  105. BSWAP(AVCPBProperties, vbv_delay);
  106. }
  107. goto pod;
  108. case AV_PKT_DATA_PRFT:
  109. if (sd->size == sizeof(AVProducerReferenceTime)) {
  110. memcpy(bswap_buf, sd->data, sizeof(AVProducerReferenceTime));
  111. data = bswap_buf;
  112. BSWAP(AVProducerReferenceTime, wallclock);
  113. BSWAP(AVProducerReferenceTime, flags);
  114. }
  115. goto pod;
  116. case AV_PKT_DATA_DYNAMIC_HDR10_PLUS:
  117. if (sd->size == sizeof(AVDynamicHDRPlus)) {
  118. memcpy(bswap_buf, sd->data, sizeof(AVDynamicHDRPlus));
  119. data = bswap_buf;
  120. for (int i = 0; i < FF_ARRAY_ELEMS(((AVDynamicHDRPlus*)0)->params); i++) {
  121. BSWAP_RAT(AVDynamicHDRPlus, params[i].window_upper_left_corner_x);
  122. BSWAP_RAT(AVDynamicHDRPlus, params[i].window_upper_left_corner_y);
  123. BSWAP_RAT(AVDynamicHDRPlus, params[i].window_lower_right_corner_x);
  124. BSWAP_RAT(AVDynamicHDRPlus, params[i].window_lower_right_corner_y);
  125. BSWAP(AVDynamicHDRPlus, params[i].center_of_ellipse_x);
  126. BSWAP(AVDynamicHDRPlus, params[i].center_of_ellipse_y);
  127. BSWAP(AVDynamicHDRPlus, params[i].semimajor_axis_internal_ellipse);
  128. BSWAP(AVDynamicHDRPlus, params[i].semimajor_axis_external_ellipse);
  129. BSWAP(AVDynamicHDRPlus, params[i].semiminor_axis_external_ellipse);
  130. //!!! overlap_process_option
  131. for(int j = 0; j < FF_ARRAY_ELEMS(((AVDynamicHDRPlus*)0)->params->maxscl); j++)
  132. BSWAP_RAT(AVDynamicHDRPlus, params[i].maxscl[j]);
  133. BSWAP_RAT(AVDynamicHDRPlus, params[i].average_maxrgb);
  134. BSWAP_RAT(AVDynamicHDRPlus, params[i].fraction_bright_pixels);
  135. BSWAP_RAT(AVDynamicHDRPlus, params[i].knee_point_x);
  136. BSWAP_RAT(AVDynamicHDRPlus, params[i].knee_point_y);
  137. for(int j = 0; j < FF_ARRAY_ELEMS(((AVDynamicHDRPlus*)0)->params->distribution_maxrgb); j++) {
  138. BSWAP_RAT(AVDynamicHDRPlus, params[i].distribution_maxrgb[j].percentile);
  139. BSWAP_RAT(AVDynamicHDRPlus, params[i].bezier_curve_anchors[j]);
  140. }
  141. BSWAP_RAT(AVDynamicHDRPlus, params[i].color_saturation_weight);
  142. }
  143. BSWAP_RAT(AVDynamicHDRPlus, targeted_system_display_maximum_luminance);
  144. for(int i = 0; i<FF_ARRAY_ELEMS(((AVDynamicHDRPlus*)0)->targeted_system_display_actual_peak_luminance); i++)
  145. for(int j = 0; j<FF_ARRAY_ELEMS(((AVDynamicHDRPlus*)0)->targeted_system_display_actual_peak_luminance[0]); j++) {
  146. BSWAP_RAT(AVDynamicHDRPlus, targeted_system_display_actual_peak_luminance[i][j]);
  147. BSWAP_RAT(AVDynamicHDRPlus, mastering_display_actual_peak_luminance[i][j]);
  148. }
  149. }
  150. pod:
  151. #endif
  152. default:
  153. side_data_crc = av_adler32_update(0, data, sd->size);
  154. break;
  155. case AV_PKT_DATA_IAMF_MIX_GAIN_PARAM:
  156. case AV_PKT_DATA_IAMF_DEMIXING_INFO_PARAM:
  157. case AV_PKT_DATA_IAMF_RECON_GAIN_INFO_PARAM:
  158. side_data_crc = 0;
  159. }
  160. av_strlcatf(buf, sizeof(buf), ", %s, %8"SIZE_SPECIFIER", 0x%08"PRIx32,
  161. av_packet_side_data_name(sd->type), sd->size, side_data_crc);
  162. }
  163. }
  164. av_strlcatf(buf, sizeof(buf), "\n");
  165. avio_write(s->pb, buf, strlen(buf));
  166. return 0;
  167. }
  168. const FFOutputFormat ff_framecrc_muxer = {
  169. .p.name = "framecrc",
  170. .p.long_name = NULL_IF_CONFIG_SMALL("framecrc testing"),
  171. .p.audio_codec = AV_CODEC_ID_PCM_S16LE,
  172. .p.video_codec = AV_CODEC_ID_RAWVIDEO,
  173. .write_header = framecrc_write_header,
  174. .write_packet = framecrc_write_packet,
  175. .p.flags = AVFMT_VARIABLE_FPS | AVFMT_TS_NONSTRICT |
  176. AVFMT_TS_NEGATIVE | AVFMT_NODIMENSIONS,
  177. };