Automatically add custom fields value to wordpress post

I think update_post_meta( $post_id, 'HD', $mydata ); has its arguments in the wrong order and should be update_post_meta( $post_id, 'quality', 'HD');

Alternatively where you need the custom field and it does not exist, why not just use “HD” as a default value? e.g.

global $post;
$theQuality = empty(get_post_meta( $post->ID, 'quality') ? 'HD' : get_post_meta( $post->ID, 'quality', true); 

Or, if you can’t get it to work on save, then try this in functions.php:

function my_add_default_cf() {
  global $post;
  if ( empty(get_post_meta( $post->ID, 'quality', true)) ) {
  // (if necessary) add additional conditional to limit which posts/pages are checked
    update_post_meta( $post->ID, 'quality', 'HD',true);
  }
}
add_action( 'pre_get_posts', 'my_add_default_cf' );

In theory inefficient as executed on every post but reality miniscule processing and unnoticeable.

Edit

I’ve removed the check for whether published (get_post_status( $post->ID ) == 'publish') from above code (my bad assumption).

Tested and works for me with WP 4.9.4. If a post/page does not already have cust field “quality” or it has no value, then it is added as “HD” in the following circumstances:
saving of draft or on publication; on opening existing post/page for edit; preview (although done, editor page won’t show it until refreshed); and when a published post with no, or empty, “quality” is visited.

If you don’t want this to retrospectively apply to previously published posts then change if ( empty(get_post_meta( $post->ID, 'quality', true)) ) { to

if (get_post_status( $post->ID ) == 'draft' &&  empty(get_post_meta( $post->ID, 'quality', true)) ) {

Additional testing/diagnostics (If needed, temporarily add this to functions.php):

function my_custfield_test($post_id) {
  global $post;
    ?>
  <meta name="mypostid" content="<?php echo $post->ID; ?>" />
  <meta name="mypoststatus" content="<?php echo get_post_status( $post->ID ); ?>" />
  <meta name="myquality" content="<?php echo get_post_meta( $post->ID,'quality', true); ?>" />
    <?php  
}
add_action( 'wp_head', 'my_custfield_test' );

Then view the HTML source of a live or preview page and somewhere in <head>:

HTML source

Your original code
I’m not familiar with save_post action maybe $post_id is not set? Within your ‘myplugin_save_postdata’ function: Try adding global $post; as the first line; and replace all occurences of $post_id by $post->ID.