FFmpeg
dv_error_marker.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2022 Michael Niedermayer
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
8  * License 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 GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with FFmpeg; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19  */
20 
21 #include "bsf.h"
22 #include "bsf_internal.h"
23 #include "libavutil/colorspace.h"
24 #include "libavutil/intreadwrite.h"
25 #include "libavutil/opt.h"
26 
27 typedef struct DVErrorMarkerContext {
28  const AVClass *class;
29  uint8_t color_rgba[4];
30  int sta;
31  uint8_t marked_block[76];
33 
34 static void setdc(uint8_t *b, const uint8_t color_rgba[4], int cblocks, int y_step, int v_step, int u_step) {
35  for (int i=0; i<4; i++) {
36  b[0] = RGB_TO_Y_JPEG(color_rgba[0], color_rgba[1],color_rgba[2]) + 128;
37  b[1] = 0x06;
38  b += y_step;
39  }
40  for (int i=0; i<cblocks; i++) {
41  b[0] = RGB_TO_V_JPEG(color_rgba[0], color_rgba[1],color_rgba[2]) - 128;
42  b[1] = 0x16;
43  b += v_step;
44  }
45  for (int i=0; i<cblocks; i++) {
46  b[0] = RGB_TO_U_JPEG(color_rgba[0], color_rgba[1],color_rgba[2]) - 128;
47  b[1] = 0x16;
48  b += u_step;
49  }
50 }
51 
53 {
55 
56  memset(s->marked_block, -1, 76);
57  setdc(s->marked_block, s->color_rgba, 1, 14, 10, 10);
58  setdc(s->marked_block, s->color_rgba, 2, 10, 10, 8);
59 
60  return 0;
61 }
62 
64 {
67  uint8_t *p;
68  int writable = 0;
69  int stamask = s->sta;
70  int match_count = 0;
71 
72  if (ret < 0)
73  return ret;
74 
75  p = pkt->data;
76  for(int i = 0; i < pkt->size - 79; i+=80) {
77  // see page 44-46 or section 5.5 of http://web.archive.org/web/20060927044735/http://www.smpte.org/smpte_store/standards/pdf/s314m.pdf.
78  if ((p[i] >> 4) == 9 && ((stamask >> (p[i+3] >> 4))&1)) {
79  if (!writable) {
81  if (ret < 0) {
83  return ret;
84  }
85  writable = 1;
86  p = pkt->data;
87  }
88  memcpy(p+i+4, s->marked_block, 76);
89  match_count ++;
90  }
91  }
92  av_log(ctx, AV_LOG_DEBUG, "%8"PRId64": Replaced %5d blocks by color %X\n", pkt->pts, match_count, AV_RB32(s->color_rgba));
93 
94  return 0;
95 }
96 
97 #define OFFSET(x) offsetof(DVErrorMarkerContext, x)
98 #define FLAGS (AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_BSF_PARAM)
99 static const AVOption options[] = {
100  { "color" , "set color", OFFSET(color_rgba), AV_OPT_TYPE_COLOR, {.str = "yellow"}, 0, 0, FLAGS },
101  { "sta" , "specify which error status value to match"
102  , OFFSET(sta ), AV_OPT_TYPE_FLAGS, {.i64 = 0xFFFE}, 0, 0xFFFF, FLAGS, .unit = "sta" },
103  { "ok" , "No error, no concealment", 0, AV_OPT_TYPE_CONST, {.i64 = 0x0001}, 0, 0xFFFF, FLAGS, .unit = "sta"},
104  { "Aa" , "No error, concealment from previous frame type a",0, AV_OPT_TYPE_CONST, {.i64 = 0x0004}, 0, 0xFFFF, FLAGS, .unit = "sta"},
105  { "Ba" , "No error, concealment from next frame type a", 0, AV_OPT_TYPE_CONST, {.i64 = 0x0010}, 0, 0xFFFF, FLAGS, .unit = "sta"},
106  { "Ca" , "No error, unspecified concealment type a", 0, AV_OPT_TYPE_CONST, {.i64 = 0x0040}, 0, 0xFFFF, FLAGS, .unit = "sta"},
107  { "erri" , "Error with inserted code, No concealment", 0, AV_OPT_TYPE_CONST, {.i64 = 0x0080}, 0, 0xFFFF, FLAGS, .unit = "sta"},
108  { "erru" , "Error with unidentified pos, No concealment", 0, AV_OPT_TYPE_CONST, {.i64 = 0x8000}, 0, 0xFFFF, FLAGS, .unit = "sta"},
109  { "err" , "Error, No concealment", 0, AV_OPT_TYPE_CONST, {.i64 = 0x8080}, 0, 0xFFFF, FLAGS, .unit = "sta"},
110  { "Ab" , "No error, concealment from previous frame type b",0, AV_OPT_TYPE_CONST, {.i64 = 0x0400}, 0, 0xFFFF, FLAGS, .unit = "sta"},
111  { "Bb" , "No error, concealment from next frame type b", 0, AV_OPT_TYPE_CONST, {.i64 = 0x1000}, 0, 0xFFFF, FLAGS, .unit = "sta"},
112  { "Cb" , "No error, unspecified concealment type b", 0, AV_OPT_TYPE_CONST, {.i64 = 0x4000}, 0, 0xFFFF, FLAGS, .unit = "sta"},
113  { "A" , "No error, concealment from previous frame", 0, AV_OPT_TYPE_CONST, {.i64 = 0x0404}, 0, 0xFFFF, FLAGS, .unit = "sta"},
114  { "B" , "No error, concealment from next frame", 0, AV_OPT_TYPE_CONST, {.i64 = 0x1010}, 0, 0xFFFF, FLAGS, .unit = "sta"},
115  { "C" , "No error, unspecified concealment", 0, AV_OPT_TYPE_CONST, {.i64 = 0x4040}, 0, 0xFFFF, FLAGS, .unit = "sta"},
116  { "a" , "No error, concealment type a", 0, AV_OPT_TYPE_CONST, {.i64 = 0x0054}, 0, 0xFFFF, FLAGS, .unit = "sta"},
117  { "b" , "No error, concealment type b", 0, AV_OPT_TYPE_CONST, {.i64 = 0x5400}, 0, 0xFFFF, FLAGS, .unit = "sta"},
118  { "res" , "Reserved", 0, AV_OPT_TYPE_CONST, {.i64 = 0x2B2A}, 0, 0xFFFF, FLAGS, .unit = "sta"},
119  { "notok" , "Error or concealment", 0, AV_OPT_TYPE_CONST, {.i64 = 0xD4D4}, 0, 0xFFFF, FLAGS, .unit = "sta"},
120  { "notres" , "Not reserved", 0, AV_OPT_TYPE_CONST, {.i64 = 0xD4D5}, 0, 0xFFFF, FLAGS, .unit = "sta"},
121  { NULL },
122 };
123 
125  .class_name = "dv_error_marker",
126  .item_name = av_default_item_name,
127  .option = options,
128  .version = LIBAVUTIL_VERSION_INT,
129 };
130 
132  .p.name = "dv_error_marker",
133  .p.codec_ids = (const enum AVCodecID []){ AV_CODEC_ID_DVVIDEO, AV_CODEC_ID_NONE },
134  .p.priv_class = &dv_error_marker_class,
135  .priv_data_size = sizeof(DVErrorMarkerContext),
138 };
setdc
static void setdc(uint8_t *b, const uint8_t color_rgba[4], int cblocks, int y_step, int v_step, int u_step)
Definition: dv_error_marker.c:34
av_packet_unref
void av_packet_unref(AVPacket *pkt)
Wipe the packet.
Definition: avpacket.c:427
opt.h
bsf_internal.h
RGB_TO_U_JPEG
#define RGB_TO_U_JPEG(r1, g1, b1)
Definition: colorspace.h:114
DVErrorMarkerContext
Definition: dv_error_marker.c:27
options
static const AVOption options[]
Definition: dv_error_marker.c:99
AVBitStreamFilter::name
const char * name
Definition: bsf.h:112
FLAGS
#define FLAGS
Definition: dv_error_marker.c:98
AVPacket::data
uint8_t * data
Definition: packet.h:522
AVOption
AVOption.
Definition: opt.h:346
b
#define b
Definition: input.c:41
filter
filter_frame For filters that do not use the this method is called when a frame is pushed to the filter s input It can be called at any time except in a reentrant way If the input frame is enough to produce then the filter should push the output frames on the output link immediately As an exception to the previous rule if the input frame is enough to produce several output frames then the filter needs output only at least one per link The additional frames can be left buffered in the filter
Definition: filter_design.txt:228
DVErrorMarkerContext::sta
int sta
Definition: dv_error_marker.c:30
AVBSFContext
The bitstream filter state.
Definition: bsf.h:68
ff_dv_error_marker_bsf
const FFBitStreamFilter ff_dv_error_marker_bsf
Definition: dv_error_marker.c:131
bsf.h
colorspace.h
pkt
AVPacket * pkt
Definition: movenc.c:59
RGB_TO_V_JPEG
#define RGB_TO_V_JPEG(r1, g1, b1)
Definition: colorspace.h:118
intreadwrite.h
s
#define s(width, name)
Definition: cbs_vp9.c:198
DVErrorMarkerContext::color_rgba
uint8_t color_rgba[4]
Definition: dv_error_marker.c:29
AV_LOG_DEBUG
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition: log.h:201
ctx
AVFormatContext * ctx
Definition: movenc.c:48
LIBAVUTIL_VERSION_INT
#define LIBAVUTIL_VERSION_INT
Definition: version.h:85
AVClass
Describe the class of an AVClass context structure.
Definition: log.h:66
NULL
#define NULL
Definition: coverity.c:32
FFBitStreamFilter
Definition: bsf_internal.h:27
AV_OPT_TYPE_COLOR
@ AV_OPT_TYPE_COLOR
Definition: opt.h:250
av_default_item_name
const char * av_default_item_name(void *ptr)
Return the context name.
Definition: log.c:237
AVCodecID
AVCodecID
Identify the syntax and semantics of the bitstream.
Definition: codec_id.h:49
FFBitStreamFilter::p
AVBitStreamFilter p
The public AVBitStreamFilter.
Definition: bsf_internal.h:31
init
int(* init)(AVBSFContext *ctx)
Definition: dts2pts.c:365
AVPacket::size
int size
Definition: packet.h:523
dv_error_marker_init
static int dv_error_marker_init(AVBSFContext *ctx)
Definition: dv_error_marker.c:52
AV_RB32
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_WL32 unsigned int_TMPL AV_WL24 unsigned int_TMPL AV_WL16 uint64_t_TMPL AV_WB64 unsigned int_TMPL AV_RB32
Definition: bytestream.h:96
AV_CODEC_ID_NONE
@ AV_CODEC_ID_NONE
Definition: codec_id.h:50
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:255
AVPacket::pts
int64_t pts
Presentation timestamp in AVStream->time_base units; the time at which the decompressed packet will b...
Definition: packet.h:515
OFFSET
#define OFFSET(x)
Definition: dv_error_marker.c:97
AV_CODEC_ID_DVVIDEO
@ AV_CODEC_ID_DVVIDEO
Definition: codec_id.h:76
ret
ret
Definition: filter_design.txt:187
AVClass::class_name
const char * class_name
The name of the class; usually it is the same name as the context structure type to which the AVClass...
Definition: log.h:71
dv_error_marker_class
static const AVClass dv_error_marker_class
Definition: dv_error_marker.c:124
av_packet_make_writable
int av_packet_make_writable(AVPacket *pkt)
Create a writable reference for the data described by a given packet, avoiding data copy if possible.
Definition: avpacket.c:509
dv_error_marker_filter
static int dv_error_marker_filter(AVBSFContext *ctx, AVPacket *pkt)
Definition: dv_error_marker.c:63
AVPacket
This structure stores compressed data.
Definition: packet.h:499
AV_OPT_TYPE_FLAGS
@ AV_OPT_TYPE_FLAGS
Definition: opt.h:234
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:27
ff_bsf_get_packet_ref
int ff_bsf_get_packet_ref(AVBSFContext *ctx, AVPacket *pkt)
Called by bitstream filters to get packet for filtering.
Definition: bsf.c:256
DVErrorMarkerContext::marked_block
uint8_t marked_block[76]
Definition: dv_error_marker.c:31
AV_OPT_TYPE_CONST
@ AV_OPT_TYPE_CONST
Definition: opt.h:244
AVFormatContext::priv_data
void * priv_data
Format private data.
Definition: avformat.h:1283
RGB_TO_Y_JPEG
#define RGB_TO_Y_JPEG(r, g, b)
Definition: colorspace.h:110